@checkdigit/eslint-plugin 7.6.0-PR.75-7ee9 → 7.6.0-PR.97-b19c

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 (77) hide show
  1. package/dist-mjs/index.mjs +8 -156
  2. package/dist-mjs/no-status-code-assert.mjs +63 -0
  3. package/dist-mjs/require-resolve-full-response.mjs +5 -5
  4. package/dist-types/no-status-code-assert.d.ts +5 -0
  5. package/package.json +1 -1
  6. package/src/index.ts +4 -152
  7. package/src/no-status-code-assert.ts +85 -0
  8. package/src/require-resolve-full-response.ts +4 -4
  9. package/dist-mjs/agent/add-assert-import.mjs +0 -58
  10. package/dist-mjs/agent/add-base-path-const.mjs +0 -65
  11. package/dist-mjs/agent/add-base-path-import.mjs +0 -60
  12. package/dist-mjs/agent/add-url-domain.mjs +0 -61
  13. package/dist-mjs/agent/agent-test-wiring.mjs +0 -221
  14. package/dist-mjs/agent/fetch-response-body-json.mjs +0 -146
  15. package/dist-mjs/agent/fetch-response-header-getter.mjs +0 -117
  16. package/dist-mjs/agent/fetch-response-status.mjs +0 -76
  17. package/dist-mjs/agent/fetch-then.mjs +0 -273
  18. package/dist-mjs/agent/fetch.mjs +0 -48
  19. package/dist-mjs/agent/file.mjs +0 -43
  20. package/dist-mjs/agent/fix-function-call-arguments.mjs +0 -153
  21. package/dist-mjs/agent/no-fixture.mjs +0 -397
  22. package/dist-mjs/agent/no-mapped-response.mjs +0 -75
  23. package/dist-mjs/agent/no-service-wrapper.mjs +0 -185
  24. package/dist-mjs/agent/no-status-code.mjs +0 -59
  25. package/dist-mjs/agent/no-supertest.mjs +0 -346
  26. package/dist-mjs/agent/no-unused-function-argument.mjs +0 -79
  27. package/dist-mjs/agent/no-unused-imports.mjs +0 -81
  28. package/dist-mjs/agent/no-unused-service-variable.mjs +0 -74
  29. package/dist-mjs/agent/response-reference.mjs +0 -78
  30. package/dist-mjs/agent/supertest-then.mjs +0 -170
  31. package/dist-mjs/agent/url.mjs +0 -32
  32. package/dist-types/agent/add-assert-import.d.ts +0 -4
  33. package/dist-types/agent/add-base-path-const.d.ts +0 -4
  34. package/dist-types/agent/add-base-path-import.d.ts +0 -4
  35. package/dist-types/agent/add-url-domain.d.ts +0 -4
  36. package/dist-types/agent/agent-test-wiring.d.ts +0 -4
  37. package/dist-types/agent/fetch-response-body-json.d.ts +0 -4
  38. package/dist-types/agent/fetch-response-header-getter.d.ts +0 -4
  39. package/dist-types/agent/fetch-response-status.d.ts +0 -4
  40. package/dist-types/agent/fetch-then.d.ts +0 -4
  41. package/dist-types/agent/fetch.d.ts +0 -8
  42. package/dist-types/agent/file.d.ts +0 -7
  43. package/dist-types/agent/fix-function-call-arguments.d.ts +0 -9
  44. package/dist-types/agent/no-fixture.d.ts +0 -4
  45. package/dist-types/agent/no-mapped-response.d.ts +0 -4
  46. package/dist-types/agent/no-service-wrapper.d.ts +0 -4
  47. package/dist-types/agent/no-status-code.d.ts +0 -4
  48. package/dist-types/agent/no-supertest.d.ts +0 -4
  49. package/dist-types/agent/no-unused-function-argument.d.ts +0 -4
  50. package/dist-types/agent/no-unused-imports.d.ts +0 -4
  51. package/dist-types/agent/no-unused-service-variable.d.ts +0 -4
  52. package/dist-types/agent/response-reference.d.ts +0 -17
  53. package/dist-types/agent/supertest-then.d.ts +0 -4
  54. package/dist-types/agent/url.d.ts +0 -4
  55. package/src/agent/add-assert-import.ts +0 -74
  56. package/src/agent/add-base-path-const.ts +0 -81
  57. package/src/agent/add-base-path-import.ts +0 -69
  58. package/src/agent/add-url-domain.ts +0 -76
  59. package/src/agent/agent-test-wiring.ts +0 -273
  60. package/src/agent/fetch-response-body-json.ts +0 -194
  61. package/src/agent/fetch-response-header-getter.ts +0 -148
  62. package/src/agent/fetch-response-status.ts +0 -100
  63. package/src/agent/fetch-then.ts +0 -359
  64. package/src/agent/fetch.ts +0 -69
  65. package/src/agent/file.ts +0 -42
  66. package/src/agent/fix-function-call-arguments.ts +0 -200
  67. package/src/agent/no-fixture.ts +0 -581
  68. package/src/agent/no-mapped-response.ts +0 -84
  69. package/src/agent/no-service-wrapper.ts +0 -241
  70. package/src/agent/no-status-code.ts +0 -69
  71. package/src/agent/no-supertest.ts +0 -517
  72. package/src/agent/no-unused-function-argument.ts +0 -98
  73. package/src/agent/no-unused-imports.ts +0 -103
  74. package/src/agent/no-unused-service-variable.ts +0 -93
  75. package/src/agent/response-reference.ts +0 -153
  76. package/src/agent/supertest-then.ts +0 -230
  77. package/src/agent/url.ts +0 -32
