@forklaunch/implementation-iam-base 0.8.24 → 0.9.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.
@@ -11,20 +11,20 @@ import {
11
11
  UpdateOrganizationDto
12
12
  } from '@forklaunch/interfaces-iam/types';
13
13
  import { AnySchemaValidator } from '@forklaunch/validator';
14
- import { EntityManager } from '@mikro-orm/core';
14
+ import { EntityManager, FilterQuery, InferEntity } from '@mikro-orm/core';
15
15
  import { OrganizationDtos } from '../domain/types/iamDto.types';
16
16
  import { OrganizationEntities } from '../domain/types/iamEntities.types';
17
17
  import { OrganizationMappers } from '../domain/types/organization.mapper.types';
18
+ import { Organization } from '../persistence/entities';
18
19
 
19
20
  export class BaseOrganizationService<
20
21
  SchemaValidator extends AnySchemaValidator,
21
22
  OrganizationStatus = unknown,
22
- MapperEntities extends
23
- OrganizationEntities<OrganizationStatus> = OrganizationEntities<OrganizationStatus>,
24
- MapperDomains extends
25
- OrganizationDtos<OrganizationStatus> = OrganizationDtos<OrganizationStatus>
26
- > implements OrganizationService<OrganizationStatus>
27
- {
23
+ MapperEntities extends OrganizationEntities<OrganizationStatus> =
24
+ OrganizationEntities<OrganizationStatus>,
25
+ MapperDomains extends OrganizationDtos<OrganizationStatus> =
26
+ OrganizationDtos<OrganizationStatus>
27
+ > implements OrganizationService<OrganizationStatus> {
28
28
  // protected _mappers: InternalMapper<InstanceTypeRecord<typeof this.mappers>>;
29
29
  private evaluatedTelemetryOptions: {
30
30
  logging?: boolean;
@@ -87,14 +87,15 @@ export class BaseOrganizationService<
87
87
  if (em) {
88
88
  await em.persist(organization);
89
89
  } else {
90
- await this.em.persistAndFlush(organization);
90
+ await this.em.persist(organization).flush();
91
91
  }
92
92
 
93
93
  return this.mappers.OrganizationMapper.toDto(organization);
94
94
  }
95
95
 
96
96
  async getOrganization(
97
- idDto: IdDto,
97
+ idDto: IdDto &
98
+ FilterQuery<InferEntity<MapperEntities['OrganizationMapper']>>,
98
99
  em?: EntityManager
99
100
  ): Promise<MapperDomains['OrganizationMapper']> {
100
101
  if (this.evaluatedTelemetryOptions.logging) {
@@ -102,15 +103,12 @@ export class BaseOrganizationService<
102
103
  }
103
104
 
104
105
  const organization = await (em ?? this.em).findOneOrFail(
105
- 'Organization',
106
- idDto,
107
- {
108
- populate: ['id', '*']
109
- }
106
+ this.mappers.OrganizationMapper.entity as typeof Organization,
107
+ idDto
110
108
  );
111
109
 
112
110
  return this.mappers.OrganizationMapper.toDto(
113
- organization as MapperEntities['OrganizationMapper']
111
+ organization as InferEntity<MapperEntities['OrganizationMapper']>
114
112
  );
115
113
  }
116
114
 
@@ -136,21 +134,31 @@ export class BaseOrganizationService<
136
134
  if (em) {
137
135
  await em.persist(updatedOrganization);
138
136
  } else {
139
- await this.em.persistAndFlush(updatedOrganization);
137
+ await this.em.persist(updatedOrganization).flush();
140
138
  }
141
139
 
142
140
  return this.mappers.OrganizationMapper.toDto(updatedOrganization);
143
141
  }
144
142
 
145
- async deleteOrganization(idDto: IdDto, em?: EntityManager): Promise<void> {
143
+ async deleteOrganization(
144
+ idDto: IdDto &
145
+ FilterQuery<InferEntity<MapperEntities['OrganizationMapper']>>,
146
+ em?: EntityManager
147
+ ): Promise<void> {
146
148
  if (this.evaluatedTelemetryOptions.logging) {
147
149
  this.openTelemetryCollector.info('Deleting organization', idDto);
148
150
  }
149
151
 
150
152
  if (em) {
151
- await em.nativeDelete('Organization', idDto);
153
+ await em.nativeDelete(
154
+ this.mappers.OrganizationMapper.entity as typeof Organization,
155
+ idDto
156
+ );
152
157
  } else {
153
- await this.em.nativeDelete('Organization', idDto);
158
+ await this.em.nativeDelete(
159
+ this.mappers.OrganizationMapper.entity as typeof Organization,
160
+ idDto
161
+ );
154
162
  }
155
163
  }
156
164
  }
@@ -15,7 +15,8 @@ import {
15
15
  UpdatePermissionDto
16
16
  } from '@forklaunch/interfaces-iam/types';
17
17
  import { AnySchemaValidator } from '@forklaunch/validator';
18
- import { EntityManager } from '@mikro-orm/core';
18
+ import { EntityManager, InferEntity } from '@mikro-orm/core';
19
+ import { Permission } from '../persistence/entities';
19
20
  import { PermissionDtos } from '../domain/types/iamDto.types';
20
21
  import { PermissionEntities } from '../domain/types/iamEntities.types';
21
22
  import { PermissionMappers } from '../domain/types/permission.mapper.types';
@@ -24,8 +25,7 @@ export class BasePermissionService<
24
25
  SchemaValidator extends AnySchemaValidator,
25
26
  MapperEntities extends PermissionEntities = PermissionEntities,
26
27
  MapperDomains extends PermissionDtos = PermissionDtos
27
- > implements PermissionService
28
- {
28
+ > implements PermissionService {
29
29
  private evaluatedTelemetryOptions: {
30
30
  logging?: boolean;
31
31
  metrics?: boolean;
@@ -63,25 +63,25 @@ export class BasePermissionService<
63
63
 
64
64
  // start: global helper functions
65
65
  private async updateRolesWithPermissions(
66
- roles: MapperEntities['RoleEntityMapper'][],
67
- permissions: MapperEntities['PermissionMapper'][]
68
- ): Promise<MapperEntities['RoleEntityMapper'][]> {
66
+ roles: InferEntity<MapperEntities['RoleEntityMapper']>[],
67
+ permissions: InferEntity<MapperEntities['PermissionMapper']>[]
68
+ ): Promise<InferEntity<MapperEntities['RoleEntityMapper']>[]> {
69
69
  return Promise.all(
70
70
  roles.map(async (role) => {
71
- permissions.forEach((permission) => role.permissions.add(permission));
71
+ permissions.forEach((permission) => role.permissions?.add(permission));
72
72
  return role;
73
73
  })
74
74
  );
75
75
  }
76
76
 
77
77
  private async removePermissionsFromRoles(
78
- roles: MapperEntities['RoleEntityMapper'][],
79
- permissions: MapperEntities['PermissionMapper'][]
80
- ): Promise<MapperEntities['RoleEntityMapper'][]> {
78
+ roles: InferEntity<MapperEntities['RoleEntityMapper']>[],
79
+ permissions: InferEntity<MapperEntities['PermissionMapper']>[]
80
+ ): Promise<InferEntity<MapperEntities['RoleEntityMapper']>[]> {
81
81
  return Promise.all(
82
82
  roles.map(async (role) => {
83
83
  permissions.forEach((permission) =>
84
- role.permissions.remove(permission)
84
+ role.permissions?.remove(permission)
85
85
  );
86
86
  return role;
87
87
  })
@@ -91,16 +91,16 @@ export class BasePermissionService<
91
91
  private async getBatchRoles(
92
92
  roles?: IdsDto,
93
93
  em?: EntityManager
94
- ): Promise<MapperEntities['RoleEntityMapper'][]> {
94
+ ): Promise<InferEntity<MapperEntities['RoleEntityMapper']>[]> {
95
95
  return roles
96
96
  ? await Promise.all(
97
97
  (await this.roleServiceFactory().getBatchRoles(roles, em)).map(
98
98
  async (role) => {
99
99
  return (em ?? this.em).merge(
100
- await this.mappers.RoleEntityMapper.toEntity(
100
+ (await this.mappers.RoleEntityMapper.toEntity(
101
101
  role,
102
102
  em ?? this.em
103
- )
103
+ )) as InferEntity<MapperEntities['RoleEntityMapper']>
104
104
  );
105
105
  }
106
106
  )
@@ -114,18 +114,21 @@ export class BasePermissionService<
114
114
  permission,
115
115
  addToRoles
116
116
  }: {
117
- permission: MapperEntities['PermissionMapper'];
118
- addToRoles: MapperEntities['RoleEntityMapper'][];
117
+ permission: InferEntity<MapperEntities['PermissionMapper']>;
118
+ addToRoles: InferEntity<MapperEntities['RoleEntityMapper']>[];
119
119
  }): Promise<{
120
- permission: MapperEntities['PermissionMapper'];
121
- roles: MapperEntities['RoleEntityMapper'][];
120
+ permission: InferEntity<MapperEntities['PermissionMapper']>;
121
+ roles: InferEntity<MapperEntities['RoleEntityMapper']>[];
122
122
  }> {
123
- let roles: MapperEntities['RoleEntityMapper'][] = [];
123
+ let roles: InferEntity<MapperEntities['RoleEntityMapper']>[] = [];
124
124
  if (addToRoles) {
125
125
  roles = await this.updateRolesWithPermissions(addToRoles, [permission]);
126
126
  }
127
127
 
128
- return { permission, roles };
128
+ return {
129
+ permission,
130
+ roles
131
+ };
129
132
  }
130
133
 
131
134
  private async extractCreatePermissionEntityToEntityData(
@@ -133,8 +136,8 @@ export class BasePermissionService<
133
136
  em?: EntityManager,
134
137
  ...args: unknown[]
135
138
  ): Promise<{
136
- permission: MapperEntities['PermissionMapper'];
137
- addToRoles: MapperEntities['RoleEntityMapper'][];
139
+ permission: InferEntity<MapperEntities['PermissionMapper']>;
140
+ addToRoles: InferEntity<MapperEntities['RoleEntityMapper']>[];
138
141
  }> {
139
142
  return {
140
143
  permission: (em ?? this.em).merge(
@@ -143,7 +146,7 @@ export class BasePermissionService<
143
146
  em ?? this.em,
144
147
  ...args
145
148
  )
146
- ),
149
+ ) as InferEntity<MapperEntities['PermissionMapper']>,
147
150
  addToRoles: permissionDto.addToRolesIds
148
151
  ? await this.getBatchRoles({ ids: permissionDto.addToRolesIds }, em)
149
152
  : []
@@ -173,7 +176,7 @@ export class BasePermissionService<
173
176
  if (em) {
174
177
  await em.persist([permission, ...roles]);
175
178
  } else {
176
- await this.em.persistAndFlush([permission, ...roles]);
179
+ await this.em.persist([permission, ...roles]).flush();
177
180
  }
178
181
 
179
182
  return this.mappers.PermissionMapper.toDto(permission);
@@ -189,8 +192,11 @@ export class BasePermissionService<
189
192
  permissionDtos
190
193
  );
191
194
  }
192
- const rolesCache: Record<string, MapperEntities['RoleEntityMapper']> = {};
193
- const permissions: MapperEntities['PermissionMapper'][] = [];
195
+ const rolesCache: Record<
196
+ string,
197
+ InferEntity<MapperEntities['RoleEntityMapper']>
198
+ > = {};
199
+ const permissions: InferEntity<MapperEntities['PermissionMapper']>[] = [];
194
200
  for (const createPermissionEntity of permissionDtos) {
195
201
  const { permission, roles } = await this.createPermissionEntity(
196
202
  await this.extractCreatePermissionEntityToEntityData(
@@ -200,15 +206,15 @@ export class BasePermissionService<
200
206
  );
201
207
  await Promise.all(
202
208
  roles.map(async (role) => {
203
- if (!role.permissions.isInitialized()) {
204
- return role.permissions.init();
209
+ if (!role.permissions?.isInitialized()) {
210
+ return role.permissions?.init();
205
211
  }
206
212
  })
207
213
  );
208
214
  await Promise.all(
209
215
  roles.map(async (role) => {
210
- if (!role.permissions.isInitialized()) {
211
- return role.permissions.init();
216
+ if (!role.permissions?.isInitialized()) {
217
+ return role.permissions?.init();
212
218
  }
213
219
  })
214
220
  );
@@ -217,9 +223,9 @@ export class BasePermissionService<
217
223
  rolesCache[role.id] &&
218
224
  role.permissions !== rolesCache[role.id].permissions
219
225
  ) {
220
- role.permissions.getItems().forEach((permission) => {
221
- if (!rolesCache[role.id].permissions.contains(permission)) {
222
- rolesCache[role.id].permissions.add(permission);
226
+ role.permissions?.getItems().forEach((permission) => {
227
+ if (!rolesCache[role.id].permissions?.contains(permission)) {
228
+ rolesCache[role.id].permissions?.add(permission);
223
229
  }
224
230
  });
225
231
  } else {
@@ -233,7 +239,7 @@ export class BasePermissionService<
233
239
  if (em) {
234
240
  await em.persist(entities);
235
241
  } else {
236
- await this.em.persistAndFlush(entities);
242
+ await this.em.persist(entities).flush();
237
243
  }
238
244
 
239
245
  return Promise.all(
@@ -250,9 +256,12 @@ export class BasePermissionService<
250
256
  if (this.evaluatedTelemetryOptions.logging) {
251
257
  this.openTelemetryCollector.info('Getting permission', idDto);
252
258
  }
253
- const permission = await (em ?? this.em).findOneOrFail('Permission', idDto);
259
+ const permission = await (em ?? this.em).findOneOrFail(
260
+ this.mappers.PermissionMapper.entity as typeof Permission,
261
+ idDto
262
+ );
254
263
  return this.mappers.PermissionMapper.toDto(
255
- permission as MapperEntities['PermissionMapper']
264
+ permission as InferEntity<MapperEntities['PermissionMapper']>
256
265
  );
257
266
  }
258
267
 
@@ -265,12 +274,15 @@ export class BasePermissionService<
265
274
  }
266
275
  return Promise.all(
267
276
  (
268
- await (em ?? this.em).find('Permission', {
269
- id: { $in: idsDto.ids }
270
- })
277
+ await (em ?? this.em).find(
278
+ this.mappers.PermissionMapper.entity as typeof Permission,
279
+ {
280
+ id: { $in: idsDto.ids }
281
+ }
282
+ )
271
283
  ).map((permission) =>
272
284
  this.mappers.PermissionMapper.toDto(
273
- permission as MapperEntities['PermissionMapper']
285
+ permission as InferEntity<MapperEntities['PermissionMapper']>
274
286
  )
275
287
  )
276
288
  );
@@ -282,8 +294,8 @@ export class BasePermissionService<
282
294
  em?: EntityManager,
283
295
  ...args: unknown[]
284
296
  ): Promise<{
285
- permission: MapperEntities['PermissionMapper'];
286
- roles: MapperEntities['RoleEntityMapper'][];
297
+ permission: InferEntity<MapperEntities['PermissionMapper']>;
298
+ roles: InferEntity<MapperEntities['RoleEntityMapper']>[];
287
299
  }> => {
288
300
  const permission = await this.mappers.UpdatePermissionMapper.toEntity(
289
301
  permissionDto,
@@ -297,17 +309,21 @@ export class BasePermissionService<
297
309
  ? await this.getBatchRoles({ ids: permissionDto.removeFromRolesIds }, em)
298
310
  : [];
299
311
 
300
- let roles: MapperEntities['RoleEntityMapper'][] = [];
312
+ let roles: InferEntity<MapperEntities['RoleEntityMapper']>[] = [];
301
313
 
302
314
  roles = roles.concat(
303
- await this.updateRolesWithPermissions(addToRoles, [permission])
315
+ await this.updateRolesWithPermissions(addToRoles, [
316
+ permission as InferEntity<MapperEntities['PermissionMapper']>
317
+ ])
304
318
  );
305
319
  roles = roles.concat(
306
- await this.removePermissionsFromRoles(removeFromRoles, [permission])
320
+ await this.removePermissionsFromRoles(removeFromRoles, [
321
+ permission as InferEntity<MapperEntities['PermissionMapper']>
322
+ ])
307
323
  );
308
324
 
309
325
  return {
310
- permission,
326
+ permission: permission as InferEntity<MapperEntities['PermissionMapper']>,
311
327
  roles
312
328
  };
313
329
  };
@@ -326,7 +342,7 @@ export class BasePermissionService<
326
342
  if (em) {
327
343
  await em.persist(entities);
328
344
  } else {
329
- await this.em.persistAndFlush(entities);
345
+ await this.em.persist(entities).flush();
330
346
  }
331
347
 
332
348
  return this.mappers.PermissionMapper.toDto(permission);
@@ -342,8 +358,11 @@ export class BasePermissionService<
342
358
  permissionDtos
343
359
  );
344
360
  }
345
- const rolesCache: Record<string, MapperEntities['RoleEntityMapper']> = {};
346
- const permissions: MapperEntities['PermissionMapper'][] = [];
361
+ const rolesCache: Record<
362
+ string,
363
+ InferEntity<MapperEntities['RoleEntityMapper']>
364
+ > = {};
365
+ const permissions: InferEntity<MapperEntities['PermissionMapper']>[] = [];
347
366
  await (em ?? this.em).transactional(async (em) => {
348
367
  permissionDtos.map(async (updatePermissionDto) => {
349
368
  const { permission, roles } =
@@ -353,9 +372,9 @@ export class BasePermissionService<
353
372
  rolesCache[role.id] &&
354
373
  role.permissions !== rolesCache[role.id].permissions
355
374
  ) {
356
- role.permissions.getItems().forEach((permission) => {
357
- if (!rolesCache[role.id].permissions.contains(permission)) {
358
- rolesCache[role.id].permissions.add(permission);
375
+ role.permissions?.getItems().forEach((permission) => {
376
+ if (!rolesCache[role.id].permissions?.contains(permission)) {
377
+ rolesCache[role.id].permissions?.add(permission);
359
378
  }
360
379
  });
361
380
  } else {
@@ -369,7 +388,7 @@ export class BasePermissionService<
369
388
  if (em) {
370
389
  await em.persist(entities);
371
390
  } else {
372
- await this.em.persistAndFlush(entities);
391
+ await this.em.persist(entities).flush();
373
392
  }
374
393
  });
375
394
 
@@ -384,7 +403,10 @@ export class BasePermissionService<
384
403
  if (this.evaluatedTelemetryOptions.logging) {
385
404
  this.openTelemetryCollector.info('Deleting permission', idDto);
386
405
  }
387
- await (em ?? this.em).nativeDelete('Permission', idDto);
406
+ await (em ?? this.em).nativeDelete(
407
+ this.mappers.PermissionMapper.entity as typeof Permission,
408
+ idDto
409
+ );
388
410
  }
389
411
 
390
412
  async deleteBatchPermissions(
@@ -394,8 +416,11 @@ export class BasePermissionService<
394
416
  if (this.evaluatedTelemetryOptions.logging) {
395
417
  this.openTelemetryCollector.info('Deleting batch permissions', idsDto);
396
418
  }
397
- await (em ?? this.em).nativeDelete('Permission', {
398
- id: { $in: idsDto.ids }
399
- });
419
+ await (em ?? this.em).nativeDelete(
420
+ this.mappers.PermissionMapper.entity as typeof Permission,
421
+ {
422
+ id: { $in: idsDto.ids }
423
+ }
424
+ );
400
425
  }
401
426
  }
@@ -5,7 +5,12 @@ import {
5
5
  TelemetryOptions
6
6
  } from '@forklaunch/core/http';
7
7
  import { RoleService } from '@forklaunch/interfaces-iam/interfaces';
8
- import { EntityManager } from '@mikro-orm/core';
8
+ import {
9
+ EntityManager,
10
+ FilterQuery,
11
+ InferEntity
12
+ } from '@mikro-orm/core';
13
+ import { Role } from '../persistence/entities';
9
14
 
10
15
  import { IdDto, IdsDto } from '@forklaunch/common';
11
16
  import {
@@ -22,8 +27,7 @@ export class BaseRoleService<
22
27
  SchemaValidator extends AnySchemaValidator,
23
28
  MapperEntities extends RoleEntities = RoleEntities,
24
29
  MapperDomains extends RoleDtos = RoleDtos
25
- > implements RoleService
26
- {
30
+ > implements RoleService {
27
31
  private evaluatedTelemetryOptions: {
28
32
  logging?: boolean;
29
33
  metrics?: boolean;
@@ -73,7 +77,7 @@ export class BaseRoleService<
73
77
  if (em) {
74
78
  await em.persist(role);
75
79
  } else {
76
- await this.em.persistAndFlush(role);
80
+ await this.em.persist(role).flush();
77
81
  }
78
82
 
79
83
  return this.mappers.RoleMapper.toDto(role);
@@ -97,7 +101,7 @@ export class BaseRoleService<
97
101
  if (em) {
98
102
  await em.persist(roles);
99
103
  } else {
100
- await this.em.persistAndFlush(roles);
104
+ await this.em.persist(roles).flush();
101
105
  }
102
106
 
103
107
  return Promise.all(
@@ -110,11 +114,17 @@ export class BaseRoleService<
110
114
  this.openTelemetryCollector.info('Getting role', { id });
111
115
  }
112
116
 
113
- const role = await (em ?? this.em).findOneOrFail('Role', id, {
114
- populate: ['id', '*']
115
- });
117
+ const role = await (em ?? this.em).findOneOrFail(
118
+ this.mappers.RoleMapper.entity as typeof Role,
119
+ id as FilterQuery<InferEntity<MapperEntities['RoleMapper']>>,
120
+ {
121
+ populate: ['id', '*']
122
+ }
123
+ );
116
124
 
117
- return this.mappers.RoleMapper.toDto(role as MapperEntities['RoleMapper']);
125
+ return this.mappers.RoleMapper.toDto(
126
+ role as InferEntity<MapperEntities['RoleMapper']>
127
+ );
118
128
  }
119
129
 
120
130
  async getBatchRoles({ ids }: IdsDto, em?: EntityManager): Promise<RoleDto[]> {
@@ -125,7 +135,7 @@ export class BaseRoleService<
125
135
  return Promise.all(
126
136
  (
127
137
  await (em ?? this.em).find(
128
- 'Role',
138
+ this.mappers.RoleMapper.entity as typeof Role,
129
139
  {
130
140
  id: { $in: ids }
131
141
  },
@@ -134,7 +144,9 @@ export class BaseRoleService<
134
144
  }
135
145
  )
136
146
  ).map((role) =>
137
- this.mappers.RoleMapper.toDto(role as MapperEntities['RoleMapper'])
147
+ this.mappers.RoleMapper.toDto(
148
+ role as InferEntity<MapperEntities['RoleMapper']>
149
+ )
138
150
  )
139
151
  );
140
152
  }
@@ -157,7 +169,7 @@ export class BaseRoleService<
157
169
  if (em) {
158
170
  await em.persist(role);
159
171
  } else {
160
- await this.em.persistAndFlush(role);
172
+ await this.em.persist(role).flush();
161
173
  }
162
174
 
163
175
  return this.mappers.RoleMapper.toDto(role);
@@ -181,12 +193,10 @@ export class BaseRoleService<
181
193
  if (em) {
182
194
  await em.persist(roles);
183
195
  } else {
184
- await this.em.persistAndFlush(roles);
196
+ await this.em.persist(roles).flush();
185
197
  }
186
198
  return Promise.all(
187
- roles.map((role) =>
188
- this.mappers.RoleMapper.toDto(role as MapperEntities['RoleMapper'])
189
- )
199
+ roles.map((role) => this.mappers.RoleMapper.toDto(role))
190
200
  );
191
201
  }
192
202
 
@@ -195,7 +205,10 @@ export class BaseRoleService<
195
205
  this.openTelemetryCollector.info('Deleting role', idDto);
196
206
  }
197
207
 
198
- await (em ?? this.em).nativeDelete('Role', idDto);
208
+ await (em ?? this.em).nativeDelete(
209
+ this.mappers.RoleMapper.entity as typeof Role,
210
+ idDto
211
+ );
199
212
  }
200
213
 
201
214
  async deleteBatchRoles(idsDto: IdsDto, em?: EntityManager): Promise<void> {
@@ -203,6 +216,11 @@ export class BaseRoleService<
203
216
  this.openTelemetryCollector.info('Deleting batch roles', idsDto);
204
217
  }
205
218
 
206
- await (em ?? this.em).nativeDelete('Role', { id: { $in: idsDto.ids } });
219
+ await (em ?? this.em).nativeDelete(
220
+ this.mappers.RoleMapper.entity as typeof Role,
221
+ {
222
+ id: { $in: idsDto.ids }
223
+ }
224
+ );
207
225
  }
208
226
  }