prisma-nestjs-graphql 20.0.1 → 20.0.3

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/generate.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
+ var module$1 = require('module');
3
4
  var assert = require('assert');
4
- var AwaitEventEmitter = require('await-event-emitter');
5
5
  var lodash = require('lodash');
6
6
  var tsMorph = require('ts-morph');
7
7
  var JSON5 = require('json5');
@@ -13,6 +13,21 @@ var filenamify = require('filenamify');
13
13
  var flat = require('flat');
14
14
  var pluralize = require('pluralize');
15
15
 
16
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
17
+ var require$1 = (
18
+ false
19
+ ? /* @__PURE__ */ module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.src || new URL('generate.cjs', document.baseURI).href)))
20
+ : require
21
+ );
22
+
23
+ function isCreateManyReturn(name) {
24
+ const lowerName = name.toLowerCase();
25
+ if (lowerName.startsWith("createmany") && (lowerName.endsWith("andreturnoutputtype") || lowerName.endsWith("andreturn"))) {
26
+ return true;
27
+ }
28
+ return false;
29
+ }
30
+
16
31
  function pascalCase(string) {
17
32
  return lodash.startCase(lodash.camelCase(string)).replaceAll(" ", "");
18
33
  }
@@ -21,6 +36,8 @@ function argsType(field, args) {
21
36
  if (["queryRaw", "executeRaw"].includes(field.name)) {
22
37
  return;
23
38
  }
39
+ if (isCreateManyReturn(field.name))
40
+ return;
24
41
  const { eventEmitter, typeNames, getModelName } = args;
25
42
  let className = pascalCase(`${field.name}Args`);
26
43
  const modelName = getModelName(className) || "";
@@ -1109,6 +1126,8 @@ const nestjsGraphql$1 = "@nestjs/graphql";
1109
1126
  function modelOutputType(outputType, args) {
1110
1127
  var _a, _b, _c, _d, _e, _f;
1111
1128
  const { getSourceFile, models, config, modelFields, fieldSettings, eventEmitter } = args;
1129
+ if (isCreateManyReturn(outputType.name))
1130
+ return;
1112
1131
  const model = models.get(outputType.name);
1113
1132
  assert.ok(model, `Cannot find model by name ${outputType.name}`);
1114
1133
  const sourceFile = getSourceFile({
@@ -1568,6 +1587,8 @@ function beforeGenerateFiles(args) {
1568
1587
  if (config.reExport === "All" /* All */) {
1569
1588
  const exportDeclarations = [];
1570
1589
  for (const directory of rootDirectory.getDirectories()) {
1590
+ if (directory.getBaseName() === "node_modules")
1591
+ continue;
1571
1592
  const sourceFile = directory.getSourceFileOrThrow("index.ts");
1572
1593
  exportDeclarations.push(getExportDeclaration(rootDirectory, sourceFile));
1573
1594
  }
@@ -1962,6 +1983,7 @@ const middleKeywords = [
1962
1983
  ["OrderBy", "Args"]
1963
1984
  ];
1964
1985
 
1986
+ const AwaitEventEmitter = require$1("await-event-emitter").default;
1965
1987
  async function generate(args) {
1966
1988
  var _a;
1967
1989
  const { connectCallback, generator, skipAddOutputSourceFiles, dmmf } = args;
package/generate.d.ts CHANGED
@@ -3,50 +3,50 @@ import AwaitEventEmitter from 'await-event-emitter';
3
3
  import { Project, SourceFile } from 'ts-morph';
4
4
 
5
5
  declare namespace DMMF {
6
- export interface Document {
6
+ export type Document = ReadonlyDeep_2<{
7
7
  datamodel: Datamodel;
8
8
  schema: Schema;
9
9
  mappings: Mappings;
10
- }
11
- export interface Mappings {
10
+ }>;
11
+ export type Mappings = ReadonlyDeep_2<{
12
12
  modelOperations: ModelMapping[];
13
13
  otherOperations: {
14
14
  read: string[];
15
15
  write: string[];
16
16
  };
17
- }
18
- export interface OtherOperationMappings {
17
+ }>;
18
+ export type OtherOperationMappings = ReadonlyDeep_2<{
19
19
  read: string[];
20
20
  write: string[];
21
- }
22
- export interface DatamodelEnum {
21
+ }>;
22
+ export type DatamodelEnum = ReadonlyDeep_2<{
23
23
  name: string;
24
24
  values: EnumValue[];
25
25
  dbName?: string | null;
26
26
  documentation?: string;
27
- }
28
- export interface SchemaEnum {
27
+ }>;
28
+ export type SchemaEnum = ReadonlyDeep_2<{
29
29
  name: string;
30
30
  values: string[];
31
- }
32
- export interface EnumValue {
31
+ }>;
32
+ export type EnumValue = ReadonlyDeep_2<{
33
33
  name: string;
34
34
  dbName: string | null;
35
- }
36
- export interface Datamodel {
35
+ }>;
36
+ export type Datamodel = ReadonlyDeep_2<{
37
37
  models: Model[];
38
38
  enums: DatamodelEnum[];
39
39
  types: Model[];
40
- }
41
- export interface uniqueIndex {
40
+ }>;
41
+ export type uniqueIndex = ReadonlyDeep_2<{
42
42
  name: string;
43
43
  fields: string[];
44
- }
45
- export interface PrimaryKey {
44
+ }>;
45
+ export type PrimaryKey = ReadonlyDeep_2<{
46
46
  name: string | null;
47
47
  fields: string[];
48
- }
49
- export interface Model {
48
+ }>;
49
+ export type Model = ReadonlyDeep_2<{
50
50
  name: string;
51
51
  dbName: string | null;
52
52
  fields: Field[];
@@ -55,11 +55,11 @@ declare namespace DMMF {
55
55
  documentation?: string;
56
56
  primaryKey: PrimaryKey | null;
57
57
  isGenerated?: boolean;
58
- }
58
+ }>;
59
59
  export type FieldKind = 'scalar' | 'object' | 'enum' | 'unsupported';
60
60
  export type FieldNamespace = 'model' | 'prisma';
61
61
  export type FieldLocation = 'scalar' | 'inputObjectTypes' | 'outputObjectTypes' | 'enumTypes' | 'fieldRefTypes';
62
- export interface Field {
62
+ export type Field = ReadonlyDeep_2<{
63
63
  kind: FieldKind;
64
64
  name: string;
65
65
  isRequired: boolean;
@@ -82,13 +82,13 @@ declare namespace DMMF {
82
82
  relationOnDelete?: string;
83
83
  relationName?: string;
84
84
  documentation?: string;
85
- }
86
- export interface FieldDefault {
85
+ }>;
86
+ export type FieldDefault = ReadonlyDeep_2<{
87
87
  name: string;
88
88
  args: any[];
89
- }
89
+ }>;
90
90
  export type FieldDefaultScalar = string | boolean | number;
91
- export interface Schema {
91
+ export type Schema = ReadonlyDeep_2<{
92
92
  rootQueryType?: string;
93
93
  rootMutationType?: string;
94
94
  inputObjectTypes: {
@@ -106,17 +106,17 @@ declare namespace DMMF {
106
106
  fieldRefTypes: {
107
107
  prisma?: FieldRefType[];
108
108
  };
109
- }
110
- export interface Query {
109
+ }>;
110
+ export type Query = ReadonlyDeep_2<{
111
111
  name: string;
112
112
  args: SchemaArg[];
113
113
  output: QueryOutput;
114
- }
115
- export interface QueryOutput {
114
+ }>;
115
+ export type QueryOutput = ReadonlyDeep_2<{
116
116
  name: string;
117
117
  isRequired: boolean;
118
118
  isList: boolean;
119
- }
119
+ }>;
120
120
  export type TypeRef<AllowedLocations extends FieldLocation> = {
121
121
  isList: boolean;
122
122
  type: string;
@@ -124,33 +124,33 @@ declare namespace DMMF {
124
124
  namespace?: FieldNamespace;
125
125
  };
126
126
  export type InputTypeRef = TypeRef<'scalar' | 'inputObjectTypes' | 'enumTypes' | 'fieldRefTypes'>;
127
- export interface SchemaArg {
127
+ export type SchemaArg = ReadonlyDeep_2<{
128
128
  name: string;
129
129
  comment?: string;
130
130
  isNullable: boolean;
131
131
  isRequired: boolean;
132
132
  inputTypes: InputTypeRef[];
133
133
  deprecation?: Deprecation;
134
- }
135
- export interface OutputType {
134
+ }>;
135
+ export type OutputType = ReadonlyDeep_2<{
136
136
  name: string;
137
137
  fields: SchemaField[];
138
- }
139
- export interface SchemaField {
138
+ }>;
139
+ export type SchemaField = ReadonlyDeep_2<{
140
140
  name: string;
141
141
  isNullable?: boolean;
142
142
  outputType: OutputTypeRef;
143
143
  args: SchemaArg[];
144
144
  deprecation?: Deprecation;
145
145
  documentation?: string;
146
- }
146
+ }>;
147
147
  export type OutputTypeRef = TypeRef<'scalar' | 'outputObjectTypes' | 'enumTypes'>;
148
- export interface Deprecation {
148
+ export type Deprecation = ReadonlyDeep_2<{
149
149
  sinceVersion: string;
150
150
  reason: string;
151
151
  plannedRemovalVersion?: string;
152
- }
153
- export interface InputType {
152
+ }>;
153
+ export type InputType = ReadonlyDeep_2<{
154
154
  name: string;
155
155
  constraints: {
156
156
  maxNumFields: number | null;
@@ -161,14 +161,14 @@ declare namespace DMMF {
161
161
  source?: string;
162
162
  };
163
163
  fields: SchemaArg[];
164
- }
165
- export interface FieldRefType {
164
+ }>;
165
+ export type FieldRefType = ReadonlyDeep_2<{
166
166
  name: string;
167
167
  allowTypes: FieldRefAllowType[];
168
168
  fields: SchemaArg[];
169
- }
169
+ }>;
170
170
  export type FieldRefAllowType = TypeRef<'scalar' | 'enumTypes'>;
171
- export interface ModelMapping {
171
+ export type ModelMapping = ReadonlyDeep_2<{
172
172
  model: string;
173
173
  plural: string;
174
174
  findUnique?: string | null;
@@ -178,6 +178,7 @@ declare namespace DMMF {
178
178
  findMany?: string | null;
179
179
  create?: string | null;
180
180
  createMany?: string | null;
181
+ createManyAndReturn?: string | null;
181
182
  update?: string | null;
182
183
  updateMany?: string | null;
183
184
  upsert?: string | null;
@@ -188,7 +189,7 @@ declare namespace DMMF {
188
189
  count?: string | null;
189
190
  findRaw?: string | null;
190
191
  aggregateRaw?: string | null;
191
- }
192
+ }>;
192
193
  export enum ModelAction {
193
194
  findUnique = "findUnique",
194
195
  findUniqueOrThrow = "findUniqueOrThrow",
@@ -197,19 +198,148 @@ declare namespace DMMF {
197
198
  findMany = "findMany",
198
199
  create = "create",
199
200
  createMany = "createMany",
201
+ createManyAndReturn = "createManyAndReturn",
200
202
  update = "update",
201
203
  updateMany = "updateMany",
202
204
  upsert = "upsert",
203
205
  delete = "delete",
204
206
  deleteMany = "deleteMany",
205
207
  groupBy = "groupBy",
206
- count = "count",
208
+ count = "count",// TODO: count does not actually exist, why?
207
209
  aggregate = "aggregate",
208
210
  findRaw = "findRaw",
209
211
  aggregateRaw = "aggregateRaw"
210
212
  }
213
+ }
214
+
215
+ declare type ReadonlyDeep_2<O> = {
216
+ +readonly [K in keyof O]: ReadonlyDeep_2<O[K]>;
217
+ };
218
+
219
+ /**
220
+ Matches any [primitive value](https://developer.mozilla.org/en-US/docs/Glossary/Primitive).
221
+
222
+ @category Type
223
+ */
224
+ type Primitive =
225
+ | null
226
+ | undefined
227
+ | string
228
+ | number
229
+ | boolean
230
+ | symbol
231
+ | bigint;
232
+
233
+ declare global {
234
+ // eslint-disable-next-line @typescript-eslint/consistent-type-definitions -- It has to be an `interface` so that it can be merged.
235
+ interface SymbolConstructor {
236
+ readonly observable: symbol;
237
+ }
211
238
  }
212
239
 
240
+ /**
241
+ Matches any primitive, `void`, `Date`, or `RegExp` value.
242
+ */
243
+ type BuiltIns = Primitive | void | Date | RegExp;
244
+
245
+ /**
246
+ Test if the given function has multiple call signatures.
247
+
248
+ Needed to handle the case of a single call signature with properties.
249
+
250
+ Multiple call signatures cannot currently be supported due to a TypeScript limitation.
251
+ @see https://github.com/microsoft/TypeScript/issues/29732
252
+ */
253
+ type HasMultipleCallSignatures<T extends (...arguments_: any[]) => unknown> =
254
+ T extends {(...arguments_: infer A): unknown; (...arguments_: infer B): unknown}
255
+ ? B extends A
256
+ ? A extends B
257
+ ? false
258
+ : true
259
+ : true
260
+ : false;
261
+
262
+ /**
263
+ Create a deeply mutable version of an `object`/`ReadonlyMap`/`ReadonlySet`/`ReadonlyArray` type. The inverse of `ReadonlyDeep<T>`. Use `Writable<T>` if you only need one level deep.
264
+
265
+ This can be used to [store and mutate options within a class](https://github.com/sindresorhus/pageres/blob/4a5d05fca19a5fbd2f53842cbf3eb7b1b63bddd2/source/index.ts#L72), [edit `readonly` objects within tests](https://stackoverflow.com/questions/50703834), [construct a `readonly` object within a function](https://github.com/Microsoft/TypeScript/issues/24509), or to define a single model where the only thing that changes is whether or not some of the keys are writable.
266
+
267
+ @example
268
+ ```
269
+ import type {WritableDeep} from 'type-fest';
270
+
271
+ type Foo = {
272
+ readonly a: number;
273
+ readonly b: readonly string[]; // To show that mutability is deeply affected.
274
+ readonly c: boolean;
275
+ };
276
+
277
+ const writableDeepFoo: WritableDeep<Foo> = {a: 1, b: ['2'], c: true};
278
+ writableDeepFoo.a = 3;
279
+ writableDeepFoo.b[0] = 'new value';
280
+ writableDeepFoo.b = ['something'];
281
+ ```
282
+
283
+ Note that types containing overloaded functions are not made deeply writable due to a [TypeScript limitation](https://github.com/microsoft/TypeScript/issues/29732).
284
+
285
+ @see Writable
286
+ @category Object
287
+ @category Array
288
+ @category Set
289
+ @category Map
290
+ */
291
+ type WritableDeep<T> = T extends BuiltIns
292
+ ? T
293
+ : T extends (...arguments_: any[]) => unknown
294
+ ? {} extends WritableObjectDeep<T>
295
+ ? T
296
+ : HasMultipleCallSignatures<T> extends true
297
+ ? T
298
+ : ((...arguments_: Parameters<T>) => ReturnType<T>) & WritableObjectDeep<T>
299
+ : T extends ReadonlyMap<unknown, unknown>
300
+ ? WritableMapDeep<T>
301
+ : T extends ReadonlySet<unknown>
302
+ ? WritableSetDeep<T>
303
+ : T extends readonly unknown[]
304
+ ? WritableArrayDeep<T>
305
+ : T extends object
306
+ ? WritableObjectDeep<T>
307
+ : unknown;
308
+
309
+ /**
310
+ Same as `WritableDeep`, but accepts only `Map`s as inputs. Internal helper for `WritableDeep`.
311
+ */
312
+ type WritableMapDeep<MapType extends ReadonlyMap<unknown, unknown>> =
313
+ MapType extends ReadonlyMap<infer KeyType, infer ValueType>
314
+ ? Map<WritableDeep<KeyType>, WritableDeep<ValueType>>
315
+ : MapType; // Should not heppen
316
+
317
+ /**
318
+ Same as `WritableDeep`, but accepts only `Set`s as inputs. Internal helper for `WritableDeep`.
319
+ */
320
+ type WritableSetDeep<SetType extends ReadonlySet<unknown>> =
321
+ SetType extends ReadonlySet<infer ItemType>
322
+ ? Set<WritableDeep<ItemType>>
323
+ : SetType; // Should not heppen
324
+
325
+ /**
326
+ Same as `WritableDeep`, but accepts only `object`s as inputs. Internal helper for `WritableDeep`.
327
+ */
328
+ type WritableObjectDeep<ObjectType extends object> = {
329
+ -readonly [KeyType in keyof ObjectType]: WritableDeep<ObjectType[KeyType]>
330
+ };
331
+
332
+ /**
333
+ Same as `WritableDeep`, but accepts only `Array`s as inputs. Internal helper for `WritableDeep`.
334
+ */
335
+ type WritableArrayDeep<ArrayType extends readonly unknown[]> =
336
+ ArrayType extends readonly [] ? []
337
+ : ArrayType extends readonly [...infer U, infer V] ? [...WritableArrayDeep<U>, WritableDeep<V>]
338
+ : ArrayType extends readonly [infer U, ...infer V] ? [WritableDeep<U>, ...WritableArrayDeep<V>]
339
+ : ArrayType extends ReadonlyArray<infer U> ? Array<WritableDeep<U>>
340
+ : ArrayType extends Array<infer U> ? Array<WritableDeep<U>>
341
+ : ArrayType;
342
+
213
343
  declare enum ReExport {
214
344
  None = "None",
215
345
  Directories = "Directories",
@@ -284,10 +414,11 @@ declare class ObjectSettings extends Array<ObjectSetting> {
284
414
  fieldArguments(): Record<string, unknown> | undefined;
285
415
  }
286
416
 
287
- type Model = DMMF.Model;
417
+ type Model = WritableDeep<DMMF.Model>;
418
+ type Schema = WritableDeep<DMMF.Schema>;
288
419
  type GeneratorConfiguration = ReturnType<typeof createConfig>;
289
420
  type EventArguments = {
290
- schema: DMMF.Schema;
421
+ schema: Schema;
291
422
  models: Map<string, Model>;
292
423
  modelNames: string[];
293
424
  modelFields: Map<string, Map<string, Field>>;
package/index.cjs CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  var generatorHelper = require('@prisma/generator-helper');
4
4
  var generate = require('./generate.cjs');
5
+ require('module');
5
6
  require('assert');
6
- require('await-event-emitter');
7
7
  require('lodash');
8
8
  require('ts-morph');
9
9
  require('json5');
package/package.json CHANGED
@@ -1,13 +1,10 @@
1
1
  {
2
2
  "name": "prisma-nestjs-graphql",
3
- "version": "20.0.1",
3
+ "version": "20.0.3",
4
4
  "license": "MIT",
5
5
  "description": "Generate object types, inputs, args, etc. from prisma schema file for usage with @nestjs/graphql module",
6
6
  "bin": "bin.js",
7
- "repository": {
8
- "type": "git",
9
- "url": "git+https://github.com/unlight/nestjs-graphql-prisma.git"
10
- },
7
+ "repository": "https://github.com/unlight/nestjs-graphql-prisma.git",
11
8
  "bugs": {
12
9
  "url": "https://github.com/unlight/nestjs-graphql-prisma/issues"
13
10
  },
@@ -72,7 +69,7 @@
72
69
  }
73
70
  },
74
71
  "dependencies": {
75
- "@prisma/generator-helper": "^5.7.0",
72
+ "@prisma/generator-helper": "^5.14.0",
76
73
  "await-event-emitter": "^2.0.2",
77
74
  "filenamify": "4.X",
78
75
  "flat": "5.X",
@@ -88,31 +85,31 @@
88
85
  "devDependencies": {
89
86
  "@commitlint/cli": "^18.4.3",
90
87
  "@commitlint/config-conventional": "^18.4.3",
91
- "@nestjs/apollo": "^12.0.11",
92
- "@nestjs/common": "^10.2.10",
93
- "@nestjs/core": "^10.2.10",
94
- "@nestjs/graphql": "^12.0.11",
95
- "@nestjs/platform-express": "^10.2.10",
88
+ "@nestjs/apollo": "^12.1.0",
89
+ "@nestjs/common": "^10.3.8",
90
+ "@nestjs/core": "^10.3.8",
91
+ "@nestjs/graphql": "^12.1.1",
92
+ "@nestjs/platform-express": "^10.3.8",
96
93
  "@paljs/plugins": "^6.0.7",
97
- "@prisma/client": "^5.7.0",
94
+ "@prisma/client": "^5.14.0",
98
95
  "@semantic-release/changelog": "^6.0.3",
99
96
  "@semantic-release/git": "^10.0.1",
100
97
  "@semantic-release/github": "^9.2.5",
101
- "@swc/core": "^1.3.100",
102
- "@swc/helpers": "^0.5.3",
98
+ "@swc/core": "^1.5.7",
99
+ "@swc/helpers": "^0.5.11",
103
100
  "@swc/register": "^0.1.10",
104
101
  "@types/flat": "^5.0.5",
105
102
  "@types/graceful-fs": "^4.1.9",
106
- "@types/lodash": "^4.14.202",
103
+ "@types/lodash": "^4.17.4",
107
104
  "@types/mocha": "^10.0.6",
108
- "@types/node": "^20.10.4",
105
+ "@types/node": "^20.12.12",
109
106
  "@types/pluralize": "^0.0.33",
110
107
  "@typescript-eslint/eslint-plugin": "^6.14.0",
111
108
  "@typescript-eslint/parser": "^6.14.0",
112
109
  "apollo-server-express": "^3.13.0",
113
- "c8": "^8.0.1",
110
+ "c8": "^9.1.0",
114
111
  "class-transformer": "^0.5.1",
115
- "class-validator": "^0.14.0",
112
+ "class-validator": "^0.14.1",
116
113
  "commitizen": "^4.3.0",
117
114
  "cz-customizable": "^7.0.0",
118
115
  "decimal.js": "^10.4.3",
@@ -121,25 +118,25 @@
121
118
  "eslint-plugin-etc": "^2.0.3",
122
119
  "eslint-plugin-import": "^2.29.1",
123
120
  "eslint-plugin-only-warn": "^1.1.0",
124
- "eslint-plugin-prettier": "^5.0.1",
125
- "eslint-plugin-regexp": "^2.1.2",
121
+ "eslint-plugin-prettier": "^5.1.3",
122
+ "eslint-plugin-regexp": "^2.5.0",
126
123
  "eslint-plugin-simple-import-sort": "^10.0.0",
127
- "eslint-plugin-sort-class-members": "^1.19.0",
128
- "eslint-plugin-unicorn": "^49.0.0",
124
+ "eslint-plugin-sort-class-members": "^1.20.0",
125
+ "eslint-plugin-unicorn": "^53.0.0",
129
126
  "eslint-plugin-wix-editor": "^3.3.0",
130
127
  "expect": "^29.7.0",
131
128
  "git-branch-is": "^4.0.0",
132
129
  "graphql": "^16.8.1",
133
- "graphql-scalars": "^1.22.4",
130
+ "graphql-scalars": "^1.23.0",
134
131
  "graphql-type-json": "^0.3.2",
135
- "mocha": "^10.2.0",
132
+ "mocha": "^10.4.0",
136
133
  "ololog": "^1.1.175",
137
- "pkgroll": "^2.0.1",
134
+ "pkgroll": "^2.1.0",
138
135
  "precise-commits": "^1.0.2",
139
- "prettier": "^3.1.1",
140
- "prisma": "^5.7.0",
136
+ "prettier": "^3.2.5",
137
+ "prisma": "^5.14.0",
141
138
  "prisma-graphql-type-decimal": "^3.0.0",
142
- "reflect-metadata": "^0.1.12",
139
+ "reflect-metadata": "^0.2.2",
143
140
  "request": "^2.88.2",
144
141
  "rxjs": "^7.8.1",
145
142
  "semantic-release": "^22.0.12",
@@ -147,7 +144,8 @@
147
144
  "temp-dir": "2.X",
148
145
  "ts-node": "^10.9.2",
149
146
  "tslib": "^2.6.2",
150
- "typescript": "^5.3.3",
147
+ "type-fest": "^4.18.2",
148
+ "typescript": "^5.4.5",
151
149
  "watchexec-bin": "^1.0.0"
152
150
  }
153
151
  }