Address Details
contract

0x4E4dcb34c778BbfFF9CE8D7c97d7B93055f63837

Contract Name
NFTKToken
Creator
0x0ca82cā€“81b919 at 0xc371e8ā€“952778
Balance
0 CELO ( )
Tokens
Fetching tokens...
Transactions
9,501 Transactions
Transfers
0 Transfers
Gas Used
573,687,161
Last Balance Update
18365744
This contract has been verified via Sourcify. View contract in Sourcify repository
Contract name:
NFTKToken




Optimization enabled
false
Compiler version
v0.8.2+commit.661d1103




EVM Version
istanbul




Verified at
2022-09-19T17:58:14.784348Z

BIP20.sol

pragma solidity 0.8.2;

interface BIP20 {
  function totalSupply() external view returns (uint24);
  function decimals() external view returns (uint8);
  function symbol() external view returns (string memory);
  function name() external view returns (string memory);
  function getOwner() external view returns (address);
  function balanceOf(address account) external view returns (uint24);
  function transfer(address recipient, uint24 amount) external returns (bool);
  function allowance(address _owner, address spender) external view returns (uint24);
  function approve(address spender, uint24 amount) external returns (bool);
  function transferFrom(address sender, address recipient, uint24 amount) external returns (bool);
  event Transfer(address indexed from, address indexed to, uint24 value);
  event Approval(address indexed owner, address indexed spender, uint24 value);
} 

library ECDSA {
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        // Divide the signature in r, s and v variables
        bytes32 r;
        bytes32 s;
        uint8 v;
        if (signature.length == 65) {
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
        } else if (signature.length == 64) {
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            // solhint-disable-next-line no-inline-assembly
            assembly {
                let vs := mload(add(signature, 0x40))
                r := mload(add(signature, 0x20))
                s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
                v := add(shr(255, vs), 27)
            }
        } else {
            revert("ECDSA: invalid signature length");
        }

        return recover(hash, v, r, s);
    }
    function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {
        require(uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, "ECDSA: invalid signature 's' value");
        require(v == 27 || v == 28, "ECDSA: invalid signature 'v' value");
        address signer = ecrecover(hash, v, r, s);
        require(signer != address(0), "ECDSA: invalid signature");
        return signer;
    }
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}
contract Context {
  constructor ()  { }

  function _msgSender() internal view returns (address ) {
    return msg.sender;
  }

  function _msgData() internal view returns (bytes memory) {
    this; 
    return msg.data;
  }
}

library SafeMath {
  function add(uint24 a, uint24 b) internal pure returns (uint24) {
    uint24 c = a + b;
    require(c >= a, "SafeMath: addition overflow");
    return c;
  }
  function sub(uint24 a, uint24 b) internal pure returns (uint24) {
    return sub(a, b, "SafeMath: subtraction overflow");
  }

  function sub(uint24 a, uint24 b, string memory errorMessage) internal pure returns (uint24) {
    require(b <= a, errorMessage);
    uint24 c = a - b;

    return c;
  }
  function mul(uint24 a, uint24 b) internal pure returns (uint24) {
    // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
    if (a == 0) {
      return 0;
    }

    uint24 c = a * b;
    require(c / a == b, "SafeMath: multiplication overflow");

    return c;
  }

  function div(uint24 a, uint24 b) internal pure returns (uint24) {
    return div(a, b, "SafeMath: division by zero");
  }

  function div(uint24 a, uint24 b, string memory errorMessage) internal pure returns (uint24) {
    // Solidity only automatically asserts when dividing by 0
    require(b > 0, errorMessage);
    uint24 c = a / b;
    // assert(a == b * c + a % b); // There is no case in which this doesn't hold

    return c;
  }

  function mod(uint24 a, uint24 b) internal pure returns (uint24) {
    return mod(a, b, "SafeMath: modulo by zero");
  }

  function mod(uint24 a, uint24 b, string memory errorMessage) internal pure returns (uint24) {
    require(b != 0, errorMessage);
    return a % b;
  }
}