@@ -1,48 +0,0 @@
1
- // src/agent/fetch.ts
2
- import { AST_NODE_TYPES } from "@typescript-eslint/utils";
3
- import "typescript";
4
- import { getParent, isBlockStatement } from "../library/ts-tree.mjs";
5
- function getResponseBodyRetrievalText(responseVariableName) {
6
- return `await ${responseVariableName}.json()`;
7
- }
8
- function getResponseStatusRetrievalText(responseVariableName) {
9
- return `${responseVariableName}.status`;
10
- }
11
- function getResponseHeadersRetrievalText(responseVariableName) {
12
- return `${responseVariableName}.headers`;
13
- }
14
- function isInvalidResponseHeadersAccess(responseHeadersAccess) {
15
- const responseHeaderAccessParent = getParent(responseHeadersAccess);
16
- if (responseHeaderAccessParent?.type === AST_NODE_TYPES.VariableDeclarator) {
17
- return false;
18
- }
19
- if (responseHeaderAccessParent?.type === AST_NODE_TYPES.CallExpression && responseHeaderAccessParent.callee.type === AST_NODE_TYPES.MemberExpression && responseHeaderAccessParent.callee.property.type === AST_NODE_TYPES.Identifier && responseHeaderAccessParent.callee.property.name === "get") {
20
- return true;
21
- }
22
- return !(responseHeaderAccessParent?.type === AST_NODE_TYPES.MemberExpression && responseHeaderAccessParent.property.type === AST_NODE_TYPES.Identifier && responseHeaderAccessParent.property.name === "get");
23
- }
24
- function hasAssertions(fixtureCall) {
25
- if (isBlockStatement(fixtureCall)) {
26
- return false;
27
- }
28
- const parent = getParent(fixtureCall);
29
- if (!parent) {
30
- return false;
31
- }
32
- if (parent.type === AST_NODE_TYPES.MemberExpression && parent.property.type === AST_NODE_TYPES.Identifier && parent.property.name === "expect" && getParent(parent)?.type === AST_NODE_TYPES.CallExpression) {
33
- return true;
34
- }
35
- return hasAssertions(parent);
36
- }
37
- function isFetchResponse(type) {
38
- return type.getProperties().some((symbol) => symbol.name === "body") && type.getProperties().some((symbol) => symbol.name === "json");
39
- }
40
- export {
41
- getResponseBodyRetrievalText,
42
- getResponseHeadersRetrievalText,
43
- getResponseStatusRetrievalText,
44
- hasAssertions,
45
- isFetchResponse,
46
- isInvalidResponseHeadersAccess
47
- };
48
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2FnZW50L2ZldGNoLnRzIl0sCiAgIm1hcHBpbmdzIjogIjtBQUVBLFNBQVMsc0JBQWdDO0FBQ3pDLE9BQWU7QUFFZixTQUFTLFdBQVcsd0JBQXdCO0FBRXJDLFNBQVMsNkJBQTZCLHNCQUE4QjtBQUN6RSxTQUFPLFNBQVMsb0JBQW9CO0FBQ3RDO0FBRU8sU0FBUywrQkFBK0Isc0JBQThCO0FBQzNFLFNBQU8sR0FBRyxvQkFBb0I7QUFDaEM7QUFFTyxTQUFTLGdDQUFnQyxzQkFBOEI7QUFDNUUsU0FBTyxHQUFHLG9CQUFvQjtBQUNoQztBQUVPLFNBQVMsK0JBQStCLHVCQUErQztBQUM1RixRQUFNLDZCQUE2QixVQUFVLHFCQUFxQjtBQUNsRSxNQUFJLDRCQUE0QixTQUFTLGVBQWUsb0JBQW9CO0FBQzFFLFdBQU87QUFBQSxFQUNUO0FBRUEsTUFDRSw0QkFBNEIsU0FBUyxlQUFlLGtCQUNwRCwyQkFBMkIsT0FBTyxTQUFTLGVBQWUsb0JBQzFELDJCQUEyQixPQUFPLFNBQVMsU0FBUyxlQUFlLGNBQ25FLDJCQUEyQixPQUFPLFNBQVMsU0FBUyxPQUNwRDtBQUNBLFdBQU87QUFBQSxFQUNUO0FBRUEsU0FBTyxFQUNMLDRCQUE0QixTQUFTLGVBQWUsb0JBQ3BELDJCQUEyQixTQUFTLFNBQVMsZUFBZSxjQUM1RCwyQkFBMkIsU0FBUyxTQUFTO0FBRWpEO0FBRU8sU0FBUyxjQUFjLGFBQXFDO0FBQ2pFLE1BQUksaUJBQWlCLFdBQVcsR0FBRztBQUNqQyxXQUFPO0FBQUEsRUFDVDtBQUVBLFFBQU0sU0FBUyxVQUFVLFdBQVc7QUFDcEMsTUFBSSxDQUFDLFFBQVE7QUFDWCxXQUFPO0FBQUEsRUFDVDtBQUVBLE1BQ0UsT0FBTyxTQUFTLGVBQWUsb0JBQy9CLE9BQU8sU0FBUyxTQUFTLGVBQWUsY0FDeEMsT0FBTyxTQUFTLFNBQVMsWUFDekIsVUFBVSxNQUFNLEdBQUcsU0FBUyxlQUFlLGdCQUMzQztBQUNBLFdBQU87QUFBQSxFQUNUO0FBRUEsU0FBTyxjQUFjLE1BQU07QUFDN0I7QUFFTyxTQUFTLGdCQUFnQixNQUF3QjtBQUN0RCxTQUNFLEtBQUssY0FBYyxFQUFFLEtBQUssQ0FBQyxXQUFXLE9BQU8sU0FBUyxNQUFNLEtBQzVELEtBQUssY0FBYyxFQUFFLEtBQUssQ0FBQyxXQUFXLE9BQU8sU0FBUyxNQUFNO0FBRWhFOyIsCiAgIm5hbWVzIjogW10KfQo=
@@ -1,43 +0,0 @@
1
- // src/agent/file.ts
2
- import fs from "node:fs";
3
- import path from "node:path";
4
- function isApiIndexFile(filename) {
5
- return /.*\/src\/api\/v\d+\/index.ts/u.test(filename);
6
- }
7
- function getProjectRootFolder(indexFilename) {
8
- return indexFilename.substring(0, indexFilename.lastIndexOf("/src/"));
9
- }
10
- function getSwaggerPathByIndexFile(indexFilename) {
11
- return indexFilename.replace(/index\.ts$/u, "swagger.yml");
12
- }
13
- function loadSwagger(filename) {
14
- return fs.readFileSync(filename, "utf8");
15
- }
16
- function loadPackageJson(projectRoot) {
17
- return fs.readFileSync(`${projectRoot}/package.json`, "utf8");
18
- }
19
- function getApiFolder(folder) {
20
- if (/^\/?(?<absolutePath>(?:[^/]+\/)*)src\/api\/v\d+$/u.test(folder)) {
21
- return folder;
22
- }
23
- const upperFolder = folder.substring(0, folder.lastIndexOf("/"));
24
- return upperFolder.trim() === "" ? void 0 : getApiFolder(upperFolder);
25
- }
26
- function getApiIndexPathByFilename(filename) {
27
- const apiFolder = getApiFolder(filename);
28
- if (apiFolder === void 0) {
29
- return void 0;
30
- }
31
- const relativePath = path.relative(path.dirname(filename), `${apiFolder}/index`);
32
- return relativePath.startsWith("../") ? relativePath : `./${relativePath}`;
33
- }
34
- export {
35
- getApiFolder,
36
- getApiIndexPathByFilename,
37
- getProjectRootFolder,
38
- getSwaggerPathByIndexFile,
39
- isApiIndexFile,
40
- loadPackageJson,
41
- loadSwagger
42
- };
43
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2FnZW50L2ZpbGUudHMiXSwKICAibWFwcGluZ3MiOiAiO0FBRUEsT0FBTyxRQUFRO0FBQ2YsT0FBTyxVQUFVO0FBRVYsU0FBUyxlQUFlLFVBQTJCO0FBQ3hELFNBQU8sZ0NBQWdDLEtBQUssUUFBUTtBQUN0RDtBQUVPLFNBQVMscUJBQXFCLGVBQStCO0FBQ2xFLFNBQU8sY0FBYyxVQUFVLEdBQUcsY0FBYyxZQUFZLE9BQU8sQ0FBQztBQUN0RTtBQUVPLFNBQVMsMEJBQTBCLGVBQStCO0FBQ3ZFLFNBQU8sY0FBYyxRQUFRLGVBQWUsYUFBYTtBQUMzRDtBQUVPLFNBQVMsWUFBWSxVQUEwQjtBQUNwRCxTQUFPLEdBQUcsYUFBYSxVQUFVLE1BQU07QUFDekM7QUFFTyxTQUFTLGdCQUFnQixhQUE2QjtBQUMzRCxTQUFPLEdBQUcsYUFBYSxHQUFHLFdBQVcsaUJBQWlCLE1BQU07QUFDOUQ7QUFFTyxTQUFTLGFBQWEsUUFBb0M7QUFDL0QsTUFBSSxvREFBb0QsS0FBSyxNQUFNLEdBQUc7QUFDcEUsV0FBTztBQUFBLEVBQ1Q7QUFDQSxRQUFNLGNBQWMsT0FBTyxVQUFVLEdBQUcsT0FBTyxZQUFZLEdBQUcsQ0FBQztBQUMvRCxTQUFPLFlBQVksS0FBSyxNQUFNLEtBQUssU0FBWSxhQUFhLFdBQVc7QUFDekU7QUFFTyxTQUFTLDBCQUEwQixVQUFzQztBQUM5RSxRQUFNLFlBQVksYUFBYSxRQUFRO0FBQ3ZDLE1BQUksY0FBYyxRQUFXO0FBQzNCLFdBQU87QUFBQSxFQUNUO0FBRUEsUUFBTSxlQUFlLEtBQUssU0FBUyxLQUFLLFFBQVEsUUFBUSxHQUFHLEdBQUcsU0FBUyxRQUFRO0FBQy9FLFNBQU8sYUFBYSxXQUFXLEtBQUssSUFBSSxlQUFlLEtBQUssWUFBWTtBQUMxRTsiLAogICJuYW1lcyI6IFtdCn0K
@@ -1,153 +0,0 @@
1
- // src/agent/fix-function-call-arguments.ts
2
- import { strict as assert } from "node:assert";
3
- import { ESLintUtils } from "@typescript-eslint/utils";
4
- import debug from "debug";
5
- import getDocumentationUrl from "../get-documentation-url.mjs";
6
- var ruleId = "fix-function-call-arguments";
7
- var DEFAULT_OPTIONS = {
8
- typesToCheck: [
9
- "Configuration<ResolvedServices>",
10
- "Fixture<ResolvedServices>",
11
- "InboundContext",
12
- "{ get: () => string; }",
13
- "Api"
14
- ]
15
- };
16
- var createRule = ESLintUtils.RuleCreator((name) => getDocumentationUrl(name));
17
- var log = debug("eslint-plugin:fix-function-call-arguments");
18
- var rule = createRule({
19
- name: ruleId,
20
- meta: {
21
- type: "suggestion",
22
- docs: {
23
- description: "Remove incompatible function arguments."
24
- },
25
- messages: {
26
- removeIncompatibleFunctionArguments: "Removing incompatible function arguments.",
27
- unknownError: 'Unknown error occurred in file "{{fileName}}": {{ error }}.'
28
- },
29
- fixable: "code",
30
- schema: [
31
- {
32
- type: "object",
33
- properties: {
34
- typesToCheck: {
35
- description: "Text representation of the types of which the function call parameters will be examine",
36
- type: "array",
37
- items: {
38
- type: "string"
39
- }
40
- }
41
- },
42
- additionalProperties: false
43
- }
44
- ]
45
- },
46
- defaultOptions: [DEFAULT_OPTIONS],
47
- create(context) {
48
- const { typesToCheck } = context.options[0] ?? DEFAULT_OPTIONS;
49
- const parserServices = ESLintUtils.getParserServices(context);
50
- const typeChecker = parserServices.program.getTypeChecker();
51
- const sourceCode = context.sourceCode;
52
- return {
53
- CallExpression(callExpression) {
54
- log("===== file name:", context.filename);
55
- log("callExpression:", sourceCode.getText(callExpression));
56
- try {
57
- const actualParameters = callExpression.arguments;
58
- if (!actualParameters.some((actualParameter) => {
59
- const actualType = typeChecker.getTypeAtLocation(
60
- parserServices.esTreeNodeToTSNodeMap.get(actualParameter)
61
- );
62
- const actualTypeString = typeChecker.typeToString(actualType);
63
- return typesToCheck.includes(actualTypeString) || actualTypeString.endsWith("RequestType");
64
- })) {
65
- return;
66
- }
67
- const calleeTsNode = parserServices.esTreeNodeToTSNodeMap.get(callExpression.callee);
68
- const calleeType = typeChecker.getTypeAtLocation(calleeTsNode);
69
- const signatures = calleeType.getCallSignatures();
70
- if (signatures.length > 1) {
71
- return;
72
- }
73
- const signature = signatures[0];
74
- assert(signature);
75
- log("signature:", signature.getDeclaration().getText());
76
- const expectedParameters = signature.getParameters();
77
- log(
78
- "expected parameters:",
79
- expectedParameters.map(
80
- (expectedParameter) => typeChecker.typeToString(typeChecker.getTypeOfSymbol(expectedParameter))
81
- )
82
- );
83
- const expectedParametersCount = expectedParameters.length;
84
- const actualParametersCount = actualParameters.length;
85
- if (actualParametersCount === 0) {
86
- return;
87
- }
88
- const parametersToKeep = [];
89
- let expectedParameterIndex = 0;
90
- for (const [actualParameterIndex, actualParameter] of actualParameters.entries()) {
91
- if (expectedParameterIndex >= expectedParametersCount) {
92
- break;
93
- }
94
- const expectedParameter = expectedParameters[expectedParameterIndex];
95
- assert.ok(expectedParameter, "Expected parameter not found.");
96
- const expectedType = typeChecker.getTypeOfSymbol(expectedParameter);
97
- const actualType = typeChecker.getTypeAtLocation(parserServices.esTreeNodeToTSNodeMap.get(actualParameter));
98
- const actualTypeString = typeChecker.typeToString(actualType);
99
- log(
100
- "expected type: #",
101
- expectedParameterIndex,
102
- expectedParameter.escapedName,
103
- typeChecker.typeToString(expectedType)
104
- );
105
- log("actual type: #", actualParameterIndex, sourceCode.getText(actualParameter), actualTypeString);
106
- if ((typesToCheck.includes(actualTypeString) || actualTypeString.endsWith("RequestType")) && !typeChecker.isTypeAssignableTo(actualType, expectedType)) {
107
- log("removing un-matched parameter", sourceCode.getText(actualParameter));
108
- continue;
109
- }
110
- parametersToKeep.push(actualParameter);
111
- expectedParameterIndex++;
112
- }
113
- if (parametersToKeep.length === actualParametersCount) {
114
- return;
115
- }
116
- const firstParameter = actualParameters[0];
117
- const lastParameter = actualParameters.at(-1);
118
- assert.ok(firstParameter !== void 0 && lastParameter !== void 0);
119
- const tokenAfterParameters = sourceCode.getTokenAfter(lastParameter);
120
- context.report({
121
- node: callExpression,
122
- messageId: "removeIncompatibleFunctionArguments",
123
- fix(fixer) {
124
- return fixer.replaceTextRange(
125
- [
126
- firstParameter.range[0],
127
- tokenAfterParameters?.value === "," ? tokenAfterParameters.range[1] : lastParameter.range[1]
128
- ],
129
- parametersToKeep.map((arg) => sourceCode.getText(arg)).join(", ")
130
- );
131
- }
132
- });
133
- } catch (error) {
134
- console.error(`Failed to apply ${ruleId} rule for file "${context.filename}":`, error);
135
- context.report({
136
- node: callExpression,
137
- messageId: "unknownError",
138
- data: {
139
- fileName: context.filename,
140
- error: error instanceof Error ? error.toString() : JSON.stringify(error)
141
- }
142
- });
143
- }
144
- }
145
- };
146
- }
147
- });
148
- var fix_function_call_arguments_default = rule;
149
- export {
150
- fix_function_call_arguments_default as default,
151
- ruleId
152
- };
153
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2FnZW50L2ZpeC1mdW5jdGlvbi1jYWxsLWFyZ3VtZW50cy50cyJdLAogICJtYXBwaW5ncyI6ICI7QUFRQSxTQUFTLFVBQVUsY0FBYztBQUNqQyxTQUFTLG1CQUE2QjtBQUN0QyxPQUFPLFdBQVc7QUFDbEIsT0FBTyx5QkFBeUI7QUFFekIsSUFBTSxTQUFTO0FBS3RCLElBQU0sa0JBQWtCO0FBQUEsRUFDdEIsY0FBYztBQUFBLElBQ1o7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsRUFDRjtBQUNGO0FBRUEsSUFBTSxhQUFhLFlBQVksWUFBWSxDQUFDLFNBQVMsb0JBQW9CLElBQUksQ0FBQztBQUM5RSxJQUFNLE1BQU0sTUFBTSwyQ0FBMkM7QUFFN0QsSUFBTSxPQUdGLFdBQVc7QUFBQSxFQUNiLE1BQU07QUFBQSxFQUNOLE1BQU07QUFBQSxJQUNKLE1BQU07QUFBQSxJQUNOLE1BQU07QUFBQSxNQUNKLGFBQWE7QUFBQSxJQUNmO0FBQUEsSUFDQSxVQUFVO0FBQUEsTUFDUixxQ0FBcUM7QUFBQSxNQUNyQyxjQUFjO0FBQUEsSUFDaEI7QUFBQSxJQUNBLFNBQVM7QUFBQSxJQUNULFFBQVE7QUFBQSxNQUNOO0FBQUEsUUFDRSxNQUFNO0FBQUEsUUFDTixZQUFZO0FBQUEsVUFDVixjQUFjO0FBQUEsWUFDWixhQUFhO0FBQUEsWUFDYixNQUFNO0FBQUEsWUFDTixPQUFPO0FBQUEsY0FDTCxNQUFNO0FBQUEsWUFDUjtBQUFBLFVBQ0Y7QUFBQSxRQUNGO0FBQUEsUUFDQSxzQkFBc0I7QUFBQSxNQUN4QjtBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBQUEsRUFDQSxnQkFBZ0IsQ0FBQyxlQUFlO0FBQUEsRUFDaEMsT0FBTyxTQUFTO0FBRWQsVUFBTSxFQUFFLGFBQWEsSUFBSSxRQUFRLFFBQVEsQ0FBQyxLQUFLO0FBQy9DLFVBQU0saUJBQWlCLFlBQVksa0JBQWtCLE9BQU87QUFDNUQsVUFBTSxjQUFjLGVB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