From 99489b90ae56080bbfd1a0e6ebb1098baaf2ee95 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Tue, 7 May 2024 16:10:12 +0800 Subject: [PATCH] `no-array-method-this-argument`: Check `Array.fromAsync()` (#2330) --- rules/no-array-method-this-argument.js | 4 +- test/no-array-method-this-argument.mjs | 31 ++ .../no-array-method-this-argument.mjs.md | 287 ++++++++++++++++-- .../no-array-method-this-argument.mjs.snap | Bin 1772 -> 2241 bytes 4 files changed, 299 insertions(+), 23 deletions(-) diff --git a/rules/no-array-method-this-argument.js b/rules/no-array-method-this-argument.js index 31f70fe04d..d6330a7c35 100644 --- a/rules/no-array-method-this-argument.js +++ b/rules/no-array-method-this-argument.js @@ -184,12 +184,12 @@ const create = context => { }); }); - // `Array.from()` + // `Array.from()` and `Array.fromAsync()` context.on('CallExpression', callExpression => { if ( !isMethodCall(callExpression, { object: 'Array', - method: 'from', + methods: ['from', 'fromAsync'], argumentsLength: 3, optionalCall: false, optionalMember: false, diff --git a/test/no-array-method-this-argument.mjs b/test/no-array-method-this-argument.mjs index c50143a9f9..9d5feba658 100644 --- a/test/no-array-method-this-argument.mjs +++ b/test/no-array-method-this-argument.mjs @@ -14,6 +14,10 @@ test.snapshot({ 'Array.from?.(iterableOrArrayLike, () => {}, thisArgument)', 'Array?.from(iterableOrArrayLike, () => {}, thisArgument)', 'NotArray.from(iterableOrArrayLike, () => {}, thisArgument)', + 'new Array.fromAsync(iterableOrArrayLike, () => {}, thisArgument)', + 'Array.fromAsync?.(iterableOrArrayLike, () => {}, thisArgument)', + 'Array?.fromAsync(iterableOrArrayLike, () => {}, thisArgument)', + 'NotArray.fromAsync(iterableOrArrayLike, () => {}, thisArgument)', // More or less arguments 'array.map()', @@ -28,6 +32,13 @@ test.snapshot({ 'Array.from(iterableOrArrayLike, ...() => {}, thisArgument)', 'Array.from(...iterableOrArrayLike, () => {}, thisArgument)', 'Array.from(iterableOrArrayLike, () => {}, thisArgument, extraArgument)', + 'Array.fromAsync()', + 'Array.fromAsync(iterableOrArrayLike)', + 'Array.fromAsync(iterableOrArrayLike, () => {},)', + 'Array.fromAsync(iterableOrArrayLike, () => {}, ...thisArgument)', + 'Array.fromAsync(iterableOrArrayLike, ...() => {}, thisArgument)', + 'Array.fromAsync(...iterableOrArrayLike, () => {}, thisArgument)', + 'Array.fromAsync(iterableOrArrayLike, () => {}, thisArgument, extraArgument)', // Ignored 'lodash.every(array, () => {})', @@ -52,8 +63,11 @@ test.snapshot({ 'array.map(1, thisArgument)', 'async () => array.map(await callback, thisArgument)', 'Array.from(iterableOrArrayLike, new Callback, thisArgument)', + 'Array.fromAsync(iterableOrArrayLike, new Callback, thisArgument)', 'Array.from(iterableOrArrayLike, 1, thisArgument)', + 'Array.fromAsync(iterableOrArrayLike, 1, thisArgument)', 'Array.from(iterableOrArrayLike, await callback, thisArgument)', + 'Array.fromAsync(iterableOrArrayLike, await callback, thisArgument)', ], invalid: [ 'array.every(() => {}, thisArgument)', @@ -66,13 +80,16 @@ test.snapshot({ 'array.forEach(() => {}, thisArgument)', 'array.map(() => {}, thisArgument)', 'Array.from(iterableOrArrayLike, () => {}, thisArgument)', + 'Array.fromAsync(iterableOrArrayLike, () => {}, thisArgument)', // Comma 'array.map(() => {}, thisArgument,)', 'array.map(() => {}, (0, thisArgument),)', 'Array.from(iterableOrArrayLike, () => {}, thisArgument,)', + 'Array.fromAsync(iterableOrArrayLike, () => {}, thisArgument,)', // Side effect 'array.map(() => {}, thisArgumentHasSideEffect())', 'Array.from(iterableOrArrayLike, () => {}, thisArgumentHasSideEffect())', + 'Array.fromAsync(iterableOrArrayLike, () => {}, thisArgumentHasSideEffect())', ], }); @@ -82,12 +99,15 @@ test.snapshot({ invalid: [ 'array.map(callback, thisArgument)', 'Array.from(iterableOrArrayLike, callback, thisArgument)', + 'Array.fromAsync(iterableOrArrayLike, callback, thisArgument)', 'array.map(callback, (0, thisArgument))', 'Array.from(iterableOrArrayLike, callback, (0, thisArgument))', + 'Array.fromAsync(iterableOrArrayLike, callback, (0, thisArgument))', 'array.map(function () {}, thisArgument)', 'Array.from(iterableOrArrayLike, function () {}, thisArgument)', 'array.map(function callback () {}, thisArgument)', 'Array.from(iterableOrArrayLike, function callback () {}, thisArgument)', + 'Array.fromAsync(iterableOrArrayLike, function callback () {}, thisArgument)', { code: 'array.map( foo as bar, (( thisArgument )),)', languageOptions: {parser: parsers.typescript}, @@ -96,6 +116,10 @@ test.snapshot({ code: 'Array.from(iterableOrArrayLike, foo as bar, (( thisArgument )),)', languageOptions: {parser: parsers.typescript}, }, + { + code: 'Array.fromAsync(iterableOrArrayLike, foo as bar, (( thisArgument )),)', + languageOptions: {parser: parsers.typescript}, + }, { code: 'array.map( (( foo as bar )), (( thisArgument )),)', languageOptions: {parser: parsers.typescript}, @@ -104,13 +128,20 @@ test.snapshot({ code: 'Array.from(iterableOrArrayLike, (( foo as bar )), (( thisArgument )),)', languageOptions: {parser: parsers.typescript}, }, + { + code: 'Array.fromAsync(iterableOrArrayLike, (( foo as bar )), (( thisArgument )),)', + languageOptions: {parser: parsers.typescript}, + }, 'array.map( (( 0, callback )), (( thisArgument )),)', 'Array.from(iterableOrArrayLike, (( 0, callback )), (( thisArgument )),)', + 'Array.fromAsync(iterableOrArrayLike, (( 0, callback )), (( thisArgument )),)', // This callback is actually arrow function, but we don't know 'array.map((0, () => {}), thisArgument)', 'Array.from(iterableOrArrayLike, (0, () => {}), thisArgument)', + 'Array.fromAsync(iterableOrArrayLike, (0, () => {}), thisArgument)', // This callback is a bound function, but we don't know 'array.map(callback.bind(foo), thisArgument)', 'Array.from(iterableOrArrayLike, callback.bind(foo), thisArgument)', + 'Array.fromAsync(iterableOrArrayLike, callback.bind(foo), thisArgument)', ], }); diff --git a/test/snapshots/no-array-method-this-argument.mjs.md b/test/snapshots/no-array-method-this-argument.mjs.md index 9691c03253..aa1fc0514d 100644 --- a/test/snapshots/no-array-method-this-argument.mjs.md +++ b/test/snapshots/no-array-method-this-argument.mjs.md @@ -214,7 +214,28 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^ Do not use the \`this\` argument in \`Array.from()\`.␊ ` -## invalid(11): array.map(() => {}, thisArgument,) +## invalid(11): Array.fromAsync(iterableOrArrayLike, () => {}, thisArgument) + +> Input + + `␊ + 1 | Array.fromAsync(iterableOrArrayLike, () => {}, thisArgument)␊ + ` + +> Output + + `␊ + 1 | Array.fromAsync(iterableOrArrayLike, () => {})␊ + ` + +> Error 1/1 + + `␊ + > 1 | Array.fromAsync(iterableOrArrayLike, () => {}, thisArgument)␊ + | ^^^^^^^^^^^^ Do not use the \`this\` argument in \`Array.fromAsync()\`.␊ + ` + +## invalid(12): array.map(() => {}, thisArgument,) > Input @@ -235,7 +256,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^ Do not use the \`this\` argument in \`Array#map()\`.␊ ` -## invalid(12): array.map(() => {}, (0, thisArgument),) +## invalid(13): array.map(() => {}, (0, thisArgument),) > Input @@ -256,7 +277,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^ Do not use the \`this\` argument in \`Array#map()\`.␊ ` -## invalid(13): Array.from(iterableOrArrayLike, () => {}, thisArgument,) +## invalid(14): Array.from(iterableOrArrayLike, () => {}, thisArgument,) > Input @@ -277,7 +298,28 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^ Do not use the \`this\` argument in \`Array.from()\`.␊ ` -## invalid(14): array.map(() => {}, thisArgumentHasSideEffect()) +## invalid(15): Array.fromAsync(iterableOrArrayLike, () => {}, thisArgument,) + +> Input + + `␊ + 1 | Array.fromAsync(iterableOrArrayLike, () => {}, thisArgument,)␊ + ` + +> Output + + `␊ + 1 | Array.fromAsync(iterableOrArrayLike, () => {},)␊ + ` + +> Error 1/1 + + `␊ + > 1 | Array.fromAsync(iterableOrArrayLike, () => {}, thisArgument,)␊ + | ^^^^^^^^^^^^ Do not use the \`this\` argument in \`Array.fromAsync()\`.␊ + ` + +## invalid(16): array.map(() => {}, thisArgumentHasSideEffect()) > Input @@ -296,7 +338,7 @@ Generated by [AVA](https://avajs.dev). 1 | array.map(() => {})␊ ` -## invalid(15): Array.from(iterableOrArrayLike, () => {}, thisArgumentHasSideEffect()) +## invalid(17): Array.from(iterableOrArrayLike, () => {}, thisArgumentHasSideEffect()) > Input @@ -315,6 +357,25 @@ Generated by [AVA](https://avajs.dev). 1 | Array.from(iterableOrArrayLike, () => {})␊ ` +## invalid(18): Array.fromAsync(iterableOrArrayLike, () => {}, thisArgumentHasSideEffect()) + +> Input + + `␊ + 1 | Array.fromAsync(iterableOrArrayLike, () => {}, thisArgumentHasSideEffect())␊ + ` + +> Error 1/1 + + `␊ + > 1 | Array.fromAsync(iterableOrArrayLike, () => {}, thisArgumentHasSideEffect())␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not use the \`this\` argument in \`Array.fromAsync()\`.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Remove this argument.␊ + 1 | Array.fromAsync(iterableOrArrayLike, () => {})␊ + ` + ## invalid(1): array.map(callback, thisArgument) > Input @@ -361,7 +422,30 @@ Generated by [AVA](https://avajs.dev). 1 | Array.from(iterableOrArrayLike, callback.bind(thisArgument))␊ ` -## invalid(3): array.map(callback, (0, thisArgument)) +## invalid(3): Array.fromAsync(iterableOrArrayLike, callback, thisArgument) + +> Input + + `␊ + 1 | Array.fromAsync(iterableOrArrayLike, callback, thisArgument)␊ + ` + +> Error 1/1 + + `␊ + > 1 | Array.fromAsync(iterableOrArrayLike, callback, thisArgument)␊ + | ^^^^^^^^^^^^ Do not use the \`this\` argument in \`Array.fromAsync()\`.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/2: Remove this argument.␊ + 1 | Array.fromAsync(iterableOrArrayLike, callback)␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 2/2: Use a bound function.␊ + 1 | Array.fromAsync(iterableOrArrayLike, callback.bind(thisArgument))␊ + ` + +## invalid(4): array.map(callback, (0, thisArgument)) > Input @@ -384,7 +468,7 @@ Generated by [AVA](https://avajs.dev). 1 | array.map(callback.bind((0, thisArgument)))␊ ` -## invalid(4): Array.from(iterableOrArrayLike, callback, (0, thisArgument)) +## invalid(5): Array.from(iterableOrArrayLike, callback, (0, thisArgument)) > Input @@ -407,7 +491,30 @@ Generated by [AVA](https://avajs.dev). 1 | Array.from(iterableOrArrayLike, callback.bind((0, thisArgument)))␊ ` -## invalid(5): array.map(function () {}, thisArgument) +## invalid(6): Array.fromAsync(iterableOrArrayLike, callback, (0, thisArgument)) + +> Input + + `␊ + 1 | Array.fromAsync(iterableOrArrayLike, callback, (0, thisArgument))␊ + ` + +> Error 1/1 + + `␊ + > 1 | Array.fromAsync(iterableOrArrayLike, callback, (0, thisArgument))␊ + | ^^^^^^^^^^^^^^^ Do not use the \`this\` argument in \`Array.fromAsync()\`.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/2: Remove this argument.␊ + 1 | Array.fromAsync(iterableOrArrayLike, callback)␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 2/2: Use a bound function.␊ + 1 | Array.fromAsync(iterableOrArrayLike, callback.bind((0, thisArgument)))␊ + ` + +## invalid(7): array.map(function () {}, thisArgument) > Input @@ -430,7 +537,7 @@ Generated by [AVA](https://avajs.dev). 1 | array.map(function () {}.bind(thisArgument))␊ ` -## invalid(6): Array.from(iterableOrArrayLike, function () {}, thisArgument) +## invalid(8): Array.from(iterableOrArrayLike, function () {}, thisArgument) > Input @@ -453,7 +560,7 @@ Generated by [AVA](https://avajs.dev). 1 | Array.from(iterableOrArrayLike, function () {}.bind(thisArgument))␊ ` -## invalid(7): array.map(function callback () {}, thisArgument) +## invalid(9): array.map(function callback () {}, thisArgument) > Input @@ -476,7 +583,7 @@ Generated by [AVA](https://avajs.dev). 1 | array.map(function callback () {}.bind(thisArgument))␊ ` -## invalid(8): Array.from(iterableOrArrayLike, function callback () {}, thisArgument) +## invalid(10): Array.from(iterableOrArrayLike, function callback () {}, thisArgument) > Input @@ -499,7 +606,30 @@ Generated by [AVA](https://avajs.dev). 1 | Array.from(iterableOrArrayLike, function callback () {}.bind(thisArgument))␊ ` -## invalid(9): array.map( foo as bar, (( thisArgument )),) +## invalid(11): Array.fromAsync(iterableOrArrayLike, function callback () {}, thisArgument) + +> Input + + `␊ + 1 | Array.fromAsync(iterableOrArrayLike, function callback () {}, thisArgument)␊ + ` + +> Error 1/1 + + `␊ + > 1 | Array.fromAsync(iterableOrArrayLike, function callback () {}, thisArgument)␊ + | ^^^^^^^^^^^^ Do not use the \`this\` argument in \`Array.fromAsync()\`.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/2: Remove this argument.␊ + 1 | Array.fromAsync(iterableOrArrayLike, function callback () {})␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 2/2: Use a bound function.␊ + 1 | Array.fromAsync(iterableOrArrayLike, function callback () {}.bind(thisArgument))␊ + ` + +## invalid(12): array.map( foo as bar, (( thisArgument )),) > Input @@ -522,7 +652,7 @@ Generated by [AVA](https://avajs.dev). 1 | array.map( (foo as bar).bind((( thisArgument ))),)␊ ` -## invalid(10): Array.from(iterableOrArrayLike, foo as bar, (( thisArgument )),) +## invalid(13): Array.from(iterableOrArrayLike, foo as bar, (( thisArgument )),) > Input @@ -545,7 +675,30 @@ Generated by [AVA](https://avajs.dev). 1 | Array.from(iterableOrArrayLike, (foo as bar).bind((( thisArgument ))),)␊ ` -## invalid(11): array.map( (( foo as bar )), (( thisArgument )),) +## invalid(14): Array.fromAsync(iterableOrArrayLike, foo as bar, (( thisArgument )),) + +> Input + + `␊ + 1 | Array.fromAsync(iterableOrArrayLike, foo as bar, (( thisArgument )),)␊ + ` + +> Error 1/1 + + `␊ + > 1 | Array.fromAsync(iterableOrArrayLike, foo as bar, (( thisArgument )),)␊ + | ^^^^^^^^^^^^ Do not use the \`this\` argument in \`Array.fromAsync()\`.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/2: Remove this argument.␊ + 1 | Array.fromAsync(iterableOrArrayLike, foo as bar,)␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 2/2: Use a bound function.␊ + 1 | Array.fromAsync(iterableOrArrayLike, (foo as bar).bind((( thisArgument ))),)␊ + ` + +## invalid(15): array.map( (( foo as bar )), (( thisArgument )),) > Input @@ -568,7 +721,7 @@ Generated by [AVA](https://avajs.dev). 1 | array.map( (( foo as bar )).bind((( thisArgument ))),)␊ ` -## invalid(12): Array.from(iterableOrArrayLike, (( foo as bar )), (( thisArgument )),) +## invalid(16): Array.from(iterableOrArrayLike, (( foo as bar )), (( thisArgument )),) > Input @@ -591,7 +744,30 @@ Generated by [AVA](https://avajs.dev). 1 | Array.from(iterableOrArrayLike, (( foo as bar )).bind((( thisArgument ))),)␊ ` -## invalid(13): array.map( (( 0, callback )), (( thisArgument )),) +## invalid(17): Array.fromAsync(iterableOrArrayLike, (( foo as bar )), (( thisArgument )),) + +> Input + + `␊ + 1 | Array.fromAsync(iterableOrArrayLike, (( foo as bar )), (( thisArgument )),)␊ + ` + +> Error 1/1 + + `␊ + > 1 | Array.fromAsync(iterableOrArrayLike, (( foo as bar )), (( thisArgument )),)␊ + | ^^^^^^^^^^^^ Do not use the \`this\` argument in \`Array.fromAsync()\`.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/2: Remove this argument.␊ + 1 | Array.fromAsync(iterableOrArrayLike, (( foo as bar )),)␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 2/2: Use a bound function.␊ + 1 | Array.fromAsync(iterableOrArrayLike, (( foo as bar )).bind((( thisArgument ))),)␊ + ` + +## invalid(18): array.map( (( 0, callback )), (( thisArgument )),) > Input @@ -614,7 +790,7 @@ Generated by [AVA](https://avajs.dev). 1 | array.map( (( 0, callback )).bind((( thisArgument ))),)␊ ` -## invalid(14): Array.from(iterableOrArrayLike, (( 0, callback )), (( thisArgument )),) +## invalid(19): Array.from(iterableOrArrayLike, (( 0, callback )), (( thisArgument )),) > Input @@ -637,7 +813,30 @@ Generated by [AVA](https://avajs.dev). 1 | Array.from(iterableOrArrayLike, (( 0, callback )).bind((( thisArgument ))),)␊ ` -## invalid(15): array.map((0, () => {}), thisArgument) +## invalid(20): Array.fromAsync(iterableOrArrayLike, (( 0, callback )), (( thisArgument )),) + +> Input + + `␊ + 1 | Array.fromAsync(iterableOrArrayLike, (( 0, callback )), (( thisArgument )),)␊ + ` + +> Error 1/1 + + `␊ + > 1 | Array.fromAsync(iterableOrArrayLike, (( 0, callback )), (( thisArgument )),)␊ + | ^^^^^^^^^^^^ Do not use the \`this\` argument in \`Array.fromAsync()\`.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/2: Remove this argument.␊ + 1 | Array.fromAsync(iterableOrArrayLike, (( 0, callback )),)␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 2/2: Use a bound function.␊ + 1 | Array.fromAsync(iterableOrArrayLike, (( 0, callback )).bind((( thisArgument ))),)␊ + ` + +## invalid(21): array.map((0, () => {}), thisArgument) > Input @@ -660,7 +859,7 @@ Generated by [AVA](https://avajs.dev). 1 | array.map((0, () => {}).bind(thisArgument))␊ ` -## invalid(16): Array.from(iterableOrArrayLike, (0, () => {}), thisArgument) +## invalid(22): Array.from(iterableOrArrayLike, (0, () => {}), thisArgument) > Input @@ -683,7 +882,30 @@ Generated by [AVA](https://avajs.dev). 1 | Array.from(iterableOrArrayLike, (0, () => {}).bind(thisArgument))␊ ` -## invalid(17): array.map(callback.bind(foo), thisArgument) +## invalid(23): Array.fromAsync(iterableOrArrayLike, (0, () => {}), thisArgument) + +> Input + + `␊ + 1 | Array.fromAsync(iterableOrArrayLike, (0, () => {}), thisArgument)␊ + ` + +> Error 1/1 + + `␊ + > 1 | Array.fromAsync(iterableOrArrayLike, (0, () => {}), thisArgument)␊ + | ^^^^^^^^^^^^ Do not use the \`this\` argument in \`Array.fromAsync()\`.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/2: Remove this argument.␊ + 1 | Array.fromAsync(iterableOrArrayLike, (0, () => {}))␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 2/2: Use a bound function.␊ + 1 | Array.fromAsync(iterableOrArrayLike, (0, () => {}).bind(thisArgument))␊ + ` + +## invalid(24): array.map(callback.bind(foo), thisArgument) > Input @@ -706,7 +928,7 @@ Generated by [AVA](https://avajs.dev). 1 | array.map(callback.bind(foo).bind(thisArgument))␊ ` -## invalid(18): Array.from(iterableOrArrayLike, callback.bind(foo), thisArgument) +## invalid(25): Array.from(iterableOrArrayLike, callback.bind(foo), thisArgument) > Input @@ -728,3 +950,26 @@ Generated by [AVA](https://avajs.dev). Suggestion 2/2: Use a bound function.␊ 1 | Array.from(iterableOrArrayLike, callback.bind(foo).bind(thisArgument))␊ ` + +## invalid(26): Array.fromAsync(iterableOrArrayLike, callback.bind(foo), thisArgument) + +> Input + + `␊ + 1 | Array.fromAsync(iterableOrArrayLike, callback.bind(foo), thisArgument)␊ + ` + +> Error 1/1 + + `␊ + > 1 | Array.fromAsync(iterableOrArrayLike, callback.bind(foo), thisArgument)␊ + | ^^^^^^^^^^^^ Do not use the \`this\` argument in \`Array.fromAsync()\`.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/2: Remove this argument.␊ + 1 | Array.fromAsync(iterableOrArrayLike, callback.bind(foo))␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 2/2: Use a bound function.␊ + 1 | Array.fromAsync(iterableOrArrayLike, callback.bind(foo).bind(thisArgument))␊ + ` diff --git a/test/snapshots/no-array-method-this-argument.mjs.snap b/test/snapshots/no-array-method-this-argument.mjs.snap index fbad73325371c437d6684b885e880c8a8e8c99c9..4ea59be7bc705e9ddf73544d7fa57bbd7ecf1c62 100644 GIT binary patch literal 2241 zcmV;y2tM~gRzVQ7D{$CE~ zLNAPME+2~s00000000B+T+MG2M--12Rh4q%+z+OzkZf?A*bd~Q5Qs=1sR&3hv_YjP zYkN(sI9_D05vcUgP^nd`N>oVwQYBRW0DA2Oj_rj?y;Q2y1HJXuN>#6wDiiP8&pSKw z-prcaIOGV*Zyvvod2e@T_^wi{*`>|qSLyqfQ*~>81liAcPGaC)_X2!a1 zHEt%8DRz90z4v~aIUCjHeB)|s%c?u6YO`)$Yi`(1^Y;C6*>udcnSCQKj&JOi)7L3H>{}8}>IT(x2{$0TShyCmeY7ua+%6z>neB!GMw?gJU_`ehJTCCq`AAUo@dRLQxj9097FHJc7zlw*LyjE_SR z8c&l9z++-Oz9jd6BzOFh2y2okqAtkORYiJCxq2M+=|N1&JRmX8C6Sz#JODk20OiZ` z0LXKXFOObo^o5eAC+n&;)m5uzIxFTiyiRWbO2;6jVlbXUV*u`e5RR|Sw?LcE`m~W$ zBvwUHkItGXC8oPd*o{TAv=NdLVlc82eQ+vDNGckL5}h?gN{qQm%y>#{QSvYaXiEXw z1VB6mQUL0uKqx-@cL4hzK=wtI1T(M3`j*7|3*Ix`L~54J@3^C3ZzZda)i8@S>wM$s zAD*plT4{zBVg;~wqQjmdJWrkzV1X=g0lsJtfoKn0(NwF(G#PDycj^);yzD8Q1q#nM zZ`MniGOq#^7JMqu*WhWr09HAwvI<}D$3XChe!&&$r>d?g{Z54<{kv~%a)?beO?+q- zAyFS%0Ty4e&w*mw*nKtq>^Ig)kM?{3?a7Hg@9?-6J+n&T1|YyUK!8t00`LkFq~i+w z2~UYdPl-w87RQt39ANUKR*&OrbrP(QqprYL@DWh(d%Z3vmh@S+xi>wPkLa~Ip40^( z#G-zmH7Ft)YT1}^F*V_utvQ=x#zHUAJ z$9jciq)%Ob4-`BPOeyd7a%Wry&N!#F_oMuB8~DXZXzkhr7s*4c>aFgU9<8~k&y0S{ zt$CK4)@wa--{MGr@yRrFVV7Lx3$E@i-c!d!E3ZEXoDrQRx6sN z&A`X{ZRBgT03fb+egfY4!QbeDz;K-{cC9RjZDsDiJ2lvfa_x#PHZ5kdqTQ;OS*2Ak zwf`o#qD-;28&8UGZy~5))%dirU)P zI!T6K>OBL3+OW~C*La;uu|7D3WgPNbUtt~X{vFeXjZOlBv-rdTQ7kDFIsf?_*xG&X z0y*v%odl7gaYv6|fzN*wjUF6CfurO8I6X8oh+h`OzI=o~gs?m})A?RPDLV-VZOkF-KK?&$Ia`2H9F=pu%cxqCRK7sx@>P7SJyG)OP^ z9z~S32%<}6A2Agc;qKYsxQLO$jxlrn+`Za&MLOe%qAbPPtW@VEj!&bm z_JUWQ**s>pBD?l2;Myf@r&F-90ltD6W9WHG*WV%U?=f&afwHKhAU%VqnUB?gD-fc- zK@Q0~AS5fKCZ&>;iy$edX*1G5;7kybO^~I_q?u~)fznLXu9~l6oG(Jv zDj_=ou2aDtIMF@qLCDe)$kHsgyJC>Jkx78a{KKEMQ0T~H49~RH$4b-=7Zs;sT(L@yE_qkXCJ0lPT9}F; zOc#i~PdQOGNYpxY?izTkG_$qaCa>70j8e8r)V%YsIe2xreWupCcP#y8F1yJiLgT*A z`W?jMG3S5F5Ftv8KOFNEU?6J429%|C6gG#sSxhsi+JzpfZH-A_+k@yiNyE&0aVmi;BBihL%qhV zXZ5i6_8269PF&QvpjWJRlOjjH;Y^5(>^rv3YTVp_FMh_V(p~34ghw+$yJ|X$bCyVD PqXP9mNVahU<81%{R1Hd8 literal 1772 zcmVsRezA)|6Eyndn_A!O8TUO5MBoxmzJt zqm4IkfFFwp00000000B+TF+}7RUFSw5h1sp{n1yXu+wff+1=Fqut^%4*aVsc5`Ti0 z%*noo%RVsbRyAADXPM!;#+|%*V7hm* zS)I+zvv=OjF@M+c7Tul3o@x8K<=Mu*x9j-cy`yT?@QpWS&Wt=g5_~dGjhxL~8fC1& z?oyye&AL%G>*lJx-|(AYmjKvv2w3>_+D5}~fB)0y_q7j3M(4@XFvi$j#{b-meAtr1 zY{zE}&t(3t$+iQSZDurqm}Rr=#bCV`PS(@6^UYDMW!H6FRv0gY>`#R37hCMtth#Ty zboyrjV>!SWj>Y3Y2hg6!(D(v;4g~lR3LuyVQ$SII=8BjG`A~yWL<74@S6~`&cCmxA zWF#K{7Xj9@$yj{$9{~2>?_?jD1>s(mdAo}8UJ7}i1iY`>Rr5BT{5e3_c#JRnhe zA&}<oQC9fgE}$sVLE06H{U=RAQ#3#GXtZrT}d^pbY`yDWC(WXA+_K z?B56MzX#dJCP`*qjrBc&_m^6Gx(R)jEuOf;b@sBBZ@NagZf>~8|9Hc?W#$-Jh&908 zLX$m3c%D29V1a_<0({ZF1)@C)MN^%c@*|U4;FGy9h1;C6-%Cl$0xu zC(Sxw@@lG%<7;<WcC)fv@0qK*6umwHz+#ldQS9mdcZanp-ivEvsrS*J@_P&*~9% z51TZ-47i^rmR=_=N7XkoKvu1gA(mJSn^tM5b2U2F<6CHqt+`~M7m*zc ze7LF@^?KQ;+)8{#00&^wz{w zl6q}z>YP%BFUF7CV2#DL7#x3N2Mi)KZq5D-?EF1evm8Xkz5V{AHZXk~mnGSQE77Az zdSy|Zxe1)PB;C9;ziQw_OgkrEzj7|_uDAd1;nVD4nIM$nr@cY4!U2M3W#q;1A@O|{ z3dgPE-+;Y;iq|m?DRS~)G&1C%*CtJxOX}fZHG0}Dvc05Bw}4BRiP@6&t_I$$YdW=> z(>c0}KL4+@bAQ=iZd$2OT!~*Q05J>epO^#DOHdjv*ZOCG_5Vg{8^6|V$629$APJKD^!^73#V_%n0Wqw|`GZmXQ6742+{jef_E>szPZ`swt$o~| zYf|@*7w0jNI>O{XK+z-akEM>>7A`uU(_o zeOD7OeAVA~VUZnJB|!_|1|y8;MEjk-L|RrrT4uSyryz5akpang%>Nl6p%YUuI6nj( ztn}L4*l;RFeg$08Bt%Ee-ERYTZ_tyfYhA1%kV3a&ypx0ha7)$LKwm>#P%1xaTh{zOZqS1_TQ7QFDAoM z%sm)&9p|Fg&c$YvGU|HEsFYJy1^d1Z?7OOTL5*l?4eV#N8QD9I>8w74W!`_eke`^8 OmVW_%#3)?`O#lE19e*1D