contract Ownable is Context {
  address private _owner;

  event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

  constructor ()  {
    address msgSender = _msgSender();
    _owner = msgSender;
    emit OwnershipTransferred(address(0), msgSender);
  }

  function owner() public view returns (address) {
    return _owner;
  }

  modifier onlyOwner() {
    require(_owner == _msgSender(), "Ownable: caller is not the owner");
    _;
  }

  function renounceOwnership() public onlyOwner {
    emit OwnershipTransferred(_owner, address(0));
    _owner = address(0);
  }

  function transferOwnership(address newOwner) public onlyOwner {
    _transferOwnership(newOwner);
  }

  function _transferOwnership(address newOwner) internal {
    require(newOwner != address(0), "Ownable: new owner is the zero address");
    emit OwnershipTransferred(_owner, newOwner);
    _owner = newOwner;
  }
}

contract NFTKToken is Context, BIP20, Ownable {
  using SafeMath for uint24;

  mapping (address => uint24) private _balances;

  mapping (address => mapping (address => uint24)) private _allowances;

  uint24 private _totalSupply;
  uint8 private _decimals;
  string private _symbol;
  string private _name;
  string private _ico;
  string private _baseURI;
 
  constructor() public {
    _name = "NFTicket Pay Token";
    _symbol = "NFTK";
    _decimals = 0;
    _ico = "QmPNAJEacA9FRnkirZxqm1xav4QizRhrNPNuSiX9yS3Vp2";
    _totalSupply = 400000;
    _balances[msg.sender] = _totalSupply;
    _baseURI="https://ipfs.io/ipfs/";
    DOMAIN_SEPARATOR = hashEIP712Domain(
    EIP712Domain({
                name : "EIP712Domain",
                version : "1",
                chainId : 100,
                verifyingContract : address(this)
                }));
    emit Transfer(address(0), msg.sender, _totalSupply);
  }

  function setBaseURI(string calldata _uri) external  returns (bool) {
    require(owner()==msg.sender,"Only owner");
    _baseURI = _uri;
    return true;
  }

  function getOwner() override external view returns (address) {
    return owner();
  }

  function getIconCID() external view returns (string memory) {
    return _ico;
  }
  function getBaseURI() external view returns (string memory) {
    return _baseURI;
  }

  function decimals() override external view returns (uint8) {
    return _decimals;
  }
  function symbol() override external view returns (string memory) {
    return _symbol;
  }
  function ico() external view returns (string memory) {
    return string(abi.encodePacked(_baseURI, _ico));
  }
  function icon() external view returns (string memory) {
    return string(abi.encodePacked(_baseURI, _ico));
  }

  /**
  * @dev Returns the token name.
  */
  function name() override external view returns (string memory) {
    return _name;
  }

  function totalSupply() override external view returns (uint24) {
    return _totalSupply;
  }

  function balanceOf(address account) override external view returns (uint24) {
    return _balances[account];
  }

  function transfer(address recipient, uint24 amount) override external returns (bool) {
    _transfer(_msgSender(), recipient, amount);
    return true;
  }

  function allowance(address owner, address spender) override external view returns (uint24) {
    return _allowances[owner][spender];
  }
  function approve(address spender, uint24 amount) override external returns (bool) {
    _approve(_msgSender(), spender, amount);
    return true;
  }

  function transferFrom(address sender, address recipient, uint24 amount) override external returns (bool) {
    _transfer(sender, recipient, amount);
    _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "NFTicket: transfer amount exceeds allowance"));
    return true;
  }

  function increaseAllowance(address spender, uint24 addedValue) public returns (bool) {
    _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
    return true;
  }

  function decreaseAllowance(address spender, uint24 subtractedValue) public returns (bool) {
    _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "NFTicket: decreased allowance below zero"));
    return true;
  }

  function mint(uint24 amount) public onlyOwner returns (bool) {
    _mint(_msgSender(), amount);
    return true;
  }

  function _transfer(address sender, address recipient, uint24 amount) internal {
    require(sender != address(0), "NFTicket: transfer from the zero address");
    require(recipient != address(0), "NFTicket: transfer to the zero address");

    _balances[sender] = _balances[sender].sub(amount, "NFTicket: transfer amount exceeds balance");
    _balances[recipient] = _balances[recipient].add(amount);
    emit Transfer(sender, recipient, amount);
  }

  function _mint(address account, uint24 amount) internal {
    require(account != address(0), "NFTicket: mint to the zero address");

    _totalSupply = _totalSupply.add(amount);
    _balances[account] = _balances[account].add(amount);
    emit Transfer(address(0), account, amount);
  }

  function _burn(address account, uint24 amount) internal {
    require(account != address(0), "NFTicket: burn from the zero address");

    _balances[account] = _balances[account].sub(amount, "NFTicket: burn amount exceeds balance");
    _totalSupply = _totalSupply.sub(amount);
    emit Transfer(account, address(0), amount);
  }

  function _approve(address owner, address spender, uint24 amount) internal {
    require(owner != address(0), "NFTicket: approve from the zero address");
    require(spender != address(0), "NFTicket: approve to the zero address");

    _allowances[owner][spender] = amount;
    emit Approval(owner, spender, amount);
  }

  function _burnFrom(address account, uint24 amount) internal {
    _burn(account, amount);
    _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, "NFTicket: burn amount exceeds allowance"));
  }

  /*SenderApprove*/
    using ECDSA for bytes32;
    bytes32 DOMAIN_SEPARATOR;
    bytes32 constant EIP712DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
    bytes32 constant internal VERIFIABLE_CREDENTIAL_TYPEHASH = keccak256("VerifiableCredential(address _from,address _to,string memory _nonce,uint24 _amount)");
    struct EIP712Domain {string name;string version;uint256 chainId;address verifyingContract;}
  
    function hashEIP712Domain(EIP712Domain memory eip712Domain) internal pure returns (bytes32) {
        return keccak256(abi.encode(EIP712DOMAIN_TYPEHASH,keccak256(bytes(eip712Domain.name)),keccak256(bytes(eip712Domain.version)),eip712Domain.chainId,eip712Domain.verifyingContract));
    }

    function hashForSigned(address _from, address _to, string memory nonce, uint24 amount) public view returns (bytes32) {
        return (_hashForSigned(nonce, _from, _to, amount));
    }

    function hashVerifiableCredential(address _from,address _to,string memory _nonce,uint24 _amount) private pure returns (bytes32) {//0xAABBCC11223344....556677
        return keccak256(abi.encode(VERIFIABLE_CREDENTIAL_TYPEHASH, _from, _to, _nonce,_amount));
    }

    function _hashForSigned(string memory _nonce, address _from, address _to, uint24 _amount) internal view returns (bytes32) {
        bytes32 digest = keccak256(
            abi.encodePacked(
                "\x19\x01",
                DOMAIN_SEPARATOR,
                hashVerifiableCredential(_from, _to, _nonce, _amount)
            )
        );
        return (digest);
    }
    struct metadata {
        address from;
        address to;
        uint24 amount;
        uint256 timestamp;
    } 
    mapping (string=>metadata) public nonces;
    
    function transferEndorsed(address _to, uint24 _amount, string calldata nonce, bytes32 _credentialHash, bytes memory _signature ) external  {
        address _from = _credentialHash.recover(_signature);
        require(nonces[nonce].timestamp==0, "nonce has been used");
        
        require(keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32",hashForSigned(_from, _to, nonce, _amount)))==_credentialHash, "Rejected Signed");
        nonces[nonce] = metadata(_from, _to, _amount, block.timestamp);
        _transfer(_from, _to, _amount);
    }
}
        

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[]},{"type":"event","name":"Approval","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"address","name":"spender","internalType":"address","indexed":true},{"type":"uint24","name":"value","internalType":"uint24","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint24","name":"value","internalType":"uint24","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint24","name":"","internalType":"uint24"}],"name":"allowance","inputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"address","name":"spender","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"approve","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint24","name":"amount","internalType":"uint24"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint24","name":"","internalType":"uint24"}],"name":"balanceOf","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"decimals","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"decreaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint24","name":"subtractedValue","internalType":"uint24"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"getBaseURI","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"getIconCID","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"getOwner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"hashForSigned","inputs":[{"type":"address","name":"_from","internalType":"address"},{"type":"address","name":"_to","internalType":"address"},{"type":"string","name":"nonce","internalType":"string"},{"type":"uint24","name":"amount","internalType":"uint24"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"ico","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"icon","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"increaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint24","name":"addedValue","internalType":"uint24"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"mint","inputs":[{"type":"uint24","name":"amount","internalType":"uint24"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint24","name":"amount","internalType":"uint24"},{"type":"uint256","name":"timestamp","internalType":"uint256"}],"name":"nonces","inputs":[{"type":"string","name":"","internalType":"string"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"setBaseURI","inputs":[{"type":"string","name":"_uri","internalType":"string"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"symbol","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint24","name":"","internalType":"uint24"}],"name":"totalSupply","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transfer","inputs":[{"type":"address","name":"recipient","internalType":"address"},{"type":"uint24","name":"amount","internalType":"uint24"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferEndorsed","inputs":[{"type":"address","name":"_to","internalType":"address"},{"type":"uint24","name":"_amount","internalType":"uint24"},{"type":"string","name":"nonce","internalType":"string"},{"type":"bytes32","name":"_credentialHash","internalType":"bytes32"},{"type":"bytes","name":"_signature","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transferFrom","inputs":[{"type":"address","name":"sender","internalType":"address"},{"type":"address","name":"recipient","internalType":"address"},{"type":"uint24","name":"amount","internalType":"uint24"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]}]
            

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106101585760003560e01c8063714c5398116100c3578063b24fce881161007c578063b24fce88146103e1578063c557b98514610414578063dd62ed3e14610432578063eaef4d8f14610462578063f2fde38b14610492578063f4de1e97146104ae57610158565b8063714c53981461032f578063715018a61461034d578063893d20e8146103575780638a65df46146103755780638da5cb5b146103a557806395d89b41146103c357610158565b80634f61fd2a116101155780634f61fd2a1461022157806355f804b3146102515780635b195c86146102815780635d452201146102b1578063601b7921146102cf57806370a08231146102ff57610158565b806306fdde031461015d578063176cd7101461017b57806318160ddd146101ab578063188743a8146101c9578063313ce567146101e75780633b983e5c14610205575b600080fd5b6101656104de565b60405161017291906127dd565b60405180910390f35b61019560048036038101906101909190612089565b610570565b6040516101a29190612708565b60405180910390f35b6101b361065d565b6040516101c091906129df565b60405180910390f35b6101d1610676565b6040516101de91906127dd565b60405180910390f35b6101ef610708565b6040516101fc91906129fa565b60405180910390f35b61021f600480360381019061021a9190612114565b61071d565b005b61023b600480360381019061023691906120d8565b610997565b6040516102489190612708565b60405180910390f35b61026b600480360381019061026691906121be565b610a78565b6040516102789190612708565b60405180910390f35b61029b600480360381019061029691906120d8565b610b0b565b6040516102a89190612708565b60405180910390f35b6102b9610b29565b6040516102c691906127dd565b60405180910390f35b6102e960048036038101906102e491906120d8565b610b54565b6040516102f69190612708565b60405180910390f35b61031960048036038101906103149190611fa9565b610b72565b60405161032691906129df565b60405180910390f35b610337610bca565b60405161034491906127dd565b60405180910390f35b610355610c5c565b005b61035f610daf565b60405161036c91906126a8565b60405180910390f35b61038f600480360381019061038a919061200e565b610dbe565b60405161039c9190612723565b60405180910390f35b6103ad610dd6565b6040516103ba91906126a8565b60405180910390f35b6103cb610dff565b6040516103d891906127dd565b60405180910390f35b6103fb60048036038101906103f69190612203565b610e91565b60405161040b94939291906126c3565b60405180910390f35b61041c610f26565b60405161042991906127dd565b60405180910390f35b61044c60048036038101906104479190611fd2565b610f51565b60405161045991906129df565b60405180910390f35b61047c60048036038101906104779190612244565b610fe7565b6040516104899190612708565b60405180910390f35b6104ac60048036038101906104a79190611fa9565b611098565b005b6104c860048036038101906104c391906120d8565b611139565b6040516104d59190612708565b60405180910390f35b6060600580546104ed90612bf5565b80601f016020809104026020016040519081016040528092919081815260200182805461051990612bf5565b80156105665780601f1061053b57610100808354040283529160200191610566565b820191906000526020600020905b81548152906001019060200180831161054957829003601f168201915b5050505050905090565b600061057d848484611200565b610652846105896114e6565b61064d856040518060600160405280602b8152602001613157602b9139600260008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006105ef6114e6565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900462ffffff1662ffffff166114ee9092919063ffffffff16565b61155c565b600190509392505050565b6000600360009054906101000a900462ffffff16905090565b60606006805461068590612bf5565b80601f01602080910402602001604051908101604052809291908181526020018280546106b190612bf5565b80156106fe5780601f106106d3576101008083540402835291602001916106fe565b820191906000526020600020905b8154815290600101906020018083116106e157829003601f168201915b5050505050905090565b600060038054906101000a900460ff16905090565b6000610732828461173f90919063ffffffff16565b905060006009868660405161074892919061260e565b9081526020016040518091039020600201541461079a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107919061281f565b60405180910390fd5b826107eb828988888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508a610dbe565b6040516020016107fb919061264b565b6040516020818303038152906040528051906020012014610851576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108489061299f565b60405180910390fd5b60405180608001604052808273ffffffffffffffffffffffffffffffffffffffff1681526020018873ffffffffffffffffffffffffffffffffffffffff1681526020018762ffffff16815260200142815250600986866040516108b592919061260e565b908152602001604051809103902060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160146101000a81548162ffffff021916908362ffffff1602179055506060820151816002015590505061098e818888611200565b50505050505050565b6000610a6e6109a46114e6565b84610a698560405180606001604052806028815260200161312f60289139600260006109ce6114e6565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900462ffffff1662ffffff166114ee9092919063ffffffff16565b61155c565b6001905092915050565b60003373ffffffffffffffffffffffffffffffffffffffff16610a99610dd6565b73ffffffffffffffffffffffffffffffffffffffff1614610aef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae69061285f565b60405180910390fd5b828260079190610b00929190611dad565b506001905092915050565b6000610b1f610b186114e6565b8484611200565b6001905092915050565b606060076006604051602001610b40929190612627565b604051602081830303815290604052905090565b6000610b68610b616114e6565b848461155c565b6001905092915050565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900462ffffff169050919050565b606060078054610bd990612bf5565b80601f0160208091040260200160405190810160405280929190818152602001828054610c0590612bf5565b8015610c525780601f10610c2757610100808354040283529160200191610c52565b820191906000526020600020905b815481529060010190602001808311610c3557829003601f168201915b5050505050905090565b610c646114e6565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610cf1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce89061297f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6000610db9610dd6565b905090565b6000610dcc83868685611809565b9050949350505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060048054610e0e90612bf5565b80601f0160208091040260200160405190810160405280929190818152602001828054610e3a90612bf5565b8015610e875780601f10610e5c57610100808354040283529160200191610e87565b820191906000526020600020905b815481529060010190602001808311610e6a57829003601f168201915b5050505050905090565b6009818051602081018201805184825260208301602085012081835280955050505050506000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010160149054906101000a900462ffffff16908060020154905084565b606060076006604051602001610f3d929190612627565b604051602081830303815290604052905090565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900462ffffff16905092915050565b6000610ff16114e6565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461107e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110759061297f565b60405180910390fd5b61108f6110896114e6565b83611850565b60019050919050565b6110a06114e6565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461112d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111249061297f565b60405180910390fd5b61113681611a32565b50565b60006111f66111466114e6565b846111f185600260006111576114e6565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900462ffffff1662ffffff16611b5f90919063ffffffff16565b61155c565b6001905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611270576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112679061291f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156112e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112d7906129bf565b60405180910390fd5b6113608160405180606001604052806029815260200161318260299139600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900462ffffff1662ffffff166114ee9092919063ffffffff16565b600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548162ffffff021916908362ffffff16021790555061142181600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900462ffffff1662ffffff16611b5f90919063ffffffff16565b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548162ffffff021916908362ffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f4c3f23e06500a14887485511327c0d579fbccac302d5839c043bcc62bf867793836040516114d991906129df565b60405180910390a3505050565b600033905090565b60008362ffffff168362ffffff1611158290611540576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161153791906127dd565b60405180910390fd5b506000838561154f9190612b11565b9050809150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156115cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115c3906128bf565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561163c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611633906128df565b60405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548162ffffff021916908362ffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3ba96ffca58a5c0843f7fa57ac208298b3b86e7feed3d33a9f706270c2626e98360405161173291906129df565b60405180910390a3505050565b60008060008060418551141561176c576020850151925060408501519150606085015160001a90506117f2565b6040855114156117b6576040850151602086015193507f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81169250601b8160ff1c019150506117f1565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117e89061283f565b60405180910390fd5b5b6117fe86828585611bc7565b935050505092915050565b60008060085461181b86868987611d52565b60405160200161182c929190612671565b60405160208183030381529060405280519060200120905080915050949350505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156118c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118b79061293f565b60405180910390fd5b6118e981600360009054906101000a900462ffffff1662ffffff16611b5f90919063ffffffff16565b600360006101000a81548162ffffff021916908362ffffff16021790555061196d81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900462ffffff1662ffffff16611b5f90919063ffffffff16565b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548162ffffff021916908362ffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f4c3f23e06500a14887485511327c0d579fbccac302d5839c043bcc62bf86779383604051611a2691906129df565b60405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611aa2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a999061287f565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000808284611b6e9190612ad8565b90508362ffffff168162ffffff161015611bbd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bb49061289f565b60405180910390fd5b8091505092915050565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08260001c1115611c2f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c26906128ff565b60405180910390fd5b601b8460ff161480611c445750601c8460ff16145b611c83576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c7a9061295f565b60405180910390fd5b600060018686868660405160008152602001604052604051611ca89493929190612798565b6020604051602081039080840390855afa158015611cca573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611d46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d3d906127ff565b60405180910390fd5b80915050949350505050565b60007f3efe3925ba93c28c7944cc84259652d04d52d8432cdf969fbc64becfa5ebf33f85858585604051602001611d8d95949392919061273e565b604051602081830303815290604052805190602001209050949350505050565b828054611db990612bf5565b90600052602060002090601f016020900481019282611ddb5760008555611e22565b82601f10611df457803560ff1916838001178555611e22565b82800160010185558215611e22579182015b82811115611e21578235825591602001919060010190611e06565b5b509050611e2f9190611e33565b5090565b5b80821115611e4c576000816000905550600101611e34565b5090565b6000611e63611e5e84612a3a565b612a15565b905082815260208101848484011115611e7b57600080fd5b611e86848285612bb3565b509392505050565b6000611ea1611e9c84612a6b565b612a15565b905082815260208101848484011115611eb957600080fd5b611ec4848285612bb3565b509392505050565b600081359050611edb816130e9565b92915050565b600081359050611ef081613100565b92915050565b600082601f830112611f0757600080fd5b8135611f17848260208601611e50565b91505092915050565b60008083601f840112611f3257600080fd5b8235905067ffffffffffffffff811115611f4b57600080fd5b602083019150836001820283011115611f6357600080fd5b9250929050565b600082601f830112611f7b57600080fd5b8135611f8b848260208601611e8e565b91505092915050565b600081359050611fa381613117565b92915050565b600060208284031215611fbb57600080fd5b6000611fc984828501611ecc565b91505092915050565b60008060408385031215611fe557600080fd5b6000611ff385828601611ecc565b925050602061200485828601611ecc565b9150509250929050565b6000806000806080858703121561202457600080fd5b600061203287828801611ecc565b945050602061204387828801611ecc565b935050604085013567ffffffffffffffff81111561206057600080fd5b61206c87828801611f6a565b925050606061207d87828801611f94565b91505092959194509250565b60008060006060848603121561209e57600080fd5b60006120ac86828701611ecc565b93505060206120bd86828701611ecc565b92505060406120ce86828701611f94565b9150509250925092565b600080604083850312156120eb57600080fd5b60006120f985828601611ecc565b925050602061210a85828601611f94565b9150509250929050565b60008060008060008060a0878903121561212d57600080fd5b600061213b89828a01611ecc565b965050602061214c89828a01611f94565b955050604087013567ffffffffffffffff81111561216957600080fd5b61217589828a01611f20565b9450945050606061218889828a01611ee1565b925050608087013567ffffffffffffffff8111156121a557600080fd5b6121b189828a01611ef6565b9150509295509295509295565b600080602083850312156121d157600080fd5b600083013567ffffffffffffffff8111156121eb57600080fd5b6121f785828601611f20565b92509250509250929050565b60006020828403121561221557600080fd5b600082013567ffffffffffffffff81111561222f57600080fd5b61223b84828501611f6a565b91505092915050565b60006020828403121561225657600080fd5b600061226484828501611f94565b91505092915050565b61227681612b45565b82525050565b61228581612b57565b82525050565b61229481612b63565b82525050565b6122ab6122a682612b63565b612c58565b82525050565b60006122bd8385612acd565b93506122ca838584612bb3565b82840190509392505050565b60006122e182612ab1565b6122eb8185612abc565b93506122fb818560208601612bc2565b61230481612cef565b840191505092915050565b6000815461231c81612bf5565b6123268186612acd565b94506001821660008114612341576001811461235257612385565b60ff19831686528186019350612385565b61235b85612a9c565b60005b8381101561237d5781548189015260018201915060208101905061235e565b838801955050505b50505092915050565b600061239b601883612abc565b91506123a682612d00565b602082019050919050565b60006123be601383612abc565b91506123c982612d29565b602082019050919050565b60006123e1601f83612abc565b91506123ec82612d52565b602082019050919050565b6000612404601c83612acd565b915061240f82612d7b565b601c82019050919050565b6000612427600a83612abc565b915061243282612da4565b602082019050919050565b600061244a602683612abc565b915061245582612dcd565b604082019050919050565b600061246d600283612acd565b915061247882612e1c565b600282019050919050565b6000612490601b83612abc565b915061249b82612e45565b602082019050919050565b60006124b3602783612abc565b91506124be82612e6e565b604082019050919050565b60006124d6602583612abc565b91506124e182612ebd565b604082019050919050565b60006124f9602283612abc565b915061250482612f0c565b604082019050919050565b600061251c602883612abc565b915061252782612f5b565b604082019050919050565b600061253f602283612abc565b915061254a82612faa565b604082019050919050565b6000612562602283612abc565b915061256d82612ff9565b604082019050919050565b6000612585602083612abc565b915061259082613048565b602082019050919050565b60006125a8600f83612abc565b91506125b382613071565b602082019050919050565b60006125cb602683612abc565b91506125d68261309a565b604082019050919050565b6125ea81612b8d565b82525050565b6125f981612b9c565b82525050565b61260881612ba6565b82525050565b600061261b8284866122b1565b91508190509392505050565b6000612633828561230f565b915061263f828461230f565b91508190509392505050565b6000612656826123f7565b9150612662828461229a565b60208201915081905092915050565b600061267c82612460565b9150612688828561229a565b602082019150612698828461229a565b6020820191508190509392505050565b60006020820190506126bd600083018461226d565b92915050565b60006080820190506126d8600083018761226d565b6126e5602083018661226d565b6126f260408301856125e1565b6126ff60608301846125f0565b95945050505050565b600060208201905061271d600083018461227c565b92915050565b6000602082019050612738600083018461228b565b92915050565b600060a082019050612753600083018861228b565b612760602083018761226d565b61276d604083018661226d565b818103606083015261277f81856122d6565b905061278e60808301846125e1565b9695505050505050565b60006080820190506127ad600083018761228b565b6127ba60208301866125ff565b6127c7604083018561228b565b6127d4606083018461228b565b95945050505050565b600060208201905081810360008301526127f781846122d6565b905092915050565b600060208201905081810360008301526128188161238e565b9050919050565b60006020820190508181036000830152612838816123b1565b9050919050565b60006020820190508181036000830152612858816123d4565b9050919050565b600060208201905081810360008301526128788161241a565b9050919050565b600060208201905081810360008301526128988161243d565b9050919050565b600060208201905081810360008301526128b881612483565b9050919050565b600060208201905081810360008301526128d8816124a6565b9050919050565b600060208201905081810360008301526128f8816124c9565b9050919050565b60006020820190508181036000830152612918816124ec565b9050919050565b600060208201905081810360008301526129388161250f565b9050919050565b6000602082019050818103600083015261295881612532565b9050919050565b6000602082019050818103600083015261297881612555565b9050919050565b6000602082019050818103600083015261299881612578565b9050919050565b600060208201905081810360008301526129b88161259b565b9050919050565b600060208201905081810360008301526129d8816125be565b9050919050565b60006020820190506129f460008301846125e1565b92915050565b6000602082019050612a0f60008301846125ff565b92915050565b6000612a1f612a30565b9050612a2b8282612c27565b919050565b6000604051905090565b600067ffffffffffffffff821115612a5557612a54612cc0565b5b612a5e82612cef565b9050602081019050919050565b600067ffffffffffffffff821115612a8657612a85612cc0565b5b612a8f82612cef565b9050602081019050919050565b60008190508160005260206000209050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b6000612ae382612b8d565b9150612aee83612b8d565b92508262ffffff03821115612b0657612b05612c62565b5b828201905092915050565b6000612b1c82612b8d565b9150612b2783612b8d565b925082821015612b3a57612b39612c62565b5b828203905092915050565b6000612b5082612b6d565b9050919050565b60008115159050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062ffffff82169050919050565b6000819050919050565b600060ff82169050919050565b82818337600083830152505050565b60005b83811015612be0578082015181840152602081019050612bc5565b83811115612bef576000848401525b50505050565b60006002820490506001821680612c0d57607f821691505b60208210811415612c2157612c20612c91565b5b50919050565b612c3082612cef565b810181811067ffffffffffffffff82111715612c4f57612c4e612cc0565b5b80604052505050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b7f6e6f6e636520686173206265656e207573656400000000000000000000000000600082015250565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b7f4f6e6c79206f776e657200000000000000000000000000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000600082015250565b7f4e465469636b65743a20617070726f76652066726f6d20746865207a65726f2060008201527f6164647265737300000000000000000000000000000000000000000000000000602082015250565b7f4e465469636b65743a20617070726f766520746f20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b7f4e465469636b65743a207472616e736665722066726f6d20746865207a65726f60008201527f2061646472657373000000000000000000000000000000000000000000000000602082015250565b7f4e465469636b65743a206d696e7420746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b7f45434453413a20696e76616c6964207369676e6174757265202776272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f52656a6563746564205369676e65640000000000000000000000000000000000600082015250565b7f4e465469636b65743a207472616e7366657220746f20746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6130f281612b45565b81146130fd57600080fd5b50565b61310981612b63565b811461311457600080fd5b50565b61312081612b8d565b811461312b57600080fd5b5056fe4e465469636b65743a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726f4e465469636b65743a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654e465469636b65743a207472616e7366657220616d6f756e7420657863656564732062616c616e6365a2646970667358221220b9c1de1d8479283b40bb6d0bc0b6df5830b728ad827041fbae55dbcd3f96eea064736f6c63430008020033