From b5ca47fb3b94a6858e3aef3959ea5b4bf87e6c72 Mon Sep 17 00:00:00 2001 From: Andrew Richardson Date: Tue, 20 Jun 2023 15:53:33 -0400 Subject: [PATCH] Extract a clearer IERC1155Factory interface Split the concept of a "pool factory" (which encompasses a single method and a single event) away from all of the other opinionated spellings in the IERC1155MixedFungible interface. The parameters of the TokenPoolCreation event have also been altered, but both the old and new parameters will be parsed by the listener. Signed-off-by: Andrew Richardson --- README.md | 3 +- .../contracts/ERC1155MixedFungible.sol | 139 +++-- .../solidity/contracts/IERC1155Factory.sol | 23 + .../contracts/IERC1155MixedFungible.sol | 77 +-- samples/solidity/copyabi.sh | 6 + samples/solidity/test/ERC1155MixedFungible.ts | 79 ++- src/abi/ERC1155MixedFungible.json | 51 +- src/abi/ERC1155MixedFungibleV1.json | 581 ++++++++++++++++++ src/tokens/abimapper.service.ts | 19 +- src/tokens/tokens.interfaces.ts | 20 +- src/tokens/tokens.listener.ts | 66 +- src/tokens/tokens.service.spec.ts | 1 + src/tokens/tokens.service.ts | 298 ++++----- src/tokens/tokens.util.spec.ts | 6 +- src/tokens/tokens.util.ts | 18 +- test/suites/api.ts | 2 +- 16 files changed, 1020 insertions(+), 369 deletions(-) create mode 100644 samples/solidity/contracts/IERC1155Factory.sol create mode 100755 samples/solidity/copyabi.sh create mode 100644 src/abi/ERC1155MixedFungibleV1.json diff --git a/README.md b/README.md index 288b6d5..44ac533 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,8 @@ token IDs (inclusive). Note: Because ERC1155 defines the token ID as uint256, th is `0x0` to `0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff`. If `config.address` is specified, the connector will invoke the `create()` method (as defined in the -`IERC1155MixedFungible` interface) of the ERC1155 token contract at the specified address. +[IERC1155Factory](samples/solidity/contracts/IERC1155Factory.sol) interface) of the ERC1155 token +contract at the specified address. If `config.address` is not specified, and `CONTRACT_ADDRESS` is set in the connector's environment, the `create()` method of that contract will be invoked. diff --git a/samples/solidity/contracts/ERC1155MixedFungible.sol b/samples/solidity/contracts/ERC1155MixedFungible.sol index cfeed2a..44c3649 100644 --- a/samples/solidity/contracts/ERC1155MixedFungible.sol +++ b/samples/solidity/contracts/ERC1155MixedFungible.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.0; -import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol"; -import "@openzeppelin/contracts/utils/Context.sol"; -import "@openzeppelin/contracts/utils/math/SafeMath.sol"; -import "./IERC1155MixedFungible.sol"; +import '@openzeppelin/contracts/token/ERC1155/ERC1155.sol'; +import '@openzeppelin/contracts/utils/Context.sol'; +import '@openzeppelin/contracts/utils/math/SafeMath.sol'; +import './IERC1155MixedFungible.sol'; /** * Example ERC1155 with mixed fungible/non-fungible token support. @@ -36,24 +36,24 @@ contract ERC1155MixedFungible is Context, ERC1155, IERC1155MixedFungible { uint256 constant TYPE_MASK = type(uint128).max << 128; uint256 constant NF_INDEX_MASK = type(uint128).max; uint256 constant TYPE_NF_BIT = 1 << 255; + uint256 constant NF_POOL_SIZE = 1 << 128; uint256 nonce; - mapping (uint256 => address) public creators; - mapping (uint256 => uint256) public maxIndex; + mapping(uint256 => address) public creators; + mapping(uint256 => uint256) public maxIndex; // inherited ERC1155 `_uri` is private, so need our own within this contract string private _baseTokenURI; // mapping from type ID | index => custom token URIs for non-fungible tokens // fallback behavior if missing is to use the default base URI - mapping (uint256 => string) private _nfTokenURIs; + mapping(uint256 => string) private _nfTokenURIs; - event TokenPoolCreation(address indexed operator, uint256 indexed type_id, bytes data); - - function isFungible(uint256 id) internal pure returns(bool) { + function isFungible(uint256 id) internal pure returns (bool) { return id & TYPE_NF_BIT == 0; } - function isNonFungible(uint256 id) internal pure returns(bool) { + + function isNonFungible(uint256 id) internal pure returns (bool) { return id & TYPE_NF_BIT == TYPE_NF_BIT; } @@ -75,73 +75,85 @@ contract ERC1155MixedFungible is Context, ERC1155, IERC1155MixedFungible { super.supportsInterface(interfaceId); } - function create(bool is_fungible, bytes calldata data) - external - virtual - override - returns(uint256 type_id) - { - type_id = (++nonce << 128); - if (!is_fungible) - type_id = type_id | TYPE_NF_BIT; + function create(bool is_fungible, bytes calldata data) external virtual override { + uint256 type_id = (++nonce << 128); + if (!is_fungible) type_id = type_id | TYPE_NF_BIT; creators[type_id] = _msgSender(); - emit TokenPoolCreation(_msgSender(), type_id, data); + emit TokenPoolCreation( + _msgSender(), + is_fungible, + type_id, + is_fungible ? type_id : type_id + NF_POOL_SIZE - 1, + data + ); } - function _setNonFungibleURI(uint256 type_id, uint256 id, string memory _uri) - private - creatorOnly(type_id) - { - require(isNonFungible(type_id), "ERC1155MixedFungible: id does not represent a non-fungible type"); + function _setNonFungibleURI( + uint256 type_id, + uint256 id, + string memory _uri + ) private creatorOnly(type_id) { + require( + isNonFungible(type_id), + 'ERC1155MixedFungible: id does not represent a non-fungible type' + ); _nfTokenURIs[id] = _uri; } - function mintNonFungible(uint256 type_id, address[] calldata to, bytes calldata data) - external - virtual - override - creatorOnly(type_id) - { - require(isNonFungible(type_id), "ERC1155MixedFungible: id does not represent a non-fungible type"); + function mintNonFungible( + uint256 type_id, + address[] calldata to, + bytes calldata data + ) external virtual override creatorOnly(type_id) { + require( + isNonFungible(type_id), + 'ERC1155MixedFungible: id does not represent a non-fungible type' + ); // Indexes are 1-based. uint256 index = maxIndex[type_id] + 1; maxIndex[type_id] = SafeMath.add(to.length, maxIndex[type_id]); for (uint256 i = 0; i < to.length; ++i) { - _mint(to[i], type_id | index + i, 1, data); + _mint(to[i], type_id | (index + i), 1, data); } } - function mintNonFungibleWithURI(uint256 type_id, address[] calldata to, bytes calldata data, string memory _uri) - external - virtual - override - creatorOnly(type_id) - { - require(isNonFungible(type_id), "ERC1155MixedFungible: id does not represent a non-fungible type"); + function mintNonFungibleWithURI( + uint256 type_id, + address[] calldata to, + bytes calldata data, + string memory _uri + ) external virtual override creatorOnly(type_id) { + require( + isNonFungible(type_id), + 'ERC1155MixedFungible: id does not represent a non-fungible type' + ); // Indexes are 1-based. uint256 index = maxIndex[type_id] + 1; maxIndex[type_id] = SafeMath.add(to.length, maxIndex[type_id]); for (uint256 i = 0; i < to.length; ++i) { - uint256 id = type_id | index + i; + uint256 id = type_id | (index + i); _mint(to[i], id, 1, data); _setNonFungibleURI(type_id, id, _uri); } } - function mintFungible(uint256 type_id, address[] calldata to, uint256[] calldata amounts, bytes calldata data) - external - virtual - override - creatorOnly(type_id) - { - require(isFungible(type_id), "ERC1155MixedFungible: id does not represent a fungible type"); - require(to.length == amounts.length, "ERC1155MixedFungible: to and amounts length mismatch"); + function mintFungible( + uint256 type_id, + address[] calldata to, + uint256[] calldata amounts, + bytes calldata data + ) external virtual override creatorOnly(type_id) { + require(isFungible(type_id), 'ERC1155MixedFungible: id does not represent a fungible type'); + require( + to.length == amounts.length, + 'ERC1155MixedFungible: to and amounts length mismatch' + ); for (uint256 i = 0; i < to.length; ++i) { _mint(to[i], type_id, amounts[i], data); @@ -150,28 +162,31 @@ contract ERC1155MixedFungible is Context, ERC1155, IERC1155MixedFungible { // Reference: // https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC1155/extensions/ERC1155Burnable.sol - function burn(address from, uint256 id, uint256 amount, bytes calldata data) - external - virtual - override - { + function burn( + address from, + uint256 id, + uint256 amount, + bytes calldata data + ) external virtual override { require( from == _msgSender() || isApprovedForAll(from, _msgSender()), - "ERC1155MixedFungible: caller is not owner nor approved" + 'ERC1155MixedFungible: caller is not owner nor approved' ); _burn(from, id, amount); } - function setApprovalForAllWithData(address operator, bool approved, bytes calldata data) - external - virtual - override - { + function setApprovalForAllWithData( + address operator, + bool approved, + bytes calldata data + ) external virtual override { setApprovalForAll(operator, approved); } - function uri(uint256 id) public view virtual override(IERC1155MixedFungible, ERC1155) returns (string memory) { + function uri( + uint256 id + ) public view virtual override(IERC1155MixedFungible, ERC1155) returns (string memory) { string memory _tokenUri = _nfTokenURIs[id]; bytes memory tempURITest = bytes(_tokenUri); diff --git a/samples/solidity/contracts/IERC1155Factory.sol b/samples/solidity/contracts/IERC1155Factory.sol new file mode 100644 index 0000000..53a7870 --- /dev/null +++ b/samples/solidity/contracts/IERC1155Factory.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: Apache-2.0 + +pragma solidity ^0.8.0; + +import '@openzeppelin/contracts/utils/introspection/IERC165.sol'; + +/** + * ERC1155 interface that supports creating partitions of fungible and non-fungible tokens. + * The implementation may decide how to allocate these "pools" of value, and should emit the + * TokenPoolCreation event to advertise each newly created partition (with start_id and end_id + * being the inclusive start and end indexes of the ERC1155 id space). + */ +interface IERC1155Factory is IERC165 { + event TokenPoolCreation( + address indexed operator, + bool indexed is_fungible, + uint256 start_id, + uint256 end_id, + bytes data + ); + + function create(bool is_fungible, bytes calldata data) external; +} diff --git a/samples/solidity/contracts/IERC1155MixedFungible.sol b/samples/solidity/contracts/IERC1155MixedFungible.sol index 176fa1d..79c4360 100644 --- a/samples/solidity/contracts/IERC1155MixedFungible.sol +++ b/samples/solidity/contracts/IERC1155MixedFungible.sol @@ -3,53 +3,40 @@ pragma solidity ^0.8.0; import '@openzeppelin/contracts/utils/introspection/IERC165.sol'; +import './IERC1155Factory.sol'; /** * ERC1155 interface with mint, burn, and attached data support for fungible & non-fungible tokens. * Non-fungible tokens also have support for custom URI's. */ - interface IERC1155MixedFungible is IERC165 { - function create( - bool is_fungible, - bytes calldata data - ) external returns (uint256); - - function mintNonFungible( - uint256 type_id, - address[] calldata to, - bytes calldata data - ) external; - - function mintNonFungibleWithURI( - uint256 type_id, - address[] calldata to, - bytes calldata data, - string memory _uri - ) external; - - function mintFungible( - uint256 type_id, - address[] calldata to, - uint256[] calldata amounts, - bytes calldata data - ) external; - - function burn( - address from, - uint256 id, - uint256 amount, - bytes calldata data - ) external; - - function setApprovalForAllWithData( - address operator, - bool approved, - bytes calldata data - ) external; - - function uri( - uint256 id - ) external returns (string memory); - - function baseTokenUri() external returns(string memory); - } \ No newline at end of file +interface IERC1155MixedFungible is IERC165, IERC1155Factory { + function create(bool is_fungible, bytes calldata data) external override; + + function mintNonFungible(uint256 type_id, address[] calldata to, bytes calldata data) external; + + function mintNonFungibleWithURI( + uint256 type_id, + address[] calldata to, + bytes calldata data, + string memory _uri + ) external; + + function mintFungible( + uint256 type_id, + address[] calldata to, + uint256[] calldata amounts, + bytes calldata data + ) external; + + function burn(address from, uint256 id, uint256 amount, bytes calldata data) external; + + function setApprovalForAllWithData( + address operator, + bool approved, + bytes calldata data + ) external; + + function uri(uint256 id) external returns (string memory); + + function baseTokenUri() external returns (string memory); +} diff --git a/samples/solidity/copyabi.sh b/samples/solidity/copyabi.sh new file mode 100755 index 0000000..98cb838 --- /dev/null +++ b/samples/solidity/copyabi.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +set -euo pipefail + +ABIS=$(ls artifacts/contracts/*/*.json | grep -v ".dbg.json") +cp ${ABIS} ../../src/abi diff --git a/samples/solidity/test/ERC1155MixedFungible.ts b/samples/solidity/test/ERC1155MixedFungible.ts index 1e1b629..0765474 100644 --- a/samples/solidity/test/ERC1155MixedFungible.ts +++ b/samples/solidity/test/ERC1155MixedFungible.ts @@ -5,17 +5,17 @@ import { ERC1155MixedFungible, InterfaceCheck } from '../typechain'; describe('ERC1155MixedFungible - Unit Tests', () => { const baseUri = 'https://firefly/{id}'; - const fungibleTokenTypeId = BigInt('340282366920938463463374607431768211456'); + const fungibleTokenTypeId = BigInt('0x100000000000000000000000000000000'); const nonFungibleTokenTypeId = BigInt( - '57896044618658097711785492504343953926975274699741220483192166611388333031424', + '0x8000000000000000000000000000000100000000000000000000000000000000', ); const nonFungibleTokenId = BigInt( - '57896044618658097711785492504343953926975274699741220483192166611388333031425', + '0x8000000000000000000000000000000100000000000000000000000000000001', ); + const nftPoolSize = BigInt(1) << (BigInt(128) - BigInt(1)); const ONE_ADDRESS = '0x1111111111111111111111111111111111111111'; - let Factory; let deployedERC1155: ERC1155MixedFungible; let deployerSignerA: SignerWithAddress; let signerB: SignerWithAddress; @@ -24,7 +24,7 @@ describe('ERC1155MixedFungible - Unit Tests', () => { beforeEach(async () => { [deployerSignerA, signerB, signerC] = await ethers.getSigners(); - Factory = await ethers.getContractFactory('ERC1155MixedFungible'); + const Factory = await ethers.getContractFactory('ERC1155MixedFungible'); deployedERC1155 = await Factory.connect(deployerSignerA).deploy(baseUri); await deployedERC1155.deployed(); }); @@ -41,15 +41,26 @@ describe('ERC1155MixedFungible - Unit Tests', () => { context('Create function', () => { it('should support deployment of a new fungible token pool without data', async () => { - await expect(deployedERC1155.connect(deployerSignerA).create(true, '0x00')).to.emit( - deployedERC1155, - 'TokenPoolCreation', - ); + await expect(deployedERC1155.connect(deployerSignerA).create(true, '0x00')) + .to.emit(deployedERC1155, 'TokenPoolCreation') + .withArgs( + '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + true, + fungibleTokenTypeId, + fungibleTokenTypeId, + '0x00', + ); }); it('should support deployment of a new non-fungible token pool without data', async () => { await expect(deployedERC1155.connect(deployerSignerA).create(false, '0x00')) .to.emit(deployedERC1155, 'TokenPoolCreation') - .withArgs('0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', nonFungibleTokenTypeId, '0x00'); + .withArgs( + '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + false, + nonFungibleTokenTypeId, + nonFungibleTokenTypeId + nftPoolSize, + '0x00', + ); }); }); @@ -58,7 +69,13 @@ describe('ERC1155MixedFungible - Unit Tests', () => { beforeEach(async () => { await expect(deployedERC1155.connect(deployerSignerA).create(false, '0x00')) .to.emit(deployedERC1155, 'TokenPoolCreation') - .withArgs('0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', nonFungibleTokenTypeId, '0x00'); + .withArgs( + '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + false, + nonFungibleTokenTypeId, + nonFungibleTokenTypeId + nftPoolSize, + '0x00', + ); }); it('signer should be able to mint their own tokens', async () => { await expect( @@ -86,7 +103,13 @@ describe('ERC1155MixedFungible - Unit Tests', () => { beforeEach(async () => { await expect(deployedERC1155.connect(deployerSignerA).create(true, '0x00')) .to.emit(deployedERC1155, 'TokenPoolCreation') - .withArgs('0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', fungibleTokenTypeId, '0x00'); + .withArgs( + '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + true, + fungibleTokenTypeId, + fungibleTokenTypeId, + '0x00', + ); }); it('signer should be able to mint their own tokens', async () => { await expect( @@ -132,7 +155,13 @@ describe('ERC1155MixedFungible - Unit Tests', () => { beforeEach(async () => { await expect(deployedERC1155.connect(deployerSignerA).create(false, '0x00')) .to.emit(deployedERC1155, 'TokenPoolCreation') - .withArgs('0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', nonFungibleTokenTypeId, '0x00'); + .withArgs( + '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + false, + nonFungibleTokenTypeId, + nonFungibleTokenTypeId + nftPoolSize, + '0x00', + ); await expect( deployedERC1155 .connect(deployerSignerA) @@ -246,7 +275,13 @@ describe('ERC1155MixedFungible - Unit Tests', () => { beforeEach(async () => { await expect(deployedERC1155.connect(deployerSignerA).create(true, '0x00')) .to.emit(deployedERC1155, 'TokenPoolCreation') - .withArgs('0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', fungibleTokenTypeId, '0x00'); + .withArgs( + '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + true, + fungibleTokenTypeId, + fungibleTokenTypeId, + '0x00', + ); await expect( deployedERC1155 .connect(deployerSignerA) @@ -372,7 +407,13 @@ describe('ERC1155MixedFungible - Unit Tests', () => { beforeEach(async () => { await expect(deployedERC1155.connect(deployerSignerA).create(false, '0x00')) .to.emit(deployedERC1155, 'TokenPoolCreation') - .withArgs('0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', nonFungibleTokenTypeId, '0x00'); + .withArgs( + '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + false, + nonFungibleTokenTypeId, + nonFungibleTokenTypeId + nftPoolSize, + '0x00', + ); }); it('signer should be able to burn their own tokens', async () => { await expect( @@ -427,7 +468,13 @@ describe('ERC1155MixedFungible - Unit Tests', () => { beforeEach(async () => { await expect(deployedERC1155.connect(deployerSignerA).create(true, '0x00')) .to.emit(deployedERC1155, 'TokenPoolCreation') - .withArgs('0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', fungibleTokenTypeId, '0x00'); + .withArgs( + '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + true, + fungibleTokenTypeId, + fungibleTokenTypeId, + '0x00', + ); }); it('signer should be able to burn their own tokens', async () => { await expect( diff --git a/src/abi/ERC1155MixedFungible.json b/src/abi/ERC1155MixedFungible.json index 8e8777c..03c41b3 100644 --- a/src/abi/ERC1155MixedFungible.json +++ b/src/abi/ERC1155MixedFungible.json @@ -50,8 +50,20 @@ }, { "indexed": true, + "internalType": "bool", + "name": "is_fungible", + "type": "bool" + }, + { + "indexed": false, "internalType": "uint256", - "name": "type_id", + "name": "start_id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "end_id", "type": "uint256" }, { @@ -157,29 +169,6 @@ "name": "URI", "type": "event" }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "type_id", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - }, - { - "internalType": "string", - "name": "_uri", - "type": "string" - } - ], - "name": "_setNonFungibleURI", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [ { @@ -283,13 +272,7 @@ } ], "name": "create", - "outputs": [ - { - "internalType": "uint256", - "name": "type_id", - "type": "uint256" - } - ], + "outputs": [], "stateMutability": "nonpayable", "type": "function" }, @@ -580,8 +563,8 @@ "type": "function" } ], - "bytecode": "0x60806040523480156200001157600080fd5b5060405162004524380380620045248339818101604052810190620000379190620001a8565b8062000049816200006a60201b60201c565b5080600690805190602001906200006292919062000086565b50506200035d565b80600290805190602001906200008292919062000086565b5050565b828054620000949062000282565b90600052602060002090601f016020900481019282620000b8576000855562000104565b82601f10620000d357805160ff191683800117855562000104565b8280016001018555821562000104579182015b8281111562000103578251825591602001919060010190620000e6565b5b50905062000113919062000117565b5090565b5b808211156200013257600081600090555060010162000118565b5090565b60006200014d620001478462000216565b620001ed565b9050828152602081018484840111156200016657600080fd5b620001738482856200024c565b509392505050565b600082601f8301126200018d57600080fd5b81516200019f84826020860162000136565b91505092915050565b600060208284031215620001bb57600080fd5b600082015167ffffffffffffffff811115620001d657600080fd5b620001e4848285016200017b565b91505092915050565b6000620001f96200020c565b9050620002078282620002b8565b919050565b6000604051905090565b600067ffffffffffffffff8211156200023457620002336200031d565b5b6200023f826200034c565b9050602081019050919050565b60005b838110156200026c5780820151818401526020810190506200024f565b838111156200027c576000848401525b50505050565b600060028204905060018216806200029b57607f821691505b60208210811415620002b257620002b1620002ee565b5b50919050565b620002c3826200034c565b810181811067ffffffffffffffff82111715620002e557620002e46200031d565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b6141b7806200036d6000396000f3fe608060405234801561001057600080fd5b50600436106101155760003560e01c806371cc1656116100a2578063a22cb46511610071578063a22cb46514610300578063b944eb291461031c578063cd53d08e14610338578063e985e9c514610368578063f242432a1461039857610115565b806371cc16561461027a5780637a0101a2146102aa5780637e53b65d146102c85780638a94b05f146102e457610115565b8063183fb254116100e9578063183fb254146101da5780631cbf311d146101f65780632eb2c2d6146102125780634e1273f41461022e57806354dbdbf41461025e57610115565b8062fdd58e1461011a57806301ffc9a71461014a57806308d7d4691461017a5780630e89341c146101aa575b600080fd5b610134600480360381019061012f9190612b85565b6103b4565b6040516101419190613737565b60405180910390f35b610164600480360381019061015f9190612d05565b61047d565b60405161017191906134b6565b60405180910390f35b610194600480360381019061018f9190612d57565b6104f7565b6040516101a19190613737565b60405180910390f35b6101c460048036038101906101bf9190612d57565b61050f565b6040516101d191906134f5565b60405180910390f35b6101f460048036038101906101ef9190612d80565b61065f565b005b610210600480360381019061020b9190612b19565b610868565b005b61022c6004803603810190610227919061298f565b610878565b005b61024860048036038101906102439190612c41565b610919565b604051610255919061345d565b60405180910390f35b61027860048036038101906102739190612e39565b610aca565b005b610294600480360381019061028f9190612cad565b610cb4565b6040516102a19190613737565b60405180910390f35b6102b2610db4565b6040516102bf91906134f5565b60405180910390f35b6102e260048036038101906102dd9190612ec2565b610e46565b005b6102fe60048036038101906102f99190612bc1565b611042565b005b61031a60048036038101906103159190612add565b6110e1565b005b61033660048036038101906103319190612f75565b6110f7565b005b610352600480360381019061034d9190612d57565b6111e0565b60405161035f9190613380565b60405180910390f35b610382600480360381019061037d9190612953565b611213565b60405161038f91906134b6565b60405180910390f35b6103b260048036038101906103ad9190612a4e565b6112a7565b005b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610425576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041c90613557565b60405180910390fd5b60008083815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60007fa1d87d57000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806104f057506104ef82611348565b5b9050919050565b60056020528060005260406000206000915090505481565b60606000600760008481526020019081526020016000208054610531906139d7565b80601f016020809104026020016040519081016040528092919081815260200182805461055d906139d7565b80156105aa5780601f1061057f576101008083540402835291602001916105aa565b820191906000526020600020905b81548152906001019060200180831161058d57829003601f168201915b50505050509050600081905060008151141561065457600680546105cd906139d7565b80601f01602080910402602001604051908101604052809291908181526020018280546105f9906139d7565b80156106465780601f1061061b57610100808354040283529160200191610646565b820191906000526020600020905b81548152906001019060200180831161062957829003601f168201915b50505050509250505061065a565b81925050505b919050565b8661066861142a565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146106d257600080fd5b6106db88611432565b61071a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610711906135f7565b60405180910390fd5b848490508787905014610762576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161075990613657565b60405180910390fd5b60005b8787905081101561085d5761084c8888838181106107ac577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020160208101906107c1919061292a565b8a8888858181106107fb577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002013587878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611460565b8061085690613a3a565b9050610765565b505050505050505050565b61087284846110e1565b50505050565b61088061142a565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614806108c657506108c5856108c061142a565b611213565b5b610905576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108fc90613637565b60405180910390fd5b6109128585858585611611565b5050505050565b6060815183511461095f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610956906136d7565b60405180910390fd5b6000835167ffffffffffffffff8111156109a2577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156109d05781602001602082028036833780820191505090505b50905060005b8451811015610abf57610a69858281518110610a1b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151858381518110610a5c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101516103b4565b828281518110610aa2577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101818152505080610ab890613a3a565b90506109d6565b508091505092915050565b84610ad361142a565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b3d57600080fd5b610b468661197f565b610b85576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b7c906135d7565b60405180910390fd5b600060016005600089815260200190815260200160002054610ba791906138cb565b9050610bc986869050600560008a8152602001908152602001600020546119ad565b600560008981526020019081526020016000208190555060005b86869050811015610caa57610c99878783818110610c2a577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002016020810190610c3f919061292a565b8284610c4b91906138cb565b8a17600188888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611460565b80610ca390613a3a565b9050610be3565b5050505050505050565b60006080600360008154610cc790613a3a565b919050819055901b905083610cfc577f8000000000000000000000000000000000000000000000000000000000000000811790505b610d0461142a565b6004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080610d5e61142a565b73ffffffffffffffffffffffffffffffffffffffff167f0d2ce24070e07853454690ae0a0416ddd4845188f8dbfe0ef3a761acb3d2e34e8585604051610da59291906134d1565b60405180910390a39392505050565b606060068054610dc3906139d7565b80601f0160208091040260200160405190810160405280929190818152602001828054610def906139d7565b8015610e3c5780601f10610e1157610100808354040283529160200191610e3c565b820191906000526020600020905b815481529060010190602001808311610e1f57829003601f168201915b5050505050905090565b85610e4f61142a565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610eb957600080fd5b610ec28761197f565b610f01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ef8906135d7565b60405180910390fd5b60006001600560008a815260200190815260200160002054610f2391906138cb565b9050610f4587879050600560008b8152602001908152602001600020546119ad565b600560008a81526020019081526020016000208190555060005b878790508110156110375760008183610f7891906138cb565b8a17905061101a898984818110610fb8577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002016020810190610fcd919061292a565b8260018a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611460565b6110258a82876110f7565b508061103090613a3a565b9050610f5f565b505050505050505050565b61104a61142a565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161480611090575061108f8561108a61142a565b611213565b5b6110cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110c690613597565b60405180910390fd5b6110da8585856119c3565b5050505050565b6110f36110ec61142a565b8383611c0a565b5050565b8261110061142a565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461116a57600080fd5b6111738461197f565b6111b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111a9906135d7565b60405180910390fd5b816007600085815260200190815260200160002090805190602001906111d9929190612544565b5050505050565b60046020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6112af61142a565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614806112f557506112f4856112ef61142a565b611213565b5b611334576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161132b906135b7565b60405180910390fd5b6113418585858585611d77565b5050505050565b60007fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061141357507f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611423575061142282612013565b5b9050919050565b600033905090565b6000807f80000000000000000000000000000000000000000000000000000000000000008316149050919050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156114d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114c790613717565b60405180910390fd5b60006114da61142a565b905060006114e78561207d565b905060006114f48561207d565b905061150583600089858589612143565b8460008088815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461156491906138cb565b925050819055508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6289896040516115e2929190613752565b60405180910390a46115f98360008985858961214b565b61160883600089898989612153565b50505050505050565b8151835114611655576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161164c906136f7565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156116c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116bc90613617565b60405180910390fd5b60006116cf61142a565b90506116df818787878787612143565b60005b84518110156118dc576000858281518110611726577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101519050600085838151811061176b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101519050600080600084815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508181101561180c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161180390613697565b60405180910390fd5b81810360008085815260200190815260200160002060008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508160008085815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546118c191906138cb565b92505081905550505050806118d590613a3a565b90506116e2565b508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb878760405161195392919061347f565b60405180910390a461196981878787878761214b565b61197781878787878761233a565b505050505050565b60007f8000000000000000000000000000000000000000000000000000000000000000808316149050919050565b600081836119bb91906138cb565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611a33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2a90613677565b60405180910390fd5b6000611a3d61142a565b90506000611a4a8461207d565b90506000611a578461207d565b9050611a7783876000858560405180602001604052806000815250612143565b600080600087815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905084811015611b0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b0590613577565b60405180910390fd5b84810360008088815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628989604051611bdb929190613752565b60405180910390a4611c018488600086866040518060200160405280600081525061214b565b50505050505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611c79576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c70906136b7565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611d6a91906134b6565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611de7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dde90613617565b60405180910390fd5b6000611df161142a565b90506000611dfe8561207d565b90506000611e0b8561207d565b9050611e1b838989858589612143565b600080600088815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905085811015611eb2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ea990613697565b60405180910390fd5b85810360008089815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508560008089815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f6791906138cb565b925050819055508773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628a8a604051611fe4929190613752565b60405180910390a4611ffa848a8a86868a61214b565b612008848a8a8a8a8a612153565b505050505050505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60606000600167ffffffffffffffff8111156120c2577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156120f05781602001602082028036833780820191505090505b509050828160008151811061212e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101818152505080915050919050565b505050505050565b505050505050565b6121728473ffffffffffffffffffffffffffffffffffffffff16612521565b15612332578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b81526004016121b8959493929190613403565b602060405180830381600087803b1580156121d257600080fd5b505af192505050801561220357506040513d601f19601f820116820180604052508101906122009190612d2e565b60015b6122a95761220f613b10565b806308c379a0141561226c575061222461408f565b8061222f575061226e565b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161226391906134f5565b60405180910390fd5b505b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122a090613517565b60405180910390fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612330576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161232790613537565b60405180910390fd5b505b505050505050565b6123598473ffffffffffffffffffffffffffffffffffffffff16612521565b15612519578373ffffffffffffffffffffffffffffffffffffffff1663bc197c8187878686866040518663ffffffff1660e01b815260040161239f95949392919061339b565b602060405180830381600087803b1580156123b957600080fd5b505af19250505080156123ea57506040513d601f19601f820116820180604052508101906123e79190612d2e565b60015b612490576123f6613b10565b806308c379a01415612453575061240b61408f565b806124165750612455565b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161244a91906134f5565b60405180910390fd5b505b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161248790613517565b60405180910390fd5b63bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612517576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161250e90613537565b60405180910390fd5b505b505050505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b828054612550906139d7565b90600052602060002090601f01602090048101928261257257600085556125b9565b82601f1061258b57805160ff19168380011785556125b9565b828001600101855582156125b9579182015b828111156125b857825182559160200191906001019061259d565b5b5090506125c691906125ca565b5090565b5b808211156125e35760008160009055506001016125cb565b5090565b60006125fa6125f5846137a0565b61377b565b9050808382526020820190508285602086028201111561261957600080fd5b60005b85811015612649578161262f888261273b565b84526020840193506020830192505060018101905061261c565b5050509392505050565b6000612666612661846137cc565b61377b565b9050808382526020820190508285602086028201111561268557600080fd5b60005b858110156126b5578161269b8882612915565b845260208401935060208301925050600181019050612688565b5050509392505050565b60006126d26126cd846137f8565b61377b565b9050828152602081018484840111156126ea57600080fd5b6126f5848285613995565b509392505050565b600061271061270b84613829565b61377b565b90508281526020810184848401111561272857600080fd5b612733848285613995565b509392505050565b60008135905061274a81614125565b92915050565b60008083601f84011261276257600080fd5b8235905067ffffffffffffffff81111561277b57600080fd5b60208301915083602082028301111561279357600080fd5b9250929050565b600082601f8301126127ab57600080fd5b81356127bb8482602086016125e7565b91505092915050565b60008083601f8401126127d657600080fd5b8235905067ffffffffffffffff8111156127ef57600080fd5b60208301915083602082028301111561280757600080fd5b9250929050565b600082601f83011261281f57600080fd5b813561282f848260208601612653565b91505092915050565b6000813590506128478161413c565b92915050565b60008135905061285c81614153565b92915050565b60008151905061287181614153565b92915050565b60008083601f84011261288957600080fd5b8235905067ffffffffffffffff8111156128a257600080fd5b6020830191508360018202830111156128ba57600080fd5b9250929050565b600082601f8301126128d257600080fd5b81356128e28482602086016126bf565b91505092915050565b600082601f8301126128fc57600080fd5b813561290c8482602086016126fd565b91505092915050565b6000813590506129248161416a565b92915050565b60006020828403121561293c57600080fd5b600061294a8482850161273b565b91505092915050565b6000806040838503121561296657600080fd5b60006129748582860161273b565b92505060206129858582860161273b565b9150509250929050565b600080600080600060a086880312156129a757600080fd5b60006129b58882890161273b565b95505060206129c68882890161273b565b945050604086013567ffffffffffffffff8111156129e357600080fd5b6129ef8882890161280e565b935050606086013567ffffffffffffffff811115612a0c57600080fd5b612a188882890161280e565b925050608086013567ffffffffffffffff811115612a3557600080fd5b612a41888289016128c1565b9150509295509295909350565b600080600080600060a08688031215612a6657600080fd5b6000612a748882890161273b565b9550506020612a858882890161273b565b9450506040612a9688828901612915565b9350506060612aa788828901612915565b925050608086013567ffffffffffffffff811115612ac457600080fd5b612ad0888289016128c1565b9150509295509295909350565b60008060408385031215612af057600080fd5b6000612afe8582860161273b565b9250506020612b0f85828601612838565b9150509250929050565b60008060008060608587031215612b2f57600080fd5b6000612b3d8782880161273b565b9450506020612b4e87828801612838565b935050604085013567ffffffffffffffff811115612b6b57600080fd5b612b7787828801612877565b925092505092959194509250565b60008060408385031215612b9857600080fd5b6000612ba68582860161273b565b9250506020612bb785828601612915565b9150509250929050565b600080600080600060808688031215612bd957600080fd5b6000612be78882890161273b565b9550506020612bf888828901612915565b9450506040612c0988828901612915565b935050606086013567ffffffffffffffff811115612c2657600080fd5b612c3288828901612877565b92509250509295509295909350565b60008060408385031215612c5457600080fd5b600083013567ffffffffffffffff811115612c6e57600080fd5b612c7a8582860161279a565b925050602083013567ffffffffffffffff811115612c9757600080fd5b612ca38582860161280e565b9150509250929050565b600080600060408486031215612cc257600080fd5b6000612cd086828701612838565b935050602084013567ffffffffffffffff811115612ced57600080fd5b612cf986828701612877565b92509250509250925092565b600060208284031215612d1757600080fd5b6000612d258482850161284d565b91505092915050565b600060208284031215612d4057600080fd5b6000612d4e84828501612862565b91505092915050565b600060208284031215612d6957600080fd5b6000612d7784828501612915565b91505092915050565b60008060008060008060006080888a031215612d9b57600080fd5b6000612da98a828b01612915565b975050602088013567ffffffffffffffff811115612dc657600080fd5b612dd28a828b01612750565b9650965050604088013567ffffffffffffffff811115612df157600080fd5b612dfd8a828b016127c4565b9450945050606088013567ffffffffffffffff811115612e1c57600080fd5b612e288a828b01612877565b925092505092959891949750929550565b600080600080600060608688031215612e5157600080fd5b6000612e5f88828901612915565b955050602086013567ffffffffffffffff811115612e7c57600080fd5b612e8888828901612750565b9450945050604086013567ffffffffffffffff811115612ea757600080fd5b612eb388828901612877565b92509250509295509295909350565b60008060008060008060808789031215612edb57600080fd5b6000612ee989828a01612915565b965050602087013567ffffffffffffffff811115612f0657600080fd5b612f1289828a01612750565b9550955050604087013567ffffffffffffffff811115612f3157600080fd5b612f3d89828a01612877565b9350935050606087013567ffffffffffffffff811115612f5c57600080fd5b612f6889828a016128eb565b9150509295509295509295565b600080600060608486031215612f8a57600080fd5b6000612f9886828701612915565b9350506020612fa986828701612915565b925050604084013567ffffffffffffffff811115612fc657600080fd5b612fd2868287016128eb565b9150509250925092565b6000612fe88383613362565b60208301905092915050565b612ffd81613921565b82525050565b600061300e8261386a565b6130188185613898565b93506130238361385a565b8060005b8381101561305457815161303b8882612fdc565b97506130468361388b565b925050600181019050613027565b5085935050505092915050565b61306a81613933565b82525050565b600061307c83856138a9565b9350613089838584613995565b61309283613b32565b840190509392505050565b60006130a882613875565b6130b281856138a9565b93506130c28185602086016139a4565b6130cb81613b32565b840191505092915050565b60006130e182613880565b6130eb81856138ba565b93506130fb8185602086016139a4565b61310481613b32565b840191505092915050565b600061311c6034836138ba565b915061312782613b50565b604082019050919050565b600061313f6028836138ba565b915061314a82613b9f565b604082019050919050565b6000613162602b836138ba565b915061316d82613bee565b604082019050919050565b60006131856024836138ba565b915061319082613c3d565b604082019050919050565b60006131a86036836138ba565b91506131b382613c8c565b604082019050919050565b60006131cb6029836138ba565b91506131d682613cdb565b604082019050919050565b60006131ee603f836138ba565b91506131f982613d2a565b604082019050919050565b6000613211603b836138ba565b915061321c82613d79565b604082019050919050565b60006132346025836138ba565b915061323f82613dc8565b604082019050919050565b60006132576032836138ba565b915061326282613e17565b604082019050919050565b600061327a6034836138ba565b915061328582613e66565b604082019050919050565b600061329d6023836138ba565b91506132a882613eb5565b604082019050919050565b60006132c0602a836138ba565b91506132cb82613f04565b604082019050919050565b60006132e36029836138ba565b91506132ee82613f53565b604082019050919050565b60006133066029836138ba565b915061331182613fa2565b604082019050919050565b60006133296028836138ba565b915061333482613ff1565b604082019050919050565b600061334c6021836138ba565b915061335782614040565b604082019050919050565b61336b8161398b565b82525050565b61337a8161398b565b82525050565b60006020820190506133956000830184612ff4565b92915050565b600060a0820190506133b06000830188612ff4565b6133bd6020830187612ff4565b81810360408301526133cf8186613003565b905081810360608301526133e38185613003565b905081810360808301526133f7818461309d565b90509695505050505050565b600060a0820190506134186000830188612ff4565b6134256020830187612ff4565b6134326040830186613371565b61343f6060830185613371565b8181036080830152613451818461309d565b90509695505050505050565b600060208201905081810360008301526134778184613003565b905092915050565b600060408201905081810360008301526134998185613003565b905081810360208301526134ad8184613003565b90509392505050565b60006020820190506134cb6000830184613061565b92915050565b600060208201905081810360008301526134ec818486613070565b90509392505050565b6000602082019050818103600083015261350f81846130d6565b905092915050565b600060208201905081810360008301526135308161310f565b9050919050565b6000602082019050818103600083015261355081613132565b9050919050565b6000602082019050818103600083015261357081613155565b9050919050565b6000602082019050818103600083015261359081613178565b9050919050565b600060208201905081810360008301526135b08161319b565b9050919050565b600060208201905081810360008301526135d0816131be565b9050919050565b600060208201905081810360008301526135f0816131e1565b9050919050565b6000602082019050818103600083015261361081613204565b9050919050565b6000602082019050818103600083015261363081613227565b9050919050565b600060208201905081810360008301526136508161324a565b9050919050565b600060208201905081810360008301526136708161326d565b9050919050565b6000602082019050818103600083015261369081613290565b9050919050565b600060208201905081810360008301526136b0816132b3565b9050919050565b600060208201905081810360008301526136d0816132d6565b9050919050565b600060208201905081810360008301526136f0816132f9565b9050919050565b600060208201905081810360008301526137108161331c565b9050919050565b600060208201905081810360008301526137308161333f565b9050919050565b600060208201905061374c6000830184613371565b92915050565b60006040820190506137676000830185613371565b6137746020830184613371565b9392505050565b6000613785613796565b90506137918282613a09565b919050565b6000604051905090565b600067ffffffffffffffff8211156137bb576137ba613ae1565b5b602082029050602081019050919050565b600067ffffffffffffffff8211156137e7576137e6613ae1565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561381357613812613ae1565b5b61381c82613b32565b9050602081019050919050565b600067ffffffffffffffff82111561384457613843613ae1565b5b61384d82613b32565b9050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b60006138d68261398b565b91506138e18361398b565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561391657613915613a83565b5b828201905092915050565b600061392c8261396b565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156139c25780820151818401526020810190506139a7565b838111156139d1576000848401525b50505050565b600060028204905060018216806139ef57607f821691505b60208210811415613a0357613a02613ab2565b5b50919050565b613a1282613b32565b810181811067ffffffffffffffff82111715613a3157613a30613ae1565b5b80604052505050565b6000613a458261398b565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613a7857613a77613a83565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060033d1115613b2f5760046000803e613b2c600051613b43565b90505b90565b6000601f19601f8301169050919050565b60008160e01c9050919050565b7f455243313135353a207472616e7366657220746f206e6f6e204552433131353560008201527f526563656976657220696d706c656d656e746572000000000000000000000000602082015250565b7f455243313135353a204552433131353552656365697665722072656a6563746560008201527f6420746f6b656e73000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a2062616c616e636520717565727920666f7220746865207a60008201527f65726f2061646472657373000000000000000000000000000000000000000000602082015250565b7f455243313135353a206275726e20616d6f756e7420657863656564732062616c60008201527f616e636500000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135354d6978656446756e6769626c653a2063616c6c65722069732060008201527f6e6f74206f776e6572206e6f7220617070726f76656400000000000000000000602082015250565b7f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260008201527f20617070726f7665640000000000000000000000000000000000000000000000602082015250565b7f455243313135354d6978656446756e6769626c653a20696420646f6573206e6f60008201527f7420726570726573656e742061206e6f6e2d66756e6769626c65207479706500602082015250565b7f455243313135354d6978656446756e6769626c653a20696420646f6573206e6f60008201527f7420726570726573656e7420612066756e6769626c6520747970650000000000602082015250565b7f455243313135353a207472616e7366657220746f20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a207472616e736665722063616c6c6572206973206e6f742060008201527f6f776e6572206e6f7220617070726f7665640000000000000000000000000000602082015250565b7f455243313135354d6978656446756e6769626c653a20746f20616e6420616d6f60008201527f756e7473206c656e677468206d69736d61746368000000000000000000000000602082015250565b7f455243313135353a206275726e2066726f6d20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a20696e73756666696369656e742062616c616e636520666f60008201527f72207472616e7366657200000000000000000000000000000000000000000000602082015250565b7f455243313135353a2073657474696e6720617070726f76616c2073746174757360008201527f20666f722073656c660000000000000000000000000000000000000000000000602082015250565b7f455243313135353a206163636f756e747320616e6420696473206c656e67746860008201527f206d69736d617463680000000000000000000000000000000000000000000000602082015250565b7f455243313135353a2069647320616e6420616d6f756e7473206c656e6774682060008201527f6d69736d61746368000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a206d696e7420746f20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b600060443d101561409f57614122565b6140a7613796565b60043d036004823e80513d602482011167ffffffffffffffff821117156140cf575050614122565b808201805167ffffffffffffffff8111156140ed5750505050614122565b80602083010160043d03850181111561410a575050505050614122565b61411982602001850186613a09565b82955050505050505b90565b61412e81613921565b811461413957600080fd5b50565b61414581613933565b811461415057600080fd5b50565b61415c8161393f565b811461416757600080fd5b50565b6141738161398b565b811461417e57600080fd5b5056fea26469706673582212204fdf750e16aa1fe5ce34d26e3ca05a16726f416ae430ccefe9a917dbb14fb7d864736f6c63430008040033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101155760003560e01c806371cc1656116100a2578063a22cb46511610071578063a22cb46514610300578063b944eb291461031c578063cd53d08e14610338578063e985e9c514610368578063f242432a1461039857610115565b806371cc16561461027a5780637a0101a2146102aa5780637e53b65d146102c85780638a94b05f146102e457610115565b8063183fb254116100e9578063183fb254146101da5780631cbf311d146101f65780632eb2c2d6146102125780634e1273f41461022e57806354dbdbf41461025e57610115565b8062fdd58e1461011a57806301ffc9a71461014a57806308d7d4691461017a5780630e89341c146101aa575b600080fd5b610134600480360381019061012f9190612b85565b6103b4565b6040516101419190613737565b60405180910390f35b610164600480360381019061015f9190612d05565b61047d565b60405161017191906134b6565b60405180910390f35b610194600480360381019061018f9190612d57565b6104f7565b6040516101a19190613737565b60405180910390f35b6101c460048036038101906101bf9190612d57565b61050f565b6040516101d191906134f5565b60405180910390f35b6101f460048036038101906101ef9190612d80565b61065f565b005b610210600480360381019061020b9190612b19565b610868565b005b61022c6004803603810190610227919061298f565b610878565b005b61024860048036038101906102439190612c41565b610919565b604051610255919061345d565b60405180910390f35b61027860048036038101906102739190612e39565b610aca565b005b610294600480360381019061028f9190612cad565b610cb4565b6040516102a19190613737565b60405180910390f35b6102b2610db4565b6040516102bf91906134f5565b60405180910390f35b6102e260048036038101906102dd9190612ec2565b610e46565b005b6102fe60048036038101906102f99190612bc1565b611042565b005b61031a60048036038101906103159190612add565b6110e1565b005b61033660048036038101906103319190612f75565b6110f7565b005b610352600480360381019061034d9190612d57565b6111e0565b60405161035f9190613380565b60405180910390f35b610382600480360381019061037d9190612953565b611213565b60405161038f91906134b6565b60405180910390f35b6103b260048036038101906103ad9190612a4e565b6112a7565b005b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610425576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041c90613557565b60405180910390fd5b60008083815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60007fa1d87d57000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806104f057506104ef82611348565b5b9050919050565b60056020528060005260406000206000915090505481565b60606000600760008481526020019081526020016000208054610531906139d7565b80601f016020809104026020016040519081016040528092919081815260200182805461055d906139d7565b80156105aa5780601f1061057f576101008083540402835291602001916105aa565b820191906000526020600020905b81548152906001019060200180831161058d57829003601f168201915b50505050509050600081905060008151141561065457600680546105cd906139d7565b80601f01602080910402602001604051908101604052809291908181526020018280546105f9906139d7565b80156106465780601f1061061b57610100808354040283529160200191610646565b820191906000526020600020905b81548152906001019060200180831161062957829003601f168201915b50505050509250505061065a565b81925050505b919050565b8661066861142a565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146106d257600080fd5b6106db88611432565b61071a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610711906135f7565b60405180910390fd5b848490508787905014610762576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161075990613657565b60405180910390fd5b60005b8787905081101561085d5761084c8888838181106107ac577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020160208101906107c1919061292a565b8a8888858181106107fb577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002013587878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611460565b8061085690613a3a565b9050610765565b505050505050505050565b61087284846110e1565b50505050565b61088061142a565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614806108c657506108c5856108c061142a565b611213565b5b610905576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108fc90613637565b60405180910390fd5b6109128585858585611611565b5050505050565b6060815183511461095f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610956906136d7565b60405180910390fd5b6000835167ffffffffffffffff8111156109a2577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156109d05781602001602082028036833780820191505090505b50905060005b8451811015610abf57610a69858281518110610a1b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151858381518110610a5c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101516103b4565b828281518110610aa2577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101818152505080610ab890613a3a565b90506109d6565b508091505092915050565b84610ad361142a565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b3d57600080fd5b610b468661197f565b610b85576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b7c906135d7565b60405180910390fd5b600060016005600089815260200190815260200160002054610ba791906138cb565b9050610bc986869050600560008a8152602001908152602001600020546119ad565b600560008981526020019081526020016000208190555060005b86869050811015610caa57610c99878783818110610c2a577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002016020810190610c3f919061292a565b8284610c4b91906138cb565b8a17600188888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611460565b80610ca390613a3a565b9050610be3565b5050505050505050565b60006080600360008154610cc790613a3a565b919050819055901b905083610cfc577f8000000000000000000000000000000000000000000000000000000000000000811790505b610d0461142a565b6004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080610d5e61142a565b73ffffffffffffffffffffffffffffffffffffffff167f0d2ce24070e07853454690ae0a0416ddd4845188f8dbfe0ef3a761acb3d2e34e8585604051610da59291906134d1565b60405180910390a39392505050565b606060068054610dc3906139d7565b80601f0160208091040260200160405190810160405280929190818152602001828054610def906139d7565b8015610e3c5780601f10610e1157610100808354040283529160200191610e3c565b820191906000526020600020905b815481529060010190602001808311610e1f57829003601f168201915b5050505050905090565b85610e4f61142a565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610eb957600080fd5b610ec28761197f565b610f01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ef8906135d7565b60405180910390fd5b60006001600560008a815260200190815260200160002054610f2391906138cb565b9050610f4587879050600560008b8152602001908152602001600020546119ad565b600560008a81526020019081526020016000208190555060005b878790508110156110375760008183610f7891906138cb565b8a17905061101a898984818110610fb8577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002016020810190610fcd919061292a565b8260018a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611460565b6110258a82876110f7565b508061103090613a3a565b9050610f5f565b505050505050505050565b61104a61142a565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161480611090575061108f8561108a61142a565b611213565b5b6110cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110c690613597565b60405180910390fd5b6110da8585856119c3565b5050505050565b6110f36110ec61142a565b8383611c0a565b5050565b8261110061142a565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461116a57600080fd5b6111738461197f565b6111b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111a9906135d7565b60405180910390fd5b816007600085815260200190815260200160002090805190602001906111d9929190612544565b5050505050565b60046020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6112af61142a565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614806112f557506112f4856112ef61142a565b611213565b5b611334576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161132b906135b7565b60405180910390fd5b6113418585858585611d77565b5050505050565b60007fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061141357507f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611423575061142282612013565b5b9050919050565b600033905090565b6000807f80000000000000000000000000000000000000000000000000000000000000008316149050919050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156114d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114c790613717565b60405180910390fd5b60006114da61142a565b905060006114e78561207d565b905060006114f48561207d565b905061150583600089858589612143565b8460008088815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461156491906138cb565b925050819055508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6289896040516115e2929190613752565b60405180910390a46115f98360008985858961214b565b61160883600089898989612153565b50505050505050565b8151835114611655576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161164c906136f7565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156116c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116bc90613617565b60405180910390fd5b60006116cf61142a565b90506116df818787878787612143565b60005b84518110156118dc576000858281518110611726577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101519050600085838151811061176b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101519050600080600084815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508181101561180c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161180390613697565b60405180910390fd5b81810360008085815260200190815260200160002060008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508160008085815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546118c191906138cb565b92505081905550505050806118d590613a3a565b90506116e2565b508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb878760405161195392919061347f565b60405180910390a461196981878787878761214b565b61197781878787878761233a565b505050505050565b60007f8000000000000000000000000000000000000000000000000000000000000000808316149050919050565b600081836119bb91906138cb565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611a33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2a90613677565b60405180910390fd5b6000611a3d61142a565b90506000611a4a8461207d565b90506000611a578461207d565b9050611a7783876000858560405180602001604052806000815250612143565b600080600087815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905084811015611b0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b0590613577565b60405180910390fd5b84810360008088815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628989604051611bdb929190613752565b60405180910390a4611c018488600086866040518060200160405280600081525061214b565b50505050505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611c79576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c70906136b7565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611d6a91906134b6565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611de7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dde90613617565b60405180910390fd5b6000611df161142a565b90506000611dfe8561207d565b90506000611e0b8561207d565b9050611e1b838989858589612143565b600080600088815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905085811015611eb2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ea990613697565b60405180910390fd5b85810360008089815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508560008089815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f6791906138cb565b925050819055508773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628a8a604051611fe4929190613752565b60405180910390a4611ffa848a8a86868a61214b565b612008848a8a8a8a8a612153565b505050505050505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60606000600167ffffffffffffffff8111156120c2577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156120f05781602001602082028036833780820191505090505b509050828160008151811061212e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101818152505080915050919050565b505050505050565b505050505050565b6121728473ffffffffffffffffffffffffffffffffffffffff16612521565b15612332578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b81526004016121b8959493929190613403565b602060405180830381600087803b1580156121d257600080fd5b505af192505050801561220357506040513d601f19601f820116820180604052508101906122009190612d2e565b60015b6122a95761220f613b10565b806308c379a0141561226c575061222461408f565b8061222f575061226e565b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161226391906134f5565b60405180910390fd5b505b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122a090613517565b60405180910390fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612330576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161232790613537565b60405180910390fd5b505b505050505050565b6123598473ffffffffffffffffffffffffffffffffffffffff16612521565b15612519578373ffffffffffffffffffffffffffffffffffffffff1663bc197c8187878686866040518663ffffffff1660e01b815260040161239f95949392919061339b565b602060405180830381600087803b1580156123b957600080fd5b505af19250505080156123ea57506040513d601f19601f820116820180604052508101906123e79190612d2e565b60015b612490576123f6613b10565b806308c379a01415612453575061240b61408f565b806124165750612455565b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161244a91906134f5565b60405180910390fd5b505b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161248790613517565b60405180910390fd5b63bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612517576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161250e90613537565b60405180910390fd5b505b505050505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b828054612550906139d7565b90600052602060002090601f01602090048101928261257257600085556125b9565b82601f1061258b57805160ff19168380011785556125b9565b828001600101855582156125b9579182015b828111156125b857825182559160200191906001019061259d565b5b5090506125c691906125ca565b5090565b5b808211156125e35760008160009055506001016125cb565b5090565b60006125fa6125f5846137a0565b61377b565b9050808382526020820190508285602086028201111561261957600080fd5b60005b85811015612649578161262f888261273b565b84526020840193506020830192505060018101905061261c565b5050509392505050565b6000612666612661846137cc565b61377b565b9050808382526020820190508285602086028201111561268557600080fd5b60005b858110156126b5578161269b8882612915565b845260208401935060208301925050600181019050612688565b5050509392505050565b60006126d26126cd846137f8565b61377b565b9050828152602081018484840111156126ea57600080fd5b6126f5848285613995565b509392505050565b600061271061270b84613829565b61377b565b90508281526020810184848401111561272857600080fd5b612733848285613995565b509392505050565b60008135905061274a81614125565b92915050565b60008083601f84011261276257600080fd5b8235905067ffffffffffffffff81111561277b57600080fd5b60208301915083602082028301111561279357600080fd5b9250929050565b600082601f8301126127ab57600080fd5b81356127bb8482602086016125e7565b91505092915050565b60008083601f8401126127d657600080fd5b8235905067ffffffffffffffff8111156127ef57600080fd5b60208301915083602082028301111561280757600080fd5b9250929050565b600082601f83011261281f57600080fd5b813561282f848260208601612653565b91505092915050565b6000813590506128478161413c565b92915050565b60008135905061285c81614153565b92915050565b60008151905061287181614153565b92915050565b60008083601f84011261288957600080fd5b8235905067ffffffffffffffff8111156128a257600080fd5b6020830191508360018202830111156128ba57600080fd5b9250929050565b600082601f8301126128d257600080fd5b81356128e28482602086016126bf565b91505092915050565b600082601f8301126128fc57600080fd5b813561290c8482602086016126fd565b91505092915050565b6000813590506129248161416a565b92915050565b60006020828403121561293c57600080fd5b600061294a8482850161273b565b91505092915050565b6000806040838503121561296657600080fd5b60006129748582860161273b565b92505060206129858582860161273b565b9150509250929050565b600080600080600060a086880312156129a757600080fd5b60006129b58882890161273b565b95505060206129c68882890161273b565b945050604086013567ffffffffffffffff8111156129e357600080fd5b6129ef8882890161280e565b935050606086013567ffffffffffffffff811115612a0c57600080fd5b612a188882890161280e565b925050608086013567ffffffffffffffff811115612a3557600080fd5b612a41888289016128c1565b9150509295509295909350565b600080600080600060a08688031215612a6657600080fd5b6000612a748882890161273b565b9550506020612a858882890161273b565b9450506040612a9688828901612915565b9350506060612aa788828901612915565b925050608086013567ffffffffffffffff811115612ac457600080fd5b612ad0888289016128c1565b9150509295509295909350565b60008060408385031215612af057600080fd5b6000612afe8582860161273b565b9250506020612b0f85828601612838565b9150509250929050565b60008060008060608587031215612b2f57600080fd5b6000612b3d8782880161273b565b9450506020612b4e87828801612838565b935050604085013567ffffffffffffffff811115612b6b57600080fd5b612b7787828801612877565b925092505092959194509250565b60008060408385031215612b9857600080fd5b6000612ba68582860161273b565b9250506020612bb785828601612915565b9150509250929050565b600080600080600060808688031215612bd957600080fd5b6000612be78882890161273b565b9550506020612bf888828901612915565b9450506040612c0988828901612915565b935050606086013567ffffffffffffffff811115612c2657600080fd5b612c3288828901612877565b92509250509295509295909350565b60008060408385031215612c5457600080fd5b600083013567ffffffffffffffff811115612c6e57600080fd5b612c7a8582860161279a565b925050602083013567ffffffffffffffff811115612c9757600080fd5b612ca38582860161280e565b9150509250929050565b600080600060408486031215612cc257600080fd5b6000612cd086828701612838565b935050602084013567ffffffffffffffff811115612ced57600080fd5b612cf986828701612877565b92509250509250925092565b600060208284031215612d1757600080fd5b6000612d258482850161284d565b91505092915050565b600060208284031215612d4057600080fd5b6000612d4e84828501612862565b91505092915050565b600060208284031215612d6957600080fd5b6000612d7784828501612915565b91505092915050565b60008060008060008060006080888a031215612d9b57600080fd5b6000612da98a828b01612915565b975050602088013567ffffffffffffffff811115612dc657600080fd5b612dd28a828b01612750565b9650965050604088013567ffffffffffffffff811115612df157600080fd5b612dfd8a828b016127c4565b9450945050606088013567ffffffffffffffff811115612e1c57600080fd5b612e288a828b01612877565b925092505092959891949750929550565b600080600080600060608688031215612e5157600080fd5b6000612e5f88828901612915565b955050602086013567ffffffffffffffff811115612e7c57600080fd5b612e8888828901612750565b9450945050604086013567ffffffffffffffff811115612ea757600080fd5b612eb388828901612877565b92509250509295509295909350565b60008060008060008060808789031215612edb57600080fd5b6000612ee989828a01612915565b965050602087013567ffffffffffffffff811115612f0657600080fd5b612f1289828a01612750565b9550955050604087013567ffffffffffffffff811115612f3157600080fd5b612f3d89828a01612877565b9350935050606087013567ffffffffffffffff811115612f5c57600080fd5b612f6889828a016128eb565b9150509295509295509295565b600080600060608486031215612f8a57600080fd5b6000612f9886828701612915565b9350506020612fa986828701612915565b925050604084013567ffffffffffffffff811115612fc657600080fd5b612fd2868287016128eb565b9150509250925092565b6000612fe88383613362565b60208301905092915050565b612ffd81613921565b82525050565b600061300e8261386a565b6130188185613898565b93506130238361385a565b8060005b8381101561305457815161303b8882612fdc565b97506130468361388b565b925050600181019050613027565b5085935050505092915050565b61306a81613933565b82525050565b600061307c83856138a9565b9350613089838584613995565b61309283613b32565b840190509392505050565b60006130a882613875565b6130b281856138a9565b93506130c28185602086016139a4565b6130cb81613b32565b840191505092915050565b60006130e182613880565b6130eb81856138ba565b93506130fb8185602086016139a4565b61310481613b32565b840191505092915050565b600061311c6034836138ba565b915061312782613b50565b604082019050919050565b600061313f6028836138ba565b915061314a82613b9f565b604082019050919050565b6000613162602b836138ba565b915061316d82613bee565b604082019050919050565b60006131856024836138ba565b915061319082613c3d565b604082019050919050565b60006131a86036836138ba565b91506131b382613c8c565b604082019050919050565b60006131cb6029836138ba565b91506131d682613cdb565b604082019050919050565b60006131ee603f836138ba565b91506131f982613d2a565b604082019050919050565b6000613211603b836138ba565b915061321c82613d79565b604082019050919050565b60006132346025836138ba565b915061323f82613dc8565b604082019050919050565b60006132576032836138ba565b915061326282613e17565b604082019050919050565b600061327a6034836138ba565b915061328582613e66565b604082019050919050565b600061329d6023836138ba565b91506132a882613eb5565b604082019050919050565b60006132c0602a836138ba565b91506132cb82613f04565b604082019050919050565b60006132e36029836138ba565b91506132ee82613f53565b604082019050919050565b60006133066029836138ba565b915061331182613fa2565b604082019050919050565b60006133296028836138ba565b915061333482613ff1565b604082019050919050565b600061334c6021836138ba565b915061335782614040565b604082019050919050565b61336b8161398b565b82525050565b61337a8161398b565b82525050565b60006020820190506133956000830184612ff4565b92915050565b600060a0820190506133b06000830188612ff4565b6133bd6020830187612ff4565b81810360408301526133cf8186613003565b905081810360608301526133e38185613003565b905081810360808301526133f7818461309d565b90509695505050505050565b600060a0820190506134186000830188612ff4565b6134256020830187612ff4565b6134326040830186613371565b61343f6060830185613371565b8181036080830152613451818461309d565b90509695505050505050565b600060208201905081810360008301526134778184613003565b905092915050565b600060408201905081810360008301526134998185613003565b905081810360208301526134ad8184613003565b90509392505050565b60006020820190506134cb6000830184613061565b92915050565b600060208201905081810360008301526134ec818486613070565b90509392505050565b6000602082019050818103600083015261350f81846130d6565b905092915050565b600060208201905081810360008301526135308161310f565b9050919050565b6000602082019050818103600083015261355081613132565b9050919050565b6000602082019050818103600083015261357081613155565b9050919050565b6000602082019050818103600083015261359081613178565b9050919050565b600060208201905081810360008301526135b08161319b565b9050919050565b600060208201905081810360008301526135d0816131be565b9050919050565b600060208201905081810360008301526135f0816131e1565b9050919050565b6000602082019050818103600083015261361081613204565b9050919050565b6000602082019050818103600083015261363081613227565b9050919050565b600060208201905081810360008301526136508161324a565b9050919050565b600060208201905081810360008301526136708161326d565b9050919050565b6000602082019050818103600083015261369081613290565b9050919050565b600060208201905081810360008301526136b0816132b3565b9050919050565b600060208201905081810360008301526136d0816132d6565b9050919050565b600060208201905081810360008301526136f0816132f9565b9050919050565b600060208201905081810360008301526137108161331c565b9050919050565b600060208201905081810360008301526137308161333f565b9050919050565b600060208201905061374c6000830184613371565b92915050565b60006040820190506137676000830185613371565b6137746020830184613371565b9392505050565b6000613785613796565b90506137918282613a09565b919050565b6000604051905090565b600067ffffffffffffffff8211156137bb576137ba613ae1565b5b602082029050602081019050919050565b600067ffffffffffffffff8211156137e7576137e6613ae1565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561381357613812613ae1565b5b61381c82613b32565b9050602081019050919050565b600067ffffffffffffffff82111561384457613843613ae1565b5b61384d82613b32565b9050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b60006138d68261398b565b91506138e18361398b565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561391657613915613a83565b5b828201905092915050565b600061392c8261396b565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156139c25780820151818401526020810190506139a7565b838111156139d1576000848401525b50505050565b600060028204905060018216806139ef57607f821691505b60208210811415613a0357613a02613ab2565b5b50919050565b613a1282613b32565b810181811067ffffffffffffffff82111715613a3157613a30613ae1565b5b80604052505050565b6000613a458261398b565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613a7857613a77613a83565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060033d1115613b2f5760046000803e613b2c600051613b43565b90505b90565b6000601f19601f8301169050919050565b60008160e01c9050919050565b7f455243313135353a207472616e7366657220746f206e6f6e204552433131353560008201527f526563656976657220696d706c656d656e746572000000000000000000000000602082015250565b7f455243313135353a204552433131353552656365697665722072656a6563746560008201527f6420746f6b656e73000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a2062616c616e636520717565727920666f7220746865207a60008201527f65726f2061646472657373000000000000000000000000000000000000000000602082015250565b7f455243313135353a206275726e20616d6f756e7420657863656564732062616c60008201527f616e636500000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135354d6978656446756e6769626c653a2063616c6c65722069732060008201527f6e6f74206f776e6572206e6f7220617070726f76656400000000000000000000602082015250565b7f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260008201527f20617070726f7665640000000000000000000000000000000000000000000000602082015250565b7f455243313135354d6978656446756e6769626c653a20696420646f6573206e6f60008201527f7420726570726573656e742061206e6f6e2d66756e6769626c65207479706500602082015250565b7f455243313135354d6978656446756e6769626c653a20696420646f6573206e6f60008201527f7420726570726573656e7420612066756e6769626c6520747970650000000000602082015250565b7f455243313135353a207472616e7366657220746f20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a207472616e736665722063616c6c6572206973206e6f742060008201527f6f776e6572206e6f7220617070726f7665640000000000000000000000000000602082015250565b7f455243313135354d6978656446756e6769626c653a20746f20616e6420616d6f60008201527f756e7473206c656e677468206d69736d61746368000000000000000000000000602082015250565b7f455243313135353a206275726e2066726f6d20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a20696e73756666696369656e742062616c616e636520666f60008201527f72207472616e7366657200000000000000000000000000000000000000000000602082015250565b7f455243313135353a2073657474696e6720617070726f76616c2073746174757360008201527f20666f722073656c660000000000000000000000000000000000000000000000602082015250565b7f455243313135353a206163636f756e747320616e6420696473206c656e67746860008201527f206d69736d617463680000000000000000000000000000000000000000000000602082015250565b7f455243313135353a2069647320616e6420616d6f756e7473206c656e6774682060008201527f6d69736d61746368000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a206d696e7420746f20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b600060443d101561409f57614122565b6140a7613796565b60043d036004823e80513d602482011167ffffffffffffffff821117156140cf575050614122565b808201805167ffffffffffffffff8111156140ed5750505050614122565b80602083010160043d03850181111561410a575050505050614122565b61411982602001850186613a09565b82955050505050505b90565b61412e81613921565b811461413957600080fd5b50565b61414581613933565b811461415057600080fd5b50565b61415c8161393f565b811461416757600080fd5b50565b6141738161398b565b811461417e57600080fd5b5056fea26469706673582212204fdf750e16aa1fe5ce34d26e3ca05a16726f416ae430ccefe9a917dbb14fb7d864736f6c63430008040033", + "bytecode": "0x60806040523480156200001157600080fd5b506040516200450b3803806200450b8339818101604052810190620000379190620001a8565b8062000049816200006a60201b60201c565b5080600690805190602001906200006292919062000086565b50506200035d565b80600290805190602001906200008292919062000086565b5050565b828054620000949062000282565b90600052602060002090601f016020900481019282620000b8576000855562000104565b82601f10620000d357805160ff191683800117855562000104565b8280016001018555821562000104579182015b8281111562000103578251825591602001919060010190620000e6565b5b50905062000113919062000117565b5090565b5b808211156200013257600081600090555060010162000118565b5090565b60006200014d620001478462000216565b620001ed565b9050828152602081018484840111156200016657600080fd5b620001738482856200024c565b509392505050565b600082601f8301126200018d57600080fd5b81516200019f84826020860162000136565b91505092915050565b600060208284031215620001bb57600080fd5b600082015167ffffffffffffffff811115620001d657600080fd5b620001e4848285016200017b565b91505092915050565b6000620001f96200020c565b9050620002078282620002b8565b919050565b6000604051905090565b600067ffffffffffffffff8211156200023457620002336200031d565b5b6200023f826200034c565b9050602081019050919050565b60005b838110156200026c5780820151818401526020810190506200024f565b838111156200027c576000848401525b50505050565b600060028204905060018216806200029b57607f821691505b60208210811415620002b257620002b1620002ee565b5b50919050565b620002c3826200034c565b810181811067ffffffffffffffff82111715620002e557620002e46200031d565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b61419e806200036d6000396000f3fe608060405234801561001057600080fd5b506004361061010a5760003560e01c806354dbdbf4116100a25780638a94b05f116100715780638a94b05f146102c5578063a22cb465146102e1578063cd53d08e146102fd578063e985e9c51461032d578063f242432a1461035d5761010a565b806354dbdbf41461025357806371cc16561461026f5780637a0101a21461028b5780637e53b65d146102a95761010a565b8063183fb254116100de578063183fb254146101cf5780631cbf311d146101eb5780632eb2c2d6146102075780634e1273f4146102235761010a565b8062fdd58e1461010f57806301ffc9a71461013f57806308d7d4691461016f5780630e89341c1461019f575b600080fd5b61012960048036038101906101249190612b83565b610379565b60405161013691906136aa565b60405180910390f35b61015960048036038101906101549190612d03565b610442565b604051610166919061344d565b60405180910390f35b61018960048036038101906101849190612d55565b6104bc565b60405161019691906136aa565b60405180910390f35b6101b960048036038101906101b49190612d55565b6104d4565b6040516101c69190613468565b60405180910390f35b6101e960048036038101906101e49190612d7e565b610624565b005b61020560048036038101906102009190612b17565b61082d565b005b610221600480360381019061021c919061298d565b61083d565b005b61023d60048036038101906102389190612c3f565b6108de565b60405161024a91906133f4565b60405180910390f35b61026d60048036038101906102689190612e37565b610a8f565b005b61028960048036038101906102849190612cab565b610c79565b005b610293610db2565b6040516102a09190613468565b60405180910390f35b6102c360048036038101906102be9190612ec0565b610e44565b005b6102df60048036038101906102da9190612bbf565b611040565b005b6102fb60048036038101906102f69190612adb565b6110df565b005b61031760048036038101906103129190612d55565b6110f5565b6040516103249190613317565b60405180910390f35b61034760048036038101906103429190612951565b611128565b604051610354919061344d565b60405180910390f35b61037760048036038101906103729190612a4c565b6111bc565b005b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156103ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e1906134ca565b60405180910390fd5b60008083815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60007fa1d87d57000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806104b557506104b48261125d565b5b9050919050565b60056020528060005260406000206000915090505481565b606060006007600084815260200190815260200160002080546104f6906139be565b80601f0160208091040260200160405190810160405280929190818152602001828054610522906139be565b801561056f5780601f106105445761010080835404028352916020019161056f565b820191906000526020600020905b81548152906001019060200180831161055257829003601f168201915b5050505050905060008190506000815114156106195760068054610592906139be565b80601f01602080910402602001604051908101604052809291908181526020018280546105be906139be565b801561060b5780601f106105e05761010080835404028352916020019161060b565b820191906000526020600020905b8154815290600101906020018083116105ee57829003601f168201915b50505050509250505061061f565b81925050505b919050565b8661062d61133f565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461069757600080fd5b6106a088611347565b6106df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106d69061356a565b60405180910390fd5b848490508787905014610727576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161071e906135ca565b60405180910390fd5b60005b8787905081101561082257610811888883818110610771577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020160208101906107869190612928565b8a8888858181106107c0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002013587878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611375565b8061081b90613a21565b905061072a565b505050505050505050565b61083784846110df565b50505050565b61084561133f565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16148061088b575061088a8561088561133f565b611128565b5b6108ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c1906135aa565b60405180910390fd5b6108d78585858585611526565b5050505050565b60608151835114610924576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091b9061364a565b60405180910390fd5b6000835167ffffffffffffffff811115610967577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156109955781602001602082028036833780820191505090505b50905060005b8451811015610a8457610a2e8582815181106109e0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151858381518110610a21577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151610379565b828281518110610a67577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101818152505080610a7d90613a21565b905061099b565b508091505092915050565b84610a9861133f565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b0257600080fd5b610b0b86611894565b610b4a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b419061354a565b60405180910390fd5b600060016005600089815260200190815260200160002054610b6c919061387e565b9050610b8e86869050600560008a8152602001908152602001600020546118c2565b600560008981526020019081526020016000208190555060005b86869050811015610c6f57610c5e878783818110610bef577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002016020810190610c049190612928565b8284610c10919061387e565b8a17600188888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611375565b80610c6890613a21565b9050610ba8565b5050505050505050565b60006080600360008154610c8c90613a21565b919050819055901b905083610cc1577f8000000000000000000000000000000000000000000000000000000000000000811790505b610cc961133f565b6004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550831515610d2561133f565b73ffffffffffffffffffffffffffffffffffffffff167fd0748cc91b663bc13cd651f6a34070388ee003d0ff74a90667a27b822099dd988387610d9057600170010000000000000000000000000000000086610d81919061387e565b610d8b91906138d4565b610d92565b845b8787604051610da494939291906136ee565b60405180910390a350505050565b606060068054610dc1906139be565b80601f0160208091040260200160405190810160405280929190818152602001828054610ded906139be565b8015610e3a5780601f10610e0f57610100808354040283529160200191610e3a565b820191906000526020600020905b815481529060010190602001808311610e1d57829003601f168201915b5050505050905090565b85610e4d61133f565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610eb757600080fd5b610ec087611894565b610eff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ef69061354a565b60405180910390fd5b60006001600560008a815260200190815260200160002054610f21919061387e565b9050610f4387879050600560008b8152602001908152602001600020546118c2565b600560008a81526020019081526020016000208190555060005b878790508110156110355760008183610f76919061387e565b8a179050611018898984818110610fb6577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002016020810190610fcb9190612928565b8260018a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611375565b6110238a82876118d8565b508061102e90613a21565b9050610f5d565b505050505050505050565b61104861133f565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16148061108e575061108d8561108861133f565b611128565b5b6110cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110c49061350a565b60405180910390fd5b6110d88585856119c1565b5050505050565b6110f16110ea61133f565b8383611c08565b5050565b60046020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6111c461133f565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16148061120a57506112098561120461133f565b611128565b5b611249576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112409061352a565b60405180910390fd5b6112568585858585611d75565b5050505050565b60007fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061132857507f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611338575061133782612011565b5b9050919050565b600033905090565b6000807f80000000000000000000000000000000000000000000000000000000000000008316149050919050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156113e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113dc9061368a565b60405180910390fd5b60006113ef61133f565b905060006113fc8561207b565b905060006114098561207b565b905061141a83600089858589612141565b8460008088815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611479919061387e565b925050819055508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6289896040516114f79291906136c5565b60405180910390a461150e83600089858589612149565b61151d83600089898989612151565b50505050505050565b815183511461156a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115619061366a565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156115da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115d19061358a565b60405180910390fd5b60006115e461133f565b90506115f4818787878787612141565b60005b84518110156117f157600085828151811061163b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015190506000858381518110611680577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101519050600080600084815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611721576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117189061360a565b60405180910390fd5b81810360008085815260200190815260200160002060008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508160008085815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546117d6919061387e565b92505081905550505050806117ea90613a21565b90506115f7565b508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051611868929190613416565b60405180910390a461187e818787878787612149565b61188c818787878787612338565b505050505050565b60007f8000000000000000000000000000000000000000000000000000000000000000808316149050919050565b600081836118d0919061387e565b905092915050565b826118e161133f565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461194b57600080fd5b61195484611894565b611993576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161198a9061354a565b60405180910390fd5b816007600085815260200190815260200160002090805190602001906119ba929190612542565b5050505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611a31576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a28906135ea565b60405180910390fd5b6000611a3b61133f565b90506000611a488461207b565b90506000611a558461207b565b9050611a7583876000858560405180602001604052806000815250612141565b600080600087815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905084811015611b0c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b03906134ea565b60405180910390fd5b84810360008088815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628989604051611bd99291906136c5565b60405180910390a4611bff84886000868660405180602001604052806000815250612149565b50505050505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611c77576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c6e9061362a565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611d68919061344d565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611de5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ddc9061358a565b60405180910390fd5b6000611def61133f565b90506000611dfc8561207b565b90506000611e098561207b565b9050611e19838989858589612141565b600080600088815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905085811015611eb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ea79061360a565b60405180910390fd5b85810360008089815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508560008089815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f65919061387e565b925050819055508773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628a8a604051611fe29291906136c5565b60405180910390a4611ff8848a8a86868a612149565b612006848a8a8a8a8a612151565b505050505050505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60606000600167ffffffffffffffff8111156120c0577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156120ee5781602001602082028036833780820191505090505b509050828160008151811061212c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101818152505080915050919050565b505050505050565b505050505050565b6121708473ffffffffffffffffffffffffffffffffffffffff1661251f565b15612330578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b81526004016121b695949392919061339a565b602060405180830381600087803b1580156121d057600080fd5b505af192505050801561220157506040513d601f19601f820116820180604052508101906121fe9190612d2c565b60015b6122a75761220d613af7565b806308c379a0141561226a5750612222614076565b8061222d575061226c565b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122619190613468565b60405180910390fd5b505b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161229e9061348a565b60405180910390fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461232e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612325906134aa565b60405180910390fd5b505b505050505050565b6123578473ffffffffffffffffffffffffffffffffffffffff1661251f565b15612517578373ffffffffffffffffffffffffffffffffffffffff1663bc197c8187878686866040518663ffffffff1660e01b815260040161239d959493929190613332565b602060405180830381600087803b1580156123b757600080fd5b505af19250505080156123e857506040513d601f19601f820116820180604052508101906123e59190612d2c565b60015b61248e576123f4613af7565b806308c379a014156124515750612409614076565b806124145750612453565b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124489190613468565b60405180910390fd5b505b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124859061348a565b60405180910390fd5b63bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612515576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161250c906134aa565b60405180910390fd5b505b505050505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b82805461254e906139be565b90600052602060002090601f01602090048101928261257057600085556125b7565b82601f1061258957805160ff19168380011785556125b7565b828001600101855582156125b7579182015b828111156125b657825182559160200191906001019061259b565b5b5090506125c491906125c8565b5090565b5b808211156125e15760008160009055506001016125c9565b5090565b60006125f86125f384613753565b61372e565b9050808382526020820190508285602086028201111561261757600080fd5b60005b85811015612647578161262d8882612739565b84526020840193506020830192505060018101905061261a565b5050509392505050565b600061266461265f8461377f565b61372e565b9050808382526020820190508285602086028201111561268357600080fd5b60005b858110156126b357816126998882612913565b845260208401935060208301925050600181019050612686565b5050509392505050565b60006126d06126cb846137ab565b61372e565b9050828152602081018484840111156126e857600080fd5b6126f384828561397c565b509392505050565b600061270e612709846137dc565b61372e565b90508281526020810184848401111561272657600080fd5b61273184828561397c565b509392505050565b6000813590506127488161410c565b92915050565b60008083601f84011261276057600080fd5b8235905067ffffffffffffffff81111561277957600080fd5b60208301915083602082028301111561279157600080fd5b9250929050565b600082601f8301126127a957600080fd5b81356127b98482602086016125e5565b91505092915050565b60008083601f8401126127d457600080fd5b8235905067ffffffffffffffff8111156127ed57600080fd5b60208301915083602082028301111561280557600080fd5b9250929050565b600082601f83011261281d57600080fd5b813561282d848260208601612651565b91505092915050565b60008135905061284581614123565b92915050565b60008135905061285a8161413a565b92915050565b60008151905061286f8161413a565b92915050565b60008083601f84011261288757600080fd5b8235905067ffffffffffffffff8111156128a057600080fd5b6020830191508360018202830111156128b857600080fd5b9250929050565b600082601f8301126128d057600080fd5b81356128e08482602086016126bd565b91505092915050565b600082601f8301126128fa57600080fd5b813561290a8482602086016126fb565b91505092915050565b60008135905061292281614151565b92915050565b60006020828403121561293a57600080fd5b600061294884828501612739565b91505092915050565b6000806040838503121561296457600080fd5b600061297285828601612739565b925050602061298385828601612739565b9150509250929050565b600080600080600060a086880312156129a557600080fd5b60006129b388828901612739565b95505060206129c488828901612739565b945050604086013567ffffffffffffffff8111156129e157600080fd5b6129ed8882890161280c565b935050606086013567ffffffffffffffff811115612a0a57600080fd5b612a168882890161280c565b925050608086013567ffffffffffffffff811115612a3357600080fd5b612a3f888289016128bf565b9150509295509295909350565b600080600080600060a08688031215612a6457600080fd5b6000612a7288828901612739565b9550506020612a8388828901612739565b9450506040612a9488828901612913565b9350506060612aa588828901612913565b925050608086013567ffffffffffffffff811115612ac257600080fd5b612ace888289016128bf565b9150509295509295909350565b60008060408385031215612aee57600080fd5b6000612afc85828601612739565b9250506020612b0d85828601612836565b9150509250929050565b60008060008060608587031215612b2d57600080fd5b6000612b3b87828801612739565b9450506020612b4c87828801612836565b935050604085013567ffffffffffffffff811115612b6957600080fd5b612b7587828801612875565b925092505092959194509250565b60008060408385031215612b9657600080fd5b6000612ba485828601612739565b9250506020612bb585828601612913565b9150509250929050565b600080600080600060808688031215612bd757600080fd5b6000612be588828901612739565b9550506020612bf688828901612913565b9450506040612c0788828901612913565b935050606086013567ffffffffffffffff811115612c2457600080fd5b612c3088828901612875565b92509250509295509295909350565b60008060408385031215612c5257600080fd5b600083013567ffffffffffffffff811115612c6c57600080fd5b612c7885828601612798565b925050602083013567ffffffffffffffff811115612c9557600080fd5b612ca18582860161280c565b9150509250929050565b600080600060408486031215612cc057600080fd5b6000612cce86828701612836565b935050602084013567ffffffffffffffff811115612ceb57600080fd5b612cf786828701612875565b92509250509250925092565b600060208284031215612d1557600080fd5b6000612d238482850161284b565b91505092915050565b600060208284031215612d3e57600080fd5b6000612d4c84828501612860565b91505092915050565b600060208284031215612d6757600080fd5b6000612d7584828501612913565b91505092915050565b60008060008060008060006080888a031215612d9957600080fd5b6000612da78a828b01612913565b975050602088013567ffffffffffffffff811115612dc457600080fd5b612dd08a828b0161274e565b9650965050604088013567ffffffffffffffff811115612def57600080fd5b612dfb8a828b016127c2565b9450945050606088013567ffffffffffffffff811115612e1a57600080fd5b612e268a828b01612875565b925092505092959891949750929550565b600080600080600060608688031215612e4f57600080fd5b6000612e5d88828901612913565b955050602086013567ffffffffffffffff811115612e7a57600080fd5b612e868882890161274e565b9450945050604086013567ffffffffffffffff811115612ea557600080fd5b612eb188828901612875565b92509250509295509295909350565b60008060008060008060808789031215612ed957600080fd5b6000612ee789828a01612913565b965050602087013567ffffffffffffffff811115612f0457600080fd5b612f1089828a0161274e565b9550955050604087013567ffffffffffffffff811115612f2f57600080fd5b612f3b89828a01612875565b9350935050606087013567ffffffffffffffff811115612f5a57600080fd5b612f6689828a016128e9565b9150509295509295509295565b6000612f7f83836132f9565b60208301905092915050565b612f9481613908565b82525050565b6000612fa58261381d565b612faf818561384b565b9350612fba8361380d565b8060005b83811015612feb578151612fd28882612f73565b9750612fdd8361383e565b925050600181019050612fbe565b5085935050505092915050565b6130018161391a565b82525050565b6000613013838561385c565b935061302083858461397c565b61302983613b19565b840190509392505050565b600061303f82613828565b613049818561385c565b935061305981856020860161398b565b61306281613b19565b840191505092915050565b600061307882613833565b613082818561386d565b935061309281856020860161398b565b61309b81613b19565b840191505092915050565b60006130b360348361386d565b91506130be82613b37565b604082019050919050565b60006130d660288361386d565b91506130e182613b86565b604082019050919050565b60006130f9602b8361386d565b915061310482613bd5565b604082019050919050565b600061311c60248361386d565b915061312782613c24565b604082019050919050565b600061313f60368361386d565b915061314a82613c73565b604082019050919050565b600061316260298361386d565b915061316d82613cc2565b604082019050919050565b6000613185603f8361386d565b915061319082613d11565b604082019050919050565b60006131a8603b8361386d565b91506131b382613d60565b604082019050919050565b60006131cb60258361386d565b91506131d682613daf565b604082019050919050565b60006131ee60328361386d565b91506131f982613dfe565b604082019050919050565b600061321160348361386d565b915061321c82613e4d565b604082019050919050565b600061323460238361386d565b915061323f82613e9c565b604082019050919050565b6000613257602a8361386d565b915061326282613eeb565b604082019050919050565b600061327a60298361386d565b915061328582613f3a565b604082019050919050565b600061329d60298361386d565b91506132a882613f89565b604082019050919050565b60006132c060288361386d565b91506132cb82613fd8565b604082019050919050565b60006132e360218361386d565b91506132ee82614027565b604082019050919050565b61330281613972565b82525050565b61331181613972565b82525050565b600060208201905061332c6000830184612f8b565b92915050565b600060a0820190506133476000830188612f8b565b6133546020830187612f8b565b81810360408301526133668186612f9a565b9050818103606083015261337a8185612f9a565b9050818103608083015261338e8184613034565b90509695505050505050565b600060a0820190506133af6000830188612f8b565b6133bc6020830187612f8b565b6133c96040830186613308565b6133d66060830185613308565b81810360808301526133e88184613034565b90509695505050505050565b6000602082019050818103600083015261340e8184612f9a565b905092915050565b600060408201905081810360008301526134308185612f9a565b905081810360208301526134448184612f9a565b90509392505050565b60006020820190506134626000830184612ff8565b92915050565b60006020820190508181036000830152613482818461306d565b905092915050565b600060208201905081810360008301526134a3816130a6565b9050919050565b600060208201905081810360008301526134c3816130c9565b9050919050565b600060208201905081810360008301526134e3816130ec565b9050919050565b600060208201905081810360008301526135038161310f565b9050919050565b6000602082019050818103600083015261352381613132565b9050919050565b6000602082019050818103600083015261354381613155565b9050919050565b6000602082019050818103600083015261356381613178565b9050919050565b600060208201905081810360008301526135838161319b565b9050919050565b600060208201905081810360008301526135a3816131be565b9050919050565b600060208201905081810360008301526135c3816131e1565b9050919050565b600060208201905081810360008301526135e381613204565b9050919050565b6000602082019050818103600083015261360381613227565b9050919050565b600060208201905081810360008301526136238161324a565b9050919050565b600060208201905081810360008301526136438161326d565b9050919050565b6000602082019050818103600083015261366381613290565b9050919050565b60006020820190508181036000830152613683816132b3565b9050919050565b600060208201905081810360008301526136a3816132d6565b9050919050565b60006020820190506136bf6000830184613308565b92915050565b60006040820190506136da6000830185613308565b6136e76020830184613308565b9392505050565b60006060820190506137036000830187613308565b6137106020830186613308565b8181036040830152613723818486613007565b905095945050505050565b6000613738613749565b905061374482826139f0565b919050565b6000604051905090565b600067ffffffffffffffff82111561376e5761376d613ac8565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561379a57613799613ac8565b5b602082029050602081019050919050565b600067ffffffffffffffff8211156137c6576137c5613ac8565b5b6137cf82613b19565b9050602081019050919050565b600067ffffffffffffffff8211156137f7576137f6613ac8565b5b61380082613b19565b9050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600061388982613972565b915061389483613972565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156138c9576138c8613a6a565b5b828201905092915050565b60006138df82613972565b91506138ea83613972565b9250828210156138fd576138fc613a6a565b5b828203905092915050565b600061391382613952565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156139a957808201518184015260208101905061398e565b838111156139b8576000848401525b50505050565b600060028204905060018216806139d657607f821691505b602082108114156139ea576139e9613a99565b5b50919050565b6139f982613b19565b810181811067ffffffffffffffff82111715613a1857613a17613ac8565b5b80604052505050565b6000613a2c82613972565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613a5f57613a5e613a6a565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060033d1115613b165760046000803e613b13600051613b2a565b90505b90565b6000601f19601f8301169050919050565b60008160e01c9050919050565b7f455243313135353a207472616e7366657220746f206e6f6e204552433131353560008201527f526563656976657220696d706c656d656e746572000000000000000000000000602082015250565b7f455243313135353a204552433131353552656365697665722072656a6563746560008201527f6420746f6b656e73000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a2062616c616e636520717565727920666f7220746865207a60008201527f65726f2061646472657373000000000000000000000000000000000000000000602082015250565b7f455243313135353a206275726e20616d6f756e7420657863656564732062616c60008201527f616e636500000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135354d6978656446756e6769626c653a2063616c6c65722069732060008201527f6e6f74206f776e6572206e6f7220617070726f76656400000000000000000000602082015250565b7f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260008201527f20617070726f7665640000000000000000000000000000000000000000000000602082015250565b7f455243313135354d6978656446756e6769626c653a20696420646f6573206e6f60008201527f7420726570726573656e742061206e6f6e2d66756e6769626c65207479706500602082015250565b7f455243313135354d6978656446756e6769626c653a20696420646f6573206e6f60008201527f7420726570726573656e7420612066756e6769626c6520747970650000000000602082015250565b7f455243313135353a207472616e7366657220746f20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a207472616e736665722063616c6c6572206973206e6f742060008201527f6f776e6572206e6f7220617070726f7665640000000000000000000000000000602082015250565b7f455243313135354d6978656446756e6769626c653a20746f20616e6420616d6f60008201527f756e7473206c656e677468206d69736d61746368000000000000000000000000602082015250565b7f455243313135353a206275726e2066726f6d20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a20696e73756666696369656e742062616c616e636520666f60008201527f72207472616e7366657200000000000000000000000000000000000000000000602082015250565b7f455243313135353a2073657474696e6720617070726f76616c2073746174757360008201527f20666f722073656c660000000000000000000000000000000000000000000000602082015250565b7f455243313135353a206163636f756e747320616e6420696473206c656e67746860008201527f206d69736d617463680000000000000000000000000000000000000000000000602082015250565b7f455243313135353a2069647320616e6420616d6f756e7473206c656e6774682060008201527f6d69736d61746368000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a206d696e7420746f20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b600060443d101561408657614109565b61408e613749565b60043d036004823e80513d602482011167ffffffffffffffff821117156140b6575050614109565b808201805167ffffffffffffffff8111156140d45750505050614109565b80602083010160043d0385018111156140f1575050505050614109565b614100826020018501866139f0565b82955050505050505b90565b61411581613908565b811461412057600080fd5b50565b61412c8161391a565b811461413757600080fd5b50565b61414381613926565b811461414e57600080fd5b50565b61415a81613972565b811461416557600080fd5b5056fea2646970667358221220fce8174728c283762219478dabb7edaeac24b4cd08a28a0c3a22f454fadf0bb864736f6c63430008040033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061010a5760003560e01c806354dbdbf4116100a25780638a94b05f116100715780638a94b05f146102c5578063a22cb465146102e1578063cd53d08e146102fd578063e985e9c51461032d578063f242432a1461035d5761010a565b806354dbdbf41461025357806371cc16561461026f5780637a0101a21461028b5780637e53b65d146102a95761010a565b8063183fb254116100de578063183fb254146101cf5780631cbf311d146101eb5780632eb2c2d6146102075780634e1273f4146102235761010a565b8062fdd58e1461010f57806301ffc9a71461013f57806308d7d4691461016f5780630e89341c1461019f575b600080fd5b61012960048036038101906101249190612b83565b610379565b60405161013691906136aa565b60405180910390f35b61015960048036038101906101549190612d03565b610442565b604051610166919061344d565b60405180910390f35b61018960048036038101906101849190612d55565b6104bc565b60405161019691906136aa565b60405180910390f35b6101b960048036038101906101b49190612d55565b6104d4565b6040516101c69190613468565b60405180910390f35b6101e960048036038101906101e49190612d7e565b610624565b005b61020560048036038101906102009190612b17565b61082d565b005b610221600480360381019061021c919061298d565b61083d565b005b61023d60048036038101906102389190612c3f565b6108de565b60405161024a91906133f4565b60405180910390f35b61026d60048036038101906102689190612e37565b610a8f565b005b61028960048036038101906102849190612cab565b610c79565b005b610293610db2565b6040516102a09190613468565b60405180910390f35b6102c360048036038101906102be9190612ec0565b610e44565b005b6102df60048036038101906102da9190612bbf565b611040565b005b6102fb60048036038101906102f69190612adb565b6110df565b005b61031760048036038101906103129190612d55565b6110f5565b6040516103249190613317565b60405180910390f35b61034760048036038101906103429190612951565b611128565b604051610354919061344d565b60405180910390f35b61037760048036038101906103729190612a4c565b6111bc565b005b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156103ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e1906134ca565b60405180910390fd5b60008083815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60007fa1d87d57000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806104b557506104b48261125d565b5b9050919050565b60056020528060005260406000206000915090505481565b606060006007600084815260200190815260200160002080546104f6906139be565b80601f0160208091040260200160405190810160405280929190818152602001828054610522906139be565b801561056f5780601f106105445761010080835404028352916020019161056f565b820191906000526020600020905b81548152906001019060200180831161055257829003601f168201915b5050505050905060008190506000815114156106195760068054610592906139be565b80601f01602080910402602001604051908101604052809291908181526020018280546105be906139be565b801561060b5780601f106105e05761010080835404028352916020019161060b565b820191906000526020600020905b8154815290600101906020018083116105ee57829003601f168201915b50505050509250505061061f565b81925050505b919050565b8661062d61133f565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461069757600080fd5b6106a088611347565b6106df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106d69061356a565b60405180910390fd5b848490508787905014610727576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161071e906135ca565b60405180910390fd5b60005b8787905081101561082257610811888883818110610771577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020160208101906107869190612928565b8a8888858181106107c0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002013587878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611375565b8061081b90613a21565b905061072a565b505050505050505050565b61083784846110df565b50505050565b61084561133f565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16148061088b575061088a8561088561133f565b611128565b5b6108ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c1906135aa565b60405180910390fd5b6108d78585858585611526565b5050505050565b60608151835114610924576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091b9061364a565b60405180910390fd5b6000835167ffffffffffffffff811115610967577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156109955781602001602082028036833780820191505090505b50905060005b8451811015610a8457610a2e8582815181106109e0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151858381518110610a21577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151610379565b828281518110610a67577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101818152505080610a7d90613a21565b905061099b565b508091505092915050565b84610a9861133f565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b0257600080fd5b610b0b86611894565b610b4a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b419061354a565b60405180910390fd5b600060016005600089815260200190815260200160002054610b6c919061387e565b9050610b8e86869050600560008a8152602001908152602001600020546118c2565b600560008981526020019081526020016000208190555060005b86869050811015610c6f57610c5e878783818110610bef577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002016020810190610c049190612928565b8284610c10919061387e565b8a17600188888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611375565b80610c6890613a21565b9050610ba8565b5050505050505050565b60006080600360008154610c8c90613a21565b919050819055901b905083610cc1577f8000000000000000000000000000000000000000000000000000000000000000811790505b610cc961133f565b6004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550831515610d2561133f565b73ffffffffffffffffffffffffffffffffffffffff167fd0748cc91b663bc13cd651f6a34070388ee003d0ff74a90667a27b822099dd988387610d9057600170010000000000000000000000000000000086610d81919061387e565b610d8b91906138d4565b610d92565b845b8787604051610da494939291906136ee565b60405180910390a350505050565b606060068054610dc1906139be565b80601f0160208091040260200160405190810160405280929190818152602001828054610ded906139be565b8015610e3a5780601f10610e0f57610100808354040283529160200191610e3a565b820191906000526020600020905b815481529060010190602001808311610e1d57829003601f168201915b5050505050905090565b85610e4d61133f565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610eb757600080fd5b610ec087611894565b610eff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ef69061354a565b60405180910390fd5b60006001600560008a815260200190815260200160002054610f21919061387e565b9050610f4387879050600560008b8152602001908152602001600020546118c2565b600560008a81526020019081526020016000208190555060005b878790508110156110355760008183610f76919061387e565b8a179050611018898984818110610fb6577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002016020810190610fcb9190612928565b8260018a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611375565b6110238a82876118d8565b508061102e90613a21565b9050610f5d565b505050505050505050565b61104861133f565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16148061108e575061108d8561108861133f565b611128565b5b6110cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110c49061350a565b60405180910390fd5b6110d88585856119c1565b5050505050565b6110f16110ea61133f565b8383611c08565b5050565b60046020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6111c461133f565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16148061120a57506112098561120461133f565b611128565b5b611249576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112409061352a565b60405180910390fd5b6112568585858585611d75565b5050505050565b60007fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061132857507f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611338575061133782612011565b5b9050919050565b600033905090565b6000807f80000000000000000000000000000000000000000000000000000000000000008316149050919050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156113e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113dc9061368a565b60405180910390fd5b60006113ef61133f565b905060006113fc8561207b565b905060006114098561207b565b905061141a83600089858589612141565b8460008088815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611479919061387e565b925050819055508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6289896040516114f79291906136c5565b60405180910390a461150e83600089858589612149565b61151d83600089898989612151565b50505050505050565b815183511461156a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115619061366a565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156115da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115d19061358a565b60405180910390fd5b60006115e461133f565b90506115f4818787878787612141565b60005b84518110156117f157600085828151811061163b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015190506000858381518110611680577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101519050600080600084815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611721576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117189061360a565b60405180910390fd5b81810360008085815260200190815260200160002060008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508160008085815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546117d6919061387e565b92505081905550505050806117ea90613a21565b90506115f7565b508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051611868929190613416565b60405180910390a461187e818787878787612149565b61188c818787878787612338565b505050505050565b60007f8000000000000000000000000000000000000000000000000000000000000000808316149050919050565b600081836118d0919061387e565b905092915050565b826118e161133f565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461194b57600080fd5b61195484611894565b611993576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161198a9061354a565b60405180910390fd5b816007600085815260200190815260200160002090805190602001906119ba929190612542565b5050505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611a31576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a28906135ea565b60405180910390fd5b6000611a3b61133f565b90506000611a488461207b565b90506000611a558461207b565b9050611a7583876000858560405180602001604052806000815250612141565b600080600087815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905084811015611b0c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b03906134ea565b60405180910390fd5b84810360008088815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628989604051611bd99291906136c5565b60405180910390a4611bff84886000868660405180602001604052806000815250612149565b50505050505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611c77576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c6e9061362a565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611d68919061344d565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611de5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ddc9061358a565b60405180910390fd5b6000611def61133f565b90506000611dfc8561207b565b90506000611e098561207b565b9050611e19838989858589612141565b600080600088815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905085811015611eb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ea79061360a565b60405180910390fd5b85810360008089815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508560008089815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f65919061387e565b925050819055508773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628a8a604051611fe29291906136c5565b60405180910390a4611ff8848a8a86868a612149565b612006848a8a8a8a8a612151565b505050505050505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60606000600167ffffffffffffffff8111156120c0577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156120ee5781602001602082028036833780820191505090505b509050828160008151811061212c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101818152505080915050919050565b505050505050565b505050505050565b6121708473ffffffffffffffffffffffffffffffffffffffff1661251f565b15612330578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b81526004016121b695949392919061339a565b602060405180830381600087803b1580156121d057600080fd5b505af192505050801561220157506040513d601f19601f820116820180604052508101906121fe9190612d2c565b60015b6122a75761220d613af7565b806308c379a0141561226a5750612222614076565b8061222d575061226c565b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122619190613468565b60405180910390fd5b505b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161229e9061348a565b60405180910390fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461232e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612325906134aa565b60405180910390fd5b505b505050505050565b6123578473ffffffffffffffffffffffffffffffffffffffff1661251f565b15612517578373ffffffffffffffffffffffffffffffffffffffff1663bc197c8187878686866040518663ffffffff1660e01b815260040161239d959493929190613332565b602060405180830381600087803b1580156123b757600080fd5b505af19250505080156123e857506040513d601f19601f820116820180604052508101906123e59190612d2c565b60015b61248e576123f4613af7565b806308c379a014156124515750612409614076565b806124145750612453565b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124489190613468565b60405180910390fd5b505b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124859061348a565b60405180910390fd5b63bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612515576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161250c906134aa565b60405180910390fd5b505b505050505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b82805461254e906139be565b90600052602060002090601f01602090048101928261257057600085556125b7565b82601f1061258957805160ff19168380011785556125b7565b828001600101855582156125b7579182015b828111156125b657825182559160200191906001019061259b565b5b5090506125c491906125c8565b5090565b5b808211156125e15760008160009055506001016125c9565b5090565b60006125f86125f384613753565b61372e565b9050808382526020820190508285602086028201111561261757600080fd5b60005b85811015612647578161262d8882612739565b84526020840193506020830192505060018101905061261a565b5050509392505050565b600061266461265f8461377f565b61372e565b9050808382526020820190508285602086028201111561268357600080fd5b60005b858110156126b357816126998882612913565b845260208401935060208301925050600181019050612686565b5050509392505050565b60006126d06126cb846137ab565b61372e565b9050828152602081018484840111156126e857600080fd5b6126f384828561397c565b509392505050565b600061270e612709846137dc565b61372e565b90508281526020810184848401111561272657600080fd5b61273184828561397c565b509392505050565b6000813590506127488161410c565b92915050565b60008083601f84011261276057600080fd5b8235905067ffffffffffffffff81111561277957600080fd5b60208301915083602082028301111561279157600080fd5b9250929050565b600082601f8301126127a957600080fd5b81356127b98482602086016125e5565b91505092915050565b60008083601f8401126127d457600080fd5b8235905067ffffffffffffffff8111156127ed57600080fd5b60208301915083602082028301111561280557600080fd5b9250929050565b600082601f83011261281d57600080fd5b813561282d848260208601612651565b91505092915050565b60008135905061284581614123565b92915050565b60008135905061285a8161413a565b92915050565b60008151905061286f8161413a565b92915050565b60008083601f84011261288757600080fd5b8235905067ffffffffffffffff8111156128a057600080fd5b6020830191508360018202830111156128b857600080fd5b9250929050565b600082601f8301126128d057600080fd5b81356128e08482602086016126bd565b91505092915050565b600082601f8301126128fa57600080fd5b813561290a8482602086016126fb565b91505092915050565b60008135905061292281614151565b92915050565b60006020828403121561293a57600080fd5b600061294884828501612739565b91505092915050565b6000806040838503121561296457600080fd5b600061297285828601612739565b925050602061298385828601612739565b9150509250929050565b600080600080600060a086880312156129a557600080fd5b60006129b388828901612739565b95505060206129c488828901612739565b945050604086013567ffffffffffffffff8111156129e157600080fd5b6129ed8882890161280c565b935050606086013567ffffffffffffffff811115612a0a57600080fd5b612a168882890161280c565b925050608086013567ffffffffffffffff811115612a3357600080fd5b612a3f888289016128bf565b9150509295509295909350565b600080600080600060a08688031215612a6457600080fd5b6000612a7288828901612739565b9550506020612a8388828901612739565b9450506040612a9488828901612913565b9350506060612aa588828901612913565b925050608086013567ffffffffffffffff811115612ac257600080fd5b612ace888289016128bf565b9150509295509295909350565b60008060408385031215612aee57600080fd5b6000612afc85828601612739565b9250506020612b0d85828601612836565b9150509250929050565b60008060008060608587031215612b2d57600080fd5b6000612b3b87828801612739565b9450506020612b4c87828801612836565b935050604085013567ffffffffffffffff811115612b6957600080fd5b612b7587828801612875565b925092505092959194509250565b60008060408385031215612b9657600080fd5b6000612ba485828601612739565b9250506020612bb585828601612913565b9150509250929050565b600080600080600060808688031215612bd757600080fd5b6000612be588828901612739565b9550506020612bf688828901612913565b9450506040612c0788828901612913565b935050606086013567ffffffffffffffff811115612c2457600080fd5b612c3088828901612875565b92509250509295509295909350565b60008060408385031215612c5257600080fd5b600083013567ffffffffffffffff811115612c6c57600080fd5b612c7885828601612798565b925050602083013567ffffffffffffffff811115612c9557600080fd5b612ca18582860161280c565b9150509250929050565b600080600060408486031215612cc057600080fd5b6000612cce86828701612836565b935050602084013567ffffffffffffffff811115612ceb57600080fd5b612cf786828701612875565b92509250509250925092565b600060208284031215612d1557600080fd5b6000612d238482850161284b565b91505092915050565b600060208284031215612d3e57600080fd5b6000612d4c84828501612860565b91505092915050565b600060208284031215612d6757600080fd5b6000612d7584828501612913565b91505092915050565b60008060008060008060006080888a031215612d9957600080fd5b6000612da78a828b01612913565b975050602088013567ffffffffffffffff811115612dc457600080fd5b612dd08a828b0161274e565b9650965050604088013567ffffffffffffffff811115612def57600080fd5b612dfb8a828b016127c2565b9450945050606088013567ffffffffffffffff811115612e1a57600080fd5b612e268a828b01612875565b925092505092959891949750929550565b600080600080600060608688031215612e4f57600080fd5b6000612e5d88828901612913565b955050602086013567ffffffffffffffff811115612e7a57600080fd5b612e868882890161274e565b9450945050604086013567ffffffffffffffff811115612ea557600080fd5b612eb188828901612875565b92509250509295509295909350565b60008060008060008060808789031215612ed957600080fd5b6000612ee789828a01612913565b965050602087013567ffffffffffffffff811115612f0457600080fd5b612f1089828a0161274e565b9550955050604087013567ffffffffffffffff811115612f2f57600080fd5b612f3b89828a01612875565b9350935050606087013567ffffffffffffffff811115612f5a57600080fd5b612f6689828a016128e9565b9150509295509295509295565b6000612f7f83836132f9565b60208301905092915050565b612f9481613908565b82525050565b6000612fa58261381d565b612faf818561384b565b9350612fba8361380d565b8060005b83811015612feb578151612fd28882612f73565b9750612fdd8361383e565b925050600181019050612fbe565b5085935050505092915050565b6130018161391a565b82525050565b6000613013838561385c565b935061302083858461397c565b61302983613b19565b840190509392505050565b600061303f82613828565b613049818561385c565b935061305981856020860161398b565b61306281613b19565b840191505092915050565b600061307882613833565b613082818561386d565b935061309281856020860161398b565b61309b81613b19565b840191505092915050565b60006130b360348361386d565b91506130be82613b37565b604082019050919050565b60006130d660288361386d565b91506130e182613b86565b604082019050919050565b60006130f9602b8361386d565b915061310482613bd5565b604082019050919050565b600061311c60248361386d565b915061312782613c24565b604082019050919050565b600061313f60368361386d565b915061314a82613c73565b604082019050919050565b600061316260298361386d565b915061316d82613cc2565b604082019050919050565b6000613185603f8361386d565b915061319082613d11565b604082019050919050565b60006131a8603b8361386d565b91506131b382613d60565b604082019050919050565b60006131cb60258361386d565b91506131d682613daf565b604082019050919050565b60006131ee60328361386d565b91506131f982613dfe565b604082019050919050565b600061321160348361386d565b915061321c82613e4d565b604082019050919050565b600061323460238361386d565b915061323f82613e9c565b604082019050919050565b6000613257602a8361386d565b915061326282613eeb565b604082019050919050565b600061327a60298361386d565b915061328582613f3a565b604082019050919050565b600061329d60298361386d565b91506132a882613f89565b604082019050919050565b60006132c060288361386d565b91506132cb82613fd8565b604082019050919050565b60006132e360218361386d565b91506132ee82614027565b604082019050919050565b61330281613972565b82525050565b61331181613972565b82525050565b600060208201905061332c6000830184612f8b565b92915050565b600060a0820190506133476000830188612f8b565b6133546020830187612f8b565b81810360408301526133668186612f9a565b9050818103606083015261337a8185612f9a565b9050818103608083015261338e8184613034565b90509695505050505050565b600060a0820190506133af6000830188612f8b565b6133bc6020830187612f8b565b6133c96040830186613308565b6133d66060830185613308565b81810360808301526133e88184613034565b90509695505050505050565b6000602082019050818103600083015261340e8184612f9a565b905092915050565b600060408201905081810360008301526134308185612f9a565b905081810360208301526134448184612f9a565b90509392505050565b60006020820190506134626000830184612ff8565b92915050565b60006020820190508181036000830152613482818461306d565b905092915050565b600060208201905081810360008301526134a3816130a6565b9050919050565b600060208201905081810360008301526134c3816130c9565b9050919050565b600060208201905081810360008301526134e3816130ec565b9050919050565b600060208201905081810360008301526135038161310f565b9050919050565b6000602082019050818103600083015261352381613132565b9050919050565b6000602082019050818103600083015261354381613155565b9050919050565b6000602082019050818103600083015261356381613178565b9050919050565b600060208201905081810360008301526135838161319b565b9050919050565b600060208201905081810360008301526135a3816131be565b9050919050565b600060208201905081810360008301526135c3816131e1565b9050919050565b600060208201905081810360008301526135e381613204565b9050919050565b6000602082019050818103600083015261360381613227565b9050919050565b600060208201905081810360008301526136238161324a565b9050919050565b600060208201905081810360008301526136438161326d565b9050919050565b6000602082019050818103600083015261366381613290565b9050919050565b60006020820190508181036000830152613683816132b3565b9050919050565b600060208201905081810360008301526136a3816132d6565b9050919050565b60006020820190506136bf6000830184613308565b92915050565b60006040820190506136da6000830185613308565b6136e76020830184613308565b9392505050565b60006060820190506137036000830187613308565b6137106020830186613308565b8181036040830152613723818486613007565b905095945050505050565b6000613738613749565b905061374482826139f0565b919050565b6000604051905090565b600067ffffffffffffffff82111561376e5761376d613ac8565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561379a57613799613ac8565b5b602082029050602081019050919050565b600067ffffffffffffffff8211156137c6576137c5613ac8565b5b6137cf82613b19565b9050602081019050919050565b600067ffffffffffffffff8211156137f7576137f6613ac8565b5b61380082613b19565b9050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600061388982613972565b915061389483613972565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156138c9576138c8613a6a565b5b828201905092915050565b60006138df82613972565b91506138ea83613972565b9250828210156138fd576138fc613a6a565b5b828203905092915050565b600061391382613952565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156139a957808201518184015260208101905061398e565b838111156139b8576000848401525b50505050565b600060028204905060018216806139d657607f821691505b602082108114156139ea576139e9613a99565b5b50919050565b6139f982613b19565b810181811067ffffffffffffffff82111715613a1857613a17613ac8565b5b80604052505050565b6000613a2c82613972565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613a5f57613a5e613a6a565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060033d1115613b165760046000803e613b13600051613b2a565b90505b90565b6000601f19601f8301169050919050565b60008160e01c9050919050565b7f455243313135353a207472616e7366657220746f206e6f6e204552433131353560008201527f526563656976657220696d706c656d656e746572000000000000000000000000602082015250565b7f455243313135353a204552433131353552656365697665722072656a6563746560008201527f6420746f6b656e73000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a2062616c616e636520717565727920666f7220746865207a60008201527f65726f2061646472657373000000000000000000000000000000000000000000602082015250565b7f455243313135353a206275726e20616d6f756e7420657863656564732062616c60008201527f616e636500000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135354d6978656446756e6769626c653a2063616c6c65722069732060008201527f6e6f74206f776e6572206e6f7220617070726f76656400000000000000000000602082015250565b7f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260008201527f20617070726f7665640000000000000000000000000000000000000000000000602082015250565b7f455243313135354d6978656446756e6769626c653a20696420646f6573206e6f60008201527f7420726570726573656e742061206e6f6e2d66756e6769626c65207479706500602082015250565b7f455243313135354d6978656446756e6769626c653a20696420646f6573206e6f60008201527f7420726570726573656e7420612066756e6769626c6520747970650000000000602082015250565b7f455243313135353a207472616e7366657220746f20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a207472616e736665722063616c6c6572206973206e6f742060008201527f6f776e6572206e6f7220617070726f7665640000000000000000000000000000602082015250565b7f455243313135354d6978656446756e6769626c653a20746f20616e6420616d6f60008201527f756e7473206c656e677468206d69736d61746368000000000000000000000000602082015250565b7f455243313135353a206275726e2066726f6d20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a20696e73756666696369656e742062616c616e636520666f60008201527f72207472616e7366657200000000000000000000000000000000000000000000602082015250565b7f455243313135353a2073657474696e6720617070726f76616c2073746174757360008201527f20666f722073656c660000000000000000000000000000000000000000000000602082015250565b7f455243313135353a206163636f756e747320616e6420696473206c656e67746860008201527f206d69736d617463680000000000000000000000000000000000000000000000602082015250565b7f455243313135353a2069647320616e6420616d6f756e7473206c656e6774682060008201527f6d69736d61746368000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a206d696e7420746f20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b600060443d101561408657614109565b61408e613749565b60043d036004823e80513d602482011167ffffffffffffffff821117156140b6575050614109565b808201805167ffffffffffffffff8111156140d45750505050614109565b80602083010160043d0385018111156140f1575050505050614109565b614100826020018501866139f0565b82955050505050505b90565b61411581613908565b811461412057600080fd5b50565b61412c8161391a565b811461413757600080fd5b50565b61414381613926565b811461414e57600080fd5b50565b61415a81613972565b811461416557600080fd5b5056fea2646970667358221220fce8174728c283762219478dabb7edaeac24b4cd08a28a0c3a22f454fadf0bb864736f6c63430008040033", "linkReferences": {}, "deployedLinkReferences": {} -} \ No newline at end of file +} diff --git a/src/abi/ERC1155MixedFungibleV1.json b/src/abi/ERC1155MixedFungibleV1.json new file mode 100644 index 0000000..4be7284 --- /dev/null +++ b/src/abi/ERC1155MixedFungibleV1.json @@ -0,0 +1,581 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "ERC1155MixedFungible", + "sourceName": "contracts/ERC1155MixedFungible.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "uri", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "type_id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "TokenPoolCreation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + } + ], + "name": "TransferBatch", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "TransferSingle", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "value", + "type": "string" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "URI", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "type_id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "string", + "name": "_uri", + "type": "string" + } + ], + "name": "_setNonFungibleURI", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "accounts", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + } + ], + "name": "balanceOfBatch", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "baseTokenUri", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "is_fungible", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "create", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "creators", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "maxIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "type_id", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "to", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "mintFungible", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "type_id", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "to", + "type": "address[]" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "mintNonFungible", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "type_id", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "to", + "type": "address[]" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "string", + "name": "_uri", + "type": "string" + } + ], + "name": "mintNonFungibleWithURI", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeBatchTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "setApprovalForAllWithData", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "uri", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x60806040523480156200001157600080fd5b5060405162004524380380620045248339818101604052810190620000379190620001a8565b8062000049816200006a60201b60201c565b5080600690805190602001906200006292919062000086565b50506200035d565b80600290805190602001906200008292919062000086565b5050565b828054620000949062000282565b90600052602060002090601f016020900481019282620000b8576000855562000104565b82601f10620000d357805160ff191683800117855562000104565b8280016001018555821562000104579182015b8281111562000103578251825591602001919060010190620000e6565b5b50905062000113919062000117565b5090565b5b808211156200013257600081600090555060010162000118565b5090565b60006200014d620001478462000216565b620001ed565b9050828152602081018484840111156200016657600080fd5b620001738482856200024c565b509392505050565b600082601f8301126200018d57600080fd5b81516200019f84826020860162000136565b91505092915050565b600060208284031215620001bb57600080fd5b600082015167ffffffffffffffff811115620001d657600080fd5b620001e4848285016200017b565b91505092915050565b6000620001f96200020c565b9050620002078282620002b8565b919050565b6000604051905090565b600067ffffffffffffffff8211156200023457620002336200031d565b5b6200023f826200034c565b9050602081019050919050565b60005b838110156200026c5780820151818401526020810190506200024f565b838111156200027c576000848401525b50505050565b600060028204905060018216806200029b57607f821691505b60208210811415620002b257620002b1620002ee565b5b50919050565b620002c3826200034c565b810181811067ffffffffffffffff82111715620002e557620002e46200031d565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b6141b7806200036d6000396000f3fe608060405234801561001057600080fd5b50600436106101155760003560e01c806371cc1656116100a2578063a22cb46511610071578063a22cb46514610300578063b944eb291461031c578063cd53d08e14610338578063e985e9c514610368578063f242432a1461039857610115565b806371cc16561461027a5780637a0101a2146102aa5780637e53b65d146102c85780638a94b05f146102e457610115565b8063183fb254116100e9578063183fb254146101da5780631cbf311d146101f65780632eb2c2d6146102125780634e1273f41461022e57806354dbdbf41461025e57610115565b8062fdd58e1461011a57806301ffc9a71461014a57806308d7d4691461017a5780630e89341c146101aa575b600080fd5b610134600480360381019061012f9190612b85565b6103b4565b6040516101419190613737565b60405180910390f35b610164600480360381019061015f9190612d05565b61047d565b60405161017191906134b6565b60405180910390f35b610194600480360381019061018f9190612d57565b6104f7565b6040516101a19190613737565b60405180910390f35b6101c460048036038101906101bf9190612d57565b61050f565b6040516101d191906134f5565b60405180910390f35b6101f460048036038101906101ef9190612d80565b61065f565b005b610210600480360381019061020b9190612b19565b610868565b005b61022c6004803603810190610227919061298f565b610878565b005b61024860048036038101906102439190612c41565b610919565b604051610255919061345d565b60405180910390f35b61027860048036038101906102739190612e39565b610aca565b005b610294600480360381019061028f9190612cad565b610cb4565b6040516102a19190613737565b60405180910390f35b6102b2610db4565b6040516102bf91906134f5565b60405180910390f35b6102e260048036038101906102dd9190612ec2565b610e46565b005b6102fe60048036038101906102f99190612bc1565b611042565b005b61031a60048036038101906103159190612add565b6110e1565b005b61033660048036038101906103319190612f75565b6110f7565b005b610352600480360381019061034d9190612d57565b6111e0565b60405161035f9190613380565b60405180910390f35b610382600480360381019061037d9190612953565b611213565b60405161038f91906134b6565b60405180910390f35b6103b260048036038101906103ad9190612a4e565b6112a7565b005b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610425576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041c90613557565b60405180910390fd5b60008083815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60007fa1d87d57000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806104f057506104ef82611348565b5b9050919050565b60056020528060005260406000206000915090505481565b60606000600760008481526020019081526020016000208054610531906139d7565b80601f016020809104026020016040519081016040528092919081815260200182805461055d906139d7565b80156105aa5780601f1061057f576101008083540402835291602001916105aa565b820191906000526020600020905b81548152906001019060200180831161058d57829003601f168201915b50505050509050600081905060008151141561065457600680546105cd906139d7565b80601f01602080910402602001604051908101604052809291908181526020018280546105f9906139d7565b80156106465780601f1061061b57610100808354040283529160200191610646565b820191906000526020600020905b81548152906001019060200180831161062957829003601f168201915b50505050509250505061065a565b81925050505b919050565b8661066861142a565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146106d257600080fd5b6106db88611432565b61071a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610711906135f7565b60405180910390fd5b848490508787905014610762576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161075990613657565b60405180910390fd5b60005b8787905081101561085d5761084c8888838181106107ac577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020160208101906107c1919061292a565b8a8888858181106107fb577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002013587878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611460565b8061085690613a3a565b9050610765565b505050505050505050565b61087284846110e1565b50505050565b61088061142a565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614806108c657506108c5856108c061142a565b611213565b5b610905576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108fc90613637565b60405180910390fd5b6109128585858585611611565b5050505050565b6060815183511461095f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610956906136d7565b60405180910390fd5b6000835167ffffffffffffffff8111156109a2577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156109d05781602001602082028036833780820191505090505b50905060005b8451811015610abf57610a69858281518110610a1b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151858381518110610a5c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101516103b4565b828281518110610aa2577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101818152505080610ab890613a3a565b90506109d6565b508091505092915050565b84610ad361142a565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b3d57600080fd5b610b468661197f565b610b85576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b7c906135d7565b60405180910390fd5b600060016005600089815260200190815260200160002054610ba791906138cb565b9050610bc986869050600560008a8152602001908152602001600020546119ad565b600560008981526020019081526020016000208190555060005b86869050811015610caa57610c99878783818110610c2a577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002016020810190610c3f919061292a565b8284610c4b91906138cb565b8a17600188888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611460565b80610ca390613a3a565b9050610be3565b5050505050505050565b60006080600360008154610cc790613a3a565b919050819055901b905083610cfc577f8000000000000000000000000000000000000000000000000000000000000000811790505b610d0461142a565b6004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080610d5e61142a565b73ffffffffffffffffffffffffffffffffffffffff167f0d2ce24070e07853454690ae0a0416ddd4845188f8dbfe0ef3a761acb3d2e34e8585604051610da59291906134d1565b60405180910390a39392505050565b606060068054610dc3906139d7565b80601f0160208091040260200160405190810160405280929190818152602001828054610def906139d7565b8015610e3c5780601f10610e1157610100808354040283529160200191610e3c565b820191906000526020600020905b815481529060010190602001808311610e1f57829003601f168201915b5050505050905090565b85610e4f61142a565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610eb957600080fd5b610ec28761197f565b610f01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ef8906135d7565b60405180910390fd5b60006001600560008a815260200190815260200160002054610f2391906138cb565b9050610f4587879050600560008b8152602001908152602001600020546119ad565b600560008a81526020019081526020016000208190555060005b878790508110156110375760008183610f7891906138cb565b8a17905061101a898984818110610fb8577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002016020810190610fcd919061292a565b8260018a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611460565b6110258a82876110f7565b508061103090613a3a565b9050610f5f565b505050505050505050565b61104a61142a565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161480611090575061108f8561108a61142a565b611213565b5b6110cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110c690613597565b60405180910390fd5b6110da8585856119c3565b5050505050565b6110f36110ec61142a565b8383611c0a565b5050565b8261110061142a565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461116a57600080fd5b6111738461197f565b6111b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111a9906135d7565b60405180910390fd5b816007600085815260200190815260200160002090805190602001906111d9929190612544565b5050505050565b60046020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6112af61142a565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614806112f557506112f4856112ef61142a565b611213565b5b611334576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161132b906135b7565b60405180910390fd5b6113418585858585611d77565b5050505050565b60007fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061141357507f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611423575061142282612013565b5b9050919050565b600033905090565b6000807f80000000000000000000000000000000000000000000000000000000000000008316149050919050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156114d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114c790613717565b60405180910390fd5b60006114da61142a565b905060006114e78561207d565b905060006114f48561207d565b905061150583600089858589612143565b8460008088815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461156491906138cb565b925050819055508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6289896040516115e2929190613752565b60405180910390a46115f98360008985858961214b565b61160883600089898989612153565b50505050505050565b8151835114611655576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161164c906136f7565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156116c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116bc90613617565b60405180910390fd5b60006116cf61142a565b90506116df818787878787612143565b60005b84518110156118dc576000858281518110611726577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101519050600085838151811061176b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101519050600080600084815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508181101561180c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161180390613697565b60405180910390fd5b81810360008085815260200190815260200160002060008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508160008085815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546118c191906138cb565b92505081905550505050806118d590613a3a565b90506116e2565b508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb878760405161195392919061347f565b60405180910390a461196981878787878761214b565b61197781878787878761233a565b505050505050565b60007f8000000000000000000000000000000000000000000000000000000000000000808316149050919050565b600081836119bb91906138cb565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611a33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2a90613677565b60405180910390fd5b6000611a3d61142a565b90506000611a4a8461207d565b90506000611a578461207d565b9050611a7783876000858560405180602001604052806000815250612143565b600080600087815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905084811015611b0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b0590613577565b60405180910390fd5b84810360008088815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628989604051611bdb929190613752565b60405180910390a4611c018488600086866040518060200160405280600081525061214b565b50505050505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611c79576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c70906136b7565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611d6a91906134b6565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611de7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dde90613617565b60405180910390fd5b6000611df161142a565b90506000611dfe8561207d565b90506000611e0b8561207d565b9050611e1b838989858589612143565b600080600088815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905085811015611eb2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ea990613697565b60405180910390fd5b85810360008089815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508560008089815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f6791906138cb565b925050819055508773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628a8a604051611fe4929190613752565b60405180910390a4611ffa848a8a86868a61214b565b612008848a8a8a8a8a612153565b505050505050505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60606000600167ffffffffffffffff8111156120c2577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156120f05781602001602082028036833780820191505090505b509050828160008151811061212e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101818152505080915050919050565b505050505050565b505050505050565b6121728473ffffffffffffffffffffffffffffffffffffffff16612521565b15612332578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b81526004016121b8959493929190613403565b602060405180830381600087803b1580156121d257600080fd5b505af192505050801561220357506040513d601f19601f820116820180604052508101906122009190612d2e565b60015b6122a95761220f613b10565b806308c379a0141561226c575061222461408f565b8061222f575061226e565b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161226391906134f5565b60405180910390fd5b505b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122a090613517565b60405180910390fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612330576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161232790613537565b60405180910390fd5b505b505050505050565b6123598473ffffffffffffffffffffffffffffffffffffffff16612521565b15612519578373ffffffffffffffffffffffffffffffffffffffff1663bc197c8187878686866040518663ffffffff1660e01b815260040161239f95949392919061339b565b602060405180830381600087803b1580156123b957600080fd5b505af19250505080156123ea57506040513d601f19601f820116820180604052508101906123e79190612d2e565b60015b612490576123f6613b10565b806308c379a01415612453575061240b61408f565b806124165750612455565b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161244a91906134f5565b60405180910390fd5b505b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161248790613517565b60405180910390fd5b63bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612517576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161250e90613537565b60405180910390fd5b505b505050505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b828054612550906139d7565b90600052602060002090601f01602090048101928261257257600085556125b9565b82601f1061258b57805160ff19168380011785556125b9565b828001600101855582156125b9579182015b828111156125b857825182559160200191906001019061259d565b5b5090506125c691906125ca565b5090565b5b808211156125e35760008160009055506001016125cb565b5090565b60006125fa6125f5846137a0565b61377b565b9050808382526020820190508285602086028201111561261957600080fd5b60005b85811015612649578161262f888261273b565b84526020840193506020830192505060018101905061261c565b5050509392505050565b6000612666612661846137cc565b61377b565b9050808382526020820190508285602086028201111561268557600080fd5b60005b858110156126b5578161269b8882612915565b845260208401935060208301925050600181019050612688565b5050509392505050565b60006126d26126cd846137f8565b61377b565b9050828152602081018484840111156126ea57600080fd5b6126f5848285613995565b509392505050565b600061271061270b84613829565b61377b565b90508281526020810184848401111561272857600080fd5b612733848285613995565b509392505050565b60008135905061274a81614125565b92915050565b60008083601f84011261276257600080fd5b8235905067ffffffffffffffff81111561277b57600080fd5b60208301915083602082028301111561279357600080fd5b9250929050565b600082601f8301126127ab57600080fd5b81356127bb8482602086016125e7565b91505092915050565b60008083601f8401126127d657600080fd5b8235905067ffffffffffffffff8111156127ef57600080fd5b60208301915083602082028301111561280757600080fd5b9250929050565b600082601f83011261281f57600080fd5b813561282f848260208601612653565b91505092915050565b6000813590506128478161413c565b92915050565b60008135905061285c81614153565b92915050565b60008151905061287181614153565b92915050565b60008083601f84011261288957600080fd5b8235905067ffffffffffffffff8111156128a257600080fd5b6020830191508360018202830111156128ba57600080fd5b9250929050565b600082601f8301126128d257600080fd5b81356128e28482602086016126bf565b91505092915050565b600082601f8301126128fc57600080fd5b813561290c8482602086016126fd565b91505092915050565b6000813590506129248161416a565b92915050565b60006020828403121561293c57600080fd5b600061294a8482850161273b565b91505092915050565b6000806040838503121561296657600080fd5b60006129748582860161273b565b92505060206129858582860161273b565b9150509250929050565b600080600080600060a086880312156129a757600080fd5b60006129b58882890161273b565b95505060206129c68882890161273b565b945050604086013567ffffffffffffffff8111156129e357600080fd5b6129ef8882890161280e565b935050606086013567ffffffffffffffff811115612a0c57600080fd5b612a188882890161280e565b925050608086013567ffffffffffffffff811115612a3557600080fd5b612a41888289016128c1565b9150509295509295909350565b600080600080600060a08688031215612a6657600080fd5b6000612a748882890161273b565b9550506020612a858882890161273b565b9450506040612a9688828901612915565b9350506060612aa788828901612915565b925050608086013567ffffffffffffffff811115612ac457600080fd5b612ad0888289016128c1565b9150509295509295909350565b60008060408385031215612af057600080fd5b6000612afe8582860161273b565b9250506020612b0f85828601612838565b9150509250929050565b60008060008060608587031215612b2f57600080fd5b6000612b3d8782880161273b565b9450506020612b4e87828801612838565b935050604085013567ffffffffffffffff811115612b6b57600080fd5b612b7787828801612877565b925092505092959194509250565b60008060408385031215612b9857600080fd5b6000612ba68582860161273b565b9250506020612bb785828601612915565b9150509250929050565b600080600080600060808688031215612bd957600080fd5b6000612be78882890161273b565b9550506020612bf888828901612915565b9450506040612c0988828901612915565b935050606086013567ffffffffffffffff811115612c2657600080fd5b612c3288828901612877565b92509250509295509295909350565b60008060408385031215612c5457600080fd5b600083013567ffffffffffffffff811115612c6e57600080fd5b612c7a8582860161279a565b925050602083013567ffffffffffffffff811115612c9757600080fd5b612ca38582860161280e565b9150509250929050565b600080600060408486031215612cc257600080fd5b6000612cd086828701612838565b935050602084013567ffffffffffffffff811115612ced57600080fd5b612cf986828701612877565b92509250509250925092565b600060208284031215612d1757600080fd5b6000612d258482850161284d565b91505092915050565b600060208284031215612d4057600080fd5b6000612d4e84828501612862565b91505092915050565b600060208284031215612d6957600080fd5b6000612d7784828501612915565b91505092915050565b60008060008060008060006080888a031215612d9b57600080fd5b6000612da98a828b01612915565b975050602088013567ffffffffffffffff811115612dc657600080fd5b612dd28a828b01612750565b9650965050604088013567ffffffffffffffff811115612df157600080fd5b612dfd8a828b016127c4565b9450945050606088013567ffffffffffffffff811115612e1c57600080fd5b612e288a828b01612877565b925092505092959891949750929550565b600080600080600060608688031215612e5157600080fd5b6000612e5f88828901612915565b955050602086013567ffffffffffffffff811115612e7c57600080fd5b612e8888828901612750565b9450945050604086013567ffffffffffffffff811115612ea757600080fd5b612eb388828901612877565b92509250509295509295909350565b60008060008060008060808789031215612edb57600080fd5b6000612ee989828a01612915565b965050602087013567ffffffffffffffff811115612f0657600080fd5b612f1289828a01612750565b9550955050604087013567ffffffffffffffff811115612f3157600080fd5b612f3d89828a01612877565b9350935050606087013567ffffffffffffffff811115612f5c57600080fd5b612f6889828a016128eb565b9150509295509295509295565b600080600060608486031215612f8a57600080fd5b6000612f9886828701612915565b9350506020612fa986828701612915565b925050604084013567ffffffffffffffff811115612fc657600080fd5b612fd2868287016128eb565b9150509250925092565b6000612fe88383613362565b60208301905092915050565b612ffd81613921565b82525050565b600061300e8261386a565b6130188185613898565b93506130238361385a565b8060005b8381101561305457815161303b8882612fdc565b97506130468361388b565b925050600181019050613027565b5085935050505092915050565b61306a81613933565b82525050565b600061307c83856138a9565b9350613089838584613995565b61309283613b32565b840190509392505050565b60006130a882613875565b6130b281856138a9565b93506130c28185602086016139a4565b6130cb81613b32565b840191505092915050565b60006130e182613880565b6130eb81856138ba565b93506130fb8185602086016139a4565b61310481613b32565b840191505092915050565b600061311c6034836138ba565b915061312782613b50565b604082019050919050565b600061313f6028836138ba565b915061314a82613b9f565b604082019050919050565b6000613162602b836138ba565b915061316d82613bee565b604082019050919050565b60006131856024836138ba565b915061319082613c3d565b604082019050919050565b60006131a86036836138ba565b91506131b382613c8c565b604082019050919050565b60006131cb6029836138ba565b91506131d682613cdb565b604082019050919050565b60006131ee603f836138ba565b91506131f982613d2a565b604082019050919050565b6000613211603b836138ba565b915061321c82613d79565b604082019050919050565b60006132346025836138ba565b915061323f82613dc8565b604082019050919050565b60006132576032836138ba565b915061326282613e17565b604082019050919050565b600061327a6034836138ba565b915061328582613e66565b604082019050919050565b600061329d6023836138ba565b91506132a882613eb5565b604082019050919050565b60006132c0602a836138ba565b91506132cb82613f04565b604082019050919050565b60006132e36029836138ba565b91506132ee82613f53565b604082019050919050565b60006133066029836138ba565b915061331182613fa2565b604082019050919050565b60006133296028836138ba565b915061333482613ff1565b604082019050919050565b600061334c6021836138ba565b915061335782614040565b604082019050919050565b61336b8161398b565b82525050565b61337a8161398b565b82525050565b60006020820190506133956000830184612ff4565b92915050565b600060a0820190506133b06000830188612ff4565b6133bd6020830187612ff4565b81810360408301526133cf8186613003565b905081810360608301526133e38185613003565b905081810360808301526133f7818461309d565b90509695505050505050565b600060a0820190506134186000830188612ff4565b6134256020830187612ff4565b6134326040830186613371565b61343f6060830185613371565b8181036080830152613451818461309d565b90509695505050505050565b600060208201905081810360008301526134778184613003565b905092915050565b600060408201905081810360008301526134998185613003565b905081810360208301526134ad8184613003565b90509392505050565b60006020820190506134cb6000830184613061565b92915050565b600060208201905081810360008301526134ec818486613070565b90509392505050565b6000602082019050818103600083015261350f81846130d6565b905092915050565b600060208201905081810360008301526135308161310f565b9050919050565b6000602082019050818103600083015261355081613132565b9050919050565b6000602082019050818103600083015261357081613155565b9050919050565b6000602082019050818103600083015261359081613178565b9050919050565b600060208201905081810360008301526135b08161319b565b9050919050565b600060208201905081810360008301526135d0816131be565b9050919050565b600060208201905081810360008301526135f0816131e1565b9050919050565b6000602082019050818103600083015261361081613204565b9050919050565b6000602082019050818103600083015261363081613227565b9050919050565b600060208201905081810360008301526136508161324a565b9050919050565b600060208201905081810360008301526136708161326d565b9050919050565b6000602082019050818103600083015261369081613290565b9050919050565b600060208201905081810360008301526136b0816132b3565b9050919050565b600060208201905081810360008301526136d0816132d6565b9050919050565b600060208201905081810360008301526136f0816132f9565b9050919050565b600060208201905081810360008301526137108161331c565b9050919050565b600060208201905081810360008301526137308161333f565b9050919050565b600060208201905061374c6000830184613371565b92915050565b60006040820190506137676000830185613371565b6137746020830184613371565b9392505050565b6000613785613796565b90506137918282613a09565b919050565b6000604051905090565b600067ffffffffffffffff8211156137bb576137ba613ae1565b5b602082029050602081019050919050565b600067ffffffffffffffff8211156137e7576137e6613ae1565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561381357613812613ae1565b5b61381c82613b32565b9050602081019050919050565b600067ffffffffffffffff82111561384457613843613ae1565b5b61384d82613b32565b9050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b60006138d68261398b565b91506138e18361398b565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561391657613915613a83565b5b828201905092915050565b600061392c8261396b565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156139c25780820151818401526020810190506139a7565b838111156139d1576000848401525b50505050565b600060028204905060018216806139ef57607f821691505b60208210811415613a0357613a02613ab2565b5b50919050565b613a1282613b32565b810181811067ffffffffffffffff82111715613a3157613a30613ae1565b5b80604052505050565b6000613a458261398b565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613a7857613a77613a83565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060033d1115613b2f5760046000803e613b2c600051613b43565b90505b90565b6000601f19601f8301169050919050565b60008160e01c9050919050565b7f455243313135353a207472616e7366657220746f206e6f6e204552433131353560008201527f526563656976657220696d706c656d656e746572000000000000000000000000602082015250565b7f455243313135353a204552433131353552656365697665722072656a6563746560008201527f6420746f6b656e73000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a2062616c616e636520717565727920666f7220746865207a60008201527f65726f2061646472657373000000000000000000000000000000000000000000602082015250565b7f455243313135353a206275726e20616d6f756e7420657863656564732062616c60008201527f616e636500000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135354d6978656446756e6769626c653a2063616c6c65722069732060008201527f6e6f74206f776e6572206e6f7220617070726f76656400000000000000000000602082015250565b7f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260008201527f20617070726f7665640000000000000000000000000000000000000000000000602082015250565b7f455243313135354d6978656446756e6769626c653a20696420646f6573206e6f60008201527f7420726570726573656e742061206e6f6e2d66756e6769626c65207479706500602082015250565b7f455243313135354d6978656446756e6769626c653a20696420646f6573206e6f60008201527f7420726570726573656e7420612066756e6769626c6520747970650000000000602082015250565b7f455243313135353a207472616e7366657220746f20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a207472616e736665722063616c6c6572206973206e6f742060008201527f6f776e6572206e6f7220617070726f7665640000000000000000000000000000602082015250565b7f455243313135354d6978656446756e6769626c653a20746f20616e6420616d6f60008201527f756e7473206c656e677468206d69736d61746368000000000000000000000000602082015250565b7f455243313135353a206275726e2066726f6d20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a20696e73756666696369656e742062616c616e636520666f60008201527f72207472616e7366657200000000000000000000000000000000000000000000602082015250565b7f455243313135353a2073657474696e6720617070726f76616c2073746174757360008201527f20666f722073656c660000000000000000000000000000000000000000000000602082015250565b7f455243313135353a206163636f756e747320616e6420696473206c656e67746860008201527f206d69736d617463680000000000000000000000000000000000000000000000602082015250565b7f455243313135353a2069647320616e6420616d6f756e7473206c656e6774682060008201527f6d69736d61746368000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a206d696e7420746f20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b600060443d101561409f57614122565b6140a7613796565b60043d036004823e80513d602482011167ffffffffffffffff821117156140cf575050614122565b808201805167ffffffffffffffff8111156140ed5750505050614122565b80602083010160043d03850181111561410a575050505050614122565b61411982602001850186613a09565b82955050505050505b90565b61412e81613921565b811461413957600080fd5b50565b61414581613933565b811461415057600080fd5b50565b61415c8161393f565b811461416757600080fd5b50565b6141738161398b565b811461417e57600080fd5b5056fea26469706673582212204fdf750e16aa1fe5ce34d26e3ca05a16726f416ae430ccefe9a917dbb14fb7d864736f6c63430008040033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101155760003560e01c806371cc1656116100a2578063a22cb46511610071578063a22cb46514610300578063b944eb291461031c578063cd53d08e14610338578063e985e9c514610368578063f242432a1461039857610115565b806371cc16561461027a5780637a0101a2146102aa5780637e53b65d146102c85780638a94b05f146102e457610115565b8063183fb254116100e9578063183fb254146101da5780631cbf311d146101f65780632eb2c2d6146102125780634e1273f41461022e57806354dbdbf41461025e57610115565b8062fdd58e1461011a57806301ffc9a71461014a57806308d7d4691461017a5780630e89341c146101aa575b600080fd5b610134600480360381019061012f9190612b85565b6103b4565b6040516101419190613737565b60405180910390f35b610164600480360381019061015f9190612d05565b61047d565b60405161017191906134b6565b60405180910390f35b610194600480360381019061018f9190612d57565b6104f7565b6040516101a19190613737565b60405180910390f35b6101c460048036038101906101bf9190612d57565b61050f565b6040516101d191906134f5565b60405180910390f35b6101f460048036038101906101ef9190612d80565b61065f565b005b610210600480360381019061020b9190612b19565b610868565b005b61022c6004803603810190610227919061298f565b610878565b005b61024860048036038101906102439190612c41565b610919565b604051610255919061345d565b60405180910390f35b61027860048036038101906102739190612e39565b610aca565b005b610294600480360381019061028f9190612cad565b610cb4565b6040516102a19190613737565b60405180910390f35b6102b2610db4565b6040516102bf91906134f5565b60405180910390f35b6102e260048036038101906102dd9190612ec2565b610e46565b005b6102fe60048036038101906102f99190612bc1565b611042565b005b61031a60048036038101906103159190612add565b6110e1565b005b61033660048036038101906103319190612f75565b6110f7565b005b610352600480360381019061034d9190612d57565b6111e0565b60405161035f9190613380565b60405180910390f35b610382600480360381019061037d9190612953565b611213565b60405161038f91906134b6565b60405180910390f35b6103b260048036038101906103ad9190612a4e565b6112a7565b005b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610425576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041c90613557565b60405180910390fd5b60008083815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60007fa1d87d57000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806104f057506104ef82611348565b5b9050919050565b60056020528060005260406000206000915090505481565b60606000600760008481526020019081526020016000208054610531906139d7565b80601f016020809104026020016040519081016040528092919081815260200182805461055d906139d7565b80156105aa5780601f1061057f576101008083540402835291602001916105aa565b820191906000526020600020905b81548152906001019060200180831161058d57829003601f168201915b50505050509050600081905060008151141561065457600680546105cd906139d7565b80601f01602080910402602001604051908101604052809291908181526020018280546105f9906139d7565b80156106465780601f1061061b57610100808354040283529160200191610646565b820191906000526020600020905b81548152906001019060200180831161062957829003601f168201915b50505050509250505061065a565b81925050505b919050565b8661066861142a565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146106d257600080fd5b6106db88611432565b61071a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610711906135f7565b60405180910390fd5b848490508787905014610762576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161075990613657565b60405180910390fd5b60005b8787905081101561085d5761084c8888838181106107ac577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020160208101906107c1919061292a565b8a8888858181106107fb577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002013587878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611460565b8061085690613a3a565b9050610765565b505050505050505050565b61087284846110e1565b50505050565b61088061142a565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614806108c657506108c5856108c061142a565b611213565b5b610905576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108fc90613637565b60405180910390fd5b6109128585858585611611565b5050505050565b6060815183511461095f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610956906136d7565b60405180910390fd5b6000835167ffffffffffffffff8111156109a2577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156109d05781602001602082028036833780820191505090505b50905060005b8451811015610abf57610a69858281518110610a1b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151858381518110610a5c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101516103b4565b828281518110610aa2577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101818152505080610ab890613a3a565b90506109d6565b508091505092915050565b84610ad361142a565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b3d57600080fd5b610b468661197f565b610b85576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b7c906135d7565b60405180910390fd5b600060016005600089815260200190815260200160002054610ba791906138cb565b9050610bc986869050600560008a8152602001908152602001600020546119ad565b600560008981526020019081526020016000208190555060005b86869050811015610caa57610c99878783818110610c2a577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002016020810190610c3f919061292a565b8284610c4b91906138cb565b8a17600188888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611460565b80610ca390613a3a565b9050610be3565b5050505050505050565b60006080600360008154610cc790613a3a565b919050819055901b905083610cfc577f8000000000000000000000000000000000000000000000000000000000000000811790505b610d0461142a565b6004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080610d5e61142a565b73ffffffffffffffffffffffffffffffffffffffff167f0d2ce24070e07853454690ae0a0416ddd4845188f8dbfe0ef3a761acb3d2e34e8585604051610da59291906134d1565b60405180910390a39392505050565b606060068054610dc3906139d7565b80601f0160208091040260200160405190810160405280929190818152602001828054610def906139d7565b8015610e3c5780601f10610e1157610100808354040283529160200191610e3c565b820191906000526020600020905b815481529060010190602001808311610e1f57829003601f168201915b5050505050905090565b85610e4f61142a565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610eb957600080fd5b610ec28761197f565b610f01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ef8906135d7565b60405180910390fd5b60006001600560008a815260200190815260200160002054610f2391906138cb565b9050610f4587879050600560008b8152602001908152602001600020546119ad565b600560008a81526020019081526020016000208190555060005b878790508110156110375760008183610f7891906138cb565b8a17905061101a898984818110610fb8577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002016020810190610fcd919061292a565b8260018a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611460565b6110258a82876110f7565b508061103090613a3a565b9050610f5f565b505050505050505050565b61104a61142a565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161480611090575061108f8561108a61142a565b611213565b5b6110cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110c690613597565b60405180910390fd5b6110da8585856119c3565b5050505050565b6110f36110ec61142a565b8383611c0a565b5050565b8261110061142a565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461116a57600080fd5b6111738461197f565b6111b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111a9906135d7565b60405180910390fd5b816007600085815260200190815260200160002090805190602001906111d9929190612544565b5050505050565b60046020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6112af61142a565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614806112f557506112f4856112ef61142a565b611213565b5b611334576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161132b906135b7565b60405180910390fd5b6113418585858585611d77565b5050505050565b60007fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061141357507f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611423575061142282612013565b5b9050919050565b600033905090565b6000807f80000000000000000000000000000000000000000000000000000000000000008316149050919050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156114d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114c790613717565b60405180910390fd5b60006114da61142a565b905060006114e78561207d565b905060006114f48561207d565b905061150583600089858589612143565b8460008088815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461156491906138cb565b925050819055508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6289896040516115e2929190613752565b60405180910390a46115f98360008985858961214b565b61160883600089898989612153565b50505050505050565b8151835114611655576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161164c906136f7565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156116c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116bc90613617565b60405180910390fd5b60006116cf61142a565b90506116df818787878787612143565b60005b84518110156118dc576000858281518110611726577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101519050600085838151811061176b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101519050600080600084815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508181101561180c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161180390613697565b60405180910390fd5b81810360008085815260200190815260200160002060008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508160008085815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546118c191906138cb565b92505081905550505050806118d590613a3a565b90506116e2565b508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb878760405161195392919061347f565b60405180910390a461196981878787878761214b565b61197781878787878761233a565b505050505050565b60007f8000000000000000000000000000000000000000000000000000000000000000808316149050919050565b600081836119bb91906138cb565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611a33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2a90613677565b60405180910390fd5b6000611a3d61142a565b90506000611a4a8461207d565b90506000611a578461207d565b9050611a7783876000858560405180602001604052806000815250612143565b600080600087815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905084811015611b0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b0590613577565b60405180910390fd5b84810360008088815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628989604051611bdb929190613752565b60405180910390a4611c018488600086866040518060200160405280600081525061214b565b50505050505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611c79576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c70906136b7565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611d6a91906134b6565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611de7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dde90613617565b60405180910390fd5b6000611df161142a565b90506000611dfe8561207d565b90506000611e0b8561207d565b9050611e1b838989858589612143565b600080600088815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905085811015611eb2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ea990613697565b60405180910390fd5b85810360008089815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508560008089815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f6791906138cb565b925050819055508773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628a8a604051611fe4929190613752565b60405180910390a4611ffa848a8a86868a61214b565b612008848a8a8a8a8a612153565b505050505050505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60606000600167ffffffffffffffff8111156120c2577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156120f05781602001602082028036833780820191505090505b509050828160008151811061212e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101818152505080915050919050565b505050505050565b505050505050565b6121728473ffffffffffffffffffffffffffffffffffffffff16612521565b15612332578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b81526004016121b8959493929190613403565b602060405180830381600087803b1580156121d257600080fd5b505af192505050801561220357506040513d601f19601f820116820180604052508101906122009190612d2e565b60015b6122a95761220f613b10565b806308c379a0141561226c575061222461408f565b8061222f575061226e565b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161226391906134f5565b60405180910390fd5b505b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122a090613517565b60405180910390fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612330576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161232790613537565b60405180910390fd5b505b505050505050565b6123598473ffffffffffffffffffffffffffffffffffffffff16612521565b15612519578373ffffffffffffffffffffffffffffffffffffffff1663bc197c8187878686866040518663ffffffff1660e01b815260040161239f95949392919061339b565b602060405180830381600087803b1580156123b957600080fd5b505af19250505080156123ea57506040513d601f19601f820116820180604052508101906123e79190612d2e565b60015b612490576123f6613b10565b806308c379a01415612453575061240b61408f565b806124165750612455565b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161244a91906134f5565b60405180910390fd5b505b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161248790613517565b60405180910390fd5b63bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612517576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161250e90613537565b60405180910390fd5b505b505050505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b828054612550906139d7565b90600052602060002090601f01602090048101928261257257600085556125b9565b82601f1061258b57805160ff19168380011785556125b9565b828001600101855582156125b9579182015b828111156125b857825182559160200191906001019061259d565b5b5090506125c691906125ca565b5090565b5b808211156125e35760008160009055506001016125cb565b5090565b60006125fa6125f5846137a0565b61377b565b9050808382526020820190508285602086028201111561261957600080fd5b60005b85811015612649578161262f888261273b565b84526020840193506020830192505060018101905061261c565b5050509392505050565b6000612666612661846137cc565b61377b565b9050808382526020820190508285602086028201111561268557600080fd5b60005b858110156126b5578161269b8882612915565b845260208401935060208301925050600181019050612688565b5050509392505050565b60006126d26126cd846137f8565b61377b565b9050828152602081018484840111156126ea57600080fd5b6126f5848285613995565b509392505050565b600061271061270b84613829565b61377b565b90508281526020810184848401111561272857600080fd5b612733848285613995565b509392505050565b60008135905061274a81614125565b92915050565b60008083601f84011261276257600080fd5b8235905067ffffffffffffffff81111561277b57600080fd5b60208301915083602082028301111561279357600080fd5b9250929050565b600082601f8301126127ab57600080fd5b81356127bb8482602086016125e7565b91505092915050565b60008083601f8401126127d657600080fd5b8235905067ffffffffffffffff8111156127ef57600080fd5b60208301915083602082028301111561280757600080fd5b9250929050565b600082601f83011261281f57600080fd5b813561282f848260208601612653565b91505092915050565b6000813590506128478161413c565b92915050565b60008135905061285c81614153565b92915050565b60008151905061287181614153565b92915050565b60008083601f84011261288957600080fd5b8235905067ffffffffffffffff8111156128a257600080fd5b6020830191508360018202830111156128ba57600080fd5b9250929050565b600082601f8301126128d257600080fd5b81356128e28482602086016126bf565b91505092915050565b600082601f8301126128fc57600080fd5b813561290c8482602086016126fd565b91505092915050565b6000813590506129248161416a565b92915050565b60006020828403121561293c57600080fd5b600061294a8482850161273b565b91505092915050565b6000806040838503121561296657600080fd5b60006129748582860161273b565b92505060206129858582860161273b565b9150509250929050565b600080600080600060a086880312156129a757600080fd5b60006129b58882890161273b565b95505060206129c68882890161273b565b945050604086013567ffffffffffffffff8111156129e357600080fd5b6129ef8882890161280e565b935050606086013567ffffffffffffffff811115612a0c57600080fd5b612a188882890161280e565b925050608086013567ffffffffffffffff811115612a3557600080fd5b612a41888289016128c1565b9150509295509295909350565b600080600080600060a08688031215612a6657600080fd5b6000612a748882890161273b565b9550506020612a858882890161273b565b9450506040612a9688828901612915565b9350506060612aa788828901612915565b925050608086013567ffffffffffffffff811115612ac457600080fd5b612ad0888289016128c1565b9150509295509295909350565b60008060408385031215612af057600080fd5b6000612afe8582860161273b565b9250506020612b0f85828601612838565b9150509250929050565b60008060008060608587031215612b2f57600080fd5b6000612b3d8782880161273b565b9450506020612b4e87828801612838565b935050604085013567ffffffffffffffff811115612b6b57600080fd5b612b7787828801612877565b925092505092959194509250565b60008060408385031215612b9857600080fd5b6000612ba68582860161273b565b9250506020612bb785828601612915565b9150509250929050565b600080600080600060808688031215612bd957600080fd5b6000612be78882890161273b565b9550506020612bf888828901612915565b9450506040612c0988828901612915565b935050606086013567ffffffffffffffff811115612c2657600080fd5b612c3288828901612877565b92509250509295509295909350565b60008060408385031215612c5457600080fd5b600083013567ffffffffffffffff811115612c6e57600080fd5b612c7a8582860161279a565b925050602083013567ffffffffffffffff811115612c9757600080fd5b612ca38582860161280e565b9150509250929050565b600080600060408486031215612cc257600080fd5b6000612cd086828701612838565b935050602084013567ffffffffffffffff811115612ced57600080fd5b612cf986828701612877565b92509250509250925092565b600060208284031215612d1757600080fd5b6000612d258482850161284d565b91505092915050565b600060208284031215612d4057600080fd5b6000612d4e84828501612862565b91505092915050565b600060208284031215612d6957600080fd5b6000612d7784828501612915565b91505092915050565b60008060008060008060006080888a031215612d9b57600080fd5b6000612da98a828b01612915565b975050602088013567ffffffffffffffff811115612dc657600080fd5b612dd28a828b01612750565b9650965050604088013567ffffffffffffffff811115612df157600080fd5b612dfd8a828b016127c4565b9450945050606088013567ffffffffffffffff811115612e1c57600080fd5b612e288a828b01612877565b925092505092959891949750929550565b600080600080600060608688031215612e5157600080fd5b6000612e5f88828901612915565b955050602086013567ffffffffffffffff811115612e7c57600080fd5b612e8888828901612750565b9450945050604086013567ffffffffffffffff811115612ea757600080fd5b612eb388828901612877565b92509250509295509295909350565b60008060008060008060808789031215612edb57600080fd5b6000612ee989828a01612915565b965050602087013567ffffffffffffffff811115612f0657600080fd5b612f1289828a01612750565b9550955050604087013567ffffffffffffffff811115612f3157600080fd5b612f3d89828a01612877565b9350935050606087013567ffffffffffffffff811115612f5c57600080fd5b612f6889828a016128eb565b9150509295509295509295565b600080600060608486031215612f8a57600080fd5b6000612f9886828701612915565b9350506020612fa986828701612915565b925050604084013567ffffffffffffffff811115612fc657600080fd5b612fd2868287016128eb565b9150509250925092565b6000612fe88383613362565b60208301905092915050565b612ffd81613921565b82525050565b600061300e8261386a565b6130188185613898565b93506130238361385a565b8060005b8381101561305457815161303b8882612fdc565b97506130468361388b565b925050600181019050613027565b5085935050505092915050565b61306a81613933565b82525050565b600061307c83856138a9565b9350613089838584613995565b61309283613b32565b840190509392505050565b60006130a882613875565b6130b281856138a9565b93506130c28185602086016139a4565b6130cb81613b32565b840191505092915050565b60006130e182613880565b6130eb81856138ba565b93506130fb8185602086016139a4565b61310481613b32565b840191505092915050565b600061311c6034836138ba565b915061312782613b50565b604082019050919050565b600061313f6028836138ba565b915061314a82613b9f565b604082019050919050565b6000613162602b836138ba565b915061316d82613bee565b604082019050919050565b60006131856024836138ba565b915061319082613c3d565b604082019050919050565b60006131a86036836138ba565b91506131b382613c8c565b604082019050919050565b60006131cb6029836138ba565b91506131d682613cdb565b604082019050919050565b60006131ee603f836138ba565b91506131f982613d2a565b604082019050919050565b6000613211603b836138ba565b915061321c82613d79565b604082019050919050565b60006132346025836138ba565b915061323f82613dc8565b604082019050919050565b60006132576032836138ba565b915061326282613e17565b604082019050919050565b600061327a6034836138ba565b915061328582613e66565b604082019050919050565b600061329d6023836138ba565b91506132a882613eb5565b604082019050919050565b60006132c0602a836138ba565b91506132cb82613f04565b604082019050919050565b60006132e36029836138ba565b91506132ee82613f53565b604082019050919050565b60006133066029836138ba565b915061331182613fa2565b604082019050919050565b60006133296028836138ba565b915061333482613ff1565b604082019050919050565b600061334c6021836138ba565b915061335782614040565b604082019050919050565b61336b8161398b565b82525050565b61337a8161398b565b82525050565b60006020820190506133956000830184612ff4565b92915050565b600060a0820190506133b06000830188612ff4565b6133bd6020830187612ff4565b81810360408301526133cf8186613003565b905081810360608301526133e38185613003565b905081810360808301526133f7818461309d565b90509695505050505050565b600060a0820190506134186000830188612ff4565b6134256020830187612ff4565b6134326040830186613371565b61343f6060830185613371565b8181036080830152613451818461309d565b90509695505050505050565b600060208201905081810360008301526134778184613003565b905092915050565b600060408201905081810360008301526134998185613003565b905081810360208301526134ad8184613003565b90509392505050565b60006020820190506134cb6000830184613061565b92915050565b600060208201905081810360008301526134ec818486613070565b90509392505050565b6000602082019050818103600083015261350f81846130d6565b905092915050565b600060208201905081810360008301526135308161310f565b9050919050565b6000602082019050818103600083015261355081613132565b9050919050565b6000602082019050818103600083015261357081613155565b9050919050565b6000602082019050818103600083015261359081613178565b9050919050565b600060208201905081810360008301526135b08161319b565b9050919050565b600060208201905081810360008301526135d0816131be565b9050919050565b600060208201905081810360008301526135f0816131e1565b9050919050565b6000602082019050818103600083015261361081613204565b9050919050565b6000602082019050818103600083015261363081613227565b9050919050565b600060208201905081810360008301526136508161324a565b9050919050565b600060208201905081810360008301526136708161326d565b9050919050565b6000602082019050818103600083015261369081613290565b9050919050565b600060208201905081810360008301526136b0816132b3565b9050919050565b600060208201905081810360008301526136d0816132d6565b9050919050565b600060208201905081810360008301526136f0816132f9565b9050919050565b600060208201905081810360008301526137108161331c565b9050919050565b600060208201905081810360008301526137308161333f565b9050919050565b600060208201905061374c6000830184613371565b92915050565b60006040820190506137676000830185613371565b6137746020830184613371565b9392505050565b6000613785613796565b90506137918282613a09565b919050565b6000604051905090565b600067ffffffffffffffff8211156137bb576137ba613ae1565b5b602082029050602081019050919050565b600067ffffffffffffffff8211156137e7576137e6613ae1565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561381357613812613ae1565b5b61381c82613b32565b9050602081019050919050565b600067ffffffffffffffff82111561384457613843613ae1565b5b61384d82613b32565b9050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b60006138d68261398b565b91506138e18361398b565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561391657613915613a83565b5b828201905092915050565b600061392c8261396b565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156139c25780820151818401526020810190506139a7565b838111156139d1576000848401525b50505050565b600060028204905060018216806139ef57607f821691505b60208210811415613a0357613a02613ab2565b5b50919050565b613a1282613b32565b810181811067ffffffffffffffff82111715613a3157613a30613ae1565b5b80604052505050565b6000613a458261398b565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613a7857613a77613a83565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060033d1115613b2f5760046000803e613b2c600051613b43565b90505b90565b6000601f19601f8301169050919050565b60008160e01c9050919050565b7f455243313135353a207472616e7366657220746f206e6f6e204552433131353560008201527f526563656976657220696d706c656d656e746572000000000000000000000000602082015250565b7f455243313135353a204552433131353552656365697665722072656a6563746560008201527f6420746f6b656e73000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a2062616c616e636520717565727920666f7220746865207a60008201527f65726f2061646472657373000000000000000000000000000000000000000000602082015250565b7f455243313135353a206275726e20616d6f756e7420657863656564732062616c60008201527f616e636500000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135354d6978656446756e6769626c653a2063616c6c65722069732060008201527f6e6f74206f776e6572206e6f7220617070726f76656400000000000000000000602082015250565b7f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260008201527f20617070726f7665640000000000000000000000000000000000000000000000602082015250565b7f455243313135354d6978656446756e6769626c653a20696420646f6573206e6f60008201527f7420726570726573656e742061206e6f6e2d66756e6769626c65207479706500602082015250565b7f455243313135354d6978656446756e6769626c653a20696420646f6573206e6f60008201527f7420726570726573656e7420612066756e6769626c6520747970650000000000602082015250565b7f455243313135353a207472616e7366657220746f20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a207472616e736665722063616c6c6572206973206e6f742060008201527f6f776e6572206e6f7220617070726f7665640000000000000000000000000000602082015250565b7f455243313135354d6978656446756e6769626c653a20746f20616e6420616d6f60008201527f756e7473206c656e677468206d69736d61746368000000000000000000000000602082015250565b7f455243313135353a206275726e2066726f6d20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a20696e73756666696369656e742062616c616e636520666f60008201527f72207472616e7366657200000000000000000000000000000000000000000000602082015250565b7f455243313135353a2073657474696e6720617070726f76616c2073746174757360008201527f20666f722073656c660000000000000000000000000000000000000000000000602082015250565b7f455243313135353a206163636f756e747320616e6420696473206c656e67746860008201527f206d69736d617463680000000000000000000000000000000000000000000000602082015250565b7f455243313135353a2069647320616e6420616d6f756e7473206c656e6774682060008201527f6d69736d61746368000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a206d696e7420746f20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b600060443d101561409f57614122565b6140a7613796565b60043d036004823e80513d602482011167ffffffffffffffff821117156140cf575050614122565b808201805167ffffffffffffffff8111156140ed5750505050614122565b80602083010160043d03850181111561410a575050505050614122565b61411982602001850186613a09565b82955050505050505b90565b61412e81613921565b811461413957600080fd5b50565b61414581613933565b811461415057600080fd5b50565b61415c8161393f565b811461416757600080fd5b50565b6141738161398b565b811461417e57600080fd5b5056fea26469706673582212204fdf750e16aa1fe5ce34d26e3ca05a16726f416ae430ccefe9a917dbb14fb7d864736f6c63430008040033", + "linkReferences": {}, + "deployedLinkReferences": {} +} \ No newline at end of file diff --git a/src/tokens/abimapper.service.ts b/src/tokens/abimapper.service.ts index ba9c424..38afd56 100644 --- a/src/tokens/abimapper.service.ts +++ b/src/tokens/abimapper.service.ts @@ -16,8 +16,9 @@ import { BadRequestException, Injectable, Logger } from '@nestjs/common'; import * as LRUCache from 'lru-cache'; -import { abi as ERC1155MixedFungibleAbi } from '../abi/ERC1155MixedFungible.json'; -import { abi as ERC1155MixedFungibleOldAbi } from '../abi/ERC1155MixedFungibleOld.json'; +import { abi as ERC1155MixedFungibleAbiV2 } from '../abi/ERC1155MixedFungible.json'; +import { abi as ERC1155MixedFungibleAbiV1 } from '../abi/ERC1155MixedFungibleV1.json'; +import { abi as ERC1155MixedFungibleAbiOld } from '../abi/ERC1155MixedFungibleOld.json'; import { Context } from '../request-context/request-context.decorator'; import { BlockchainConnectorService } from './blockchain.service'; import { SupportsInterface } from './erc165'; @@ -35,7 +36,7 @@ import { encodeHex } from './tokens.util'; const CUSTOM_URI_IID = '0xa1d87d57'; const tokenCreateFunctionName = 'create'; -const tokenCreateEvent = 'TokenPoolCreation'; +export const tokenCreateEvent = 'TokenPoolCreation'; @Injectable() export class AbiMapperService { @@ -58,7 +59,7 @@ export class AbiMapperService { async getAbi(ctx: Context, address: string) { const uriSupport = await this.supportsInterface(ctx, address, CUSTOM_URI_IID); - return uriSupport ? ERC1155MixedFungibleAbi : ERC1155MixedFungibleOldAbi; + return uriSupport ? ERC1155MixedFungibleAbiV2 : ERC1155MixedFungibleAbiOld; } private signatureMatch(method: IAbiMethod, signature: MethodSignature) { @@ -106,11 +107,15 @@ export class AbiMapperService { } getCreateMethod() { - return ERC1155MixedFungibleAbi.find(m => m.name === tokenCreateFunctionName); + return ERC1155MixedFungibleAbiV2.find(m => m.name === tokenCreateFunctionName); } - getCreateEvent() { - return ERC1155MixedFungibleAbi.find(m => m.name === tokenCreateEvent); + getCreateEventV1() { + return ERC1155MixedFungibleAbiV1.find(m => m.name === tokenCreateEvent); + } + + getCreateEventV2() { + return ERC1155MixedFungibleAbiV2.find(m => m.name === tokenCreateEvent); } getCreateMethodAndParams(dto: TokenPool) { diff --git a/src/tokens/tokens.interfaces.ts b/src/tokens/tokens.interfaces.ts index 03d8ff9..1671c86 100644 --- a/src/tokens/tokens.interfaces.ts +++ b/src/tokens/tokens.interfaces.ts @@ -47,12 +47,22 @@ export interface ContractInfoResponse { address: string; } +interface TokenPoolCreationDataV1 { + operator: string; + type_id: string; + data: string; +} + +interface TokenPoolCreationDataV2 { + operator: string; + is_fungible: boolean; + start_id: string; + end_id: string; + data: string; +} + export interface TokenPoolCreationEvent extends Event { - data: { - operator: string; - type_id: string; - data: string; - }; + data: TokenPoolCreationDataV1 | TokenPoolCreationDataV2; } export interface ApprovalForAllEvent extends Event { diff --git a/src/tokens/tokens.listener.ts b/src/tokens/tokens.listener.ts index 0c0ce97..4d83815 100644 --- a/src/tokens/tokens.listener.ts +++ b/src/tokens/tokens.listener.ts @@ -52,7 +52,8 @@ export const TOKEN_STANDARD = 'ERC1155'; const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; const tokenCreateEventSignatureOld = 'TokenCreate(address,uint256,bytes)'; -const tokenCreateEventSignature = 'TokenPoolCreation(address,uint256,bytes)'; +const tokenCreateEventSignatureV1 = 'TokenPoolCreation(address,uint256,bytes)'; +const tokenCreateEventSignatureV2 = 'TokenPoolCreation(address,bool,uint256,uint256,bytes)'; const transferSingleEventSignature = 'TransferSingle(address,address,address,uint256,uint256)'; const transferBatchEventSignature = 'TransferBatch(address,address,address,uint256[],uint256[])'; const approvalForAllEventSignature = 'ApprovalForAll(address,address,bool)'; @@ -65,7 +66,8 @@ export class TokenListener implements EventListener { async onEvent(subName: string, event: Event, process: EventProcessor) { switch (this.trimEventSignature(event.signature)) { case tokenCreateEventSignatureOld: - case tokenCreateEventSignature: + case tokenCreateEventSignatureV1: + case tokenCreateEventSignatureV2: process(this.transformTokenPoolCreationEvent(subName, event)); break; case transferSingleEventSignature: @@ -128,25 +130,51 @@ export class TokenListener implements EventListener { let poolLocator: PoolLocator; let packedPoolLocator = unpackedSub.poolLocator; if (packedPoolLocator === BASE_SUBSCRIPTION_NAME) { - const unpackedId = unpackTypeId(output.type_id); - poolLocator = { - address: event.address.toLowerCase(), - isFungible: unpackedId.isFungible, - startId: unpackedId.startId, - endId: unpackedId.endId, - blockNumber: event.blockNumber, - }; - packedPoolLocator = packPoolLocator( - event.address.toLowerCase(), - unpackedId.isFungible, - unpackedId.startId, - unpackedId.endId, - event.blockNumber, - ); + if ('type_id' in output) { + // Older creation event - must interpret the "type_id" parameter + const unpackedId = unpackTypeId(output.type_id); + poolLocator = { + address: event.address.toLowerCase(), + isFungible: unpackedId.isFungible, + startId: unpackedId.startId, + endId: unpackedId.endId, + blockNumber: event.blockNumber, + }; + packedPoolLocator = packPoolLocator( + event.address.toLowerCase(), + unpackedId.isFungible, + unpackedId.startId, + unpackedId.endId, + event.blockNumber, + ); + } else { + // Newer creation event - all needed params are in the event + poolLocator = { + address: event.address.toLowerCase(), + isFungible: output.is_fungible, + startId: output.start_id, + endId: output.end_id, + blockNumber: event.blockNumber, + }; + packedPoolLocator = packPoolLocator( + event.address.toLowerCase(), + output.is_fungible, + output.start_id, + output.end_id, + event.blockNumber, + ); + } } else { poolLocator = unpackPoolLocator(packedPoolLocator); - if (!poolContainsId(poolLocator, output.type_id)) { - // this is a pool-specific subscription, and this event is not from the subscribed pool + if ( + ('type_id' in output && BigInt(poolLocator.startId) !== BigInt(output.type_id)) || + (!('type_id' in output) && + !( + BigInt(poolLocator.startId) === BigInt(output.start_id) && + BigInt(poolLocator.endId) === BigInt(output.end_id) + )) + ) { + // This is a pool-specific subscription, and this event is not from the subscribed pool return undefined; } } diff --git a/src/tokens/tokens.service.spec.ts b/src/tokens/tokens.service.spec.ts index 8e81c30..2ed8739 100644 --- a/src/tokens/tokens.service.spec.ts +++ b/src/tokens/tokens.service.spec.ts @@ -148,6 +148,7 @@ describe('TokensService', () => { eventStream.getStreams.mockReturnValueOnce([{ name: 'tokens:0x123' }]); eventStream.getSubscriptions.mockReturnValueOnce([ { name: 'fft:0x123:p1:TokenPoolCreation:ns1' }, + { name: 'fft:0x123:p1:TokenPoolCreationV2:ns1' }, { name: 'fft:0x123:p1:TransferSingle:ns1' }, { name: 'fft:0x123:p1:TransferBatch:ns1' }, { name: 'fft:0x123:p1:ApprovalForAll:ns1' }, diff --git a/src/tokens/tokens.service.ts b/src/tokens/tokens.service.ts index 0975f46..72cda75 100644 --- a/src/tokens/tokens.service.ts +++ b/src/tokens/tokens.service.ts @@ -54,7 +54,7 @@ import { } from './tokens.util'; import { TOKEN_STANDARD, TokenListener } from './tokens.listener'; import { BlockchainConnectorService } from './blockchain.service'; -import { AbiMapperService } from './abimapper.service'; +import { AbiMapperService, tokenCreateEvent } from './abimapper.service'; import { AllEvents, ApprovalForAll, @@ -66,8 +66,11 @@ import { export const BASE_SUBSCRIPTION_NAME = 'base'; -const tokenCreateEvent = 'TokenPoolCreation'; -const ALL_SUBSCRIBED_EVENTS = [tokenCreateEvent, ...AllEvents.map(e => e.name)]; +const ALL_SUBSCRIBED_EVENTS = [ + tokenCreateEvent, + tokenCreateEvent + 'V2', + ...AllEvents.map(e => e.name), +]; @Injectable() export class TokensService { @@ -76,7 +79,6 @@ export class TokensService { baseUrl: string; instancePath: string; - instanceUrl: string; topic: string; stream: EventStream | undefined; @@ -90,7 +92,6 @@ export class TokensService { configure(baseUrl: string, instancePath: string, topic: string, contractAddress: string) { this.baseUrl = baseUrl; this.instancePath = instancePath; - this.instanceUrl = this.instancePath ? new URL(this.instancePath, this.baseUrl).href : ''; this.topic = topic; this.contractAddress = contractAddress.toLowerCase(); this.proxy.addConnectionListener(this); @@ -109,37 +110,63 @@ export class TokensService { async init(ctx: Context) { const defaultContract = await this.getContractAddress(ctx); if (defaultContract) { - await this.createPoolSubscription(ctx, defaultContract); + await this.createPoolSubscription(ctx, defaultContract, BASE_SUBSCRIPTION_NAME); } } - private async createPoolSubscription(ctx: Context, address: string, blockNumber?: string) { + private async createPoolSubscription( + ctx: Context, + address: string, + poolLocator: string, + blockNumber?: string, + poolData?: string, + ) { const stream = await this.getStream(ctx); - const eventABI = this.mapper.getCreateEvent(); + const eventABIV1 = this.mapper.getCreateEventV1(); + const eventABIV2 = this.mapper.getCreateEventV2(); const methodABI = this.mapper.getCreateMethod(); - if (eventABI !== undefined && methodABI !== undefined) { - await this.eventstream.getOrCreateSubscription( - ctx, - this.baseUrl, - eventABI, - stream.id, - packSubscriptionName(address, BASE_SUBSCRIPTION_NAME, tokenCreateEvent), - address, - [methodABI], - blockNumber ?? '0', + const promises: Promise[] = []; + if (eventABIV1 !== undefined && methodABI !== undefined) { + promises.push( + this.eventstream.getOrCreateSubscription( + ctx, + this.baseUrl, + eventABIV1, + stream.id, + packSubscriptionName(address, poolLocator, tokenCreateEvent, poolData), + address, + [methodABI], + blockNumber ?? '0', + ), ); } + if (eventABIV2 !== undefined && methodABI !== undefined) { + promises.push( + this.eventstream.getOrCreateSubscription( + ctx, + this.baseUrl, + eventABIV2, + stream.id, + packSubscriptionName(address, poolLocator, tokenCreateEvent + 'V2', poolData), + address, + [methodABI], + blockNumber ?? '0', + ), + ); + } + return Promise.all(promises); } private async getContractAddress(ctx: Context) { if (!this.contractAddress) { - if (!this.instanceUrl) { + if (!this.instancePath) { return undefined; } + const instanceUrl = new URL(this.instancePath, this.baseUrl).href; this.logger.debug( - `CONTRACT_ADDRESS is not set - fetching the address using instance url: ${this.instanceUrl}`, + `CONTRACT_ADDRESS is not set - fetching the address using instance url: ${instanceUrl}`, ); - const data = await this.blockchain.getContractInfo(ctx, this.instanceUrl); + const data = await this.blockchain.getContractInfo(ctx, instanceUrl); this.contractAddress = '0x' + data.address.toLowerCase(); this.logger.debug(`Contract address: ${this.contractAddress}`); } @@ -151,9 +178,9 @@ export class TokensService { if (stream !== undefined) { return stream; } - await this.migrationCheck(ctx); - const name = this.stream?.name ?? packStreamName(this.topic, this.instancePath); - this.logger.log('Creating stream with name ' + name); + await this.migrationCheck(ctx); // note: may update this.stream + const name = this.stream?.name ?? packStreamName(this.topic, this.contractAddress); + this.logger.log('Using event stream with name ' + name); this.stream = await this.eventstream.createOrUpdateStream(ctx, name, name); return this.stream; } @@ -166,19 +193,25 @@ export class TokensService { * subscriptions manually and reactivate the pool directly. */ async migrationCheck(ctx: Context) { - const name = packStreamName(this.topic, this.instancePath); + const currentName = packStreamName(this.topic, this.contractAddress); + const oldName1 = packStreamName(this.topic, this.instancePath); + const oldName2 = this.topic; + const streams = await this.eventstream.getStreams(); - let existingStream = streams.find(s => s.name === name); + let existingStream = streams.find(s => s.name === currentName); if (existingStream === undefined) { - // Look for the old stream name (topic alone) - existingStream = streams.find(s => s.name === this.topic); + // Look for the old stream names + existingStream = streams.find(s => s.name === oldName1); if (existingStream === undefined) { - return false; + existingStream = streams.find(s => s.name === oldName2); + if (existingStream === undefined) { + return false; + } } this.logger.warn( `Old event stream found with name ${existingStream.name}. ` + `The connector will continue to use this stream, but it is recommended ` + - `to create a new stream with the name ${name}.`, + `to create a new stream with the name ${currentName}.`, ); } this.stream = existingStream; @@ -190,18 +223,12 @@ export class TokensService { return false; } - const baseSubscription = packSubscriptionName( - this.instancePath, - BASE_SUBSCRIPTION_NAME, - tokenCreateEvent, - ); - const foundEvents = new Map(); for (const sub of subscriptions) { - if (sub.name === baseSubscription) { + const parts = unpackSubscriptionName(sub.name); + if (parts.poolLocator === BASE_SUBSCRIPTION_NAME) { continue; } - const parts = unpackSubscriptionName(sub.name); if (parts.poolLocator === undefined || parts.event === undefined) { this.logger.warn( `Non-parseable subscription name '${sub.name}' found in event stream '${existingStream.name}'.` + @@ -209,7 +236,7 @@ export class TokensService { ); return true; } - const key = packSubscriptionName(parts.instancePath, parts.poolLocator, '', parts.poolData); + const key = packSubscriptionName(parts.address, parts.poolLocator, '', parts.poolData); const existing = foundEvents.get(key); if (existing !== undefined) { existing.push(parts.event); @@ -246,7 +273,12 @@ export class TokensService { dto, ); } - await this.createPoolSubscription(ctx, dto.config.address, dto.config.blockNumber); + await this.createPoolSubscription( + ctx, + dto.config.address, + BASE_SUBSCRIPTION_NAME, + dto.config.blockNumber, + ); return this.createWithAddress(ctx, dto.config.address, dto); } @@ -295,140 +327,76 @@ export class TokensService { } const abi = await this.mapper.getAbi(ctx, address); - const tokenCreateEvent = this.mapper.getCreateEvent(); - const tokenCreateMethod = this.mapper.getCreateMethod(); const possibleMethods = this.mapper.allInvokeMethods(abi); - const promises: Promise[] = []; - if (tokenCreateEvent?.name !== undefined && tokenCreateMethod !== undefined) { - promises.push( - this.eventstream.getOrCreateSubscription( - ctx, - this.baseUrl, - tokenCreateEvent, - stream.id, - packSubscriptionName( - this.instancePath, - dto.poolLocator, - tokenCreateEvent.name, - dto.poolData, - ), - address, - [tokenCreateMethod], - poolLocator.blockNumber ?? '0', - ), - ); - } - promises.push( - ...[ - this.eventstream.getOrCreateSubscription( - ctx, - this.baseUrl, - TransferSingle, - stream.id, - packSubscriptionName( - this.instancePath, - dto.poolLocator, - TransferSingle.name, - dto.poolData, - ), - address, - possibleMethods, - poolLocator.blockNumber ?? '0', - ), - this.eventstream.getOrCreateSubscription( - ctx, - this.baseUrl, - TransferBatch, - stream.id, - packSubscriptionName( - this.instancePath, - dto.poolLocator, - TransferBatch.name, - dto.poolData, - ), - address, - possibleMethods, - poolLocator.blockNumber ?? '0', - ), - this.eventstream.getOrCreateSubscription( - ctx, - this.baseUrl, - ApprovalForAll, - stream.id, - packSubscriptionName( - this.instancePath, - dto.poolLocator, - ApprovalForAll.name, - dto.poolData, - ), - address, - possibleMethods, - // Block number is 0 because it is important to receive all approval events, - // so existing approvals will be reflected in the newly created pool - '0', - ), - ], - ); + const promises: Promise[] = [ + this.createPoolSubscription( + ctx, + address, + dto.poolLocator, + poolLocator.blockNumber, + dto.poolData, + ), + this.eventstream.getOrCreateSubscription( + ctx, + this.baseUrl, + TransferSingle, + stream.id, + packSubscriptionName(address, dto.poolLocator, TransferSingle.name, dto.poolData), + address, + possibleMethods, + poolLocator.blockNumber ?? '0', + ), + this.eventstream.getOrCreateSubscription( + ctx, + this.baseUrl, + TransferBatch, + stream.id, + packSubscriptionName(address, dto.poolLocator, TransferBatch.name, dto.poolData), + address, + possibleMethods, + poolLocator.blockNumber ?? '0', + ), + this.eventstream.getOrCreateSubscription( + ctx, + this.baseUrl, + ApprovalForAll, + stream.id, + packSubscriptionName(address, dto.poolLocator, ApprovalForAll.name, dto.poolData), + address, + possibleMethods, + // Block number is 0 because it is important to receive all approval events, + // so existing approvals will be reflected in the newly created pool + '0', + ), + ]; await Promise.all(promises); } async deactivatePool(ctx: Context, dto: TokenPoolDeactivate) { - const tokenCreateEvent = this.mapper.getCreateEvent(); - const stream = await this.getStream(ctx); - - const promises: Promise[] = []; - if (tokenCreateEvent?.name !== undefined) { - promises.push( - this.eventstream.deleteSubscriptionByName( - ctx, - stream.id, - packSubscriptionName( - this.instancePath, - dto.poolLocator, - tokenCreateEvent.name, - dto.poolData, - ), - ), - ); - } + const poolLocator = unpackPoolLocator(dto.poolLocator); + const address = poolLocator.address ?? ''; + const subscriptionNames = [ + // current subscription names + packSubscriptionName(address, dto.poolLocator, tokenCreateEvent, dto.poolData), + packSubscriptionName(address, dto.poolLocator, tokenCreateEvent + 'V2', dto.poolData), + packSubscriptionName(address, dto.poolLocator, TransferSingle.name, dto.poolData), + packSubscriptionName(address, dto.poolLocator, TransferBatch.name, dto.poolData), + packSubscriptionName(address, dto.poolLocator, ApprovalForAll.name, dto.poolData), + // older name format + packSubscriptionName(this.instancePath, dto.poolLocator, tokenCreateEvent, dto.poolData), + packSubscriptionName(this.instancePath, dto.poolLocator, TransferSingle.name, dto.poolData), + packSubscriptionName(this.instancePath, dto.poolLocator, TransferBatch.name, dto.poolData), + packSubscriptionName(this.instancePath, dto.poolLocator, ApprovalForAll.name, dto.poolData), + ]; - promises.push( - ...[ - this.eventstream.deleteSubscriptionByName( - ctx, - stream.id, - packSubscriptionName( - this.instancePath, - dto.poolLocator, - TransferSingle.name, - dto.poolData, - ), - ), - this.eventstream.deleteSubscriptionByName( - ctx, - stream.id, - packSubscriptionName( - this.instancePath, - dto.poolLocator, - TransferBatch.name, - dto.poolData, - ), - ), - this.eventstream.deleteSubscriptionByName( - ctx, - stream.id, - packSubscriptionName( - this.instancePath, - dto.poolLocator, - ApprovalForAll.name, - dto.poolData, - ), - ), - ], + const stream = await this.getStream(ctx); + const results = await Promise.all( + subscriptionNames.map(name => + this.eventstream.deleteSubscriptionByName(ctx, stream.id, name), + ), ); - const results = await Promise.all(promises); if (results.every(deleted => !deleted)) { throw new NotFoundException('No listeners found'); } diff --git a/src/tokens/tokens.util.spec.ts b/src/tokens/tokens.util.spec.ts index 80810ea..98d00e4 100644 --- a/src/tokens/tokens.util.spec.ts +++ b/src/tokens/tokens.util.spec.ts @@ -115,19 +115,19 @@ describe('Util', () => { it('unpackSubscriptionName', () => { expect(unpackSubscriptionName('fft:0x123:F1:create:ns1')).toEqual({ - instancePath: '0x123', + address: '0x123', poolLocator: 'F1', event: 'create', poolData: 'ns1', }); expect(unpackSubscriptionName('token:0x123:F1:create')).toEqual({ - instancePath: '0x123', + address: '0x123', poolLocator: 'F1', event: 'create', poolData: undefined, }); expect(unpackSubscriptionName('fft:0x123:F1:create:ns1%3Atest')).toEqual({ - instancePath: '0x123', + address: '0x123', poolLocator: 'F1', event: 'create', poolData: 'ns1:test', diff --git a/src/tokens/tokens.util.ts b/src/tokens/tokens.util.ts index 172dcc9..7419f74 100644 --- a/src/tokens/tokens.util.ts +++ b/src/tokens/tokens.util.ts @@ -169,35 +169,31 @@ export function packStreamName(prefix: string, instancePath: string) { } export function packSubscriptionName( - instancePath: string, + address: string, poolLocator: string, event: string, poolData?: string, ) { if (poolData !== undefined) { - return [ - SUBSCRIPTION_PREFIX, - instancePath, - poolLocator, - event, - encodeURIComponent(poolData), - ].join(':'); + return [SUBSCRIPTION_PREFIX, address, poolLocator, event, encodeURIComponent(poolData)].join( + ':', + ); } - return [SUBSCRIPTION_PREFIX, instancePath, poolLocator, event].join(':'); + return [SUBSCRIPTION_PREFIX, address, poolLocator, event].join(':'); } export function unpackSubscriptionName(data: string) { const parts = data.split(':'); if (parts.length === 5 && parts[0] === SUBSCRIPTION_PREFIX) { return { - instancePath: parts[1], + address: parts[1], poolLocator: parts[2], event: parts[3], poolData: decodeURIComponent(parts[4]), }; } else if (parts.length === 4) { return { - instancePath: parts[1], + address: parts[1], poolLocator: parts[2], event: parts[3], poolData: undefined, diff --git a/test/suites/api.ts b/test/suites/api.ts index 670f78b..7707eaf 100644 --- a/test/suites/api.ts +++ b/test/suites/api.ts @@ -14,7 +14,7 @@ import { CheckInterfaceResponse, } from '../../src/tokens/tokens.interfaces'; import { TestContext, FakeObservable, BASE_URL, CONTRACT_ADDRESS } from '../app.e2e-context'; -import { abi as ERC1155MixedFungibleAbi } from '../../src/abi/ERC1155MixedFungible.json'; +import { abi as ERC1155MixedFungibleAbi } from '../../src/abi/ERC1155MixedFungibleV1.json'; const queryHeader = 'Query'; const sendTransactionHeader = 'SendTransaction';