@gataca/qr 2.0.1 → 2.0.2

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 (65) hide show
  1. package/dist/gatacaqr/app-globals-0f993ce5.js +3 -0
  2. package/dist/gatacaqr/css-shim-8eec97b3.js +4 -0
  3. package/dist/gatacaqr/dom-1b0cf05d.js +73 -0
  4. package/dist/{components/gat-icon-refresh.js → gatacaqr/gat-icon-refresh-8d3dc25f.js} +1 -23
  5. package/dist/{components/gataca-autoqr.js → gatacaqr/gataca-autoqr.entry.js} +7 -69
  6. package/dist/{components/gataca-qr2.js → gatacaqr/gataca-qr.entry.js} +9 -49
  7. package/dist/gatacaqr/gataca-qrdisplay-0320bb25.js +97 -0
  8. package/dist/gatacaqr/gataca-qrdisplay.entry.js +2 -0
  9. package/dist/{components/gataca-qrws2.js → gatacaqr/gataca-qrws.entry.js} +9 -49
  10. package/dist/{components/gataca-ssibutton2.js → gatacaqr/gataca-ssibutton.entry.js} +8 -52
  11. package/dist/{components/gataca-ssibuttonws2.js → gatacaqr/gataca-ssibuttonws.entry.js} +7 -53
  12. package/dist/gatacaqr/gatacaqr.esm.js +129 -1
  13. package/dist/gatacaqr/index-d0db23e4.js +3262 -0
  14. package/dist/gatacaqr/index.esm.js +1 -1
  15. package/dist/gatacaqr/shadow-css-146f2f6f.js +387 -0
  16. package/package.json +1 -1
  17. package/dist/cjs/gataca-autoqr_6.cjs.entry.js +0 -624
  18. package/dist/cjs/gatacaqr.cjs.js +0 -19
  19. package/dist/cjs/index-0b7a1532.js +0 -1410
  20. package/dist/cjs/index.cjs.js +0 -16
  21. package/dist/cjs/loader.cjs.js +0 -21
  22. package/dist/cjs/utils-383ee834.js +0 -26
  23. package/dist/collection/assets/icons/gat-icon-alert.svg +0 -5
  24. package/dist/collection/assets/icons/gat-icon-check.svg +0 -5
  25. package/dist/collection/assets/icons/gat-icon-refresh.svg +0 -4
  26. package/dist/collection/assets/images/logo_gataca.svg +0 -26
  27. package/dist/collection/collection-manifest.json +0 -17
  28. package/dist/collection/components/gataca-autoqr/gataca-autoqr.css +0 -116
  29. package/dist/collection/components/gataca-autoqr/gataca-autoqr.js +0 -325
  30. package/dist/collection/components/gataca-qr/gataca-qr.css +0 -251
  31. package/dist/collection/components/gataca-qr/gataca-qr.js +0 -557
  32. package/dist/collection/components/gataca-qrdisplay/gataca-qrdisplay.js +0 -154
  33. package/dist/collection/components/gataca-qrws/gataca-qrws.css +0 -251
  34. package/dist/collection/components/gataca-qrws/gataca-qrws.js +0 -566
  35. package/dist/collection/components/gataca-ssibutton/gataca-ssibutton.css +0 -116
  36. package/dist/collection/components/gataca-ssibutton/gataca-ssibutton.js +0 -395
  37. package/dist/collection/components/gataca-ssibuttonws/gataca-ssibuttonws.css +0 -116
  38. package/dist/collection/components/gataca-ssibuttonws/gataca-ssibuttonws.js +0 -410
  39. package/dist/collection/index.js +0 -2
  40. package/dist/collection/utils/index.js +0 -1
  41. package/dist/collection/utils/utils.js +0 -21
  42. package/dist/components/gataca-qr.js +0 -6
  43. package/dist/components/gataca-qrdisplay.js +0 -6
  44. package/dist/components/gataca-qrdisplay2.js +0 -93
  45. package/dist/components/gataca-qrws.js +0 -6
  46. package/dist/components/gataca-ssibutton.js +0 -6
  47. package/dist/components/gataca-ssibuttonws.js +0 -6
  48. package/dist/components/index.js +0 -8
  49. package/dist/esm/gataca-autoqr_6.entry.js +0 -615
  50. package/dist/esm/gatacaqr.js +0 -17
  51. package/dist/esm/index-19eef502.js +0 -1384
  52. package/dist/esm/index.js +0 -1
  53. package/dist/esm/loader.js +0 -17
  54. package/dist/esm/polyfills/core-js.js +0 -11
  55. package/dist/esm/polyfills/css-shim.js +0 -1
  56. package/dist/esm/polyfills/dom.js +0 -79
  57. package/dist/esm/polyfills/es5-html-element.js +0 -1
  58. package/dist/esm/polyfills/index.js +0 -34
  59. package/dist/esm/polyfills/system.js +0 -6
  60. package/dist/gatacaqr/p-4807b345.entry.js +0 -1
  61. package/dist/gatacaqr/p-a6f85341.js +0 -2
  62. package/dist/gatacaqr/p-b8ba109f.js +0 -1
  63. package/dist/index.cjs.js +0 -1
  64. package/dist/index.js +0 -1
  65. /package/dist/{esm → gatacaqr}/utils-05ba6c9f.js +0 -0
