typescript 4.7.0-dev.20220223 → 4.7.0-dev.20220226

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.
@@ -89,7 +89,7 @@ var ts;
89
89
  // The following is baselined as a literal template type without intervention
90
90
  /** The version of the TypeScript compiler release */
91
91
  // eslint-disable-next-line @typescript-eslint/no-inferrable-types
92
- ts.version = ts.versionMajorMinor + ".0-dev.20220223";
92
+ ts.version = ts.versionMajorMinor + ".0-dev.20220226";
93
93
  /* @internal */
94
94
  var Comparison;
95
95
  (function (Comparison) {
@@ -27179,6 +27179,19 @@ var ts;
27179
27179
  return node;
27180
27180
  }
27181
27181
  ts.ignoreSourceNewlines = ignoreSourceNewlines;
27182
+ /* @internal */
27183
+ function setTypeNode(node, type) {
27184
+ var emitNode = getOrCreateEmitNode(node);
27185
+ emitNode.typeNode = type;
27186
+ return node;
27187
+ }
27188
+ ts.setTypeNode = setTypeNode;
27189
+ /* @internal */
27190
+ function getTypeNode(node) {
27191
+ var _a;
27192
+ return (_a = node.emitNode) === null || _a === void 0 ? void 0 : _a.typeNode;
27193
+ }
27194
+ ts.getTypeNode = getTypeNode;
27182
27195
  })(ts || (ts = {}));
27183
27196
  /* @internal */
27184
27197
  var ts;
@@ -33449,10 +33462,10 @@ var ts;
33449
33462
  setDecoratorContext(/*val*/ false);
33450
33463
  }
33451
33464
  var pos = getNodePos();
33452
- var expr = parseAssignmentExpressionOrHigher();
33465
+ var expr = parseAssignmentExpressionOrHigher(/*disallowReturnTypeInArrowFunction*/ false);
33453
33466
  var operatorToken;
33454
33467
  while ((operatorToken = parseOptionalToken(27 /* CommaToken */))) {
33455
- expr = makeBinaryExpression(expr, operatorToken, parseAssignmentExpressionOrHigher(), pos);
33468
+ expr = makeBinaryExpression(expr, operatorToken, parseAssignmentExpressionOrHigher(/*disallowReturnTypeInArrowFunction*/ false), pos);
33456
33469
  }
33457
33470
  if (saveDecoratorContext) {
33458
33471
  setDecoratorContext(/*val*/ true);
@@ -33460,9 +33473,9 @@ var ts;
33460
33473
  return expr;
33461
33474
  }
33462
33475
  function parseInitializer() {
33463
- return parseOptional(63 /* EqualsToken */) ? parseAssignmentExpressionOrHigher() : undefined;
33476
+ return parseOptional(63 /* EqualsToken */) ? parseAssignmentExpressionOrHigher(/*disallowReturnTypeInArrowFunction*/ false) : undefined;
33464
33477
  }
33465
- function parseAssignmentExpressionOrHigher() {
33478
+ function parseAssignmentExpressionOrHigher(disallowReturnTypeInArrowFunction) {
33466
33479
  // AssignmentExpression[in,yield]:
33467
33480
  // 1) ConditionalExpression[?in,?yield]
33468
33481
  // 2) LeftHandSideExpression = AssignmentExpression[?in,?yield]
@@ -33488,7 +33501,7 @@ var ts;
33488
33501
  // If we do successfully parse arrow-function, we must *not* recurse for productions 1, 2 or 3. An ArrowFunction is
33489
33502
  // not a LeftHandSideExpression, nor does it start a ConditionalExpression. So we are done
33490
33503
  // with AssignmentExpression if we see one.
33491
- var arrowExpression = tryParseParenthesizedArrowFunctionExpression() || tryParseAsyncSimpleArrowFunctionExpression();
33504
+ var arrowExpression = tryParseParenthesizedArrowFunctionExpression(disallowReturnTypeInArrowFunction) || tryParseAsyncSimpleArrowFunctionExpression(disallowReturnTypeInArrowFunction);
33492
33505
  if (arrowExpression) {
33493
33506
  return arrowExpression;
33494
33507
  }
@@ -33507,7 +33520,7 @@ var ts;
33507
33520
  // parameter ('x => ...') above. We handle it here by checking if the parsed expression was a single
33508
33521
  // identifier and the current token is an arrow.
33509
33522
  if (expr.kind === 79 /* Identifier */ && token() === 38 /* EqualsGreaterThanToken */) {
33510
- return parseSimpleArrowFunctionExpression(pos, expr, /*asyncModifier*/ undefined);
33523
+ return parseSimpleArrowFunctionExpression(pos, expr, disallowReturnTypeInArrowFunction, /*asyncModifier*/ undefined);
33511
33524
  }
33512
33525
  // Now see if we might be in cases '2' or '3'.
33513
33526
  // If the expression was a LHS expression, and we have an assignment operator, then
@@ -33516,7 +33529,7 @@ var ts;
33516
33529
  // Note: we call reScanGreaterToken so that we get an appropriately merged token
33517
33530
  // for cases like `> > =` becoming `>>=`
33518
33531
  if (ts.isLeftHandSideExpression(expr) && ts.isAssignmentOperator(reScanGreaterToken())) {
33519
- return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher(), pos);
33532
+ return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher(disallowReturnTypeInArrowFunction), pos);
33520
33533
  }
