@aws-amplify/auth 5.0.2-unstable.5 → 5.0.2-unstable.8
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/lib/Auth.d.ts +3 -0
- package/lib/Auth.js +155 -143
- package/lib/Auth.js.map +1 -1
- package/lib-esm/Auth.d.ts +3 -0
- package/lib-esm/Auth.js +155 -143
- package/lib-esm/Auth.js.map +1 -1
- package/package.json +4 -4
- package/src/Auth.ts +113 -112
package/lib/Auth.d.ts
CHANGED
|
@@ -16,6 +16,8 @@ export declare class AuthClass {
|
|
|
16
16
|
private oAuthFlowInProgress;
|
|
17
17
|
private pendingSignIn;
|
|
18
18
|
private autoSignInInitiated;
|
|
19
|
+
private inflightSessionPromise;
|
|
20
|
+
private inflightSessionPromiseCounter;
|
|
19
21
|
Credentials: import("@aws-amplify/core").CredentialsClass;
|
|
20
22
|
/**
|
|
21
23
|
* Initialize Auth with AWS configurations
|
|
@@ -199,6 +201,7 @@ export declare class AuthClass {
|
|
|
199
201
|
* @return - A promise resolves to session object if success
|
|
200
202
|
*/
|
|
201
203
|
currentSession(): Promise<CognitoUserSession>;
|
|
204
|
+
private _userSession;
|
|
202
205
|
/**
|
|
203
206
|
* Get the corresponding user session
|
|
204
207
|
* @param {Object} user - The CognitoUser object
|
package/lib/Auth.js
CHANGED
|
@@ -40,6 +40,8 @@ var AuthClass = /** @class */ (function () {
|
|
|
40
40
|
this.user = null;
|
|
41
41
|
this.oAuthFlowInProgress = false;
|
|
42
42
|
this.autoSignInInitiated = false;
|
|
43
|
+
this.inflightSessionPromise = null;
|
|
44
|
+
this.inflightSessionPromiseCounter = 0;
|
|
43
45
|
this.Credentials = core_1.Credentials;
|
|
44
46
|
this.wrapRefreshSessionCallback = function (callback) {
|
|
45
47
|
var wrapped = function (error, data) {
|
|
@@ -1376,10 +1378,10 @@ var AuthClass = /** @class */ (function () {
|
|
|
1376
1378
|
return new Promise(function (res, rej) {
|
|
1377
1379
|
_this._storageSync
|
|
1378
1380
|
.then(function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
1379
|
-
var user, clientMetadata;
|
|
1381
|
+
var user, session, bypassCache, clientMetadata, _a, scope, err_1;
|
|
1380
1382
|
var _this = this;
|
|
1381
|
-
return tslib_1.__generator(this, function (
|
|
1382
|
-
switch (
|
|
1383
|
+
return tslib_1.__generator(this, function (_b) {
|
|
1384
|
+
switch (_b.label) {
|
|
1383
1385
|
case 0:
|
|
1384
1386
|
if (!this.isOAuthInProgress()) return [3 /*break*/, 2];
|
|
1385
1387
|
logger.debug('OAuth signIn in progress, waiting for resolution...');
|
|
@@ -1403,8 +1405,8 @@ var AuthClass = /** @class */ (function () {
|
|
|
1403
1405
|
}
|
|
1404
1406
|
})];
|
|
1405
1407
|
case 1:
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
+
_b.sent();
|
|
1409
|
+
_b.label = 2;
|
|
1408
1410
|
case 2:
|
|
1409
1411
|
user = this.userPool.getCurrentUser();
|
|
1410
1412
|
if (!user) {
|
|
@@ -1412,96 +1414,77 @@ var AuthClass = /** @class */ (function () {
|
|
|
1412
1414
|
rej('No current user');
|
|
1413
1415
|
return [2 /*return*/];
|
|
1414
1416
|
}
|
|
1417
|
+
_b.label = 3;
|
|
1418
|
+
case 3:
|
|
1419
|
+
_b.trys.push([3, 7, , 8]);
|
|
1420
|
+
return [4 /*yield*/, this._userSession(user)];
|
|
1421
|
+
case 4:
|
|
1422
|
+
session = _b.sent();
|
|
1423
|
+
bypassCache = params ? params.bypassCache : false;
|
|
1424
|
+
if (!bypassCache) return [3 /*break*/, 6];
|
|
1425
|
+
return [4 /*yield*/, this.Credentials.clear()];
|
|
1426
|
+
case 5:
|
|
1427
|
+
_b.sent();
|
|
1428
|
+
_b.label = 6;
|
|
1429
|
+
case 6:
|
|
1415
1430
|
clientMetadata = this._config.clientMetadata;
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
return [
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
logger.debug('getting user data failed', err);
|
|
1458
|
-
if (!this.isSessionInvalid(err)) return [3 /*break*/, 5];
|
|
1459
|
-
_a.label = 1;
|
|
1460
|
-
case 1:
|
|
1461
|
-
_a.trys.push([1, 3, , 4]);
|
|
1462
|
-
return [4 /*yield*/, this.cleanUpInvalidSession(user)];
|
|
1463
|
-
case 2:
|
|
1464
|
-
_a.sent();
|
|
1465
|
-
return [3 /*break*/, 4];
|
|
1466
|
-
case 3:
|
|
1467
|
-
cleanUpError_6 = _a.sent();
|
|
1468
|
-
rej(new Error("Session is invalid due to: " + err.message + " and failed to clean up invalid session: " + cleanUpError_6.message));
|
|
1469
|
-
return [2 /*return*/];
|
|
1470
|
-
case 4:
|
|
1471
|
-
rej(err);
|
|
1472
|
-
return [3 /*break*/, 6];
|
|
1473
|
-
case 5:
|
|
1474
|
-
res(user);
|
|
1475
|
-
_a.label = 6;
|
|
1476
|
-
case 6: return [2 /*return*/];
|
|
1477
|
-
case 7:
|
|
1478
|
-
preferredMFA = data.PreferredMfaSetting || 'NOMFA';
|
|
1479
|
-
attributeList = [];
|
|
1480
|
-
for (i = 0; i < data.UserAttributes.length; i++) {
|
|
1481
|
-
attribute = {
|
|
1482
|
-
Name: data.UserAttributes[i].Name,
|
|
1483
|
-
Value: data.UserAttributes[i].Value,
|
|
1484
|
-
};
|
|
1485
|
-
userAttribute = new amazon_cognito_identity_js_1.CognitoUserAttribute(attribute);
|
|
1486
|
-
attributeList.push(userAttribute);
|
|
1487
|
-
}
|
|
1488
|
-
attributes = this.attributesToObject(attributeList);
|
|
1489
|
-
Object.assign(user, { attributes: attributes, preferredMFA: preferredMFA });
|
|
1490
|
-
return [2 /*return*/, res(user)];
|
|
1491
|
-
}
|
|
1492
|
-
});
|
|
1493
|
-
}); }, { bypassCache: bypassCache, clientMetadata: clientMetadata });
|
|
1494
|
-
}
|
|
1495
|
-
else {
|
|
1496
|
-
logger.debug("Unable to get the user data because the " + USER_ADMIN_SCOPE + " " +
|
|
1497
|
-
"is not in the scopes of the access token");
|
|
1431
|
+
_a = session.getAccessToken().decodePayload().scope, scope = _a === void 0 ? '' : _a;
|
|
1432
|
+
if (scope.split(' ').includes(USER_ADMIN_SCOPE)) {
|
|
1433
|
+
user.getUserData(function (err, data) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
1434
|
+
var cleanUpError_5, preferredMFA, attributeList, i, attribute, userAttribute, attributes;
|
|
1435
|
+
return tslib_1.__generator(this, function (_a) {
|
|
1436
|
+
switch (_a.label) {
|
|
1437
|
+
case 0:
|
|
1438
|
+
if (!err) return [3 /*break*/, 7];
|
|
1439
|
+
logger.debug('getting user data failed', err);
|
|
1440
|
+
if (!this.isSessionInvalid(err)) return [3 /*break*/, 5];
|
|
1441
|
+
_a.label = 1;
|
|
1442
|
+
case 1:
|
|
1443
|
+
_a.trys.push([1, 3, , 4]);
|
|
1444
|
+
return [4 /*yield*/, this.cleanUpInvalidSession(user)];
|
|
1445
|
+
case 2:
|
|
1446
|
+
_a.sent();
|
|
1447
|
+
return [3 /*break*/, 4];
|
|
1448
|
+
case 3:
|
|
1449
|
+
cleanUpError_5 = _a.sent();
|
|
1450
|
+
rej(new Error("Session is invalid due to: " + err.message + " and failed to clean up invalid session: " + cleanUpError_5.message));
|
|
1451
|
+
return [2 /*return*/];
|
|
1452
|
+
case 4:
|
|
1453
|
+
rej(err);
|
|
1454
|
+
return [3 /*break*/, 6];
|
|
1455
|
+
case 5:
|
|
1456
|
+
res(user);
|
|
1457
|
+
_a.label = 6;
|
|
1458
|
+
case 6: return [2 /*return*/];
|
|
1459
|
+
case 7:
|
|
1460
|
+
preferredMFA = data.PreferredMfaSetting || 'NOMFA';
|
|
1461
|
+
attributeList = [];
|
|
1462
|
+
for (i = 0; i < data.UserAttributes.length; i++) {
|
|
1463
|
+
attribute = {
|
|
1464
|
+
Name: data.UserAttributes[i].Name,
|
|
1465
|
+
Value: data.UserAttributes[i].Value,
|
|
1466
|
+
};
|
|
1467
|
+
userAttribute = new amazon_cognito_identity_js_1.CognitoUserAttribute(attribute);
|
|
1468
|
+
attributeList.push(userAttribute);
|
|
1469
|
+
}
|
|
1470
|
+
attributes = this.attributesToObject(attributeList);
|
|
1471
|
+
Object.assign(user, { attributes: attributes, preferredMFA: preferredMFA });
|
|
1498
1472
|
return [2 /*return*/, res(user)];
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1473
|
+
}
|
|
1474
|
+
});
|
|
1475
|
+
}); }, { bypassCache: bypassCache, clientMetadata: clientMetadata });
|
|
1476
|
+
}
|
|
1477
|
+
else {
|
|
1478
|
+
logger.debug("Unable to get the user data because the " + USER_ADMIN_SCOPE + " " +
|
|
1479
|
+
"is not in the scopes of the access token");
|
|
1480
|
+
return [2 /*return*/, res(user)];
|
|
1481
|
+
}
|
|
1482
|
+
return [3 /*break*/, 8];
|
|
1483
|
+
case 7:
|
|
1484
|
+
err_1 = _b.sent();
|
|
1485
|
+
rej(err_1);
|
|
1486
|
+
return [3 /*break*/, 8];
|
|
1487
|
+
case 8: return [2 /*return*/];
|
|
1505
1488
|
}
|
|
1506
1489
|
});
|
|
1507
1490
|
}); })
|
|
@@ -1611,50 +1594,79 @@ var AuthClass = /** @class */ (function () {
|
|
|
1611
1594
|
});
|
|
1612
1595
|
});
|
|
1613
1596
|
};
|
|
1597
|
+
AuthClass.prototype._userSession = function (user) {
|
|
1598
|
+
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
1599
|
+
var clientMetadata, userSession;
|
|
1600
|
+
var _this = this;
|
|
1601
|
+
return tslib_1.__generator(this, function (_a) {
|
|
1602
|
+
switch (_a.label) {
|
|
1603
|
+
case 0:
|
|
1604
|
+
if (!user) {
|
|
1605
|
+
logger.debug('the user is null');
|
|
1606
|
+
return [2 /*return*/, this.rejectAuthError(Auth_1.AuthErrorTypes.NoUserSession)];
|
|
1607
|
+
}
|
|
1608
|
+
clientMetadata = this._config.clientMetadata;
|
|
1609
|
+
// Debouncing the concurrent userSession calls by caching the promise.
|
|
1610
|
+
// This solution assumes users will always call this function with the same CognitoUser instance.
|
|
1611
|
+
if (this.inflightSessionPromiseCounter === 0) {
|
|
1612
|
+
this.inflightSessionPromise = new Promise(function (res, rej) {
|
|
1613
|
+
user.getSession(function (err, session) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
1614
|
+
var cleanUpError_6;
|
|
1615
|
+
return tslib_1.__generator(this, function (_a) {
|
|
1616
|
+
switch (_a.label) {
|
|
1617
|
+
case 0:
|
|
1618
|
+
if (!err) return [3 /*break*/, 5];
|
|
1619
|
+
logger.debug('Failed to get the session from user', user);
|
|
1620
|
+
if (!this.isSessionInvalid(err)) return [3 /*break*/, 4];
|
|
1621
|
+
_a.label = 1;
|
|
1622
|
+
case 1:
|
|
1623
|
+
_a.trys.push([1, 3, , 4]);
|
|
1624
|
+
return [4 /*yield*/, this.cleanUpInvalidSession(user)];
|
|
1625
|
+
case 2:
|
|
1626
|
+
_a.sent();
|
|
1627
|
+
return [3 /*break*/, 4];
|
|
1628
|
+
case 3:
|
|
1629
|
+
cleanUpError_6 = _a.sent();
|
|
1630
|
+
rej(new Error("Session is invalid due to: " + err.message + " and failed to clean up invalid session: " + cleanUpError_6.message));
|
|
1631
|
+
return [2 /*return*/];
|
|
1632
|
+
case 4:
|
|
1633
|
+
rej(err);
|
|
1634
|
+
return [2 /*return*/];
|
|
1635
|
+
case 5:
|
|
1636
|
+
logger.debug('Succeed to get the user session', session);
|
|
1637
|
+
res(session);
|
|
1638
|
+
return [2 /*return*/];
|
|
1639
|
+
}
|
|
1640
|
+
});
|
|
1641
|
+
}); }, { clientMetadata: clientMetadata });
|
|
1642
|
+
});
|
|
1643
|
+
}
|
|
1644
|
+
this.inflightSessionPromiseCounter++;
|
|
1645
|
+
_a.label = 1;
|
|
1646
|
+
case 1:
|
|
1647
|
+
_a.trys.push([1, , 3, 4]);
|
|
1648
|
+
return [4 /*yield*/, this.inflightSessionPromise];
|
|
1649
|
+
case 2:
|
|
1650
|
+
userSession = _a.sent();
|
|
1651
|
+
// Set private member. Avoid user.setSignInUserSession() to prevent excessive localstorage refresh.
|
|
1652
|
+
// @ts-ignore
|
|
1653
|
+
user.signInUserSession = userSession;
|
|
1654
|
+
return [2 /*return*/, userSession];
|
|
1655
|
+
case 3:
|
|
1656
|
+
this.inflightSessionPromiseCounter--;
|
|
1657
|
+
return [7 /*endfinally*/];
|
|
1658
|
+
case 4: return [2 /*return*/];
|
|
1659
|
+
}
|
|
1660
|
+
});
|
|
1661
|
+
});
|
|
1662
|
+
};
|
|
1614
1663
|
/**
|
|
1615
1664
|
* Get the corresponding user session
|
|
1616
1665
|
* @param {Object} user - The CognitoUser object
|
|
1617
1666
|
* @return - A promise resolves to the session
|
|
1618
1667
|
*/
|
|
1619
1668
|
AuthClass.prototype.userSession = function (user) {
|
|
1620
|
-
|
|
1621
|
-
if (!user) {
|
|
1622
|
-
logger.debug('the user is null');
|
|
1623
|
-
return this.rejectAuthError(Auth_1.AuthErrorTypes.NoUserSession);
|
|
1624
|
-
}
|
|
1625
|
-
var clientMetadata = this._config.clientMetadata; // TODO: verify behavior if this is override during signIn
|
|
1626
|
-
return new Promise(function (res, rej) {
|
|
1627
|
-
logger.debug('Getting the session from this user:', user);
|
|
1628
|
-
user.getSession(function (err, session) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
1629
|
-
var cleanUpError_7;
|
|
1630
|
-
return tslib_1.__generator(this, function (_a) {
|
|
1631
|
-
switch (_a.label) {
|
|
1632
|
-
case 0:
|
|
1633
|
-
if (!err) return [3 /*break*/, 5];
|
|
1634
|
-
logger.debug('Failed to get the session from user', user);
|
|
1635
|
-
if (!this.isSessionInvalid(err)) return [3 /*break*/, 4];
|
|
1636
|
-
_a.label = 1;
|
|
1637
|
-
case 1:
|
|
1638
|
-
_a.trys.push([1, 3, , 4]);
|
|
1639
|
-
return [4 /*yield*/, this.cleanUpInvalidSession(user)];
|
|
1640
|
-
case 2:
|
|
1641
|
-
_a.sent();
|
|
1642
|
-
return [3 /*break*/, 4];
|
|
1643
|
-
case 3:
|
|
1644
|
-
cleanUpError_7 = _a.sent();
|
|
1645
|
-
rej(new Error("Session is invalid due to: " + err.message + " and failed to clean up invalid session: " + cleanUpError_7.message));
|
|
1646
|
-
return [2 /*return*/];
|
|
1647
|
-
case 4:
|
|
1648
|
-
rej(err);
|
|
1649
|
-
return [2 /*return*/];
|
|
1650
|
-
case 5:
|
|
1651
|
-
logger.debug('Succeed to get the user session', session);
|
|
1652
|
-
res(session);
|
|
1653
|
-
return [2 /*return*/];
|
|
1654
|
-
}
|
|
1655
|
-
});
|
|
1656
|
-
}); }, { clientMetadata: clientMetadata });
|
|
1657
|
-
});
|
|
1669
|
+
return this._userSession(user);
|
|
1658
1670
|
};
|
|
1659
1671
|
/**
|
|
1660
1672
|
* Get authenticated credentials of current user.
|
|
@@ -1798,7 +1810,7 @@ var AuthClass = /** @class */ (function () {
|
|
|
1798
1810
|
// we must validate the user as an authenticated user by using getSession
|
|
1799
1811
|
var clientMetadata = _this._config.clientMetadata; // TODO: verify behavior if this is override during signIn
|
|
1800
1812
|
user.getSession(function (err, result) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
1801
|
-
var
|
|
1813
|
+
var cleanUpError_7;
|
|
1802
1814
|
var _this = this;
|
|
1803
1815
|
return tslib_1.__generator(this, function (_a) {
|
|
1804
1816
|
switch (_a.label) {
|
|
@@ -1814,8 +1826,8 @@ var AuthClass = /** @class */ (function () {
|
|
|
1814
1826
|
_a.sent();
|
|
1815
1827
|
return [3 /*break*/, 4];
|
|
1816
1828
|
case 3:
|
|
1817
|
-
|
|
1818
|
-
rej(new Error("Session is invalid due to: " + err.message + " and failed to clean up invalid session: " +
|
|
1829
|
+
cleanUpError_7 = _a.sent();
|
|
1830
|
+
rej(new Error("Session is invalid due to: " + err.message + " and failed to clean up invalid session: " + cleanUpError_7.message));
|
|
1819
1831
|
return [2 /*return*/];
|
|
1820
1832
|
case 4: return [2 /*return*/, rej(err)];
|
|
1821
1833
|
case 5:
|
|
@@ -2039,7 +2051,7 @@ var AuthClass = /** @class */ (function () {
|
|
|
2039
2051
|
*/
|
|
2040
2052
|
AuthClass.prototype.currentUserInfo = function () {
|
|
2041
2053
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
2042
|
-
var source, user, attributes, userAttrs, credentials, e_12, info,
|
|
2054
|
+
var source, user, attributes, userAttrs, credentials, e_12, info, err_2, user;
|
|
2043
2055
|
return tslib_1.__generator(this, function (_a) {
|
|
2044
2056
|
switch (_a.label) {
|
|
2045
2057
|
case 0:
|
|
@@ -2080,8 +2092,8 @@ var AuthClass = /** @class */ (function () {
|
|
|
2080
2092
|
};
|
|
2081
2093
|
return [2 /*return*/, info];
|
|
2082
2094
|
case 8:
|
|
2083
|
-
|
|
2084
|
-
logger.error('currentUserInfo error',
|
|
2095
|
+
err_2 = _a.sent();
|
|
2096
|
+
logger.error('currentUserInfo error', err_2);
|
|
2085
2097
|
return [2 /*return*/, {}];
|
|
2086
2098
|
case 9:
|
|
2087
2099
|
if (source === 'federated') {
|
|
@@ -2162,7 +2174,7 @@ var AuthClass = /** @class */ (function () {
|
|
|
2162
2174
|
*/
|
|
2163
2175
|
AuthClass.prototype._handleAuthResponse = function (URL) {
|
|
2164
2176
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
2165
|
-
var currentUrl, hasCodeOrError, hasTokenOrError, _a, accessToken, idToken, refreshToken, state, session, credentials, isCustomStateIncluded, currentUser, customState,
|
|
2177
|
+
var currentUrl, hasCodeOrError, hasTokenOrError, _a, accessToken, idToken, refreshToken, state, session, credentials, isCustomStateIncluded, currentUser, customState, err_3;
|
|
2166
2178
|
return tslib_1.__generator(this, function (_b) {
|
|
2167
2179
|
switch (_b.label) {
|
|
2168
2180
|
case 0:
|
|
@@ -2235,16 +2247,16 @@ var AuthClass = /** @class */ (function () {
|
|
|
2235
2247
|
//#endregion
|
|
2236
2248
|
return [2 /*return*/, credentials];
|
|
2237
2249
|
case 6:
|
|
2238
|
-
|
|
2239
|
-
logger.debug('Error in cognito hosted auth response',
|
|
2250
|
+
err_3 = _b.sent();
|
|
2251
|
+
logger.debug('Error in cognito hosted auth response', err_3);
|
|
2240
2252
|
// Just like a successful handling of `?code`, replace the window history to "dispose" of the `code`.
|
|
2241
2253
|
// Otherwise, reloading the page will throw errors as the `code` has already been spent.
|
|
2242
2254
|
if (window && typeof window.history !== 'undefined') {
|
|
2243
2255
|
window.history.replaceState({}, null, this._config.oauth.redirectSignIn);
|
|
2244
2256
|
}
|
|
2245
|
-
dispatchAuthEvent('signIn_failure',
|
|
2246
|
-
dispatchAuthEvent('cognitoHostedUI_failure',
|
|
2247
|
-
dispatchAuthEvent('customState_failure',
|
|
2257
|
+
dispatchAuthEvent('signIn_failure', err_3, "The OAuth response flow failed");
|
|
2258
|
+
dispatchAuthEvent('cognitoHostedUI_failure', err_3, "A failure occurred when returning to the Cognito Hosted UI");
|
|
2259
|
+
dispatchAuthEvent('customState_failure', err_3, "A failure occurred when returning state");
|
|
2248
2260
|
return [3 /*break*/, 7];
|
|
2249
2261
|
case 7: return [3 /*break*/, 9];
|
|
2250
2262
|
case 8:
|