@eggjs/koa 2.17.0 → 2.18.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.
@@ -0,0 +1,225 @@
1
+ /// <reference types="node" resolution-mode="require"/>
2
+ /// <reference types="node" resolution-mode="require"/>
3
+ /// <reference types="node" resolution-mode="require"/>
4
+ /// <reference types="node" resolution-mode="require"/>
5
+ /// <reference types="node" resolution-mode="require"/>
6
+ import util from 'node:util';
7
+ import Stream from 'node:stream';
8
+ import type { IncomingMessage, ServerResponse } from 'node:http';
9
+ import type Application from './application.js';
10
+ import type { ContextDelegation } from './context.js';
11
+ import type Request from './request.js';
12
+ export default class Response {
13
+ app: Application;
14
+ req: IncomingMessage;
15
+ res: ServerResponse;
16
+ ctx: ContextDelegation;
17
+ request: Request;
18
+ constructor(app: Application, ctx: ContextDelegation, req: IncomingMessage, res: ServerResponse);
19
+ /**
20
+ * Return the request socket.
21
+ */
22
+ get socket(): import("net").Socket | null;
23
+ /**
24
+ * Return response header.
25
+ */
26
+ get header(): import("http").OutgoingHttpHeaders;
27
+ /**
28
+ * Return response header, alias as response.header
29
+ */
30
+ get headers(): import("http").OutgoingHttpHeaders;
31
+ _explicitStatus: boolean;
32
+ /**
33
+ * Get response status code.
34
+ */
35
+ get status(): number;
36
+ /**
37
+ * Set response status code.
38
+ */
39
+ set status(code: number);
40
+ /**
41
+ * Get response status message
42
+ */
43
+ get message(): string;
44
+ /**
45
+ * Set response status message
46
+ */
47
+ set message(msg: string);
48
+ _body: any;
49
+ _explicitNullBody: boolean;
50
+ /**
51
+ * Get response body.
52
+ */
53
+ get body(): string | Buffer | object | Stream | null | undefined | boolean;
54
+ /**
55
+ * Set response body.
56
+ */
57
+ set body(val: string | Buffer | object | Stream | null | undefined | boolean);
58
+ /**
59
+ * Set Content-Length field to `n`.
60
+ */
61
+ set length(n: number | string | undefined);
62
+ /**
63
+ * Return parsed response Content-Length when present.
64
+ */
65
+ get length(): number | string | undefined;
66
+ /**
67
+ * Check if a header has been written to the socket.
68
+ */
69
+ get headerSent(): boolean;
70
+ /**
71
+ * Vary on `field`.
72
+ */
73
+ vary(field: string): void;
74
+ /**
75
+ * Perform a 302 redirect to `url`.
76
+ *
77
+ * The string "back" is special-cased
78
+ * to provide Referrer support, when Referrer
79
+ * is not present `alt` or "/" is used.
80
+ *
81
+ * Examples:
82
+ *
83
+ * this.redirect('back');
84
+ * this.redirect('back', '/index.html');
85
+ * this.redirect('/login');
86
+ * this.redirect('http://google.com'); // will format to 'http://google.com/'
87
+ */
88
+ redirect(url: string, alt?: string): void;
89
+ /**
90
+ * Set Content-Disposition header to "attachment" with optional `filename`.
91
+ */
92
+ attachment(filename?: string, options?: any): void;
93
+ /**
94
+ * Set Content-Type response header with `type` through `mime.lookup()`
95
+ * when it does not contain a charset.
96
+ *
97
+ * Examples:
98
+ *
99
+ * this.type = '.html';
100
+ * this.type = 'html';
101
+ * this.type = 'json';
102
+ * this.type = 'application/json';
103
+ * this.type = 'png';
104
+ */
105
+ set type(type: string | null | undefined);
106
+ /**
107
+ * Return the response mime type void of
108
+ * parameters such as "charset".
109
+ */
110
+ get type(): string | null | undefined;
111
+ /**
112
+ * Check whether the response is one of the listed types.
113
+ * Pretty much the same as `this.request.is()`.
114
+ *
115
+ * this.response.is('html')
116
+ * this.response.is('html', 'json')
117
+ */
118
+ is(type?: string | string[], ...types: string[]): string | false;
119
+ /**
120
+ * Set the Last-Modified date using a string or a Date.
121
+ *
122
+ * this.response.lastModified = new Date();
123
+ * this.response.lastModified = '2013-09-13';
124
+ */
125
+ set lastModified(val: string | Date | undefined);
126
+ /**
127
+ * Get the Last-Modified date in Date form, if it exists.
128
+ */
129
+ get lastModified(): Date | undefined;
130
+ /**
131
+ * Set the ETag of a response.
132
+ * This will normalize the quotes if necessary.
133
+ *
134
+ * this.response.etag = 'md5-hash-sum';
135
+ * this.response.etag = '"md5-hash-sum"';
136
+ * this.response.etag = 'W/"123456789"';
137
+ */
138
+ set etag(val: string);
139
+ /**
140
+ * Get the ETag of a response.
141
+ */
142
+ get etag(): string;
143
+ /**
144
+ * Return response header.
145
+ *
146
+ * Examples:
147
+ *
148
+ * this.get('Content-Type');
149
+ * // => "text/plain"
150
+ *
151
+ * this.get('content-type');
152
+ * // => "text/plain"
153
+ */
154
+ get<T = string | string[] | number>(field: string): T;
155
+ /**
156
+ * Returns true if the header identified by name is currently set in the outgoing headers.
157
+ * The header name matching is case-insensitive.
158
+ *
159
+ * Examples:
160
+ *
161
+ * this.has('Content-Type');
162
+ * // => true
163
+ *
164
+ * this.get('content-type');
165
+ * // => true
166
+ */
167
+ has(field: string): boolean;
168
+ /**
169
+ * Set header `field` to `val` or pass
170
+ * an object of header fields.
171
+ *
172
+ * Examples:
173
+ *
174
+ * this.set('Foo', ['bar', 'baz']);
175
+ * this.set('Accept', 'application/json');
176
+ * this.set({ Accept: 'text/plain', 'X-API-Key': 'tobi' });
177
+ */
178
+ set(field: string | Record<string, string>, val?: string | number | any[]): void;
179
+ /**
180
+ * Append additional header `field` with value `val`.
181
+ *
182
+ * Examples:
183
+ *
184
+ * ```
185
+ * this.append('Link', ['<http://localhost/>', '<http://localhost:3000/>']);
186
+ * this.append('Set-Cookie', 'foo=bar; Path=/; HttpOnly');
187
+ * this.append('Warning', '199 Miscellaneous warning');
188
+ */
189
+ append(field: string, val: string | string[]): void;
190
+ /**
191
+ * Remove header `field`.
192
+ */
193
+ remove(field: string): void;
194
+ /**
195
+ * Checks if the request is writable.
196
+ * Tests for the existence of the socket
197
+ * as node sometimes does not set it.
198
+ */
199
+ get writable(): boolean;
200
+ /**
201
+ * Inspect implementation.
202
+ */
203
+ inspect(): {
204
+ status: number;
205
+ message: string;
206
+ header: import("http").OutgoingHttpHeaders;
207
+ } | undefined;
208
+ [util.inspect.custom](): {
209
+ status: number;
210
+ message: string;
211
+ header: import("http").OutgoingHttpHeaders;
212
+ } | undefined;
213
+ /**
214
+ * Return JSON representation.
215
+ */
216
+ toJSON(): {
217
+ status: number;
218
+ message: string;
219
+ header: import("http").OutgoingHttpHeaders;
220
+ };
221
+ /**
222
+ * Flush any set headers and begin the body
223
+ */
224
+ flushHeaders(): void;
225
+ }
@@ -0,0 +1,447 @@
1
+ import assert from 'node:assert';
2
+ import { extname } from 'node:path';
3
+ import util from 'node:util';
4
+ import Stream from 'node:stream';
5
+ import contentDisposition from 'content-disposition';
6
+ import getType from 'cache-content-type';
7
+ import onFinish from 'on-finished';
8
+ import escape from 'escape-html';
9
+ import { is as typeis } from 'type-is';
10
+ import statuses from 'statuses';
11
+ import destroy from 'destroy';
12
+ import vary from 'vary';
13
+ import encodeUrl from 'encodeurl';
14
+ export default class Response {
15
+ app;
16
+ req;
17
+ res;
18
+ ctx;
19
+ request;
20
+ constructor(app, ctx, req, res) {
21
+ this.app = app;
22
+ this.req = req;
23
+ this.res = res;
24
+ this.ctx = ctx;
25
+ }
26
+ /**
27
+ * Return the request socket.
28
+ */
29
+ get socket() {
30
+ return this.res.socket;
31
+ }
32
+ /**
33
+ * Return response header.
34
+ */
35
+ get header() {
36
+ return this.res.getHeaders() || {};
37
+ }
38
+ /**
39
+ * Return response header, alias as response.header
40
+ */
41
+ get headers() {
42
+ return this.header;
43
+ }
44
+ _explicitStatus;
45
+ /**
46
+ * Get response status code.
47
+ */
48
+ get status() {
49
+ return this.res.statusCode;
50
+ }
51
+ /**
52
+ * Set response status code.
53
+ */
54
+ set status(code) {
55
+ if (this.headerSent)
56
+ return;
57
+ assert(Number.isInteger(code), 'status code must be a number');
58
+ assert(code >= 100 && code <= 999, `invalid status code: ${code}`);
59
+ this._explicitStatus = true;
60
+ this.res.statusCode = code;
61
+ if (this.req.httpVersionMajor < 2) {
62
+ this.res.statusMessage = statuses.message[code];
63
+ }
64
+ if (this.body && statuses.empty[code])
65
+ this.body = null;
66
+ }
67
+ /**
68
+ * Get response status message
69
+ */
70
+ get message() {
71
+ return this.res.statusMessage || statuses.message[this.status];
72
+ }
73
+ /**
74
+ * Set response status message
75
+ */
76
+ set message(msg) {
77
+ this.res.statusMessage = msg;
78
+ }
79
+ _body;
80
+ _explicitNullBody;
81
+ /**
82
+ * Get response body.
83
+ */
84
+ get body() {
85
+ return this._body;
86
+ }
87
+ /**
88
+ * Set response body.
89
+ */
90
+ set body(val) {
91
+ const original = this._body;
92
+ this._body = val;
93
+ // no content
94
+ if (val == null) {
95
+ if (!statuses.empty[this.status])
96
+ this.status = 204;
97
+ if (val === null)
98
+ this._explicitNullBody = true;
99
+ this.remove('Content-Type');
100
+ this.remove('Content-Length');
101
+ this.remove('Transfer-Encoding');
102
+ return;
103
+ }
104
+ // set the status
105
+ if (!this._explicitStatus)
106
+ this.status = 200;
107
+ // set the content-type only if not yet set
108
+ const setType = !this.has('Content-Type');
109
+ // string
110
+ if (typeof val === 'string') {
111
+ if (setType)
112
+ this.type = /^\s*</.test(val) ? 'html' : 'text';
113
+ this.length = Buffer.byteLength(val);
114
+ return;
115
+ }
116
+ // buffer
117
+ if (Buffer.isBuffer(val)) {
118
+ if (setType)
119
+ this.type = 'bin';
120
+ this.length = val.length;
121
+ return;
122
+ }
123
+ // stream
124
+ if (val instanceof Stream) {
125
+ onFinish(this.res, destroy.bind(null, val));
126
+ // eslint-disable-next-line eqeqeq
127
+ if (original != val) {
128
+ val.once('error', err => this.ctx.onerror(err));
129
+ // overwriting
130
+ if (original != null)
131
+ this.remove('Content-Length');
132
+ }
133
+ if (setType)
134
+ this.type = 'bin';
135
+ return;
136
+ }
137
+ // json
138
+ this.remove('Content-Length');
139
+ this.type = 'json';
140
+ }
141
+ /**
142
+ * Set Content-Length field to `n`.
143
+ */
144
+ set length(n) {
145
+ if (n === undefined)
146
+ return;
147
+ if (!this.has('Transfer-Encoding')) {
148
+ this.set('Content-Length', n);
149
+ }
150
+ }
151
+ /**
152
+ * Return parsed response Content-Length when present.
153
+ */
154
+ get length() {
155
+ if (this.has('Content-Length')) {
156
+ return parseInt(this.get('Content-Length'), 10) || 0;
157
+ }
158
+ const { body } = this;
159
+ if (!body || body instanceof Stream)
160
+ return undefined;
161
+ if (typeof body === 'string')
162
+ return Buffer.byteLength(body);
163
+ if (Buffer.isBuffer(body))
164
+ return body.length;
165
+ return Buffer.byteLength(JSON.stringify(body));
166
+ }
167
+ /**
168
+ * Check if a header has been written to the socket.
169
+ */
170
+ get headerSent() {
171
+ return this.res.headersSent;
172
+ }
173
+ /**
174
+ * Vary on `field`.
175
+ */
176
+ vary(field) {
177
+ if (this.headerSent)
178
+ return;
179
+ vary(this.res, field);
180
+ }
181
+ /**
182
+ * Perform a 302 redirect to `url`.
183
+ *
184
+ * The string "back" is special-cased
185
+ * to provide Referrer support, when Referrer
186
+ * is not present `alt` or "/" is used.
187
+ *
188
+ * Examples:
189
+ *
190
+ * this.redirect('back');
191
+ * this.redirect('back', '/index.html');
192
+ * this.redirect('/login');
193
+ * this.redirect('http://google.com'); // will format to 'http://google.com/'
194
+ */
195
+ redirect(url, alt) {
196
+ // location
197
+ if (url === 'back')
198
+ url = this.ctx.get('Referrer') || alt || '/';
199
+ if (url.startsWith('https://') || url.startsWith('http://')) {
200
+ // formatting url again avoid security escapes
201
+ url = new URL(url).toString();
202
+ }
203
+ this.set('Location', encodeUrl(url));
204
+ // status
205
+ if (!statuses.redirect[this.status])
206
+ this.status = 302;
207
+ // html
208
+ if (this.ctx.accepts('html')) {
209
+ url = escape(url);
210
+ this.type = 'text/html; charset=utf-8';
211
+ this.body = `Redirecting to <a href="${url}">${url}</a>.`;
212
+ return;
213
+ }
214
+ // text
215
+ this.type = 'text/plain; charset=utf-8';
216
+ this.body = `Redirecting to ${url}.`;
217
+ }
218
+ /**
219
+ * Set Content-Disposition header to "attachment" with optional `filename`.
220
+ */
221
+ attachment(filename, options) {
222
+ if (filename)
223
+ this.type = extname(filename);
224
+ this.set('Content-Disposition', contentDisposition(filename, options));
225
+ }
226
+ /**
227
+ * Set Content-Type response header with `type` through `mime.lookup()`
228
+ * when it does not contain a charset.
229
+ *
230
+ * Examples:
231
+ *
232
+ * this.type = '.html';
233
+ * this.type = 'html';
234
+ * this.type = 'json';
235
+ * this.type = 'application/json';
236
+ * this.type = 'png';
237
+ */
238
+ set type(type) {
239
+ if (!type) {
240
+ this.remove('Content-Type');
241
+ return;
242
+ }
243
+ const mimeType = getType(type);
244
+ if (mimeType) {
245
+ this.set('Content-Type', mimeType);
246
+ }
247
+ }
248
+ /**
249
+ * Return the response mime type void of
250
+ * parameters such as "charset".
251
+ */
252
+ get type() {
253
+ const type = this.get('Content-Type');
254
+ if (!type)
255
+ return '';
256
+ return type.split(';', 1)[0];
257
+ }
258
+ /**
259
+ * Check whether the response is one of the listed types.
260
+ * Pretty much the same as `this.request.is()`.
261
+ *
262
+ * this.response.is('html')
263
+ * this.response.is('html', 'json')
264
+ */
265
+ is(type, ...types) {
266
+ const testTypes = Array.isArray(type) ? type :
267
+ (type ? [type] : []);
268
+ return typeis(this.type, [...testTypes, ...types]);
269
+ }
270
+ /**
271
+ * Set the Last-Modified date using a string or a Date.
272
+ *
273
+ * this.response.lastModified = new Date();
274
+ * this.response.lastModified = '2013-09-13';
275
+ */
276
+ set lastModified(val) {
277
+ if (typeof val === 'string')
278
+ val = new Date(val);
279
+ if (val) {
280
+ this.set('Last-Modified', val.toUTCString());
281
+ }
282
+ }
283
+ /**
284
+ * Get the Last-Modified date in Date form, if it exists.
285
+ */
286
+ get lastModified() {
287
+ const date = this.get('last-modified');
288
+ if (date)
289
+ return new Date(date);
290
+ }
291
+ /**
292
+ * Set the ETag of a response.
293
+ * This will normalize the quotes if necessary.
294
+ *
295
+ * this.response.etag = 'md5-hash-sum';
296
+ * this.response.etag = '"md5-hash-sum"';
297
+ * this.response.etag = 'W/"123456789"';
298
+ */
299
+ set etag(val) {
300
+ if (!/^(W\/)?"/.test(val))
301
+ val = `"${val}"`;
302
+ this.set('ETag', val);
303
+ }
304
+ /**
305
+ * Get the ETag of a response.
306
+ */
307
+ get etag() {
308
+ return this.get('ETag');
309
+ }
310
+ /**
311
+ * Return response header.
312
+ *
313
+ * Examples:
314
+ *
315
+ * this.get('Content-Type');
316
+ * // => "text/plain"
317
+ *
318
+ * this.get('content-type');
319
+ * // => "text/plain"
320
+ */
321
+ get(field) {
322
+ return (this.header[field.toLowerCase()] || '');
323
+ }
324
+ /**
325
+ * Returns true if the header identified by name is currently set in the outgoing headers.
326
+ * The header name matching is case-insensitive.
327
+ *
328
+ * Examples:
329
+ *
330
+ * this.has('Content-Type');
331
+ * // => true
332
+ *
333
+ * this.get('content-type');
334
+ * // => true
335
+ */
336
+ has(field) {
337
+ return this.res.hasHeader(field);
338
+ }
339
+ /**
340
+ * Set header `field` to `val` or pass
341
+ * an object of header fields.
342
+ *
343
+ * Examples:
344
+ *
345
+ * this.set('Foo', ['bar', 'baz']);
346
+ * this.set('Accept', 'application/json');
347
+ * this.set({ Accept: 'text/plain', 'X-API-Key': 'tobi' });
348
+ */
349
+ set(field, val) {
350
+ if (this.headerSent)
351
+ return;
352
+ if (typeof field === 'string') {
353
+ if (Array.isArray(val)) {
354
+ val = val.map(v => {
355
+ return typeof v === 'string' ? v : String(v);
356
+ });
357
+ }
358
+ else if (typeof val !== 'string') {
359
+ val = String(val);
360
+ }
361
+ this.res.setHeader(field, val);
362
+ }
363
+ else {
364
+ for (const key in field) {
365
+ this.set(key, field[key]);
366
+ }
367
+ }
368
+ }
369
+ /**
370
+ * Append additional header `field` with value `val`.
371
+ *
372
+ * Examples:
373
+ *
374
+ * ```
375
+ * this.append('Link', ['<http://localhost/>', '<http://localhost:3000/>']);
376
+ * this.append('Set-Cookie', 'foo=bar; Path=/; HttpOnly');
377
+ * this.append('Warning', '199 Miscellaneous warning');
378
+ */
379
+ append(field, val) {
380
+ const prev = this.get(field);
381
+ let value = val;
382
+ if (prev) {
383
+ value = Array.isArray(prev)
384
+ ? prev.concat(value)
385
+ : [prev].concat(val);
386
+ }
387
+ return this.set(field, value);
388
+ }
389
+ /**
390
+ * Remove header `field`.
391
+ */
392
+ remove(field) {
393
+ if (this.headerSent)
394
+ return;
395
+ this.res.removeHeader(field);
396
+ }
397
+ /**
398
+ * Checks if the request is writable.
399
+ * Tests for the existence of the socket
400
+ * as node sometimes does not set it.
401
+ */
402
+ get writable() {
403
+ // can't write any more after response finished
404
+ // response.writableEnded is available since Node > 12.9
405
+ // https://nodejs.org/api/http.html#http_response_writableended
406
+ // response.finished is undocumented feature of previous Node versions
407
+ // https://stackoverflow.com/questions/16254385/undocumented-response-finished-in-node-js
408
+ if (this.res.writableEnded || this.res.finished)
409
+ return false;
410
+ const socket = this.res.socket;
411
+ // There are already pending outgoing res, but still writable
412
+ // https://github.com/nodejs/node/blob/v4.4.7/lib/_http_server.js#L486
413
+ if (!socket)
414
+ return true;
415
+ return socket.writable;
416
+ }
417
+ /**
418
+ * Inspect implementation.
419
+ */
420
+ inspect() {
421
+ if (!this.res)
422
+ return;
423
+ const o = this.toJSON();
424
+ Reflect.set(o, 'body', this.body);
425
+ return o;
426
+ }
427
+ [util.inspect.custom]() {
428
+ return this.inspect();
429
+ }
430
+ /**
431
+ * Return JSON representation.
432
+ */
433
+ toJSON() {
434
+ return {
435
+ status: this.status,
436
+ message: this.message,
437
+ header: this.header,
438
+ };
439
+ }
440
+ /**
441
+ * Flush any set headers and begin the body
442
+ */
443
+ flushHeaders() {
444
+ this.res.flushHeaders();
445
+ }
446
+ }
447
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzcG9uc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcmVzcG9uc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxNQUFNLE1BQU0sYUFBYSxDQUFDO0FBQ2pDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDcEMsT0FBTyxJQUFJLE1BQU0sV0FBVyxDQUFDO0FBQzdCLE9BQU8sTUFBTSxNQUFNLGFBQWEsQ0FBQztBQUVqQyxPQUFPLGtCQUFrQixNQUFNLHFCQUFxQixDQUFDO0FBQ3JELE9BQU8sT0FBTyxNQUFNLG9CQUFvQixDQUFDO0FBQ3pDLE9BQU8sUUFBUSxNQUFNLGFBQWEsQ0FBQztBQUNuQyxPQUFPLE1BQU0sTUFBTSxhQUFhLENBQUM7QUFDakMsT0FBTyxFQUFFLEVBQUUsSUFBSSxNQUFNLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFDdkMsT0FBTyxRQUFRLE1BQU0sVUFBVSxDQUFDO0FBQ2hDLE9BQU8sT0FBTyxNQUFNLFNBQVMsQ0FBQztBQUM5QixPQUFPLElBQUksTUFBTSxNQUFNLENBQUM7QUFDeEIsT0FBTyxTQUFTLE1BQU0sV0FBVyxDQUFDO0FBS2xDLE1BQU0sQ0FBQyxPQUFPLE9BQU8sUUFBUTtJQUMzQixHQUFHLENBQWM7SUFDakIsR0FBRyxDQUFrQjtJQUNyQixHQUFHLENBQWlCO0lBQ3BCLEdBQUcsQ0FBb0I7SUFDdkIsT0FBTyxDQUFVO0lBRWpCLFlBQVksR0FBZ0IsRUFBRSxHQUFzQixFQUFFLEdBQW9CLEVBQUUsR0FBbUI7UUFDN0YsSUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUM7UUFDZixJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQztRQUNmLElBQUksQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDO1FBQ2YsSUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUM7SUFDakIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsSUFBSSxNQUFNO1FBQ1IsT0FBTyxJ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
@@ -0,0 +1,10 @@
1
+ export type CustomError = Error & {
2
+ headers?: Record<string, string>;
3
+ status?: number;
4
+ statusCode?: number;
5
+ code?: string;
6
+ expose?: boolean;
7
+ };
8
+ export type AnyProto = {
9
+ [key: string]: any;
10
+ };