@@ -1,557 +0,0 @@
1
- import { h, } from "@stencil/core";
2
- import alertIcon from "../../assets/icons/gat-icon-alert.svg";
3
- import successIcon from "../../assets/icons/gat-icon-check.svg";
4
- import refreshIcon from "../../assets/icons/gat-icon-refresh.svg";
5
- import logoGataca from "../../assets/images/logo_gataca.svg";
6
- import "../gataca-qrdisplay/gataca-qrdisplay";
7
- import { base64UrlEncode, checkMobile, RESULT_STATUS } from "../../utils/utils";
8
- const DEEP_LINK_PREFIX = "https://gataca.page.link/?apn=com.gatacaapp&ibi=com.gataca.wallet&link=";
9
- //Default values
10
- const DEFAULT_SESSION_TIMEOUT = 300; //5mins as in connect
11
- const DEFAULT_POLLING_FREQ = 3;
12
- const QR_ROLE_CONNECT = "connect";
13
- const FUNCTION_ROLES = {
14
- connect: "scan",
15
- certify: "credential",
16
- };
17
- export class GatacaQR {
18
- constructor() { this.checkStatus = undefined; this.createSession = undefined; this.successCallback = undefined; this.errorCallback = undefined; this.qrRole = undefined; this.callbackServer = undefined; this.autostart = true; this.autorefresh = false; this.v2 = false; this.qrModalTitle = "Quick Access"; this.qrModalDescription = "Sign up or sign in by scanning the QR Code with the Gataca Wallet"; this.hideBrandTitle = false; this.sessionTimeout = DEFAULT_SESSION_TIMEOUT; this.pollingFrequency = DEFAULT_POLLING_FREQ; this.dynamicLink = true; this.sessionId = undefined; this.authenticationRequest = undefined; this.sessionData = undefined; this.result = RESULT_STATUS.NOT_STARTED; }
19
- disconnectedCallback() {
20
- this.stop();
21
- }
22
- async componentDidLoad() {
23
- if (this.autostart) {
24
- await this.display();
25
- }
26
- }
27
- /**
28
- * Force manually the display of a QR
29
- */
30
- async display() {
31
- await this.getSessionId();
32
- this.result = RESULT_STATUS.ONGOING;
33
- this.poll()
34
- .then((data) => {
35
- this.result = RESULT_STATUS.SUCCESS;
36
- this.sessionData = data;
37
- this.gatacaLoginCompleted.emit(data);
38
- this.successCallback(data);
39
- })
40
- .catch((err) => {
41
- this.clean();
42
- let expired = err === RESULT_STATUS.EXPIRED;
43
- if (expired && this.autorefresh) {
44
- this.display();
45
- }
46
- else {
47
- if (err !== RESULT_STATUS.NOT_STARTED) {
48
- let error = expired
49
- ? new Error("User did not scan the QR in the alloted time")
50
- : new Error("Provided user credentials couldn't be validated");
51
- this.result = err;
52
- this.gatacaLoginFailed.emit(error);
53
- this.errorCallback(error);
54
- }
55
- }
56
- });
57
- if (checkMobile() && this.dynamicLink) {
58
- window.location.href = this.getLink();
59
- }
60
- }
61
- /**
62
- * Stop manually an ongoing session
63
- */
64
- async stop() {
65
- this.clean();
66
- if (this.result === RESULT_STATUS.ONGOING) {
67
- this.result = RESULT_STATUS.NOT_STARTED;
68
- }
69
- }
70
- clean() {
71
- this.sessionData = undefined;
72
- this.sessionId = undefined;
73
- }
74
- /**
75
- * Retrieve manually the session data on a successful login
76
- */
77
- async getSessionData() {
78
- return this.sessionData
79
- ? Promise.resolve(this.sessionData)
80
- : Promise.reject(new Error("No successful login"));
81
- }
82
- async getSessionId() {
83
- if (this.sessionId) {
84
- return this.sessionId;
85
- }
86
- let { sessionId, authenticationRequest } = await this.createSession();
87
- this.sessionId = sessionId;
88
- this.authenticationRequest = authenticationRequest;
89
- return this.sessionId;
90
- }
91
- getLink() {
92
- if (this.v2 && this.qrRole == QR_ROLE_CONNECT) {
93
- return this.authenticationRequest;
94
- }
95
- let op = FUNCTION_ROLES[this.qrRole];
96
- let link = "https://gataca.page.link/" + op + "?";
97
- link +=
98
- this.qrRole === QR_ROLE_CONNECT
99
- ? "session=" + this.sessionId
100
- : "process=" + this.sessionId;
101
- link +=
102
- "&callback=" + base64UrlEncode(encodeURIComponent(this.callbackServer));
103
- link = encodeURIComponent(link);
104
- return this.dynamicLink ? DEEP_LINK_PREFIX + link : link;
105
- }
106
- async poll() {
107
- let endTime = new Date().getTime() +
108
- (this.sessionTimeout || DEFAULT_SESSION_TIMEOUT) * 1000;
109
- let interval = (this.pollingFrequency || DEFAULT_POLLING_FREQ) * 1000;
110
- let checkFunc = async (component) => {
111
- if (component.result === RESULT_STATUS.NOT_STARTED) {
112
- return { result: RESULT_STATUS.NOT_STARTED };
113
- }
114
- let id = await component.getSessionId();
115
- return component.checkStatus(id);
116
- };
117
- let component = this;
118
- let checkCondition = async function (resolve, reject) {
119
- // If the condition is met, we're done!
120
- let { result, data } = await checkFunc(component);
121
- switch (result) {
122
- case RESULT_STATUS.SUCCESS:
123
- resolve(data);
124
- break;
125
- case RESULT_STATUS.ONGOING:
126
- if (component.sessionTimeout > 0 && new Date().getTime() < endTime) {
127
- setTimeout(checkCondition, interval, resolve, reject);
128
- }
129
- else {
130
- reject(RESULT_STATUS.EXPIRED);
131
- }
132
- break;
133
- default:
134
- reject(result);
135
- break;
136
- }
137
- };
138
- return new Promise(checkCondition);
139
- }
140
- renderQRSection() {
141
- switch (this.result) {
142
- case RESULT_STATUS.NOT_STARTED:
143
- return this.renderRetryButton();
144
- case RESULT_STATUS.ONGOING:
145
- return this.renderQR(this.getLink(), 300, true);
146
- case RESULT_STATUS.EXPIRED:
147
- return this.renderRetryButton("QR Code expired");
148
- case RESULT_STATUS.FAILED:
149
- return this.renderRetryButton("User credentials not validated");
150
- case RESULT_STATUS.SUCCESS:
151
- return this.renderSuccess();
152
- }
153
- }
154
- renderSuccess() {
155
- return (h("div", { class: "success" }, h("img", { src: successIcon, height: 52, width: 52 }), h("p", { class: "successMsg" }, "Successful Connection!")));
156
- }
157
- renderRetryButton(errorMessage) {
158
- return (h("div", { class: "reload" }, h("div", { id: "notify", onClick: () => this.display() }, h("img", { src: refreshIcon, height: 24, width: 24 }), h("p", { class: "qrDescription" }, "Click inside the box to "), errorMessage ? (h("p", { class: "qrDescription bold" }, "Refresh QR Code")) : (h("p", { class: "qrDescription bold" }, "Scan QR Code")), errorMessage && (h("div", { class: "alert" }, h("img", { src: alertIcon, height: 24, width: 24 }), h("p", null, errorMessage)))), h("div", { id: "qrwait" }, this.renderQR("waiting to start a session", 250))));
159
- }
160
- renderQR(value, size, useLogo) {
161
- return (h("gataca-qrdisplay", { qrData: value, rounded: true, size: size, "logo-size": useLogo ? 0.33 : 0 }));
162
- }
163
- render() {
164
- return (h("div", { class: "popUpContainer" }, h("div", { class: "modal-window is-visible", onClick: (event) => {
165
- event.stopPropagation();
166
- } }, h("div", { class: "modal-window__content" }, h("div", { class: "qrTitleContainer" }, h("p", { class: "qrTitle" }, this.qrModalTitle), !this.hideBrandTitle && (h("p", { class: "qrBrand" }, "by Gataca", " ", h("span", null, h("img", { src: logoGataca })))), this.result !== RESULT_STATUS.SUCCESS && (h("p", { class: "qrDescription" }, this.qrModalDescription))), h("div", { class: "qrSection" }, this.renderQRSection())))));
167
- }
168
- static get is() { return "gataca-qr"; }
169
- static get encapsulation() { return "shadow"; }
170
- static get originalStyleUrls() {
171
- return {
172
- "$": ["gataca-qr.scss"]
173
- };
174
- }
175
- static get styleUrls() {
176
- return {
177
- "$": ["gataca-qr.css"]
178
- };
179
- }
180
- static get properties() {
181
- return {
182
- "checkStatus": {
183
- "type": "unknown",
184
- "mutable": false,
185
- "complexType": {
186
- "original": "(\n id?: string\n ) => Promise<{ result: RESULT_STATUS; data?: any }>",
187
- "resolved": "(id?: string) => Promise<{ result: RESULT_STATUS; data?: any; }>",
188
- "references": {
189
- "Promise": {
190
- "location": "global"
191
- },
192
- "RESULT_STATUS": {
193
- "location": "import",
194
- "path": "../../utils/utils"
195
- }
196
- }
197
- },
198
- "required": false,
199
- "optional": true,
200
- "docs": {
201
- "tags": [],
202
- "text": "***Mandatory***\nCheck status function to query the current status of the session\nThe function must query a client endpoint to check the status. That endpoint must return an error if the session has expired."
203
- },
204
- "defaultValue": "undefined"
205
- },
206
- "createSession": {
207
- "type": "unknown",
208
- "mutable": false,
209
- "complexType": {
210
- "original": "() => Promise<{\n sessionId: string;\n authenticationRequest?: string;\n }>",
211
- "resolved": "() => Promise<{ sessionId: string; authenticationRequest?: string; }>",
212
- "references": {
213
- "Promise": {
214
- "location": "global"
215
- }
216
- }
217
- },
218
- "required": false,
219
- "optional": true,
220
- "docs": {
221
- "tags": [],
222
- "text": "***Mandatory***\nCreate session function to generate a new Session\nUsing V1, it can provide just a session Id\nUsing V2, it must provide also the authentication request. The session Id is the id of the presentation definition"
223
- },
224
- "defaultValue": "undefined"
225
- },
226
- "successCallback": {
227
- "type": "unknown",
228
- "mutable": false,
229
- "complexType": {
230
- "original": "(data?: any) => void",
231
- "resolved": "(data?: any) => void",
232
- "references": {}
233
- },
234
- "required": false,
235
- "optional": false,
236
- "docs": {
237
- "tags": [],
238
- "text": "***Mandatory***\nCallback fired upon session correctly verified\nIf not set, session validation wouldn't trigger any action\nThe session data and a possible token will be sent as parameters to the callback"
239
- },
240
- "defaultValue": "undefined"
241
- },
242
- "errorCallback": {
243
- "type": "unknown",
244
- "mutable": false,
245
- "complexType": {
246
- "original": "(error?: Error) => void",
247
- "resolved": "(error?: Error) => void",
248
- "references": {
249
- "Error": {
250
- "location": "global"
251
- }
252
- }
253
- },
254
- "required": false,
255
- "optional": false,
256
- "docs": {
257
- "tags": [],
258
- "text": "***Mandatory***\nCallback fired upon session expired or invalid\nIf not set, session error would not be handled\nAn error containing information will be passed as parameter"
259
- },
260
- "defaultValue": "undefined"
261
- },
262
- "qrRole": {
263
- "type": "string",
264
- "mutable": false,
265
- "complexType": {
266
- "original": "string",
267
- "resolved": "string",
268
- "references": {}
269
- },
270
- "required": false,
271
- "optional": false,
272
- "docs": {
273
- "tags": [],
274
- "text": "***Mandatory***\nDecide if scanning the credential as a verifier to request credentials\nor as an issuer too issue credentials.\nOptions: connect | certify"
275
- },
276
- "attribute": "qr-role",
277
- "reflect": false
278
- },
279
- "callbackServer": {
280
- "type": "string",
281
- "mutable": false,
282
- "complexType": {
283
- "original": "string",
284
- "resolved": "string",
285
- "references": {}
286
- },
287
- "required": false,
288
- "optional": false,
289
- "docs": {
290
- "tags": [],
291
- "text": "***Mandatory just for V1***\nConnect/Certify Server where the wallet will send the data"
292
- },
293
- "attribute": "callback-server",
294
- "reflect": false
295
- },
296
- "autostart": {
297
- "type": "boolean",
298
- "mutable": false,
299
- "complexType": {
300
- "original": "boolean",
301
- "resolved": "boolean",
302
- "references": {}
303
- },
304
- "required": false,
305
- "optional": false,
306
- "docs": {
307
- "tags": [],
308
- "text": "_[Optional]_\nSet to enable autoload when the QR is displayed. By default it is true"
309
- },
310
- "attribute": "autostart",
311
- "reflect": false,
312
- "defaultValue": "true"
313
- },
314
- "autorefresh": {
315
- "type": "boolean",
316
- "mutable": false,
317
- "complexType": {
318
- "original": "boolean",
319
- "resolved": "boolean",
320
- "references": {}
321
- },
322
- "required": false,
323
- "optional": false,
324
- "docs": {
325
- "tags": [],
326
- "text": "_[Optional]_\nSet to refresh the session automatically upon expiration. By default it is false"
327
- },
328
- "attribute": "autorefresh",
329
- "reflect": false,
330
- "defaultValue": "false"
331
- },
332
- "v2": {
333
- "type": "boolean",
334
- "mutable": false,
335
- "complexType": {
336
- "original": "boolean",
337
- "resolved": "boolean",
338
- "references": {}
339
- },
340
- "required": false,
341
- "optional": true,
342
- "docs": {
343
- "tags": [],
344
- "text": "_[Optional]_\nSet to use v2 links. The create session must be providing both an authentication request and a session Id"
345
- },
346
- "attribute": "v-2",
347
- "reflect": false,
348
- "defaultValue": "false"
349
- },
350
- "qrModalTitle": {
351
- "type": "string",
352
- "mutable": false,
353
- "complexType": {
354
- "original": "string",
355
- "resolved": "string",
356
- "references": {}
357
- },
358
- "required": false,
359
- "optional": true,
360
- "docs": {
361
- "tags": [],
362
- "text": "_[Optional]_\nModifies the qr headline title"
363
- },
364
- "attribute": "qr-modal-title",
365
- "reflect": false,
366
- "defaultValue": "\"Quick Access\""
367
- },
368
- "qrModalDescription": {
369
- "type": "string",
370
- "mutable": false,
371
- "complexType": {
372
- "original": "string",
373
- "resolved": "string",
374
- "references": {}
375
- },
376
- "required": false,
377
- "optional": true,
378
- "docs": {
379
- "tags": [],
380
- "text": "_[Optional]_\nModifies the Modal description"
381
- },
382
- "attribute": "qr-modal-description",
383
- "reflect": false,
384
- "defaultValue": "\"Sign up or sign in by scanning the QR Code with the Gataca Wallet\""
385
- },
386
- "hideBrandTitle": {
387
- "type": "boolean",
388
- "mutable": false,
389
- "complexType": {
390
- "original": "boolean",
391
- "resolved": "boolean",
392
- "references": {}
393
- },
394
- "required": false,
395
- "optional": true,
396
- "docs": {
397
- "tags": [],
398
- "text": "_[Optional]_\nBoolean to show or not show the gataca brand title"
399
- },
400
- "attribute": "hide-brand-title",
401
- "reflect": false,
402
- "defaultValue": "false"
403
- },
404
- "sessionTimeout": {
405
- "type": "number",
406
- "mutable": false,
407
- "complexType": {
408
- "original": "number",
409
- "resolved": "number",
410
- "references": {}
411
- },
412
- "required": false,
413
- "optional": true,
414
- "docs": {
415
- "tags": [],
416
- "text": "_[Optional]_\nMaximum time window to display the session"
417
- },
418
- "attribute": "session-timeout",
419
- "reflect": false,
420
- "defaultValue": "DEFAULT_SESSION_TIMEOUT"
421
- },
422
- "pollingFrequency": {
423
- "type": "number",
424
- "mutable": false,
425
- "complexType": {
426
- "original": "number",
427
- "resolved": "number",
428
- "references": {}
429
- },
430
- "required": false,
431
- "optional": true,
432
- "docs": {
433
- "tags": [],
434
- "text": "_[Optional]_\nFrequency in seconds to check if the session has been validated"
435
- },
436
- "attribute": "polling-frequency",
437
- "reflect": false,
438
- "defaultValue": "DEFAULT_POLLING_FREQ"
439
- },
440
- "dynamicLink": {
441
- "type": "boolean",
442
- "mutable": false,
443
- "complexType": {
444
- "original": "boolean",
445
- "resolved": "boolean",
446
- "references": {}
447
- },
448
- "required": false,
449
- "optional": true,
450
- "docs": {
451
- "tags": [],
452
- "text": "_[Optional]_\nDisplay a link containing a dynamic link to invoke the wallet if closed"
453
- },
454
- "attribute": "dynamic-link",
455
- "reflect": false,
456
- "defaultValue": "true"
457
- }
458
- };
459
- }
460
- static get states() {
461
- return {
462
- "sessionId": {},
463
- "authenticationRequest": {},
464
- "sessionData": {},
465
- "result": {}
466
- };
467
- }
468
- static get events() {
469
- return [{
470
- "method": "gatacaLoginCompleted",
471
- "name": "gatacaLoginCompleted",
472
- "bubbles": true,
473
- "cancelable": true,
474
- "composed": true,
475
- "docs": {
476
- "tags": [],
477
- "text": "GatacaLoginCompleted event, triggered with session data upon login success"
478
- },
479
- "complexType": {
480
- "original": "any",
481
- "resolved": "any",
482
- "references": {}
483
- }
484
- }, {
485
- "method": "gatacaLoginFailed",
486
- "name": "gatacaLoginFailed",
487
- "bubbles": true,
488
- "cancelable": true,
489
- "composed": true,
490
- "docs": {
491
- "tags": [],
492
- "text": "GatacaLoginFailed event, triggered with error upon login failure"
493
- },
494
- "complexType": {
495
- "original": "any",
496
- "resolved": "any",
497
- "references": {}
498
- }
499
- }];
500
- }
501
- static get methods() {
502
- return {
503
- "display": {
504
- "complexType": {
505
- "signature": "() => Promise<void>",
506
- "parameters": [],
507
- "references": {
508
- "Promise": {
509
- "location": "global"
510
- },
511
- "RESULT_STATUS": {
512
- "location": "import",
513
- "path": "../../utils/utils"
514
- }
515
- },
516
- "return": "Promise<void>"
517
- },
518
- "docs": {
519
- "text": "Force manually the display of a QR",
520
- "tags": []
521
- }
522
- },
523
- "stop": {
524
- "complexType": {
525
- "signature": "() => Promise<void>",
526
- "parameters": [],
527
- "references": {
528
- "Promise": {
529
- "location": "global"
530
- }
531
- },
532
- "return": "Promise<void>"
533
- },
534
- "docs": {
535
- "text": "Stop manually an ongoing session",
536
- "tags": []
537
- }
538
- },
539
- "getSessionData": {
540
- "complexType": {
541
- "signature": "() => Promise<any>",
542
- "parameters": [],
543
- "references": {
544
- "Promise": {
545
- "location": "global"
546
- }
547
- },
548
- "return": "Promise<any>"
549
- },
550
- "docs": {
551
- "text": "Retrieve manually the session data on a successful login",
552
- "tags": []
553
- }
554
- }
555
- };
556
- }
557
- }