@leonardo-ai/sdk 4.6.0 → 4.10.1
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/README.md +2 -1
- package/docs/sdks/dataset/README.md +6 -16
- package/docs/sdks/generation/README.md +5 -23
- package/docs/sdks/initimage/README.md +2 -6
- package/docs/sdks/model/README.md +3 -10
- package/docs/sdks/variation/README.md +43 -3
- package/hooks/hooks.d.ts +5 -1
- package/hooks/hooks.d.ts.map +1 -1
- package/hooks/hooks.js +11 -0
- package/hooks/hooks.js.map +1 -1
- package/hooks/types.d.ts +29 -16
- package/hooks/types.d.ts.map +1 -1
- package/lib/config.d.ts +3 -3
- package/lib/config.js +3 -3
- package/lib/config.js.map +1 -1
- package/lib/encodings.d.ts +0 -1
- package/lib/encodings.d.ts.map +1 -1
- package/lib/http.d.ts +10 -1
- package/lib/http.d.ts.map +1 -1
- package/lib/http.js +45 -15
- package/lib/http.js.map +1 -1
- package/lib/sdks.d.ts +1 -1
- package/lib/sdks.d.ts.map +1 -1
- package/lib/sdks.js +10 -6
- package/lib/sdks.js.map +1 -1
- package/lib/security.d.ts +1 -1
- package/lib/security.d.ts.map +1 -1
- package/package.json +7 -7
- package/sdk/dataset.d.ts +1 -1
- package/sdk/dataset.d.ts.map +1 -1
- package/sdk/dataset.js +23 -17
- package/sdk/dataset.js.map +1 -1
- package/sdk/element.d.ts.map +1 -1
- package/sdk/element.js +4 -3
- package/sdk/element.js.map +1 -1
- package/sdk/generation.d.ts +7 -7
- package/sdk/generation.d.ts.map +1 -1
- package/sdk/generation.js +65 -47
- package/sdk/generation.js.map +1 -1
- package/sdk/initimage.d.ts +1 -1
- package/sdk/initimage.d.ts.map +1 -1
- package/sdk/initimage.js +15 -11
- package/sdk/initimage.js.map +1 -1
- package/sdk/model.d.ts +2 -2
- package/sdk/model.d.ts.map +1 -1
- package/sdk/model.js +30 -22
- package/sdk/model.js.map +1 -1
- package/sdk/models/errors/sdkerror.d.ts +1 -0
- package/sdk/models/errors/sdkerror.d.ts.map +1 -1
- package/sdk/models/errors/sdkerror.js +3 -1
- package/sdk/models/errors/sdkerror.js.map +1 -1
- package/sdk/models/operations/creategeneration.d.ts +6 -6
- package/sdk/models/operations/creategeneration.d.ts.map +1 -1
- package/sdk/models/operations/creategeneration.js +24 -24
- package/sdk/models/operations/creategeneration.js.map +1 -1
- package/sdk/models/operations/createuniversalupscalerjob.d.ts +131 -0
- package/sdk/models/operations/createuniversalupscalerjob.d.ts.map +1 -0
- package/sdk/models/operations/createuniversalupscalerjob.js +170 -0
- package/sdk/models/operations/createuniversalupscalerjob.js.map +1 -0
- package/sdk/models/operations/getgenerationbyid.d.ts +1 -1
- package/sdk/models/operations/getgenerationbyid.d.ts.map +1 -1
- package/sdk/models/operations/getgenerationbyid.js +4 -4
- package/sdk/models/operations/getgenerationbyid.js.map +1 -1
- package/sdk/models/operations/getgenerationsbyuserid.d.ts +1 -1
- package/sdk/models/operations/getgenerationsbyuserid.d.ts.map +1 -1
- package/sdk/models/operations/getgenerationsbyuserid.js +4 -4
- package/sdk/models/operations/getgenerationsbyuserid.js.map +1 -1
- package/sdk/models/operations/index.d.ts +1 -0
- package/sdk/models/operations/index.d.ts.map +1 -1
- package/sdk/models/operations/index.js +1 -0
- package/sdk/models/operations/index.js.map +1 -1
- package/sdk/models/shared/index.d.ts +1 -0
- package/sdk/models/shared/index.d.ts.map +1 -1
- package/sdk/models/shared/index.js +1 -0
- package/sdk/models/shared/index.js.map +1 -1
- package/sdk/models/shared/universalupscalerstyle.d.ts +13 -0
- package/sdk/models/shared/universalupscalerstyle.d.ts.map +1 -0
- package/sdk/models/shared/universalupscalerstyle.js +43 -0
- package/sdk/models/shared/universalupscalerstyle.js.map +1 -0
- package/sdk/prompt.d.ts +1 -1
- package/sdk/prompt.d.ts.map +1 -1
- package/sdk/prompt.js +11 -8
- package/sdk/prompt.js.map +1 -1
- package/sdk/user.d.ts.map +1 -1
- package/sdk/user.js +4 -3
- package/sdk/user.js.map +1 -1
- package/sdk/variation.d.ts +10 -3
- package/sdk/variation.d.ts.map +1 -1
- package/sdk/variation.js +89 -18
- package/sdk/variation.js.map +1 -1
- package/src/hooks/hooks.ts +18 -0
- package/src/hooks/types.ts +31 -16
- package/src/lib/config.ts +3 -3
- package/src/lib/http.ts +64 -16
- package/src/lib/sdks.ts +15 -6
- package/src/lib/security.ts +1 -1
- package/src/sdk/dataset.ts +48 -17
- package/src/sdk/element.ts +9 -3
- package/src/sdk/generation.ts +120 -47
- package/src/sdk/initimage.ts +30 -11
- package/src/sdk/model.ts +60 -22
- package/src/sdk/models/errors/sdkerror.ts +4 -1
- package/src/sdk/models/operations/creategeneration.ts +34 -30
- package/src/sdk/models/operations/createuniversalupscalerjob.ts +296 -0
- package/src/sdk/models/operations/getgenerationbyid.ts +9 -5
- package/src/sdk/models/operations/getgenerationsbyuserid.ts +9 -5
- package/src/sdk/models/operations/index.ts +1 -0
- package/src/sdk/models/shared/index.ts +1 -0
- package/src/sdk/models/shared/universalupscalerstyle.ts +19 -0
- package/src/sdk/prompt.ts +21 -8
- package/src/sdk/user.ts +9 -3
- package/src/sdk/variation.ts +134 -18
package/src/lib/http.ts
CHANGED
|
@@ -9,7 +9,28 @@ export type Fetcher = (
|
|
|
9
9
|
|
|
10
10
|
export type Awaitable<T> = T | Promise<T>;
|
|
11
11
|
|
|
12
|
-
const DEFAULT_FETCHER: Fetcher = (input, init) =>
|
|
12
|
+
const DEFAULT_FETCHER: Fetcher = (input, init) => {
|
|
13
|
+
// If input is a Request and init is undefined, Bun will discard the method,
|
|
14
|
+
// headers, body and other options that were set on the request object.
|
|
15
|
+
// Node.js and browers would ignore an undefined init value. This check is
|
|
16
|
+
// therefore needed for interop with Bun.
|
|
17
|
+
if (init == null) {
|
|
18
|
+
return fetch(input);
|
|
19
|
+
} else {
|
|
20
|
+
return fetch(input, init);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export type RequestInput = {
|
|
25
|
+
/**
|
|
26
|
+
* The URL the request will use.
|
|
27
|
+
*/
|
|
28
|
+
url: URL;
|
|
29
|
+
/**
|
|
30
|
+
* Options used to create a [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request/Request).
|
|
31
|
+
*/
|
|
32
|
+
options?: RequestInit | undefined;
|
|
33
|
+
};
|
|
13
34
|
|
|
14
35
|
export interface HTTPClientOptions {
|
|
15
36
|
fetcher?: Fetcher;
|
|
@@ -130,29 +151,56 @@ export class HTTPClient {
|
|
|
130
151
|
}
|
|
131
152
|
}
|
|
132
153
|
|
|
133
|
-
|
|
134
|
-
|
|
154
|
+
// A semicolon surrounded by optional whitespace characters is used to separate
|
|
155
|
+
// segments in a media type string.
|
|
156
|
+
const mediaParamSeparator = /\s*;\s*/g;
|
|
157
|
+
|
|
158
|
+
function matchContentType(response: Response, pattern: string): boolean {
|
|
159
|
+
// `*` is a special case which means anything is acceptable.
|
|
160
|
+
if (pattern === "*") {
|
|
135
161
|
return true;
|
|
136
162
|
}
|
|
137
163
|
|
|
138
|
-
|
|
139
|
-
response.headers.get("content-type")
|
|
164
|
+
let contentType =
|
|
165
|
+
response.headers.get("content-type")?.trim() || "application/octet-stream";
|
|
166
|
+
contentType = contentType.toLowerCase();
|
|
140
167
|
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
168
|
+
const wantParts = pattern.toLowerCase().trim().split(mediaParamSeparator);
|
|
169
|
+
const [wantType = "", ...wantParams] = wantParts;
|
|
170
|
+
|
|
171
|
+
if (wantType.split("/").length !== 2) {
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const gotParts = contentType.split(mediaParamSeparator);
|
|
176
|
+
const [gotType = "", ...gotParams] = gotParts;
|
|
146
177
|
|
|
147
|
-
|
|
148
|
-
|
|
178
|
+
const [type = "", subtype = ""] = gotType.split("/");
|
|
179
|
+
if (!type || !subtype) {
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (
|
|
184
|
+
wantType !== "*/*" &&
|
|
185
|
+
gotType !== wantType &&
|
|
186
|
+
`${type}/*` !== wantType &&
|
|
187
|
+
`*/${subtype}` !== wantType
|
|
188
|
+
) {
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (gotParams.length < wantParams.length) {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const params = new Set(gotParams);
|
|
197
|
+
for (const wantParam of wantParams) {
|
|
198
|
+
if (!params.has(wantParam)) {
|
|
149
199
|
return false;
|
|
150
200
|
}
|
|
201
|
+
}
|
|
151
202
|
|
|
152
|
-
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
return idx >= 0;
|
|
203
|
+
return true;
|
|
156
204
|
}
|
|
157
205
|
|
|
158
206
|
const codeRangeRE = new RegExp("^[0-9]xx$", "i");
|
package/src/lib/sdks.ts
CHANGED
|
@@ -40,7 +40,11 @@ export class ClientSDK {
|
|
|
40
40
|
this.client = client;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
protected createRequest$(
|
|
43
|
+
protected createRequest$(
|
|
44
|
+
context: HookContext,
|
|
45
|
+
conf: RequestConfig,
|
|
46
|
+
options?: RequestOptions
|
|
47
|
+
): Request {
|
|
44
48
|
const { method, path, query, headers: opHeaders, security } = conf;
|
|
45
49
|
|
|
46
50
|
const base = conf.baseURL ?? this.baseURL;
|
|
@@ -95,12 +99,17 @@ export class ClientSDK {
|
|
|
95
99
|
headers.set(k, v);
|
|
96
100
|
}
|
|
97
101
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
102
|
+
const input = this.hooks$.beforeCreateRequest(context, {
|
|
103
|
+
url: reqURL,
|
|
104
|
+
options: {
|
|
105
|
+
...options?.fetchOptions,
|
|
106
|
+
body: conf.body ?? null,
|
|
107
|
+
headers,
|
|
108
|
+
method,
|
|
109
|
+
},
|
|
103
110
|
});
|
|
111
|
+
|
|
112
|
+
return new Request(input.url, input.options);
|
|
104
113
|
}
|
|
105
114
|
|
|
106
115
|
protected async do$(
|
package/src/lib/security.ts
CHANGED
package/src/sdk/dataset.ts
CHANGED
|
@@ -45,16 +45,17 @@ export class Dataset extends ClientSDK {
|
|
|
45
45
|
* This endpoint creates a new dataset
|
|
46
46
|
*/
|
|
47
47
|
async createDataset(
|
|
48
|
-
|
|
48
|
+
request: operations.CreateDatasetRequestBody,
|
|
49
49
|
options?: RequestOptions
|
|
50
50
|
): Promise<operations.CreateDatasetResponse> {
|
|
51
|
+
const input$ = request;
|
|
51
52
|
const headers$ = new Headers();
|
|
52
53
|
headers$.set("user-agent", SDK_METADATA.userAgent);
|
|
53
54
|
headers$.set("Content-Type", "application/json");
|
|
54
55
|
headers$.set("Accept", "application/json");
|
|
55
56
|
|
|
56
57
|
const payload$ = schemas$.parse(
|
|
57
|
-
input
|
|
58
|
+
input$,
|
|
58
59
|
(value$) => operations.CreateDatasetRequestBody$.outboundSchema.parse(value$),
|
|
59
60
|
"Input validation failed"
|
|
60
61
|
);
|
|
@@ -80,7 +81,8 @@ export class Dataset extends ClientSDK {
|
|
|
80
81
|
const securitySettings$ = this.resolveGlobalSecurity(security$);
|
|
81
82
|
|
|
82
83
|
const doOptions = { context, errorCodes: [] };
|
|
83
|
-
const request = this.createRequest$(
|
|
84
|
+
const request$ = this.createRequest$(
|
|
85
|
+
context,
|
|
84
86
|
{
|
|
85
87
|
security: securitySettings$,
|
|
86
88
|
method: "POST",
|
|
@@ -92,12 +94,13 @@ export class Dataset extends ClientSDK {
|
|
|
92
94
|
options
|
|
93
95
|
);
|
|
94
96
|
|
|
95
|
-
const response = await this.do$(request
|
|
97
|
+
const response = await this.do$(request$, doOptions);
|
|
96
98
|
|
|
97
99
|
const responseFields$ = {
|
|
98
100
|
ContentType: response.headers.get("content-type") ?? "application/octet-stream",
|
|
99
101
|
StatusCode: response.status,
|
|
100
102
|
RawResponse: response,
|
|
103
|
+
Headers: {},
|
|
101
104
|
};
|
|
102
105
|
|
|
103
106
|
if (this.matchResponse(response, 200, "application/json")) {
|
|
@@ -115,7 +118,11 @@ export class Dataset extends ClientSDK {
|
|
|
115
118
|
return result;
|
|
116
119
|
} else {
|
|
117
120
|
const responseBody = await response.text();
|
|
118
|
-
throw new errors.SDKError(
|
|
121
|
+
throw new errors.SDKError(
|
|
122
|
+
"Unexpected API response status or content-type",
|
|
123
|
+
response,
|
|
124
|
+
responseBody
|
|
125
|
+
);
|
|
119
126
|
}
|
|
120
127
|
}
|
|
121
128
|
|
|
@@ -166,7 +173,8 @@ export class Dataset extends ClientSDK {
|
|
|
166
173
|
const securitySettings$ = this.resolveGlobalSecurity(security$);
|
|
167
174
|
|
|
168
175
|
const doOptions = { context, errorCodes: [] };
|
|
169
|
-
const request = this.createRequest$(
|
|
176
|
+
const request$ = this.createRequest$(
|
|
177
|
+
context,
|
|
170
178
|
{
|
|
171
179
|
security: securitySettings$,
|
|
172
180
|
method: "DELETE",
|
|
@@ -178,12 +186,13 @@ export class Dataset extends ClientSDK {
|
|
|
178
186
|
options
|
|
179
187
|
);
|
|
180
188
|
|
|
181
|
-
const response = await this.do$(request
|
|
189
|
+
const response = await this.do$(request$, doOptions);
|
|
182
190
|
|
|
183
191
|
const responseFields$ = {
|
|
184
192
|
ContentType: response.headers.get("content-type") ?? "application/octet-stream",
|
|
185
193
|
StatusCode: response.status,
|
|
186
194
|
RawResponse: response,
|
|
195
|
+
Headers: {},
|
|
187
196
|
};
|
|
188
197
|
|
|
189
198
|
if (this.matchResponse(response, 200, "application/json")) {
|
|
@@ -201,7 +210,11 @@ export class Dataset extends ClientSDK {
|
|
|
201
210
|
return result;
|
|
202
211
|
} else {
|
|
203
212
|
const responseBody = await response.text();
|
|
204
|
-
throw new errors.SDKError(
|
|
213
|
+
throw new errors.SDKError(
|
|
214
|
+
"Unexpected API response status or content-type",
|
|
215
|
+
response,
|
|
216
|
+
responseBody
|
|
217
|
+
);
|
|
205
218
|
}
|
|
206
219
|
}
|
|
207
220
|
|
|
@@ -252,7 +265,8 @@ export class Dataset extends ClientSDK {
|
|
|
252
265
|
const securitySettings$ = this.resolveGlobalSecurity(security$);
|
|
253
266
|
|
|
254
267
|
const doOptions = { context, errorCodes: [] };
|
|
255
|
-
const request = this.createRequest$(
|
|
268
|
+
const request$ = this.createRequest$(
|
|
269
|
+
context,
|
|
256
270
|
{
|
|
257
271
|
security: securitySettings$,
|
|
258
272
|
method: "GET",
|
|
@@ -264,12 +278,13 @@ export class Dataset extends ClientSDK {
|
|
|
264
278
|
options
|
|
265
279
|
);
|
|
266
280
|
|
|
267
|
-
const response = await this.do$(request
|
|
281
|
+
const response = await this.do$(request$, doOptions);
|
|
268
282
|
|
|
269
283
|
const responseFields$ = {
|
|
270
284
|
ContentType: response.headers.get("content-type") ?? "application/octet-stream",
|
|
271
285
|
StatusCode: response.status,
|
|
272
286
|
RawResponse: response,
|
|
287
|
+
Headers: {},
|
|
273
288
|
};
|
|
274
289
|
|
|
275
290
|
if (this.matchResponse(response, 200, "application/json")) {
|
|
@@ -287,7 +302,11 @@ export class Dataset extends ClientSDK {
|
|
|
287
302
|
return result;
|
|
288
303
|
} else {
|
|
289
304
|
const responseBody = await response.text();
|
|
290
|
-
throw new errors.SDKError(
|
|
305
|
+
throw new errors.SDKError(
|
|
306
|
+
"Unexpected API response status or content-type",
|
|
307
|
+
response,
|
|
308
|
+
responseBody
|
|
309
|
+
);
|
|
291
310
|
}
|
|
292
311
|
}
|
|
293
312
|
|
|
@@ -344,7 +363,8 @@ export class Dataset extends ClientSDK {
|
|
|
344
363
|
const securitySettings$ = this.resolveGlobalSecurity(security$);
|
|
345
364
|
|
|
346
365
|
const doOptions = { context, errorCodes: [] };
|
|
347
|
-
const request = this.createRequest$(
|
|
366
|
+
const request$ = this.createRequest$(
|
|
367
|
+
context,
|
|
348
368
|
{
|
|
349
369
|
security: securitySettings$,
|
|
350
370
|
method: "POST",
|
|
@@ -356,12 +376,13 @@ export class Dataset extends ClientSDK {
|
|
|
356
376
|
options
|
|
357
377
|
);
|
|
358
378
|
|
|
359
|
-
const response = await this.do$(request
|
|
379
|
+
const response = await this.do$(request$, doOptions);
|
|
360
380
|
|
|
361
381
|
const responseFields$ = {
|
|
362
382
|
ContentType: response.headers.get("content-type") ?? "application/octet-stream",
|
|
363
383
|
StatusCode: response.status,
|
|
364
384
|
RawResponse: response,
|
|
385
|
+
Headers: {},
|
|
365
386
|
};
|
|
366
387
|
|
|
367
388
|
if (this.matchResponse(response, 200, "application/json")) {
|
|
@@ -379,7 +400,11 @@ export class Dataset extends ClientSDK {
|
|
|
379
400
|
return result;
|
|
380
401
|
} else {
|
|
381
402
|
const responseBody = await response.text();
|
|
382
|
-
throw new errors.SDKError(
|
|
403
|
+
throw new errors.SDKError(
|
|
404
|
+
"Unexpected API response status or content-type",
|
|
405
|
+
response,
|
|
406
|
+
responseBody
|
|
407
|
+
);
|
|
383
408
|
}
|
|
384
409
|
}
|
|
385
410
|
|
|
@@ -436,7 +461,8 @@ export class Dataset extends ClientSDK {
|
|
|
436
461
|
const securitySettings$ = this.resolveGlobalSecurity(security$);
|
|
437
462
|
|
|
438
463
|
const doOptions = { context, errorCodes: [] };
|
|
439
|
-
const request = this.createRequest$(
|
|
464
|
+
const request$ = this.createRequest$(
|
|
465
|
+
context,
|
|
440
466
|
{
|
|
441
467
|
security: securitySettings$,
|
|
442
468
|
method: "POST",
|
|
@@ -448,12 +474,13 @@ export class Dataset extends ClientSDK {
|
|
|
448
474
|
options
|
|
449
475
|
);
|
|
450
476
|
|
|
451
|
-
const response = await this.do$(request
|
|
477
|
+
const response = await this.do$(request$, doOptions);
|
|
452
478
|
|
|
453
479
|
const responseFields$ = {
|
|
454
480
|
ContentType: response.headers.get("content-type") ?? "application/octet-stream",
|
|
455
481
|
StatusCode: response.status,
|
|
456
482
|
RawResponse: response,
|
|
483
|
+
Headers: {},
|
|
457
484
|
};
|
|
458
485
|
|
|
459
486
|
if (this.matchResponse(response, 200, "application/json")) {
|
|
@@ -471,7 +498,11 @@ export class Dataset extends ClientSDK {
|
|
|
471
498
|
return result;
|
|
472
499
|
} else {
|
|
473
500
|
const responseBody = await response.text();
|
|
474
|
-
throw new errors.SDKError(
|
|
501
|
+
throw new errors.SDKError(
|
|
502
|
+
"Unexpected API response status or content-type",
|
|
503
|
+
response,
|
|
504
|
+
responseBody
|
|
505
|
+
);
|
|
475
506
|
}
|
|
476
507
|
}
|
|
477
508
|
}
|
package/src/sdk/element.ts
CHANGED
|
@@ -68,7 +68,8 @@ export class Element extends ClientSDK {
|
|
|
68
68
|
const securitySettings$ = this.resolveGlobalSecurity(security$);
|
|
69
69
|
|
|
70
70
|
const doOptions = { context, errorCodes: [] };
|
|
71
|
-
const request = this.createRequest$(
|
|
71
|
+
const request$ = this.createRequest$(
|
|
72
|
+
context,
|
|
72
73
|
{
|
|
73
74
|
security: securitySettings$,
|
|
74
75
|
method: "GET",
|
|
@@ -79,12 +80,13 @@ export class Element extends ClientSDK {
|
|
|
79
80
|
options
|
|
80
81
|
);
|
|
81
82
|
|
|
82
|
-
const response = await this.do$(request
|
|
83
|
+
const response = await this.do$(request$, doOptions);
|
|
83
84
|
|
|
84
85
|
const responseFields$ = {
|
|
85
86
|
ContentType: response.headers.get("content-type") ?? "application/octet-stream",
|
|
86
87
|
StatusCode: response.status,
|
|
87
88
|
RawResponse: response,
|
|
89
|
+
Headers: {},
|
|
88
90
|
};
|
|
89
91
|
|
|
90
92
|
if (this.matchResponse(response, 200, "application/json")) {
|
|
@@ -102,7 +104,11 @@ export class Element extends ClientSDK {
|
|
|
102
104
|
return result;
|
|
103
105
|
} else {
|
|
104
106
|
const responseBody = await response.text();
|
|
105
|
-
throw new errors.SDKError(
|
|
107
|
+
throw new errors.SDKError(
|
|
108
|
+
"Unexpected API response status or content-type",
|
|
109
|
+
response,
|
|
110
|
+
responseBody
|
|
111
|
+
);
|
|
106
112
|
}
|
|
107
113
|
}
|
|
108
114
|
}
|