diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 856d222d3..05a315756 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -20,5 +20,6 @@ "packages/lsp20-contracts": "0.15.0", "packages/lsp23-contracts": "0.15.0", "packages/lsp25-contracts": "0.15.0", + "packages/lsp26-contracts": "0.15.0", "packages/universalprofile-contracts": "0.15.0" } diff --git a/package-lock.json b/package-lock.json index 39e4e2e0c..0902a743a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2009,6 +2009,10 @@ "resolved": "packages/lsp25-contracts", "link": true }, + "node_modules/@lukso/lsp26-contracts": { + "resolved": "packages/lsp26-contracts", + "link": true + }, "node_modules/@lukso/lsp3-contracts": { "resolved": "packages/lsp3-contracts", "link": true @@ -22540,62 +22544,63 @@ }, "packages/lsp-smart-contracts": { "name": "@lukso/lsp-smart-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { - "@lukso/lsp0-contracts": "~0.15.0-rc.5", - "@lukso/lsp1-contracts": "~0.15.0-rc.5", - "@lukso/lsp10-contracts": "~0.15.0-rc.5", - "@lukso/lsp12-contracts": "~0.15.0-rc.5", - "@lukso/lsp14-contracts": "~0.15.0-rc.5", - "@lukso/lsp16-contracts": "~0.15.0-rc.5", - "@lukso/lsp17-contracts": "~0.15.0-rc.5", - "@lukso/lsp17contractextension-contracts": "~0.15.0-rc.5", - "@lukso/lsp1delegate-contracts": "~0.15.0-rc.5", - "@lukso/lsp2-contracts": "~0.15.0-rc.5", - "@lukso/lsp20-contracts": "~0.15.0-rc.5", - "@lukso/lsp23-contracts": "~0.15.0-rc.5", - "@lukso/lsp25-contracts": "~0.15.0-rc.5", - "@lukso/lsp3-contracts": "~0.15.0-rc.5", - "@lukso/lsp4-contracts": "~0.15.0-rc.5", - "@lukso/lsp5-contracts": "~0.15.0-rc.5", - "@lukso/lsp6-contracts": "~0.15.0-rc.5", - "@lukso/lsp7-contracts": "~0.15.0-rc.5", - "@lukso/lsp8-contracts": "~0.15.0-rc.5", - "@lukso/lsp9-contracts": "~0.15.0-rc.5", - "@lukso/universalprofile-contracts": "~0.15.0-rc.5" + "@lukso/lsp0-contracts": "~0.15.0", + "@lukso/lsp1-contracts": "~0.15.0", + "@lukso/lsp10-contracts": "~0.15.0", + "@lukso/lsp12-contracts": "~0.15.0", + "@lukso/lsp14-contracts": "~0.15.0", + "@lukso/lsp16-contracts": "~0.15.0", + "@lukso/lsp17-contracts": "~0.15.0", + "@lukso/lsp17contractextension-contracts": "~0.15.0", + "@lukso/lsp1delegate-contracts": "~0.15.0", + "@lukso/lsp2-contracts": "~0.15.0", + "@lukso/lsp20-contracts": "~0.15.0", + "@lukso/lsp23-contracts": "~0.15.0", + "@lukso/lsp25-contracts": "~0.15.0", + "@lukso/lsp26-contracts": "~0.15.0", + "@lukso/lsp3-contracts": "~0.15.0", + "@lukso/lsp4-contracts": "~0.15.0", + "@lukso/lsp5-contracts": "~0.15.0", + "@lukso/lsp6-contracts": "~0.15.0", + "@lukso/lsp7-contracts": "~0.15.0", + "@lukso/lsp8-contracts": "~0.15.0", + "@lukso/lsp9-contracts": "~0.15.0", + "@lukso/universalprofile-contracts": "~0.15.0" } }, "packages/lsp0-contracts": { "name": "@lukso/lsp0-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^7.0.0", - "@lukso/lsp1-contracts": "~0.15.0-rc.5", - "@lukso/lsp14-contracts": "~0.15.0-rc.5", - "@lukso/lsp17contractextension-contracts": "~0.15.0-rc.5", - "@lukso/lsp2-contracts": "~0.15.0-rc.5", - "@lukso/lsp20-contracts": "~0.15.0-rc.5", + "@lukso/lsp1-contracts": "~0.15.0", + "@lukso/lsp14-contracts": "~0.15.0", + "@lukso/lsp17contractextension-contracts": "~0.15.0", + "@lukso/lsp2-contracts": "~0.15.0", + "@lukso/lsp20-contracts": "~0.15.0", "@openzeppelin/contracts": "^4.9.3" } }, "packages/lsp1-contracts": { "name": "@lukso/lsp1-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { - "@lukso/lsp2-contracts": "~0.15.0-rc.5", + "@lukso/lsp2-contracts": "~0.15.0", "@openzeppelin/contracts": "^4.9.3" } }, "packages/lsp10-contracts": { "name": "@lukso/lsp10-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^6.0.0", - "@lukso/lsp2-contracts": "~0.15.0-rc.5" + "@lukso/lsp2-contracts": "~0.15.0" } }, "packages/lsp10-contracts/node_modules/@erc725/smart-contracts": { @@ -22609,24 +22614,24 @@ }, "packages/lsp12-contracts": { "name": "@lukso/lsp12-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { - "@lukso/lsp2-contracts": "~0.15.0-rc.5" + "@lukso/lsp2-contracts": "~0.15.0" } }, "packages/lsp14-contracts": { "name": "@lukso/lsp14-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^7.0.0", - "@lukso/lsp1-contracts": "~0.15.0-rc.5" + "@lukso/lsp1-contracts": "~0.15.0" } }, "packages/lsp16-contracts": { "name": "@lukso/lsp16-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^7.0.0", @@ -22636,21 +22641,21 @@ }, "packages/lsp17-contracts": { "name": "@lukso/lsp17-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@account-abstraction/contracts": "^0.6.0", "@erc725/smart-contracts": "^7.0.0", - "@lukso/lsp14-contracts": "~0.15.0-rc.5", - "@lukso/lsp17contractextension-contracts": "~0.15.0-rc.5", - "@lukso/lsp20-contracts": "~0.15.0-rc.5", - "@lukso/lsp6-contracts": "~0.15.0-rc.5", + "@lukso/lsp14-contracts": "~0.15.0", + "@lukso/lsp17contractextension-contracts": "~0.15.0", + "@lukso/lsp20-contracts": "~0.15.0", + "@lukso/lsp6-contracts": "~0.15.0", "@openzeppelin/contracts": "^4.9.3" } }, "packages/lsp17contractextension-contracts": { "name": "@lukso/lsp17contractextension-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^7.0.0", @@ -22659,22 +22664,22 @@ }, "packages/lsp1delegate-contracts": { "name": "@lukso/lsp1delegate-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^7.0.0", - "@lukso/lsp1-contracts": "~0.15.0-rc.5", - "@lukso/lsp10-contracts": "~0.15.0-rc.5", - "@lukso/lsp5-contracts": "~0.15.0-rc.5", - "@lukso/lsp7-contracts": "~0.15.0-rc.5", - "@lukso/lsp8-contracts": "~0.15.0-rc.5", - "@lukso/lsp9-contracts": "~0.15.0-rc.5", + "@lukso/lsp1-contracts": "~0.15.0", + "@lukso/lsp10-contracts": "~0.15.0", + "@lukso/lsp5-contracts": "~0.15.0", + "@lukso/lsp7-contracts": "~0.15.0", + "@lukso/lsp8-contracts": "~0.15.0", + "@lukso/lsp9-contracts": "~0.15.0", "@openzeppelin/contracts": "^4.9.3" } }, "packages/lsp2-contracts": { "name": "@lukso/lsp2-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^7.0.0", @@ -22683,113 +22688,123 @@ }, "packages/lsp20-contracts": { "name": "@lukso/lsp20-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0" }, "packages/lsp23-contracts": { "name": "@lukso/lsp23-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^7.0.0", - "@lukso/universalprofile-contracts": "~0.15.0-rc.5", + "@lukso/universalprofile-contracts": "~0.15.0", "@openzeppelin/contracts": "^4.9.3" } }, "packages/lsp25-contracts": { "name": "@lukso/lsp25-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", + "license": "Apache-2.0", + "dependencies": { + "@openzeppelin/contracts": "^4.9.3" + } + }, + "packages/lsp26-contracts": { + "name": "@lukso/lsp26-contracts", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { + "@lukso/lsp0-contracts": "~0.15.0", + "@lukso/lsp1-contracts": "~0.15.0", "@openzeppelin/contracts": "^4.9.3" } }, "packages/lsp3-contracts": { "name": "@lukso/lsp3-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { - "@lukso/lsp2-contracts": "~0.15.0-rc.5" + "@lukso/lsp2-contracts": "~0.15.0" } }, "packages/lsp4-contracts": { "name": "@lukso/lsp4-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^7.0.0", - "@lukso/lsp2-contracts": "~0.15.0-rc.5" + "@lukso/lsp2-contracts": "~0.15.0" } }, "packages/lsp5-contracts": { "name": "@lukso/lsp5-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^7.0.0", - "@lukso/lsp2-contracts": "~0.15.0-rc.5" + "@lukso/lsp2-contracts": "~0.15.0" } }, "packages/lsp6-contracts": { "name": "@lukso/lsp6-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^7.0.0", - "@lukso/lsp1-contracts": "~0.15.0-rc.5", - "@lukso/lsp14-contracts": "~0.15.0-rc.5", - "@lukso/lsp17contractextension-contracts": "~0.15.0-rc.5", - "@lukso/lsp2-contracts": "~0.15.0-rc.5", - "@lukso/lsp20-contracts": "~0.15.0-rc.5", - "@lukso/lsp25-contracts": "~0.15.0-rc.5", + "@lukso/lsp1-contracts": "~0.15.0", + "@lukso/lsp14-contracts": "~0.15.0", + "@lukso/lsp17contractextension-contracts": "~0.15.0", + "@lukso/lsp2-contracts": "~0.15.0", + "@lukso/lsp20-contracts": "~0.15.0", + "@lukso/lsp25-contracts": "~0.15.0", "@openzeppelin/contracts": "^4.9.3" } }, "packages/lsp7-contracts": { "name": "@lukso/lsp7-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^7.0.0", - "@lukso/lsp1-contracts": "~0.15.0-rc.5", - "@lukso/lsp17contractextension-contracts": "~0.15.0-rc.5", - "@lukso/lsp2-contracts": "~0.15.0-rc.5", - "@lukso/lsp4-contracts": "~0.15.0-rc.5", + "@lukso/lsp1-contracts": "~0.15.0", + "@lukso/lsp17contractextension-contracts": "~0.15.0", + "@lukso/lsp2-contracts": "~0.15.0", + "@lukso/lsp4-contracts": "~0.15.0", "@openzeppelin/contracts": "^4.9.3" } }, "packages/lsp8-contracts": { "name": "@lukso/lsp8-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^7.0.0", - "@lukso/lsp1-contracts": "~0.15.0-rc.5", - "@lukso/lsp17contractextension-contracts": "~0.15.0-rc.5", - "@lukso/lsp2-contracts": "~0.15.0-rc.5", - "@lukso/lsp4-contracts": "~0.15.0-rc.5", + "@lukso/lsp1-contracts": "~0.15.0", + "@lukso/lsp17contractextension-contracts": "~0.15.0", + "@lukso/lsp2-contracts": "~0.15.0", + "@lukso/lsp4-contracts": "~0.15.0", "@openzeppelin/contracts": "^4.9.3" } }, "packages/lsp9-contracts": { "name": "@lukso/lsp9-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^7.0.0", - "@lukso/lsp1-contracts": "~0.15.0-rc.5", - "@lukso/lsp6-contracts": "~0.15.0-rc.5", + "@lukso/lsp1-contracts": "~0.15.0", + "@lukso/lsp6-contracts": "~0.15.0", "@openzeppelin/contracts": "^4.9.3" } }, "packages/universalprofile-contracts": { "name": "@lukso/universalprofile-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^7.0.0", - "@lukso/lsp0-contracts": "~0.15.0-rc.5", - "@lukso/lsp3-contracts": "~0.15.0-rc.5", + "@lukso/lsp0-contracts": "~0.15.0", + "@lukso/lsp3-contracts": "~0.15.0", "@openzeppelin/contracts": "^4.9.3" } } diff --git a/packages/lsp-smart-contracts/constants.ts b/packages/lsp-smart-contracts/constants.ts index 6e5e705f7..58933b61c 100644 --- a/packages/lsp-smart-contracts/constants.ts +++ b/packages/lsp-smart-contracts/constants.ts @@ -53,6 +53,7 @@ import { INTERFACE_ID_LSP20CallVerifier, } from '@lukso/lsp20-contracts'; import { INTERFACE_ID_LSP25 } from '@lukso/lsp25-contracts'; +import { INTERFACE_ID_LSP26 } from '@lukso/lsp26-contracts'; // LSP1 Type IDs of each LSP import { LSP0_TYPE_IDS } from '@lukso/lsp0-contracts'; @@ -60,6 +61,7 @@ import { LSP7_TYPE_IDS } from '@lukso/lsp7-contracts'; import { LSP8_TYPE_IDS } from '@lukso/lsp8-contracts'; import { LSP9_TYPE_IDS } from '@lukso/lsp9-contracts'; import { LSP14_TYPE_IDS } from '@lukso/lsp14-contracts'; +import { LSP26_TYPE_IDS } from '@lukso/lsp26-contracts'; // ERC725Y Data Keys of each LSP import { LSP1DataKeys } from '@lukso/lsp1-contracts'; @@ -117,6 +119,7 @@ export const INTERFACE_IDS = { LSP20CallVerifier: INTERFACE_ID_LSP20CallVerifier, LSP11BasicSocialRecovery: '0x049a28f1', LSP25ExecuteRelayCall: INTERFACE_ID_LSP25, + LSP26FollowingSystem: INTERFACE_ID_LSP26, }; // ERC725Y @@ -147,4 +150,5 @@ export const LSP1_TYPE_IDS = { ...LSP8_TYPE_IDS, ...LSP9_TYPE_IDS, ...LSP14_TYPE_IDS, + ...LSP26_TYPE_IDS, }; diff --git a/packages/lsp-smart-contracts/contracts/LSP26FollowerSystem/ILSP26FollowingSystem.sol b/packages/lsp-smart-contracts/contracts/LSP26FollowerSystem/ILSP26FollowingSystem.sol new file mode 100644 index 000000000..12336b054 --- /dev/null +++ b/packages/lsp-smart-contracts/contracts/LSP26FollowerSystem/ILSP26FollowingSystem.sol @@ -0,0 +1,4 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.17; + +import "@lukso/lsp26-contracts/contracts/ILSP26FollowingSystem.sol"; diff --git a/packages/lsp-smart-contracts/contracts/LSP26FollowerSystem/LSP26Constants.sol b/packages/lsp-smart-contracts/contracts/LSP26FollowerSystem/LSP26Constants.sol new file mode 100644 index 000000000..2c5643f61 --- /dev/null +++ b/packages/lsp-smart-contracts/contracts/LSP26FollowerSystem/LSP26Constants.sol @@ -0,0 +1,4 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.4; + +import "@lukso/lsp26-contracts/contracts/LSP26Constants.sol"; diff --git a/packages/lsp-smart-contracts/contracts/LSP26FollowerSystem/LSP26Errors.sol b/packages/lsp-smart-contracts/contracts/LSP26FollowerSystem/LSP26Errors.sol new file mode 100644 index 000000000..17ca329c6 --- /dev/null +++ b/packages/lsp-smart-contracts/contracts/LSP26FollowerSystem/LSP26Errors.sol @@ -0,0 +1,4 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.4; + +import "@lukso/lsp26-contracts/contracts/LSP26Errors.sol"; diff --git a/packages/lsp-smart-contracts/contracts/LSP26FollowerSystem/LSP26FollowingSystem.sol b/packages/lsp-smart-contracts/contracts/LSP26FollowerSystem/LSP26FollowingSystem.sol new file mode 100644 index 000000000..5412051ae --- /dev/null +++ b/packages/lsp-smart-contracts/contracts/LSP26FollowerSystem/LSP26FollowingSystem.sol @@ -0,0 +1,4 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.17; + +import "@lukso/lsp26-contracts/contracts/LSP26FollowingSystem.sol"; diff --git a/packages/lsp-smart-contracts/contracts/Mocks/ERC165Interfaces.sol b/packages/lsp-smart-contracts/contracts/Mocks/ERC165Interfaces.sol index 9ef3ba1af..a37e2d72e 100644 --- a/packages/lsp-smart-contracts/contracts/Mocks/ERC165Interfaces.sol +++ b/packages/lsp-smart-contracts/contracts/Mocks/ERC165Interfaces.sol @@ -64,6 +64,9 @@ import { import { ILSP25ExecuteRelayCall as ILSP25 } from "@lukso/lsp25-contracts/contracts/ILSP25ExecuteRelayCall.sol"; +import { + ILSP26FollowingSystem as ILSP26 +} from "@lukso/lsp26-contracts/contracts/ILSP26FollowingSystem.sol"; // constants import { @@ -102,6 +105,9 @@ import { import { _INTERFACEID_LSP25 } from "@lukso/lsp25-contracts/contracts/LSP25Constants.sol"; +import { + _INTERFACEID_LSP26 +} from "@lukso/lsp26-contracts/contracts/LSP26Constants.sol"; // libraries import { @@ -302,6 +308,16 @@ contract CalculateLSPInterfaces { return interfaceId; } + + function calculateInterfaceLSP26() public pure returns (bytes4) { + bytes4 interfaceId = type(ILSP26).interfaceId; + require( + interfaceId == _INTERFACEID_LSP26, + "hardcoded _INTERFACEID_LSP26 does not match type(ILSP26).interfaceId" + ); + + return interfaceId; + } } /** diff --git a/packages/lsp-smart-contracts/contracts/Mocks/LSP1TypeIDsTester.sol b/packages/lsp-smart-contracts/contracts/Mocks/LSP1TypeIDsTester.sol index ac2dc7156..d9c7c1ced 100644 --- a/packages/lsp-smart-contracts/contracts/Mocks/LSP1TypeIDsTester.sol +++ b/packages/lsp-smart-contracts/contracts/Mocks/LSP1TypeIDsTester.sol @@ -28,6 +28,10 @@ import { _TYPEID_LSP14_OwnershipTransferred_SenderNotification, _TYPEID_LSP14_OwnershipTransferred_RecipientNotification } from "@lukso/lsp14-contracts/contracts/LSP14Constants.sol"; +import { + _TYPEID_LSP26_FOLLOW, + _TYPEID_LSP26_UNFOLLOW +} from "@lukso/lsp26-contracts/contracts/LSP26Constants.sol"; error LSP1TypeIdHashIsWrong(bytes32 typeIdHash, string typeIdname); @@ -92,6 +96,15 @@ contract LSP1TypeIDsTester { "LSP14OwnershipTransferred_RecipientNotification" ] = _TYPEID_LSP14_OwnershipTransferred_RecipientNotification; // ------------------- + + // ------ LSP26 ------ + _typeIds[ + "LSP26FollowerSystem_FollowNotification" + ] = _TYPEID_LSP26_FOLLOW; + _typeIds[ + "LSP26FollowerSystem_UnfollowNotification" + ] = _TYPEID_LSP26_UNFOLLOW; + // ------------------- } function verifyLSP1TypeID( diff --git a/packages/lsp-smart-contracts/package.json b/packages/lsp-smart-contracts/package.json index 99ff1fc80..b28f91f54 100644 --- a/packages/lsp-smart-contracts/package.json +++ b/packages/lsp-smart-contracts/package.json @@ -81,6 +81,7 @@ "@lukso/lsp20-contracts": "~0.15.0", "@lukso/lsp23-contracts": "~0.15.0", "@lukso/lsp25-contracts": "~0.15.0", + "@lukso/lsp26-contracts": "~0.15.0", "@lukso/lsp3-contracts": "~0.15.0", "@lukso/lsp4-contracts": "~0.15.0", "@lukso/lsp5-contracts": "~0.15.0", diff --git a/packages/lsp-smart-contracts/tests/Mocks/ERC165Interfaces.test.ts b/packages/lsp-smart-contracts/tests/Mocks/ERC165Interfaces.test.ts index 72d10f1d7..af31f2909 100644 --- a/packages/lsp-smart-contracts/tests/Mocks/ERC165Interfaces.test.ts +++ b/packages/lsp-smart-contracts/tests/Mocks/ERC165Interfaces.test.ts @@ -98,6 +98,11 @@ describe('Calculate LSP interfaces', () => { const result = await contract.calculateInterfaceLSP25ExecuteRelayCall(); expect(result).to.equal(INTERFACE_IDS.LSP25ExecuteRelayCall); }); + + it('LSP26FollowingSystem', async () => { + const result = await contract.calculateInterfaceLSP26(); + expect(result).to.equal(INTERFACE_IDS.LSP26FollowingSystem); + }); }); describe('Calculate ERC interfaces', () => { diff --git a/packages/lsp26-contracts/.eslintrc.js b/packages/lsp26-contracts/.eslintrc.js new file mode 100644 index 000000000..03ee7431b --- /dev/null +++ b/packages/lsp26-contracts/.eslintrc.js @@ -0,0 +1,4 @@ +module.exports = { + root: true, + extends: ['custom'], +}; diff --git a/packages/lsp26-contracts/.solhint.json b/packages/lsp26-contracts/.solhint.json new file mode 100644 index 000000000..26e01c48a --- /dev/null +++ b/packages/lsp26-contracts/.solhint.json @@ -0,0 +1,25 @@ +{ + "extends": "solhint:recommended", + "rules": { + "avoid-sha3": "error", + "avoid-suicide": "error", + "avoid-throw": "error", + "avoid-tx-origin": "error", + "check-send-result": "error", + "compiler-version": ["error", "^0.8.0"], + "func-visibility": ["error", { "ignoreConstructors": true }], + "not-rely-on-block-hash": "error", + "not-rely-on-time": "error", + "reentrancy": "error", + "constructor-syntax": "error", + "private-vars-leading-underscore": ["error", { "strict": false }], + "imports-on-top": "error", + "visibility-modifier-order": "error", + "no-unused-import": "error", + "no-global-import": "error", + "reason-string": ["warn", { "maxLength": 120 }], + "avoid-low-level-calls": "off", + "no-empty-blocks": ["error", { "ignoreConstructors": true }], + "custom-errors": "off" + } +} diff --git a/packages/lsp26-contracts/README.md b/packages/lsp26-contracts/README.md new file mode 100644 index 000000000..1a17db82a --- /dev/null +++ b/packages/lsp26-contracts/README.md @@ -0,0 +1,17 @@ +# LSP26 Following System · [![npm version](https://img.shields.io/npm/v/@lukso/lsp26-contracts.svg?style=flat)](https://www.npmjs.com/package/@lukso/lsp26-contracts) + +Package for the LSP26 Following System standard. + +## Installation + +```bash +npm i @lukso/lsp26-contracts +``` + +## Available Constants & Types + +The `@lukso/lsp26-contracts` npm package contains useful constants such as InterfaceIds, and specific constants related to the LSP26 Standard. You can import and access them as follow: + +```js +import { INTERFACE_ID_LSP26, LSP26_TYPE_IDS } from "@lukso/lsp26-contracts"; +``` diff --git a/packages/lsp26-contracts/build.config.ts b/packages/lsp26-contracts/build.config.ts new file mode 100644 index 000000000..dc4f36906 --- /dev/null +++ b/packages/lsp26-contracts/build.config.ts @@ -0,0 +1,9 @@ +import { defineBuildConfig } from 'unbuild'; + +export default defineBuildConfig({ + entries: ['./index'], + declaration: 'compatible', // generate .d.ts files + rollup: { + emitCJS: true, + }, +}); diff --git a/packages/lsp26-contracts/constants.ts b/packages/lsp26-contracts/constants.ts new file mode 100644 index 000000000..fe81df8a2 --- /dev/null +++ b/packages/lsp26-contracts/constants.ts @@ -0,0 +1,11 @@ +export const INTERFACE_ID_LSP26 = '0x2b299cea'; + +export const LSP26_TYPE_IDS = { + // keccak256('LSP26FollowerSystem_FollowNotification') + LSP26FollowerSystem_FollowNotification: + '0x71e02f9f05bcd5816ec4f3134aa2e5a916669537ec6c77fe66ea595fabc2d51a', + + // keccak256('LSP26FollowerSystem_UnfollowNotification') + LSP26FollowerSystem_UnfollowNotification: + '0x9d3c0b4012b69658977b099bdaa51eff0f0460f421fba96d15669506c00d1c4f', +}; diff --git a/packages/lsp26-contracts/contracts/ILSP26FollowingSystem.sol b/packages/lsp26-contracts/contracts/ILSP26FollowingSystem.sol new file mode 100644 index 000000000..32d91f509 --- /dev/null +++ b/packages/lsp26-contracts/contracts/ILSP26FollowingSystem.sol @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.17; + +interface ILSP26FollowingSystem { + /// @notice Emitted when following an address. + /// @param follower The address that follows `addr` + /// @param addr The address that is followed by `follower` + event Follow(address follower, address addr); + + /// @notice Emitted when unfollowing an address. + /// @param unfollower The address that unfollows `addr` + /// @param addr The address that is unfollowed by `follower` + event Unfollow(address unfollower, address addr); + + /// @notice Follow an specific address. + /// @param addr The address to start following. + /// @custom:events {Follow} event when following an address. + function follow(address addr) external; + + /// @notice Follow a list of addresses. + /// @param addresses The list of addresses to follow. + /// @custom:events {Follow} event when following each address in the list. + function followBatch(address[] memory addresses) external; + + /// @notice Unfollow a specific address. + /// @param addr The address to stop following. + /// @custom:events {Unfollow} event when unfollowing an address. + function unfollow(address addr) external; + + /// @notice Unfollow a list of addresses. + /// @param addresses The list of addresses to unfollow. + /// @custom:events {Follow} event when unfollowing each address in the list. + function unfollowBatch(address[] memory addresses) external; + + /// @notice Check if an address is following a specific address. + /// @param follower The address of the follower to check. + /// @param addr The address being followed. + /// @return True if `follower` is following `addr`, false otherwise. + function isFollowing( + address follower, + address addr + ) external view returns (bool); + + /// @notice Get the number of followers for an address. + /// @param addr The address whose followers count is requested. + /// @return The number of followers of `addr`. + function followerCount(address addr) external view returns (uint256); + + /// @notice Get the number of addresses an address is following. + /// @param addr The address of the follower whose following count is requested. + /// @return The number of addresses that `addr` is following. + function followingCount(address addr) external view returns (uint256); + + /// @notice Get the list of addresses the given address is following within a specified range. + /// @param addr The address whose followed addresses are requested. + /// @param startIndex The start index of the range (inclusive). + /// @param endIndex The end index of the range (exclusive). + /// @return An array of addresses followed by the given address. + function getFollowsByIndex( + address addr, + uint256 startIndex, + uint256 endIndex + ) external view returns (address[] memory); + + /// @notice Get the list of addresses that follow an address within a specified range. + /// @param addr The address whose followers are requested. + /// @param startIndex The start index of the range (inclusive). + /// @param endIndex The end index of the range (exclusive). + /// @return An array of addresses that are following an addresses. + function getFollowersByIndex( + address addr, + uint256 startIndex, + uint256 endIndex + ) external view returns (address[] memory); +} diff --git a/packages/lsp26-contracts/contracts/Imports.sol b/packages/lsp26-contracts/contracts/Imports.sol new file mode 100644 index 000000000..262912d42 --- /dev/null +++ b/packages/lsp26-contracts/contracts/Imports.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.17; + +// solhint-disable no-unused-import +import { + LSP0ERC725Account +} from "@lukso/lsp0-contracts/contracts/LSP0ERC725Account.sol"; diff --git a/packages/lsp26-contracts/contracts/LSP26Constants.sol b/packages/lsp26-contracts/contracts/LSP26Constants.sol new file mode 100644 index 000000000..48e3c8eb4 --- /dev/null +++ b/packages/lsp26-contracts/contracts/LSP26Constants.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.17; + +bytes4 constant _INTERFACEID_LSP26 = 0x2b299cea; + +// keccak256('LSP26FollowerSystem_FollowNotification') +bytes32 constant _TYPEID_LSP26_FOLLOW = 0x71e02f9f05bcd5816ec4f3134aa2e5a916669537ec6c77fe66ea595fabc2d51a; + +// keccak256('LSP26FollowerSystem_UnfollowNotification') +bytes32 constant _TYPEID_LSP26_UNFOLLOW = 0x9d3c0b4012b69658977b099bdaa51eff0f0460f421fba96d15669506c00d1c4f; diff --git a/packages/lsp26-contracts/contracts/LSP26Errors.sol b/packages/lsp26-contracts/contracts/LSP26Errors.sol new file mode 100644 index 000000000..7c404adb7 --- /dev/null +++ b/packages/lsp26-contracts/contracts/LSP26Errors.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.17; + +error LSP26CannotSelfFollow(); + +error LSP26AlreadyFollowing(address addr); + +error LSP26NotFollowing(address addr); diff --git a/packages/lsp26-contracts/contracts/LSP26FollowingSystem.sol b/packages/lsp26-contracts/contracts/LSP26FollowingSystem.sol new file mode 100644 index 000000000..748ca0921 --- /dev/null +++ b/packages/lsp26-contracts/contracts/LSP26FollowingSystem.sol @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.17; + +// interfaces +import {ILSP26FollowingSystem} from "./ILSP26FollowingSystem.sol"; +import { + ILSP1UniversalReceiver +} from "@lukso/lsp1-contracts/contracts/ILSP1UniversalReceiver.sol"; + +// libraries +import { + EnumerableSet +} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import { + ERC165Checker +} from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; + +// constants +import { + _TYPEID_LSP26_FOLLOW, + _TYPEID_LSP26_UNFOLLOW +} from "./LSP26Constants.sol"; +import { + _INTERFACEID_LSP1 +} from "@lukso/lsp1-contracts/contracts/LSP1Constants.sol"; + +// errors +import { + LSP26CannotSelfFollow, + LSP26AlreadyFollowing, + LSP26NotFollowing +} from "./LSP26Errors.sol"; + +contract LSP26FollowingSystem is ILSP26FollowingSystem { + using EnumerableSet for EnumerableSet.AddressSet; + using ERC165Checker for address; + + mapping(address => EnumerableSet.AddressSet) private _followersOf; + mapping(address => EnumerableSet.AddressSet) private _followingsOf; + + // @inheritdoc ILSP26FollowingSystem + function follow(address addr) public { + _follow(addr); + } + + // @inheritdoc ILSP26FollowingSystem + function followBatch(address[] memory addresses) public { + for (uint256 index = 0; index < addresses.length; ++index) { + _follow(addresses[index]); + } + } + + // @inheritdoc ILSP26FollowingSystem + function unfollow(address addr) public { + _unfollow(addr); + } + + // @inheritdoc ILSP26FollowingSystem + function unfollowBatch(address[] memory addresses) public { + for (uint256 index = 0; index < addresses.length; ++index) { + _unfollow(addresses[index]); + } + } + + // @inheritdoc ILSP26FollowingSystem + function isFollowing( + address follower, + address addr + ) public view returns (bool) { + return _followingsOf[follower].contains(addr); + } + + // @inheritdoc ILSP26FollowingSystem + function followerCount(address addr) public view returns (uint256) { + return _followersOf[addr].length(); + } + + // @inheritdoc ILSP26FollowingSystem + function followingCount(address addr) public view returns (uint256) { + return _followingsOf[addr].length(); + } + + // @inheritdoc ILSP26FollowingSystem + function getFollowsByIndex( + address addr, + uint256 startIndex, + uint256 endIndex + ) public view returns (address[] memory) { + uint256 sliceLength = endIndex - startIndex; + + address[] memory followings = new address[](sliceLength); + + for (uint256 index = 0; index < sliceLength; ++index) { + followings[index] = _followingsOf[addr].at(startIndex + index); + } + + return followings; + } + + // @inheritdoc ILSP26FollowingSystem + function getFollowersByIndex( + address addr, + uint256 startIndex, + uint256 endIndex + ) public view returns (address[] memory) { + uint256 sliceLength = endIndex - startIndex; + + address[] memory followers = new address[](sliceLength); + + for (uint256 index = 0; index < sliceLength; ++index) { + followers[index] = _followersOf[addr].at(startIndex + index); + } + + return followers; + } + + function _follow(address addr) internal { + if (msg.sender == addr) { + revert LSP26CannotSelfFollow(); + } + + bool isAdded = _followingsOf[msg.sender].add(addr); + + if (!isAdded) { + revert LSP26AlreadyFollowing(addr); + } + + _followersOf[addr].add(msg.sender); + + emit Follow(msg.sender, addr); + + if (addr.supportsERC165InterfaceUnchecked(_INTERFACEID_LSP1)) { + // solhint-disable no-empty-blocks + try + ILSP1UniversalReceiver(addr).universalReceiver( + _TYPEID_LSP26_FOLLOW, + abi.encodePacked(msg.sender) + ) + {} catch {} + } + } + + function _unfollow(address addr) internal { + bool isRemoved = _followingsOf[msg.sender].remove(addr); + + if (!isRemoved) { + revert LSP26NotFollowing(addr); + } + + _followersOf[addr].remove(msg.sender); + + emit Unfollow(msg.sender, addr); + + if (addr.supportsERC165InterfaceUnchecked(_INTERFACEID_LSP1)) { + // solhint-disable no-empty-blocks + try + ILSP1UniversalReceiver(addr).universalReceiver( + _TYPEID_LSP26_UNFOLLOW, + abi.encodePacked(msg.sender) + ) + {} catch {} + } + } +} diff --git a/packages/lsp26-contracts/contracts/mock/RevertOnFollow.sol b/packages/lsp26-contracts/contracts/mock/RevertOnFollow.sol new file mode 100644 index 000000000..3670a4894 --- /dev/null +++ b/packages/lsp26-contracts/contracts/mock/RevertOnFollow.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.17; + +// interfaces +import { + ILSP1UniversalReceiver +} from "@lukso/lsp1-contracts/contracts/ILSP1UniversalReceiver.sol"; + +contract RevertOnFollow is ILSP1UniversalReceiver { + function supportsInterface(bytes4) external pure returns (bool) { + return true; + } + + function universalReceiver( + bytes32, + bytes memory + ) external payable returns (bytes memory) { + revert("Block LSP1 notifications"); + } +} diff --git a/packages/lsp26-contracts/gasCost.json b/packages/lsp26-contracts/gasCost.json new file mode 100644 index 000000000..000832ffe --- /dev/null +++ b/packages/lsp26-contracts/gasCost.json @@ -0,0 +1,1120 @@ +{ + "followCost": 143167, + "unfollowCost": 35700, + "batchFollowCost": 1227152, + "executeBatchFollowCost": 1264096, + "followingGasCost": [ + 160255, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155 + ] +} diff --git a/packages/lsp26-contracts/hardhat.config.ts b/packages/lsp26-contracts/hardhat.config.ts new file mode 100644 index 000000000..606a22ef3 --- /dev/null +++ b/packages/lsp26-contracts/hardhat.config.ts @@ -0,0 +1,133 @@ +import { HardhatUserConfig } from 'hardhat/config'; +import { NetworkUserConfig } from 'hardhat/types'; +import { config as dotenvConfig } from 'dotenv'; +import { resolve } from 'path'; + +/** + * this package includes: + * - @nomiclabs/hardhat-ethers + * - @nomicfoundation/hardhat-chai-matchers + * - @nomicfoundation/hardhat-network-helpers + * - @nomiclabs/hardhat-etherscan + * - hardhat-gas-reporter (is this true? Why do we have it as a separate dependency?) + * - @typechain/hardhat + * - solidity-coverage + */ +import '@nomicfoundation/hardhat-toolbox'; + +// additional hardhat plugins +import 'hardhat-packager'; +import 'hardhat-contract-sizer'; +import 'hardhat-deploy'; +import { hexlify, randomBytes } from 'ethers'; + +// custom built hardhat plugins and scripts +// can be imported here (e.g: docs generation, gas benchmark, etc...) + +dotenvConfig({ path: resolve(__dirname, './.env') }); + +function getTestnetChainConfig(): NetworkUserConfig { + const config: NetworkUserConfig = { + live: true, + url: 'https://rpc.testnet.lukso.network', + chainId: 4201, + }; + + if (process.env.CONTRACT_VERIFICATION_TESTNET_PK !== undefined) { + config['accounts'] = [process.env.CONTRACT_VERIFICATION_TESTNET_PK]; + } + + return config; +} + +const config: HardhatUserConfig = { + defaultNetwork: 'hardhat', + networks: { + hardhat: { + live: false, + saveDeployments: false, + allowBlocksWithSameTimestamp: true, + accounts: new Array(10_100).fill('').map(() => ({ + privateKey: hexlify(randomBytes(32)), + balance: '1000000000000000000', + })), + }, + luksoTestnet: getTestnetChainConfig(), + }, + namedAccounts: { + owner: 0, + }, + // uncomment if the contracts from this LSP package must be deployed at deterministic + // // addresses across multiple chains + // deterministicDeployment: { + // luksoTestnet: { + // // Nick Factory. See https://github.com/Arachnid/deterministic-deployment-proxy + // factory: '0x4e59b44847b379578588920ca78fbf26c0b4956c', + // deployer: '0x3fab184622dc19b6109349b94811493bf2a45362', + // funding: '0x0000000000000000000000000000000000000000000000000000000000000000', + // signedTx: + // '0xf8a58085174876e800830186a08080b853604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf31ba02222222222222222222222222222222222222222222222222222222222222222a02222222222222222222222222222222222222222222222222222222222222222', + // }, + // }, + etherscan: { + apiKey: 'no-api-key-needed', + customChains: [ + { + network: 'luksoTestnet', + chainId: 4201, + urls: { + apiURL: 'https://api.explorer.execution.testnet.lukso.network/api', + browserURL: 'https://explorer.execution.testnet.lukso.network/', + }, + }, + ], + }, + gasReporter: { + enabled: true, + currency: 'USD', + gasPrice: 21, + excludeContracts: ['Helpers/'], + src: './contracts', + showMethodSig: true, + }, + solidity: { + version: '0.8.17', + settings: { + optimizer: { + enabled: true, + /** + * Optimize for how many times you intend to run the code. + * Lower values will optimize more for initial deployment cost, higher + * values will optimize more for high-frequency usage. + * @see https://docs.soliditylang.org/en/v0.8.6/internals/optimizer.html#opcode-based-optimizer-module + */ + runs: 1000, + }, + outputSelection: { + '*': { + '*': ['storageLayout'], + }, + }, + }, + }, + packager: { + // What contracts to keep the artifacts and the bindings for. + contracts: ['ILSP26FollowingSystem', 'LSP26FollowingSystem'], + // Whether to include the TypeChain factories or not. + // If this is enabled, you need to run the TypeChain files through the TypeScript compiler before shipping to the registry. + includeFactories: true, + }, + paths: { + artifacts: 'artifacts', + tests: 'tests', + }, + typechain: { + outDir: 'types', + target: 'ethers-v6', + }, + mocha: { + timeout: 10000000, + }, +}; + +export default config; diff --git a/packages/lsp26-contracts/index.ts b/packages/lsp26-contracts/index.ts new file mode 100644 index 000000000..c94f80f84 --- /dev/null +++ b/packages/lsp26-contracts/index.ts @@ -0,0 +1 @@ +export * from './constants'; diff --git a/packages/lsp26-contracts/package.json b/packages/lsp26-contracts/package.json new file mode 100644 index 000000000..1f7021329 --- /dev/null +++ b/packages/lsp26-contracts/package.json @@ -0,0 +1,55 @@ +{ + "name": "@lukso/lsp26-contracts", + "version": "0.15.0", + "description": "Package for the LSP26 Following System standard", + "license": "Apache-2.0", + "author": "", + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "typings": "./dist/index.d.ts", + "exports": { + ".": { + "require": "./dist/index.cjs", + "import": "./dist/index.mjs", + "types": "./dist/index.d.ts" + }, + "./artifacts/*": "./artifacts/*", + "./package.json": "./package.json" + }, + "keywords": [ + "LUKSO", + "LSP", + "Blockchain", + "Standards", + "Smart Contracts", + "Ethereum", + "EVM", + "Solidity" + ], + "files": [ + "contracts/**/*.sol", + "!contracts/Mocks/**/*.sol", + "artifacts/*.json", + "dist", + "types", + "!types/factories", + "./README.md" + ], + "scripts": { + "build": "hardhat compile --show-stack-traces", + "build:js": "unbuild", + "build:types": "npx wagmi generate", + "clean": "hardhat clean && rm -Rf dist/", + "format": "prettier --write .", + "lint": "eslint . --ext .ts,.js", + "lint:solidity": "solhint 'contracts/**/*.sol' && prettier --check 'contracts/**/*.sol'", + "test": "hardhat test --no-compile tests/*.test.ts", + "test:coverage": "hardhat coverage", + "package": "hardhat prepare-package" + }, + "dependencies": { + "@openzeppelin/contracts": "^4.9.3", + "@lukso/lsp0-contracts": "~0.15.0", + "@lukso/lsp1-contracts": "~0.15.0" + } +} diff --git a/packages/lsp26-contracts/tests/LSP26FollowingSystem.test.ts b/packages/lsp26-contracts/tests/LSP26FollowingSystem.test.ts new file mode 100644 index 000000000..c8e897a9a --- /dev/null +++ b/packages/lsp26-contracts/tests/LSP26FollowingSystem.test.ts @@ -0,0 +1,209 @@ +import { expect } from 'chai'; +import { ethers } from 'hardhat'; +import { ContractTransactionResponse, getAddress, hexlify, randomBytes } from 'ethers'; +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; +import { writeFileSync } from 'fs'; + +// constants +import { OPERATION_TYPES } from '@lukso/lsp0-contracts'; + +// types +import { + LSP26FollowingSystem, + LSP26FollowingSystem__factory, + LSP0ERC725Account, + LSP0ERC725Account__factory, + RevertOnFollow__factory, + RevertOnFollow, +} from '../types'; + +describe('testing `LSP26FollowingSystem`', () => { + let context: { + followerSystem: LSP26FollowingSystem; + followerSystemAddress: string; + revertOnFollow: RevertOnFollow; + revertOnFollowAddress: string; + universalProfile: LSP0ERC725Account; + owner: SignerWithAddress; + singleFollowSigner: SignerWithAddress; + executeBatchFollowSigners: SignerWithAddress[]; + batchFollowSigners: SignerWithAddress[]; + multiFollowSigners: SignerWithAddress[]; + }; + + before(async () => { + const signers = await ethers.getSigners(); + const [owner, singleFollowSigner] = signers; + const followerSystem = await new LSP26FollowingSystem__factory(owner).deploy(); + const followerSystemAddress = await followerSystem.getAddress(); + const universalProfile = await new LSP0ERC725Account__factory(owner).deploy(owner.address); + + const revertOnFollow = await new RevertOnFollow__factory(owner).deploy(); + const revertOnFollowAddress = await revertOnFollow.getAddress(); + + const executeBatchFollowSigners = signers.slice(2, 12); + const batchFollowSigners = signers.slice(12, 22); + const multiFollowSigners = signers.slice(22, 10_022); + + context = { + followerSystem, + followerSystemAddress, + revertOnFollow, + revertOnFollowAddress, + universalProfile, + owner, + singleFollowSigner, + executeBatchFollowSigners, + batchFollowSigners, + multiFollowSigners, + }; + }); + + describe('testing `follow(address)`', () => { + it('should revert when following your own address', async () => { + await expect( + context.followerSystem.connect(context.owner).follow(context.owner.address), + ).to.be.revertedWithCustomError(context.followerSystem, 'LSP26CannotSelfFollow'); + }); + + it('should revert when following an address that is already followed', async () => { + const randomAddress = getAddress(hexlify(randomBytes(20))); + + await context.followerSystem.connect(context.owner).follow(randomAddress); + + await expect(context.followerSystem.connect(context.owner).follow(randomAddress)) + .to.be.revertedWithCustomError(context.followerSystem, 'LSP26AlreadyFollowing') + .withArgs(randomAddress); + }); + + it('should not revert if follow recipient reverts inside the LSP1 hook', async () => { + await context.followerSystem.connect(context.owner).follow(context.revertOnFollowAddress); + + expect( + await context.followerSystem.isFollowing( + context.owner.address, + context.revertOnFollowAddress, + ), + ).to.be.true; + }); + }); + + describe('testing `unfollow(address)`', () => { + it('should revert when unfollowing your own address', async () => { + await expect(context.followerSystem.connect(context.owner).unfollow(context.owner.address)) + .to.be.revertedWithCustomError(context.followerSystem, 'LSP26NotFollowing') + .withArgs(context.owner.address); + }); + + it('should revert when unfollowing an address that is not followed', async () => { + const randomAddress = getAddress(hexlify(randomBytes(20))); + + await expect(context.followerSystem.connect(context.owner).unfollow(randomAddress)) + .to.be.revertedWithCustomError(context.followerSystem, 'LSP26NotFollowing') + .withArgs(randomAddress); + }); + + it('should not revert if unfollow recipient reverts inside the LSP1 hook', async () => { + await context.followerSystem.connect(context.owner).unfollow(context.revertOnFollowAddress); + + expect( + await context.followerSystem.isFollowing( + context.owner.address, + context.revertOnFollowAddress, + ), + ).to.be.false; + }); + }); + + describe.skip('gas tests', () => { + const gasCostResult: { + followingGasCost?: number[]; + followCost?: number; + unfollowCost?: number; + batchFollowCost?: number; + executeBatchFollowCost?: number; + } = {}; + + after(() => { + writeFileSync('gasCost.json', JSON.stringify(gasCostResult)); + }); + + it('gas: testing follow', async () => { + const txResponse = await context.followerSystem + .connect(context.owner) + .follow(context.singleFollowSigner.address); + const txReceipt = await txResponse.wait(); + + gasCostResult.followCost = Number(txReceipt.gasUsed); + }); + + it('gas: testing unfollow', async () => { + const txResponse = await context.followerSystem + .connect(context.owner) + .unfollow(context.singleFollowSigner.address); + const txReceipt = await txResponse.wait(); + + gasCostResult.unfollowCost = Number(txReceipt.gasUsed); + }); + + it('gas: testing `followBatch`', async () => { + const followBatch = context.followerSystem.interface.encodeFunctionData('followBatch', [ + context.batchFollowSigners.map(({ address }) => address), + ]); + + const txResponse = (await context.universalProfile + .connect(context.owner) + .execute( + OPERATION_TYPES.CALL, + context.followerSystemAddress, + 0, + followBatch, + )) as ContractTransactionResponse; + const txReceipt = await txResponse.wait(); + + gasCostResult.batchFollowCost = Number(txReceipt.gasUsed); + }); + + it('gas: testing `executeBatchFollow`', async () => { + const follows = context.executeBatchFollowSigners.map(({ address }) => + context.followerSystem.interface.encodeFunctionData('follow', [address]), + ); + + const txResponse = (await context.universalProfile.connect(context.owner).executeBatch( + follows.map(() => OPERATION_TYPES.CALL), + follows.map(() => context.followerSystemAddress), + follows.map(() => 0), + follows, + )) as ContractTransactionResponse; + const txReceipt = await txResponse.wait(); + + gasCostResult.executeBatchFollowCost = Number(txReceipt.gasUsed); + }); + + describe('gas: testing following a single account 10_000 times', () => { + const followingGasCost: number[] = []; + + after(() => { + gasCostResult.followingGasCost = followingGasCost; + }); + + it(`testing signers`, async () => { + let count = 1; + + for (const signer of context.multiFollowSigners) { + if (count % 1000 === 0) { + console.log(`Testing signer #${count}`); + } + + const txResponse = await context.followerSystem + .connect(signer) + .follow(context.owner.address); + const txReceipt = await txResponse.wait(); + + followingGasCost.push(Number(txReceipt.gasUsed)); + count++; + } + }); + }); + }); +}); diff --git a/packages/lsp26-contracts/tsconfig.json b/packages/lsp26-contracts/tsconfig.json new file mode 100644 index 000000000..b7a34e03f --- /dev/null +++ b/packages/lsp26-contracts/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "tsconfig/contracts.json", + "include": ["**/*.ts"] +} diff --git a/packages/lsp26-contracts/wagmi.config.ts b/packages/lsp26-contracts/wagmi.config.ts new file mode 100644 index 000000000..9f838fb8d --- /dev/null +++ b/packages/lsp26-contracts/wagmi.config.ts @@ -0,0 +1,19 @@ +import { defineConfig } from '@wagmi/cli'; +import { react } from '@wagmi/cli/plugins'; +import fs from 'fs'; + +const artifacts = fs.readdirSync('./artifacts', {}); + +const contractsWagmiInputs = artifacts.map((artifact) => { + const jsonArtifact = JSON.parse(fs.readFileSync(`./artifacts/${artifact}`, 'utf-8')); + return { + name: jsonArtifact.contractName, + abi: jsonArtifact.abi, + }; +}); + +export default defineConfig({ + out: 'types/index.ts', + contracts: contractsWagmiInputs, + plugins: [react()], +}); diff --git a/release-please-config.json b/release-please-config.json index 03817b931..6c1fd88d7 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -215,6 +215,16 @@ "draft": false, "prerelease-type": "rc" }, + "packages/lsp26-contracts": { + "component": "lsp26-contracts", + "package-name": "@lukso/lsp26-contracts", + "include-component-in-tag": true, + "release-type": "node", + "bump-minor-pre-major": true, + "bump-patch-for-minor-pre-major": false, + "draft": false, + "prerelease-type": "rc" + }, "packages/universalprofile-contracts": { "component": "universalprofile-contracts", "package-name": "@lukso/universalprofile-contracts", diff --git a/template/build.config.ts b/template/build.config.ts index 71798d1ff..dc4f36906 100644 --- a/template/build.config.ts +++ b/template/build.config.ts @@ -1,7 +1,7 @@ import { defineBuildConfig } from 'unbuild'; export default defineBuildConfig({ - entries: ['./constants'], + entries: ['./index'], declaration: 'compatible', // generate .d.ts files rollup: { emitCJS: true, diff --git a/template/package.json b/template/package.json index 806ae2641..d9439ca23 100644 --- a/template/package.json +++ b/template/package.json @@ -1,6 +1,6 @@ { "name": "lspN", - "version": "0.12.1", + "version": "0.15.0", "description": "Package for the LSPN standard", "license": "Apache-2.0", "author": "",