33521
33534
  // It wasn't an assignment or a lambda. This is a conditional expression:
33522
33535
  return parseConditionalExpressionRest(expr, pos);
@@ -33559,7 +33572,7 @@ var ts;
33559
33572
  nextToken();
33560
33573
  if (!scanner.hasPrecedingLineBreak() &&
33561
33574
  (token() === 41 /* AsteriskToken */ || isStartOfExpression())) {
33562
- return finishNode(factory.createYieldExpression(parseOptionalToken(41 /* AsteriskToken */), parseAssignmentExpressionOrHigher()), pos);
33575
+ return finishNode(factory.createYieldExpression(parseOptionalToken(41 /* AsteriskToken */), parseAssignmentExpressionOrHigher(/*disallowReturnTypeInArrowFunction*/ false)), pos);
33563
33576
  }
33564
33577
  else {
33565
33578
  // if the next token is not on the same line as yield. or we don't have an '*' or
@@ -33567,7 +33580,7 @@ var ts;
33567
33580
  return finishNode(factory.createYieldExpression(/*asteriskToken*/ undefined, /*expression*/ undefined), pos);
33568
33581
  }
33569
33582
  }
33570
- function parseSimpleArrowFunctionExpression(pos, identifier, asyncModifier) {
33583
+ function parseSimpleArrowFunctionExpression(pos, identifier, disallowReturnTypeInArrowFunction, asyncModifier) {
33571
33584
  ts.Debug.assert(token() === 38 /* EqualsGreaterThanToken */, "parseSimpleArrowFunctionExpression should only have been called if we had a =>");
33572
33585
  var parameter = factory.createParameterDeclaration(
33573
33586
  /*decorators*/ undefined,
@@ -33579,11 +33592,11 @@ var ts;
33579
33592
  finishNode(parameter, identifier.pos);
33580
33593
  var parameters = createNodeArray([parameter], parameter.pos, parameter.end);
33581
33594
  var equalsGreaterThanToken = parseExpectedToken(38 /* EqualsGreaterThanToken */);
33582
- var body = parseArrowFunctionExpressionBody(/*isAsync*/ !!asyncModifier);
33595
+ var body = parseArrowFunctionExpressionBody(/*isAsync*/ !!asyncModifier, disallowReturnTypeInArrowFunction);
33583
33596
  var node = factory.createArrowFunction(asyncModifier, /*typeParameters*/ undefined, parameters, /*type*/ undefined, equalsGreaterThanToken, body);
33584
33597
  return addJSDocComment(finishNode(node, pos));
33585
33598
  }
33586
- function tryParseParenthesizedArrowFunctionExpression() {
33599
+ function tryParseParenthesizedArrowFunctionExpression(disallowReturnTypeInArrowFunction) {
33587
33600
  var triState = isParenthesizedArrowFunctionExpression();
33588
33601
  if (triState === 0 /* False */) {
33589
33602
  // It's definitely not a parenthesized arrow function expression.
@@ -33594,8 +33607,8 @@ var ts;
33594
33607
  // it out, but don't allow any ambiguity, and return 'undefined' if this could be an
33595
33608
  // expression instead.
33596
33609
  return triState === 1 /* True */ ?
33597
- parseParenthesizedArrowFunctionExpression(/*allowAmbiguity*/ true) :
33598
- tryParse(parsePossibleParenthesizedArrowFunctionExpression);
33610
+ parseParenthesizedArrowFunctionExpression(/*allowAmbiguity*/ true, /*disallowReturnTypeInArrowFunction*/ false) :
33611
+ tryParse(function () { return parsePossibleParenthesizedArrowFunctionExpression(disallowReturnTypeInArrowFunction); });
33599
33612
  }
33600
33613
  // True -> We definitely expect a parenthesized arrow function here.
33601
33614
  // False -> There *cannot* be a parenthesized arrow function here.
@@ -33725,25 +33738,25 @@ var ts;
33725
33738
  return 2 /* Unknown */;
33726
33739
  }
33727
33740
  }
33728
- function parsePossibleParenthesizedArrowFunctionExpression() {
33741
+ function parsePossibleParenthesizedArrowFunctionExpression(disallowReturnTypeInArrowFunction) {
33729
33742
  var tokenPos = scanner.getTokenPos();
33730
33743
  if (notParenthesizedArrow === null || notParenthesizedArrow === void 0 ? void 0 : notParenthesizedArrow.has(tokenPos)) {
33731
33744
  return undefined;
33732
33745
  }
33733
- var result = parseParenthesizedArrowFunctionExpression(/*allowAmbiguity*/ false);
33746
+ var result = parseParenthesizedArrowFunctionExpression(/*allowAmbiguity*/ false, disallowReturnTypeInArrowFunction);
33734
33747
  if (!result) {
33735
33748
  (notParenthesizedArrow || (notParenthesizedArrow = new ts.Set())).add(tokenPos);
33736
33749
  }
33737
33750
  return result;
33738
33751
  }
33739
- function tryParseAsyncSimpleArrowFunctionExpression() {
33752
+ function tryParseAsyncSimpleArrowFunctionExpression(disallowReturnTypeInArrowFunction) {
33740
33753
  // We do a check here so that we won't be doing unnecessarily call to "lookAhead"
33741
33754
  if (token() === 131 /* AsyncKeyword */) {
33742
33755
  if (lookAhead(isUnParenthesizedAsyncArrowFunctionWorker) === 1 /* True */) {
33743
33756
  var pos = getNodePos();
33744
33757
  var asyncModifier = parseModifiersForArrowFunction();
33745
33758
  var expr = parseBinaryExpressionOrHigher(0 /* Lowest */);
33746
- return parseSimpleArrowFunctionExpression(pos, expr, asyncModifier);
33759
+ return parseSimpleArrowFunctionExpression(pos, expr, disallowReturnTypeInArrowFunction, asyncModifier);
33747
33760
  }
33748
33761
  }
33749
33762
  return undefined;
@@ -33767,7 +33780,7 @@ var ts;
33767
33780
  }
33768
33781
  return 0 /* False */;
33769
33782
  }
33770
- function parseParenthesizedArrowFunctionExpression(allowAmbiguity) {
33783
+ function parseParenthesizedArrowFunctionExpression(allowAmbiguity, disallowReturnTypeInArrowFunction) {
33771
33784
  var pos = getNodePos();
33772
33785
  var hasJSDoc = hasPrecedingJSDocComment();
33773
33786
  var modifiers = parseModifiersForArrowFunction();
@@ -33793,6 +33806,23 @@ var ts;
33793
33806
  return undefined;
33794
33807
  }
33795
33808
  }
33809
+ // Given:
33810
+ // x ? y => ({ y }) : z => ({ z })
33811
+ // We try to parse the body of the first arrow function by looking at:
33812
+ // ({ y }) : z => ({ z })
33813
+ // This is a valid arrow function with "z" as the return type.
33814
+ //
33815
+ // But, if we're in the true side of a conditional expression, this colon
33816
+ // terminates the expression, so we cannot allow a return type if we aren't
33817
+ // certain whether or not the preceding text was parsed as a parameter list.
33818
+ //
33819
+ // For example,
33820
+ // a() ? (b: number, c?: string): void => d() : e
33821
+ // is determined by isParenthesizedArrowFunctionExpression to unambiguously
33822
+ // be an arrow expression, so we allow a return type.
33823
+ if (disallowReturnTypeInArrowFunction && token() === 58 /* ColonToken */) {
33824
+ return undefined;
33825
+ }
33796
33826
  var type = parseReturnType(58 /* ColonToken */, /*isType*/ false);
33797
33827
  if (type && !allowAmbiguity && typeHasArrowFunctionBlockingParseError(type)) {
33798
33828
  return undefined;
@@ -33821,12 +33851,12 @@ var ts;
33821
33851
  var lastToken = token();
33822
33852
  var equalsGreaterThanToken = parseExpectedToken(38 /* EqualsGreaterThanToken */);
33823
33853
  var body = (lastToken === 38 /* EqualsGreaterThanToken */ || lastToken === 18 /* OpenBraceToken */)
33824
- ? parseArrowFunctionExpressionBody(ts.some(modifiers, ts.isAsyncModifier))
33854
+ ? parseArrowFunctionExpressionBody(ts.some(modifiers, ts.isAsyncModifier), disallowReturnTypeInArrowFunction)
33825
33855
  : parseIdentifier();
33826
33856
  var node = factory.createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body);
33827
33857
  return withJSDoc(finishNode(node, pos), hasJSDoc);
33828
33858
  }
33829
- function parseArrowFunctionExpressionBody(isAsync) {
33859
+ function parseArrowFunctionExpressionBody(isAsync, disallowReturnTypeInArrowFunction) {
33830
33860
  if (token() === 18 /* OpenBraceToken */) {
33831
33861
  return parseFunctionBlock(isAsync ? 2 /* Await */ : 0 /* None */);
33832
33862
  }
@@ -33854,8 +33884,8 @@ var ts;
33854
33884
  var savedTopLevel = topLevel;
33855
33885
  topLevel = false;
33856
33886
  var node = isAsync
33857
- ? doInAwaitContext(parseAssignmentExpressionOrHigher)
33858
- : doOutsideOfAwaitContext(parseAssignmentExpressionOrHigher);
33887
+ ? doInAwaitContext(function () { return parseAssignmentExpressionOrHigher(disallowReturnTypeInArrowFunction); })
33888
+ : doOutsideOfAwaitContext(function () { return parseAssignmentExpressionOrHigher(disallowReturnTypeInArrowFunction); });
33859
33889
  topLevel = savedTopLevel;
33860
33890
  return node;
33861
33891
  }
@@ -33868,8 +33898,8 @@ var ts;
33868
33898
  // Note: we explicitly 'allowIn' in the whenTrue part of the condition expression, and
33869
33899
  // we do not that for the 'whenFalse' part.
33870
33900
  var colonToken;
33871
- return finishNode(factory.createConditionalExpression(leftOperand, questionToken, doOutsideOfContext(disallowInAndDecoratorContext, parseAssignmentExpressionOrHigher), colonToken = parseExpectedToken(58 /* ColonToken */), ts.nodeIsPresent(colonToken)
33872
- ? parseAssignmentExpressionOrHigher()
33901
+ return finishNode(factory.createConditionalExpression(leftOperand, questionToken, doOutsideOfContext(disallowInAndDecoratorContext, function () { return parseAssignmentExpressionOrHigher(/*disallowReturnTypeInArrowFunction*/ true); }), colonToken = parseExpectedToken(58 /* ColonToken */), ts.nodeIsPresent(colonToken)
33902
+ ? parseAssignmentExpressionOrHigher(/*disallowReturnTypeInArrowFunction*/ true)
33873
33903
  : createMissingNode(79 /* Identifier */, /*reportAtCurrentPosition*/ false, ts.Diagnostics._0_expected, ts.tokenToString(58 /* ColonToken */))), pos);
33874
33904
  }
33875
33905
  function parseBinaryExpressionOrHigher(precedence) {
@@ -34785,13 +34815,13 @@ var ts;
34785
34815
  function parseSpreadElement() {
34786
34816
  var pos = getNodePos();
34787
34817
  parseExpected(25 /* DotDotDotToken */);
34788
- var expression = parseAssignmentExpressionOrHigher();
34818
+ var expression = parseAssignmentExpressionOrHigher(/*disallowReturnTypeInArrowFunction*/ false);
34789
34819
  return finishNode(factory.createSpreadElement(expression), pos);
34790
34820
  }
34791
34821
  function parseArgumentOrArrayLiteralElement() {
34792
34822
  return token() === 25 /* DotDotDotToken */ ? parseSpreadElement() :
34793
34823
  token() === 27 /* CommaToken */ ? finishNode(factory.createOmittedExpression(), getNodePos()) :
34794
- parseAssignmentExpressionOrHigher();
34824
+ parseAssignmentExpressionOrHigher(/*disallowReturnTypeInArrowFunction*/ false);
34795
34825
  }
34796
34826
  function parseArgumentExpression() {
34797
34827
  return doOutsideOfContext(disallowInAndDecoratorContext, parseArgumentOrArrayLiteralElement);
@@ -34808,7 +34838,7 @@ var ts;
34808
34838
  var pos = getNodePos();
34809
34839
  var hasJSDoc = hasPrecedingJSDocComment();
34810
34840
  if (parseOptionalToken(25 /* DotDotDotToken */)) {
34811
- var expression = parseAssignmentExpressionOrHigher();
34841
+ var expression = parseAssignmentExpressionOrHigher(/*disallowReturnTypeInArrowFunction*/ false);
34812
34842
  return withJSDoc(finishNode(factory.createSpreadAssignment(expression), pos), hasJSDoc);
34813
34843
  }
34814
34844
  var decorators = parseDecorators();
@@ -34837,7 +34867,7 @@ var ts;
34837
34867
  var isShorthandPropertyAssignment = tokenIsIdentifier && (token() !== 58 /* ColonToken */);
34838
34868
  if (isShorthandPropertyAssignment) {
34839
34869
  var equalsToken = parseOptionalToken(63 /* EqualsToken */);
34840
- var objectAssignmentInitializer = equalsToken ? allowInAnd(parseAssignmentExpressionOrHigher) : undefined;
34870
+ var objectAssignmentInitializer = equalsToken ? allowInAnd(function () { return parseAssignmentExpressionOrHigher(/*disallowReturnTypeInArrowFunction*/ false); }) : undefined;
34841
34871
  node = factory.createShorthandPropertyAssignment(name, objectAssignmentInitializer);
34842
34872
  // Save equals token for error reporting.
34843
34873
  // TODO(rbuckton): Consider manufacturing this when we need to report an error as it is otherwise not useful.
@@ -34845,7 +34875,7 @@ var ts;
34845
34875
  }
34846
34876
  else {
34847
34877
  parseExpected(58 /* ColonToken */);
34848
- var initializer = allowInAnd(parseAssignmentExpressionOrHigher);
34878
+ var initializer = allowInAnd(function () { return parseAssignmentExpressionOrHigher(/*disallowReturnTypeInArrowFunction*/ false); });
34849
34879
  node = factory.createPropertyAssignment(name, initializer);
34850
34880
  }
34851
34881
  // Decorators, Modifiers, questionToken, and exclamationToken are not supported by property assignments and are reported in the grammar checker
@@ -35025,7 +35055,7 @@ var ts;
35025
35055
  }
35026
35056
  var node;
35027
35057
  if (awaitToken ? parseExpected(159 /* OfKeyword */) : parseOptional(159 /* OfKeyword */)) {
35028
- var expression = allowInAnd(parseAssignmentExpressionOrHigher);
35058
+ var expression = allowInAnd(function () { return parseAssignmentExpressionOrHigher(/*disallowReturnTypeInArrowFunction*/ false); });
35029
35059
  parseExpected(21 /* CloseParenToken */);
35030
35060
  node = factory.createForOfStatement(awaitToken, initializer, expression, parseStatement());
35031
35061
  }
@@ -36192,7 +36222,7 @@ var ts;
36192
36222
  var pos = getNodePos();
36193
36223
  var name = ts.tokenIsIdentifierOrKeyword(token()) ? parseIdentifierName() : parseLiteralLikeNode(10 /* StringLiteral */);
36194
36224
  parseExpected(58 /* ColonToken */);
36195
- var value = parseAssignmentExpressionOrHigher();
36225
+ var value = parseAssignmentExpressionOrHigher(/*disallowReturnTypeInArrowFunction*/ false);
36196
36226
  return finishNode(factory.createAssertEntry(name, value), pos);
36197
36227
  }
36198
36228
  function parseAssertClause() {
@@ -36429,7 +36459,7 @@ var ts;
36429
36459
  else {
36430
36460
  parseExpected(88 /* DefaultKeyword */);
36431
36461
  }
36432
- var expression = parseAssignmentExpressionOrHigher();
36462
+ var expression = parseAssignmentExpressionOrHigher(/*disallowReturnTypeInArrowFunction*/ false);
36433
36463
  parseSemicolon();
36434
36464
  setAwaitContext(savedAwaitContext);
36435
36465
  var node = factory.createExportAssignment(decorators, modifiers, isExportEquals, expression);
@@ -91609,9 +91639,13 @@ var ts;
91609
91639
  }
91610
91640
  }
91611
91641
  function visitVariableDeclaration(node) {
91612
- return factory.updateVariableDeclaration(node, ts.visitNode(node.name, visitor, ts.isBindingName),
91642
+ var updated = factory.updateVariableDeclaration(node, ts.visitNode(node.name, visitor, ts.isBindingName),
91613
91643
  /*exclamationToken*/ undefined,
91614
91644
  /*type*/ undefined, ts.visitNode(node.initializer, visitor, ts.isExpression));
91645
+ if (node.type) {
91646
+ ts.setTypeNode(updated.name, node.type);
91647
+ }
91648
+ return updated;
91615
91649
  }
91616
91650
  function visitParenthesizedExpression(node) {
91617
91651
  var innerExpression = ts.skipOuterExpressions(node.expression, ~6 /* Assertions */);
@@ -110943,10 +110977,11 @@ var ts;
110943
110977
  // Declarations
110944
110978
  //
110945
110979
  function emitVariableDeclaration(node) {
110980
+ var _a, _b, _c, _d, _e;
110946
110981
  emit(node.name);
110947
110982
  emit(node.exclamationToken);
110948
110983
  emitTypeAnnotation(node.type);
110949
- emitInitializer(node.initializer, node.type ? node.type.end : node.name.end, node, parenthesizer.parenthesizeExpressionForDisallowedComma);
110984
+ emitInitializer(node.initializer, (_e = (_b = (_a = node.type) === null || _a === void 0 ? void 0 : _a.end) !== null && _b !== void 0 ? _b : (_d = (_c = node.name.emitNode) === null || _c === void 0 ? void 0 : _c.typeNode) === null || _d === void 0 ? void 0 : _d.end) !== null && _e !== void 0 ? _e : node.name.end, node, parenthesizer.parenthesizeExpressionForDisallowedComma);
110950
110985
  }
110951
110986
  function emitVariableDeclarationList(node) {
110952
110987
  writeKeyword(ts.isLet(node) ? "let" : ts.isVarConst(node) ? "const" : "var");
@@ -112928,6 +112963,10 @@ var ts;
112928
112963
  commentsDisabled = false;
112929
112964
  }
112930
112965
  emitTrailingCommentsOfNode(node, emitFlags, commentRange.pos, commentRange.end, savedContainerPos, savedContainerEnd, savedDeclarationListContainerEnd);
112966
+ var typeNode = ts.getTypeNode(node);
112967
+ if (typeNode) {
112968
+ emitTrailingCommentsOfNode(node, emitFlags, typeNode.pos, typeNode.end, savedContainerPos, savedContainerEnd, savedDeclarationListContainerEnd);
112969
+ }
112931
112970
  }
112932
112971
  function emitLeadingCommentsOfNode(node, emitFlags, pos, end) {
112933
112972
  enterComment();
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "typescript",
3
3
  "author": "Microsoft Corp.",
4
4
  "homepage": "https://www.typescriptlang.org/",
5
- "version": "4.7.0-dev.20220223",
5
+ "version": "4.7.0-dev.20220226",
6
6
  "license": "Apache-2.0",
7
7
  "description": "TypeScript is a language for application scale JavaScript development",
8
8
  "keywords": [