ETH Price: $3,317.16 (-0.67%)
Gas: 6.44 Gwei
 

Overview

Max Total Supply

177 PTC

Holders

32

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
maksimi4.eth
Balance
1 PTC
0xffe1ce2814116b47b5f4d20a208b773dcc1fef20
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

Own, trade and game with collectible plots of planet earth.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
PlanetCryptoToken

Compiler Version
v0.4.24+commit.e67f0147

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2018-11-16
*/

pragma solidity ^0.4.24;

/**
 * @title IERC165
 * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md
 */
interface IERC165 {

  /**
   * @notice Query if a contract implements an interface
   * @param interfaceId The interface identifier, as specified in ERC-165
   * @dev Interface identification is specified in ERC-165. This function
   * uses less than 30,000 gas.
   */
  function supportsInterface(bytes4 interfaceId)
    external
    view
    returns (bool);
}



/**
 * @title ERC165
 * @author Matt Condon (@shrugs)
 * @dev Implements ERC165 using a lookup table.
 */
contract ERC165 is IERC165 {

  bytes4 private constant _InterfaceId_ERC165 = 0x01ffc9a7;
  /**
   * 0x01ffc9a7 ===
   *   bytes4(keccak256('supportsInterface(bytes4)'))
   */

  /**
   * @dev a mapping of interface id to whether or not it's supported
   */
  mapping(bytes4 => bool) private _supportedInterfaces;

  /**
   * @dev A contract implementing SupportsInterfaceWithLookup
   * implement ERC165 itself
   */
  constructor()
    internal
  {
    _registerInterface(_InterfaceId_ERC165);
  }

  /**
   * @dev implement supportsInterface(bytes4) using a lookup table
   */
  function supportsInterface(bytes4 interfaceId)
    external
    view
    returns (bool)
  {
    return _supportedInterfaces[interfaceId];
  }

  /**
   * @dev internal method for registering an interface
   */
  function _registerInterface(bytes4 interfaceId)
    internal
  {
    require(interfaceId != 0xffffffff);
    _supportedInterfaces[interfaceId] = true;
  }
}

// current address: 0x499E33164116002329Bf4bB8f7B2dfc97A31F223












/**
 * @title ERC721 Non-Fungible Token Standard basic interface
 * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract IERC721 is IERC165 {

  event Transfer(
    address indexed from,
    address indexed to,
    uint256 indexed tokenId
  );
  event Approval(
    address indexed owner,
    address indexed approved,
    uint256 indexed tokenId
  );
  event ApprovalForAll(
    address indexed owner,
    address indexed operator,
    bool approved
  );

  function balanceOf(address owner) public view returns (uint256 balance);
  function ownerOf(uint256 tokenId) public view returns (address owner);

  function approve(address to, uint256 tokenId) public;
  function getApproved(uint256 tokenId)
    public view returns (address operator);

  function setApprovalForAll(address operator, bool _approved) public;
  function isApprovedForAll(address owner, address operator)
    public view returns (bool);

  function transferFrom(address from, address to, uint256 tokenId) public;
  function safeTransferFrom(address from, address to, uint256 tokenId)
    public;

  function safeTransferFrom(
    address from,
    address to,
    uint256 tokenId,
    bytes data
  )
    public;
}


/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
contract IERC721Receiver {
  /**
   * @notice Handle the receipt of an NFT
   * @dev The ERC721 smart contract calls this function on the recipient
   * after a `safeTransfer`. This function MUST return the function selector,
   * otherwise the caller will revert the transaction. The selector to be
   * returned can be obtained as `this.onERC721Received.selector`. This
   * function MAY throw to revert and reject the transfer.
   * Note: the ERC721 contract address is always the message sender.
   * @param operator The address which called `safeTransferFrom` function
   * @param from The address which previously owned the token
   * @param tokenId The NFT identifier which is being transferred
   * @param data Additional data with no specified format
   * @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
   */
  function onERC721Received(
    address operator,
    address from,
    uint256 tokenId,
    bytes data
  )
    public
    returns(bytes4);
}


/**
 * @title SafeMath
 * @dev Math operations with safety checks that revert on error
 */
library SafeMath {

  /**
  * @dev Multiplies two numbers, reverts on overflow.
  */
  function mul(uint256 a, uint256 b) internal pure returns (uint256) {
    // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
    // benefit is lost if 'b' is also tested.
    // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
    if (a == 0) {
      return 0;
    }

    uint256 c = a * b;
    require(c / a == b);

    return c;
  }

  /**
  * @dev Integer division of two numbers truncating the quotient, reverts on division by zero.
  */
  function div(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b > 0); // Solidity only automatically asserts when dividing by 0
    uint256 c = a / b;
    // assert(a == b * c + a % b); // There is no case in which this doesn't hold

    return c;
  }

  /**
  * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).
  */
  function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b <= a);
    uint256 c = a - b;

    return c;
  }

  /**
  * @dev Adds two numbers, reverts on overflow.
  */
  function add(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a + b;
    require(c >= a);

    return c;
  }

  /**
  * @dev Divides two numbers and returns the remainder (unsigned integer modulo),
  * reverts when dividing by zero.
  */
  function mod(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b != 0);
    return a % b;
  }
}


/**
 * Utility library of inline functions on addresses
 */
library Address {

  /**
   * Returns whether the target address is a contract
   * @dev This function will return false if invoked during the constructor of a contract,
   * as the code is not actually created until after the constructor finishes.
   * @param account address of the account to check
   * @return whether the target address is a contract
   */
  function isContract(address account) internal view returns (bool) {
    uint256 size;
    // XXX Currently there is no better way to check if there is a contract in an address
    // than to check the size of the code at that address.
    // See https://ethereum.stackexchange.com/a/14016/36603
    // for more details about how this works.
    // TODO Check this again before the Serenity release, because all addresses will be
    // contracts then.
    // solium-disable-next-line security/no-inline-assembly
    assembly { size := extcodesize(account) }
    return size > 0;
  }

}


/**
 * @title ERC721 Non-Fungible Token Standard basic implementation
 * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721_custom is ERC165, IERC721 {

  using SafeMath for uint256;
  using Address for address;

  // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
  // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`
  bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;

  // Mapping from token ID to owner
  mapping (uint256 => address) private _tokenOwner;

  // Mapping from token ID to approved address
  mapping (uint256 => address) private _tokenApprovals;

  // Mapping from owner to number of owned token
  mapping (address => uint256) private _ownedTokensCount;

  // Mapping from owner to operator approvals
  mapping (address => mapping (address => bool)) private _operatorApprovals;

  bytes4 private constant _InterfaceId_ERC721 = 0x80ac58cd;
  /*
   * 0x80ac58cd ===
   *   bytes4(keccak256('balanceOf(address)')) ^
   *   bytes4(keccak256('ownerOf(uint256)')) ^
   *   bytes4(keccak256('approve(address,uint256)')) ^
   *   bytes4(keccak256('getApproved(uint256)')) ^
   *   bytes4(keccak256('setApprovalForAll(address,bool)')) ^
   *   bytes4(keccak256('isApprovedForAll(address,address)')) ^
   *   bytes4(keccak256('transferFrom(address,address,uint256)')) ^
   *   bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^
   *   bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)'))
   */

  constructor()
    public
  {
    // register the supported interfaces to conform to ERC721 via ERC165
    _registerInterface(_InterfaceId_ERC721);
  }

  /**
   * @dev Gets the balance of the specified address
   * @param owner address to query the balance of
   * @return uint256 representing the amount owned by the passed address
   */
  function balanceOf(address owner) public view returns (uint256) {
    require(owner != address(0));
    return _ownedTokensCount[owner];
  }

  /**
   * @dev Gets the owner of the specified token ID
   * @param tokenId uint256 ID of the token to query the owner of
   * @return owner address currently marked as the owner of the given token ID
   */
  function ownerOf(uint256 tokenId) public view returns (address) {
    address owner = _tokenOwner[tokenId];
    require(owner != address(0));
    return owner;
  }

  /**
   * @dev Approves another address to transfer the given token ID
   * The zero address indicates there is no approved address.
   * There can only be one approved address per token at a given time.
   * Can only be called by the token owner or an approved operator.
   * @param to address to be approved for the given token ID
   * @param tokenId uint256 ID of the token to be approved
   */
  function approve(address to, uint256 tokenId) public {
    address owner = ownerOf(tokenId);
    require(to != owner);
    require(msg.sender == owner || isApprovedForAll(owner, msg.sender));

    _tokenApprovals[tokenId] = to;
    emit Approval(owner, to, tokenId);
  }

  /**
   * @dev Gets the approved address for a token ID, or zero if no address set
   * Reverts if the token ID does not exist.
   * @param tokenId uint256 ID of the token to query the approval of
   * @return address currently approved for the given token ID
   */
  function getApproved(uint256 tokenId) public view returns (address) {
    require(_exists(tokenId));
    return _tokenApprovals[tokenId];
  }

  /**
   * @dev Sets or unsets the approval of a given operator
   * An operator is allowed to transfer all tokens of the sender on their behalf
   * @param to operator address to set the approval
   * @param approved representing the status of the approval to be set
   */
  function setApprovalForAll(address to, bool approved) public {
    require(to != msg.sender);
    _operatorApprovals[msg.sender][to] = approved;
    emit ApprovalForAll(msg.sender, to, approved);
  }

  /**
   * @dev Tells whether an operator is approved by a given owner
   * @param owner owner address which you want to query the approval of
   * @param operator operator address which you want to query the approval of
   * @return bool whether the given operator is approved by the given owner
   */
  function isApprovedForAll(
    address owner,
    address operator
  )
    public
    view
    returns (bool)
  {
    return _operatorApprovals[owner][operator];
  }

  /**
   * @dev Transfers the ownership of a given token ID to another address
   * Usage of this method is discouraged, use `safeTransferFrom` whenever possible
   * Requires the msg sender to be the owner, approved, or operator
   * @param from current owner of the token
   * @param to address to receive the ownership of the given token ID
   * @param tokenId uint256 ID of the token to be transferred
  */
  function transferFrom(
    address from,
    address to,
    uint256 tokenId
  )
    public
  {
    require(_isApprovedOrOwner(msg.sender, tokenId));
    require(to != address(0));

    _clearApproval(from, tokenId);
    _removeTokenFrom(from, tokenId);
    _addTokenTo(to, tokenId);

    emit Transfer(from, to, tokenId);
  }
  
  
  
  
    function internal_transferFrom(
        address _from,
        address to,
        uint256 tokenId
    )
    internal
  {
    // permissions already checked on price basis
    
    require(to != address(0));

    if (_tokenApprovals[tokenId] != address(0)) {
      _tokenApprovals[tokenId] = address(0);
    }
    
    //_removeTokenFrom(from, tokenId);
    if(_ownedTokensCount[_from] > 1) {
    _ownedTokensCount[_from] = _ownedTokensCount[_from] -1; //.sub(1); // error here
    // works without .sub()????
    
    }
    _tokenOwner[tokenId] = address(0); 
    
    _addTokenTo(to, tokenId); // error here?

    emit Transfer(_from, to, tokenId);
    
  }

  /**
   * @dev Safely transfers the ownership of a given token ID to another address
   * If the target address is a contract, it must implement `onERC721Received`,
   * which is called upon a safe transfer, and return the magic value
   * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
   * the transfer is reverted.
   *
   * Requires the msg sender to be the owner, approved, or operator
   * @param from current owner of the token
   * @param to address to receive the ownership of the given token ID
   * @param tokenId uint256 ID of the token to be transferred
  */
  function safeTransferFrom(
    address from,
    address to,
    uint256 tokenId
  )
    public
  {
    // solium-disable-next-line arg-overflow
    safeTransferFrom(from, to, tokenId, "");
  }

  /**
   * @dev Safely transfers the ownership of a given token ID to another address
   * If the target address is a contract, it must implement `onERC721Received`,
   * which is called upon a safe transfer, and return the magic value
   * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
   * the transfer is reverted.
   * Requires the msg sender to be the owner, approved, or operator
   * @param from current owner of the token
   * @param to address to receive the ownership of the given token ID
   * @param tokenId uint256 ID of the token to be transferred
   * @param _data bytes data to send along with a safe transfer check
   */
  function safeTransferFrom(
    address from,
    address to,
    uint256 tokenId,
    bytes _data
  )
    public
  {
    transferFrom(from, to, tokenId);
    // solium-disable-next-line arg-overflow
    require(_checkOnERC721Received(from, to, tokenId, _data));
  }

  /**
   * @dev Returns whether the specified token exists
   * @param tokenId uint256 ID of the token to query the existence of
   * @return whether the token exists
   */
  function _exists(uint256 tokenId) internal view returns (bool) {
    address owner = _tokenOwner[tokenId];
    return owner != address(0);
  }

  /**
   * @dev Returns whether the given spender can transfer a given token ID
   * @param spender address of the spender to query
   * @param tokenId uint256 ID of the token to be transferred
   * @return bool whether the msg.sender is approved for the given token ID,
   *  is an operator of the owner, or is the owner of the token
   */
  function _isApprovedOrOwner(
    address spender,
    uint256 tokenId
  )
    internal
    view
    returns (bool)
  {
    address owner = ownerOf(tokenId);
    // Disable solium check because of
    // https://github.com/duaraghav8/Solium/issues/175
    // solium-disable-next-line operator-whitespace
    return (
      spender == owner ||
      getApproved(tokenId) == spender ||
      isApprovedForAll(owner, spender)
    );
  }

  /**
   * @dev Internal function to mint a new token
   * Reverts if the given token ID already exists
   * @param to The address that will own the minted token
   * @param tokenId uint256 ID of the token to be minted by the msg.sender
   */
  function _mint(address to, uint256 tokenId) internal {
    require(to != address(0));
    _addTokenTo(to, tokenId);
    emit Transfer(address(0), to, tokenId);
  }

  /**
   * @dev Internal function to burn a specific token
   * Reverts if the token does not exist
   * @param tokenId uint256 ID of the token being burned by the msg.sender
   */
  function _burn(address owner, uint256 tokenId) internal {
    _clearApproval(owner, tokenId);
    _removeTokenFrom(owner, tokenId);
    emit Transfer(owner, address(0), tokenId);
  }

  /**
   * @dev Internal function to add a token ID to the list of a given address
   * Note that this function is left internal to make ERC721Enumerable possible, but is not
   * intended to be called by custom derived contracts: in particular, it emits no Transfer event.
   * @param to address representing the new owner of the given token ID
   * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
   */
  function _addTokenTo(address to, uint256 tokenId) internal {
    require(_tokenOwner[tokenId] == address(0));
    _tokenOwner[tokenId] = to;
    _ownedTokensCount[to] = _ownedTokensCount[to].add(1);
  }

  /**
   * @dev Internal function to remove a token ID from the list of a given address
   * Note that this function is left internal to make ERC721Enumerable possible, but is not
   * intended to be called by custom derived contracts: in particular, it emits no Transfer event,
   * and doesn't clear approvals.
   * @param from address representing the previous owner of the given token ID
   * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
   */
  function _removeTokenFrom(address from, uint256 tokenId) internal {
    require(ownerOf(tokenId) == from);
    _ownedTokensCount[from] = _ownedTokensCount[from].sub(1);
    _tokenOwner[tokenId] = address(0);
  }
  
  

  /**
   * @dev Internal function to invoke `onERC721Received` on a target address
   * The call is not executed if the target address is not a contract
   * @param from address representing the previous owner of the given token ID
   * @param to target address that will receive the tokens
   * @param tokenId uint256 ID of the token to be transferred
   * @param _data bytes optional data to send along with the call
   * @return whether the call correctly returned the expected magic value
   */
  function _checkOnERC721Received(
    address from,
    address to,
    uint256 tokenId,
    bytes _data
  )
    internal
    returns (bool)
  {
    if (!to.isContract()) {
      return true;
    }
    bytes4 retval = IERC721Receiver(to).onERC721Received(
      msg.sender, from, tokenId, _data);
    return (retval == _ERC721_RECEIVED);
  }

  /**
   * @dev Private function to clear current approval of a given token ID
   * Reverts if the given address is not indeed the owner of the token
   * @param owner owner of the token
   * @param tokenId uint256 ID of the token to be transferred
   */
  function _clearApproval(address owner, uint256 tokenId) private {
    require(ownerOf(tokenId) == owner);
    if (_tokenApprovals[tokenId] != address(0)) {
      _tokenApprovals[tokenId] = address(0);
    }
  }
}






/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract IERC721Enumerable is IERC721 {
  function totalSupply() public view returns (uint256);
  function tokenOfOwnerByIndex(
    address owner,
    uint256 index
  )
    public
    view
    returns (uint256 tokenId);

  function tokenByIndex(uint256 index) public view returns (uint256);
}



/**
 * @title ERC-721 Non-Fungible Token with optional enumeration extension logic
 * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721Enumerable_custom is ERC165, ERC721_custom, IERC721Enumerable {
  // Mapping from owner to list of owned token IDs
  mapping(address => uint256[]) private _ownedTokens;

  // Mapping from token ID to index of the owner tokens list
  mapping(uint256 => uint256) private _ownedTokensIndex;

  // Array with all token ids, used for enumeration
  uint256[] private _allTokens;

  // Mapping from token id to position in the allTokens array
  mapping(uint256 => uint256) private _allTokensIndex;

  bytes4 private constant _InterfaceId_ERC721Enumerable = 0x780e9d63;
  /**
   * 0x780e9d63 ===
   *   bytes4(keccak256('totalSupply()')) ^
   *   bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) ^
   *   bytes4(keccak256('tokenByIndex(uint256)'))
   */

  /**
   * @dev Constructor function
   */
  constructor() public {
    // register the supported interface to conform to ERC721 via ERC165
    _registerInterface(_InterfaceId_ERC721Enumerable);
  }

  /**
   * @dev Gets the token ID at a given index of the tokens list of the requested owner
   * @param owner address owning the tokens list to be accessed
   * @param index uint256 representing the index to be accessed of the requested tokens list
   * @return uint256 token ID at the given index of the tokens list owned by the requested address
   */
  function tokenOfOwnerByIndex(
    address owner,
    uint256 index
  )
    public
    view
    returns (uint256)
  {
    require(index < balanceOf(owner));
    return _ownedTokens[owner][index];
  }

  /**
   * @dev Gets the total amount of tokens stored by the contract
   * @return uint256 representing the total amount of tokens
   */
  function totalSupply() public view returns (uint256) {
    return _allTokens.length;
  }

  /**
   * @dev Gets the token ID at a given index of all the tokens in this contract
   * Reverts if the index is greater or equal to the total number of tokens
   * @param index uint256 representing the index to be accessed of the tokens list
   * @return uint256 token ID at the given index of the tokens list
   */
  function tokenByIndex(uint256 index) public view returns (uint256) {
    require(index < totalSupply());
    return _allTokens[index];
  }

  /**
   * @dev Internal function to add a token ID to the list of a given address
   * This function is internal due to language limitations, see the note in ERC721.sol.
   * It is not intended to be called by custom derived contracts: in particular, it emits no Transfer event.
   * @param to address representing the new owner of the given token ID
   * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
   */
  function _addTokenTo(address to, uint256 tokenId) internal {
    super._addTokenTo(to, tokenId);
    uint256 length = _ownedTokens[to].length;
    _ownedTokens[to].push(tokenId);
    _ownedTokensIndex[tokenId] = length;
  }

  /**
   * @dev Internal function to remove a token ID from the list of a given address
   * This function is internal due to language limitations, see the note in ERC721.sol.
   * It is not intended to be called by custom derived contracts: in particular, it emits no Transfer event,
   * and doesn't clear approvals.
   * @param from address representing the previous owner of the given token ID
   * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
   */
  function _removeTokenFrom(address from, uint256 tokenId) internal {
    super._removeTokenFrom(from, tokenId);

    // To prevent a gap in the array, we store the last token in the index of the token to delete, and
    // then delete the last slot.
    uint256 tokenIndex = _ownedTokensIndex[tokenId];
    uint256 lastTokenIndex = _ownedTokens[from].length.sub(1);
    uint256 lastToken = _ownedTokens[from][lastTokenIndex];

    _ownedTokens[from][tokenIndex] = lastToken;
    // This also deletes the contents at the last position of the array
    _ownedTokens[from].length--;

    // Note that this will handle single-element arrays. In that case, both tokenIndex and lastTokenIndex are going to
    // be zero. Then we can make sure that we will remove tokenId from the ownedTokens list since we are first swapping
    // the lastToken to the first position, and then dropping the element placed in the last position of the list

    _ownedTokensIndex[tokenId] = 0;
    _ownedTokensIndex[lastToken] = tokenIndex;
  }

  /**
   * @dev Internal function to mint a new token
   * Reverts if the given token ID already exists
   * @param to address the beneficiary that will own the minted token
   * @param tokenId uint256 ID of the token to be minted by the msg.sender
   */
  function _mint(address to, uint256 tokenId) internal {
    super._mint(to, tokenId);

    _allTokensIndex[tokenId] = _allTokens.length;
    _allTokens.push(tokenId);
  }

  /**
   * @dev Internal function to burn a specific token
   * Reverts if the token does not exist
   * @param owner owner of the token to burn
   * @param tokenId uint256 ID of the token being burned by the msg.sender
   */
  function _burn(address owner, uint256 tokenId) internal {
    super._burn(owner, tokenId);

    // Reorg all tokens array
    uint256 tokenIndex = _allTokensIndex[tokenId];
    uint256 lastTokenIndex = _allTokens.length.sub(1);
    uint256 lastToken = _allTokens[lastTokenIndex];

    _allTokens[tokenIndex] = lastToken;
    _allTokens[lastTokenIndex] = 0;

    _allTokens.length--;
    _allTokensIndex[tokenId] = 0;
    _allTokensIndex[lastToken] = tokenIndex;
  }
}








contract IERC721Metadata is IERC721 {
  function name() external view returns (string);
  function symbol() external view returns (string);
  function tokenURI(uint256 tokenId) external view returns (string);
}


contract ERC721Metadata_custom is ERC165, ERC721_custom, IERC721Metadata {
  // Token name
  string private _name;

  // Token symbol
  string private _symbol;

  // Optional mapping for token URIs
  mapping(uint256 => string) private _tokenURIs;

  bytes4 private constant InterfaceId_ERC721Metadata = 0x5b5e139f;
  /**
   * 0x5b5e139f ===
   *   bytes4(keccak256('name()')) ^
   *   bytes4(keccak256('symbol()')) ^
   *   bytes4(keccak256('tokenURI(uint256)'))
   */

  /**
   * @dev Constructor function
   */
  constructor(string name, string symbol) public {
    _name = name;
    _symbol = symbol;

    // register the supported interfaces to conform to ERC721 via ERC165
    _registerInterface(InterfaceId_ERC721Metadata);
  }

  function name() external view returns (string) {
    return _name;
  }

  
  function symbol() external view returns (string) {
    return _symbol;
  }

  
  function tokenURI(uint256 tokenId) external view returns (string) {
    require(_exists(tokenId));
    return _tokenURIs[tokenId];
  }

  
  function _setTokenURI(uint256 tokenId, string uri) internal {
    require(_exists(tokenId));
    _tokenURIs[tokenId] = uri;
  }

  
  function _burn(address owner, uint256 tokenId) internal {
    super._burn(owner, tokenId);

    // Clear metadata (if any)
    if (bytes(_tokenURIs[tokenId]).length != 0) {
      delete _tokenURIs[tokenId];
    }
  }
}


contract ERC721Full_custom is ERC721_custom, ERC721Enumerable_custom, ERC721Metadata_custom {
  constructor(string name, string symbol) ERC721Metadata_custom(name, symbol)
    public
  {
  }
}


interface PlanetCryptoCoin_I {
    function balanceOf(address owner) external returns(uint256);
    function transfer(address to, uint256 value) external returns (bool);
    function transferFrom(address from, address to, uint256 value) external returns(bool);
}

interface PlanetCryptoUtils_I {
    function validateLand(address _sender, int256[] plots_lat, int256[] plots_lng) external returns(bool);
    function validatePurchase(address _sender, uint256 _value, int256[] plots_lat, int256[] plots_lng) external returns(bool);
    function validateTokenPurchase(address _sender, int256[] plots_lat, int256[] plots_lng) external returns(bool);
    function validateResale(address _sender, uint256 _value, uint256 _token_id) external returns(bool);

    //UTILS
    function strConcat(string _a, string _b, string _c, string _d, string _e, string _f) external view returns (string);
    function strConcat(string _a, string _b, string _c, string _d, string _e) external view returns (string);
    function strConcat(string _a, string _b, string _c, string _d) external view returns (string);
    function strConcat(string _a, string _b, string _c) external view returns (string);
    function strConcat(string _a, string _b) external view returns (string);
    function int2str(int i) external view returns (string);
    function uint2str(uint i) external view returns (string);
    function substring(string str, uint startIndex, uint endIndex) external view returns (string);
    function utfStringLength(string str) external view returns (uint length);
    function ceil1(int256 a, int256 m) external view returns (int256 );
    function parseInt(string _a, uint _b) external view returns (uint);
}

library Percent {

  struct percent {
    uint num;
    uint den;
  }
  function mul(percent storage p, uint a) internal view returns (uint) {
    if (a == 0) {
      return 0;
    }
    return a*p.num/p.den;
  }

  function div(percent storage p, uint a) internal view returns (uint) {
    return a/p.num*p.den;
  }

  function sub(percent storage p, uint a) internal view returns (uint) {
    uint b = mul(p, a);
    if (b >= a) return 0;
    return a - b;
  }

  function add(percent storage p, uint a) internal view returns (uint) {
    return a + mul(p, a);
  }
}



contract PlanetCryptoToken is ERC721Full_custom{
    
    using Percent for Percent.percent;
    
    
    // EVENTS
        
    event referralPaid(address indexed search_to,
                    address to, uint256 amnt, uint256 timestamp);
    
    event issueCoinTokens(address indexed searched_to, 
                    address to, uint256 amnt, uint256 timestamp);
    
    event landPurchased(uint256 indexed search_token_id, address indexed search_buyer, 
            uint256 token_id, address buyer, bytes32 name, int256 center_lat, int256 center_lng, uint256 size, uint256 bought_at, uint256 empire_score, uint256 timestamp);
    
    event taxDistributed(uint256 amnt, uint256 total_players, uint256 timestamp);
    
    event cardBought(
                    uint256 indexed search_token_id, address indexed search_from, address indexed search_to,
                    uint256 token_id, address from, address to, 
                    bytes32 name,
                    uint256 orig_value, 
                    uint256 new_value,
                    uint256 empireScore, uint256 newEmpireScore, uint256 now);

    // CONTRACT MANAGERS
    address owner;
    address devBankAddress; // where marketing funds are sent
    address tokenBankAddress; 

    // MODIFIERS
    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }
    
    modifier validateLand(int256[] plots_lat, int256[] plots_lng) {
        
        require(planetCryptoUtils_interface.validateLand(msg.sender, plots_lat, plots_lng) == true, "Some of this land already owned!");

        
        _;
    }
    
    modifier validatePurchase(int256[] plots_lat, int256[] plots_lng) {

        require(planetCryptoUtils_interface.validatePurchase(msg.sender, msg.value, plots_lat, plots_lng) == true, "Not enough ETH!");
        _;
    }
    
    
    modifier validateTokenPurchase(int256[] plots_lat, int256[] plots_lng) {

        require(planetCryptoUtils_interface.validateTokenPurchase(msg.sender, plots_lat, plots_lng) == true, "Not enough COINS to buy these plots!");
        

        

        require(planetCryptoCoin_interface.transferFrom(msg.sender, tokenBankAddress, plots_lat.length) == true, "Token transfer failed");
        
        
        _;
    }
    
    
    modifier validateResale(uint256 _token_id) {
        require(planetCryptoUtils_interface.validateResale(msg.sender, msg.value, _token_id) == true, "Not enough ETH to buy this card!");
        _;
    }
    
    
    modifier updateUsersLastAccess() {
        
        uint256 allPlyersIdx = playerAddressToPlayerObjectID[msg.sender];
        if(allPlyersIdx == 0){

            all_playerObjects.push(player(msg.sender,now,0,0));
            playerAddressToPlayerObjectID[msg.sender] = all_playerObjects.length-1;
        } else {
            all_playerObjects[allPlyersIdx].lastAccess = now;
        }
        
        _;
    }
    
    // STRUCTS
    struct plotDetail {
        bytes32 name;
        uint256 orig_value;
        uint256 current_value;
        uint256 empire_score;
        int256[] plots_lat;
        int256[] plots_lng;
    }
    
    struct plotBasic {
        int256 lat;
        int256 lng;
    }
    
    struct player {
        address playerAddress;
        uint256 lastAccess;
        uint256 totalEmpireScore;
        uint256 totalLand;
        
        
    }
    

    // INTERFACES
    address planetCryptoCoinAddress = 0xa1c8031ef18272d8bfed22e1b61319d6d9d2881b;
    PlanetCryptoCoin_I internal planetCryptoCoin_interface;
    

    address planetCryptoUtilsAddress = 0x19BfDF25542F1380790B6880ad85D6D5B02fee32;
    PlanetCryptoUtils_I internal planetCryptoUtils_interface;
    
    
    // settings
    Percent.percent private m_newPlot_devPercent = Percent.percent(75,100); //75/100*100% = 75%
    Percent.percent private m_newPlot_taxPercent = Percent.percent(25,100); //25%
    
    Percent.percent private m_resalePlot_devPercent = Percent.percent(10,100); // 10%
    Percent.percent private m_resalePlot_taxPercent = Percent.percent(10,100); // 10%
    Percent.percent private m_resalePlot_ownerPercent = Percent.percent(80,100); // 80%
    
    Percent.percent private m_refPercent = Percent.percent(5,100); // 5% referral 
    
    Percent.percent private m_empireScoreMultiplier = Percent.percent(150,100); // 150%
    Percent.percent private m_resaleMultipler = Percent.percent(200,100); // 200%;

    
    
    
    uint256 public devHoldings = 0; // holds dev funds in cases where the instant transfer fails


    mapping(address => uint256) internal playersFundsOwed; // can sit within all_playerObjects




    // add in limit of land plots before tokens stop being distributed
    uint256 public tokens_rewards_available;
    uint256 public tokens_rewards_allocated;
    
    // add in spend amount required to earn tokens
    uint256 public min_plots_purchase_for_token_reward = 10;
    uint256 public plots_token_reward_divisor = 10;
    
    
    // GAME SETTINGS
    uint256 public current_plot_price = 20000000000000000;
    uint256 public price_update_amount = 2000000000000;

    uint256 public current_plot_empire_score = 100;

    
    
    uint256 public tax_fund = 0;
    uint256 public tax_distributed = 0;


    // GAME STATS
    uint256 public total_land_sold = 0;
    uint256 public total_trades = 0;

    
    uint256 public total_empire_score; 
    player[] public all_playerObjects;
    mapping(address => uint256) internal playerAddressToPlayerObjectID;
    
    
    
    
    plotDetail[] plotDetails;
    mapping(uint256 => uint256) internal tokenIDplotdetailsIndexId; // e.g. tokenIDplotdetailsIndexId shows us the index of the detail obj for each token



    
    mapping(int256 => mapping(int256 => uint256)) internal latlngTokenID_grids;
    mapping(uint256 => plotBasic[]) internal tokenIDlatlngLookup;
    
    
    
    mapping(uint8 => mapping(int256 => mapping(int256 => uint256))) internal latlngTokenID_zoomAll;

    mapping(uint8 => mapping(uint256 => plotBasic[])) internal tokenIDlatlngLookup_zoomAll;


   
    
    constructor() ERC721Full_custom("PlanetCrypto", "PTC") public {
        owner = msg.sender;
        tokenBankAddress = owner;
        devBankAddress = owner;
        planetCryptoCoin_interface = PlanetCryptoCoin_I(planetCryptoCoinAddress);
        planetCryptoUtils_interface = PlanetCryptoUtils_I(planetCryptoUtilsAddress);
        
        // empty playerAddressToPlayerObjectID player to allow easy checks...

        all_playerObjects.push(player(address(0x0),0,0,0));
        playerAddressToPlayerObjectID[address(0x0)] = 0;
    }

    

    

    function getToken(uint256 _tokenId, bool isBasic) public view returns(
        address token_owner,
        bytes32  name,
        uint256 orig_value,
        uint256 current_value,
        uint256 empire_score,
        int256[] plots_lat,
        int256[] plots_lng
        ) {
        token_owner = ownerOf(_tokenId);
        plotDetail memory _plotDetail = plotDetails[tokenIDplotdetailsIndexId[_tokenId]];
        name = _plotDetail.name;
        empire_score = _plotDetail.empire_score;
        orig_value = _plotDetail.orig_value;
        current_value = _plotDetail.current_value;
        if(!isBasic){
            plots_lat = _plotDetail.plots_lat;
            plots_lng = _plotDetail.plots_lng;
        } else {
        }
    }
    
    

    function taxEarningsAvailable() public view returns(uint256) {
        return playersFundsOwed[msg.sender];
    }

    function withdrawTaxEarning() public {
        uint256 taxEarnings = playersFundsOwed[msg.sender];
        playersFundsOwed[msg.sender] = 0;
        tax_fund = tax_fund.sub(taxEarnings);
        
        if(!msg.sender.send(taxEarnings)) {
            playersFundsOwed[msg.sender] = playersFundsOwed[msg.sender] + taxEarnings;
            tax_fund = tax_fund.add(taxEarnings);
        }
    }

    function buyLandWithTokens(bytes32 _name, int256[] _plots_lat, int256[] _plots_lng)
     validateTokenPurchase(_plots_lat, _plots_lng) validateLand(_plots_lat, _plots_lng) updateUsersLastAccess() public {
        require(_name.length > 4);
        

        processPurchase(_name, _plots_lat, _plots_lng); 
    }
    

    
    function buyLand(bytes32 _name, 
            int256[] _plots_lat, int256[] _plots_lng,
            address _referrer
            )
                validatePurchase(_plots_lat, _plots_lng) 
                validateLand(_plots_lat, _plots_lng) 
                updateUsersLastAccess()
                public payable {
       require(_name.length > 4);
       
        // split payment
        uint256 _runningTotal = msg.value;
        uint256 _referrerAmnt = 0;
        if(_referrer != msg.sender && _referrer != address(0)) {
            _referrerAmnt = m_refPercent.mul(msg.value);
            if(_referrer.send(_referrerAmnt)) {
                emit referralPaid(_referrer, _referrer, _referrerAmnt, now);
                _runningTotal = _runningTotal.sub(_referrerAmnt);
            }
        }
        
        tax_fund = tax_fund.add(m_newPlot_taxPercent.mul(_runningTotal));
        
        
        
        if(!devBankAddress.send(m_newPlot_devPercent.mul(_runningTotal))){
            devHoldings = devHoldings.add(m_newPlot_devPercent.mul(_runningTotal));
        }
        
        
        

        processPurchase(_name, _plots_lat, _plots_lng);
        
        calcPlayerDivs(m_newPlot_taxPercent.mul(_runningTotal));
        
        if(_plots_lat.length >= min_plots_purchase_for_token_reward
            && tokens_rewards_available > 0) {
                
            uint256 _token_rewards = _plots_lat.length / plots_token_reward_divisor;
            if(_token_rewards > tokens_rewards_available)
                _token_rewards = tokens_rewards_available;
                
                
            planetCryptoCoin_interface.transfer(msg.sender, _token_rewards);
                
            emit issueCoinTokens(msg.sender, msg.sender, _token_rewards, now);
            tokens_rewards_allocated = tokens_rewards_allocated + _token_rewards;
            tokens_rewards_available = tokens_rewards_available - _token_rewards;
        }
    
    }
    
    

    function buyCard(uint256 _token_id, address _referrer) validateResale(_token_id) updateUsersLastAccess() public payable {
        
        
        // split payment
        uint256 _runningTotal = msg.value;
        uint256 _referrerAmnt = 0;
        if(_referrer != msg.sender && _referrer != address(0)) {
            _referrerAmnt = m_refPercent.mul(msg.value);
            if(_referrer.send(_referrerAmnt)) {
                emit referralPaid(_referrer, _referrer, _referrerAmnt, now);
                _runningTotal = _runningTotal.sub(_referrerAmnt);
            }
        }
        
        
        tax_fund = tax_fund.add(m_resalePlot_taxPercent.mul(_runningTotal));
        
        
        
        if(!devBankAddress.send(m_resalePlot_devPercent.mul(_runningTotal))){
            devHoldings = devHoldings.add(m_resalePlot_devPercent.mul(_runningTotal));
        }
        
        

        address from = ownerOf(_token_id);
        
        if(!from.send(m_resalePlot_ownerPercent.mul(_runningTotal))) {
            playersFundsOwed[from] = playersFundsOwed[from].add(m_resalePlot_ownerPercent.mul(_runningTotal));
        }
        
        

        our_transferFrom(from, msg.sender, _token_id);
        

        plotDetail memory _plotDetail = plotDetails[tokenIDplotdetailsIndexId[_token_id]];
        uint256 _empireScore = _plotDetail.empire_score;
        uint256 _newEmpireScore = m_empireScoreMultiplier.mul(_empireScore);
        uint256 _origValue = _plotDetail.current_value;
        
        uint256 _playerObject_idx = playerAddressToPlayerObjectID[msg.sender];
        

        all_playerObjects[_playerObject_idx].totalEmpireScore
            = all_playerObjects[_playerObject_idx].totalEmpireScore + (_newEmpireScore - _empireScore);
        
        
        plotDetails[tokenIDplotdetailsIndexId[_token_id]].empire_score = _newEmpireScore;

        total_empire_score = total_empire_score + (_newEmpireScore - _empireScore);
        
        plotDetails[tokenIDplotdetailsIndexId[_token_id]].current_value = 
            m_resaleMultipler.mul(plotDetails[tokenIDplotdetailsIndexId[_token_id]].current_value);
        
        total_trades = total_trades + 1;
        
        
        calcPlayerDivs(m_resalePlot_taxPercent.mul(_runningTotal));
        
        
        // emit event
        emit cardBought(_token_id, from, msg.sender,
                    _token_id, from, msg.sender, 
                    _plotDetail.name,
                    _origValue, 
                    msg.value,
                    _empireScore, _newEmpireScore, now);
    }
    
    function processPurchase(bytes32 _name, 
            int256[] _plots_lat, int256[] _plots_lng) internal {
    
        uint256 _token_id = totalSupply().add(1);
        _mint(msg.sender, _token_id);
        

        

        uint256 _empireScore =
                    current_plot_empire_score * _plots_lng.length;
            
            
        plotDetails.push(plotDetail(
            _name,
            current_plot_price * _plots_lat.length,
            current_plot_price * _plots_lat.length,
            _empireScore,
            _plots_lat, _plots_lng
        ));
        
        tokenIDplotdetailsIndexId[_token_id] = plotDetails.length-1;
        
        
        setupPlotOwnership(_token_id, _plots_lat, _plots_lng);
        
        
        
        uint256 _playerObject_idx = playerAddressToPlayerObjectID[msg.sender];
        all_playerObjects[_playerObject_idx].totalEmpireScore
            = all_playerObjects[_playerObject_idx].totalEmpireScore + _empireScore;
            
        total_empire_score = total_empire_score + _empireScore;
            
        all_playerObjects[_playerObject_idx].totalLand
            = all_playerObjects[_playerObject_idx].totalLand + _plots_lat.length;
            
        
        emit landPurchased(
                _token_id, msg.sender,
                _token_id, msg.sender, _name, _plots_lat[0], _plots_lng[0], _plots_lat.length, current_plot_price, _empireScore, now);


        current_plot_price = current_plot_price + (price_update_amount * _plots_lat.length);
        total_land_sold = total_land_sold + _plots_lat.length;
        
    }




    uint256 internal tax_carried_forward = 0;
    
    function calcPlayerDivs(uint256 _value) internal {
        // total up amount split so we can emit it
        if(totalSupply() > 1) {
            uint256 _totalDivs = 0;
            uint256 _totalPlayers = 0;
            
            uint256 _taxToDivide = _value + tax_carried_forward;
            
            // ignore player 0
            for(uint256 c=1; c< all_playerObjects.length; c++) {
                
                // allow for 0.0001 % =  * 10000
                
                uint256 _playersPercent 
                    = (all_playerObjects[c].totalEmpireScore*10000000 / total_empire_score * 10000000) / 10000000;
                uint256 _playerShare = _taxToDivide / 10000000 * _playersPercent;
                
                //uint256 _playerShare =  _taxToDivide * (all_playerObjects[c].totalEmpireScore / total_empire_score);
                //_playerShare = _playerShare / 10000;
                
                if(_playerShare > 0) {
                    
                    incPlayerOwed(all_playerObjects[c].playerAddress,_playerShare);
                    _totalDivs = _totalDivs + _playerShare;
                    _totalPlayers = _totalPlayers + 1;
                
                }
            }

            tax_carried_forward = 0;
            emit taxDistributed(_totalDivs, _totalPlayers, now);

        } else {
            // first land purchase - no divs this time, carried forward
            tax_carried_forward = tax_carried_forward + _value;
        }
    }
    
    
    function incPlayerOwed(address _playerAddr, uint256 _amnt) internal {
        playersFundsOwed[_playerAddr] = playersFundsOwed[_playerAddr].add(_amnt);
        tax_distributed = tax_distributed.add(_amnt);
    }
    
    
    function setupPlotOwnership(uint256 _token_id, int256[] _plots_lat, int256[] _plots_lng) internal {

       for(uint256 c=0;c< _plots_lat.length;c++) {
         
            //mapping(int256 => mapping(int256 => uint256)) internal latlngTokenID_grids;
            latlngTokenID_grids[_plots_lat[c]]
                [_plots_lng[c]] = _token_id;
                
            //mapping(uint256 => plotBasic[]) internal tokenIDlatlngLookup;
            tokenIDlatlngLookup[_token_id].push(plotBasic(
                _plots_lat[c], _plots_lng[c]
            ));
            
        }
       
        
        int256 _latInt = _plots_lat[0];
        int256 _lngInt = _plots_lng[0];



        setupZoomLvl(1,_latInt, _lngInt, _token_id); // correct rounding / 10 on way out
        setupZoomLvl(2,_latInt, _lngInt, _token_id); // correct rounding / 100
        setupZoomLvl(3,_latInt, _lngInt, _token_id); // correct rounding / 1000
        setupZoomLvl(4,_latInt, _lngInt, _token_id); // correct rounding / 10000

      
    }

    function setupZoomLvl(uint8 zoom, int256 lat, int256 lng, uint256 _token_id) internal  {
        
        lat = roundLatLng(zoom, lat);
        lng  = roundLatLng(zoom, lng); 
        
        
        uint256 _remover = 5;
        if(zoom == 1)
            _remover = 5;
        if(zoom == 2)
            _remover = 4;
        if(zoom == 3)
            _remover = 3;
        if(zoom == 4)
            _remover = 2;
        
        string memory _latStr;  // = int2str(lat);
        string memory _lngStr; // = int2str(lng);

        
        
        bool _tIsNegative = false;
        
        if(lat < 0) {
            _tIsNegative = true;   
            lat = lat * -1;
        }
        _latStr = planetCryptoUtils_interface.int2str(lat);
        _latStr = planetCryptoUtils_interface.substring(_latStr,0,planetCryptoUtils_interface.utfStringLength(_latStr)-_remover); //_lat_len-_remover);
        lat = int256(planetCryptoUtils_interface.parseInt(_latStr,0));
        if(_tIsNegative)
            lat = lat * -1;
        
        
        //emit debugInt("ZOOM LNG1", lng); // 1.1579208923731619542...
        
        if(lng < 0) {
            _tIsNegative = true;
            lng = lng * -1;
        } else {
            _tIsNegative = false;
        }
            
        //emit debugInt("ZOOM LNG2", lng); // 100000
            
        _lngStr = planetCryptoUtils_interface.int2str(lng);
        
        _lngStr = planetCryptoUtils_interface.substring(_lngStr,0,planetCryptoUtils_interface.utfStringLength(_lngStr)-_remover);
        
        lng = int256(planetCryptoUtils_interface.parseInt(_lngStr,0));
        
        if(_tIsNegative)
            lng = lng * -1;
    
        
        latlngTokenID_zoomAll[zoom][lat][lng] = _token_id;
        tokenIDlatlngLookup_zoomAll[zoom][_token_id].push(plotBasic(lat,lng));
        
      
   
        
        
    }




    


    function getAllPlayerObjectLen() public view returns(uint256){
        return all_playerObjects.length;
    }
    

    function queryMap(uint8 zoom, int256[] lat_rows, int256[] lng_columns) public view returns(string _outStr) {
        
        
        for(uint256 y=0; y< lat_rows.length; y++) {

            for(uint256 x=0; x< lng_columns.length; x++) {
                
                
                
                if(zoom == 0){
                    if(latlngTokenID_grids[lat_rows[y]][lng_columns[x]] > 0){
                        
                        
                      _outStr = planetCryptoUtils_interface.strConcat(
                            _outStr, '[', planetCryptoUtils_interface.int2str(lat_rows[y]) , ':', planetCryptoUtils_interface.int2str(lng_columns[x]) );
                      _outStr = planetCryptoUtils_interface.strConcat(_outStr, ':', 
                                    planetCryptoUtils_interface.uint2str(latlngTokenID_grids[lat_rows[y]][lng_columns[x]]), ']');
                    }
                    
                } else {
                    //_out[c] = latlngTokenID_zoomAll[zoom][lat_rows[y]][lng_columns[x]];
                    if(latlngTokenID_zoomAll[zoom][lat_rows[y]][lng_columns[x]] > 0){
                      _outStr = planetCryptoUtils_interface.strConcat(_outStr, '[', planetCryptoUtils_interface.int2str(lat_rows[y]) , ':', planetCryptoUtils_interface.int2str(lng_columns[x]) );
                      _outStr = planetCryptoUtils_interface.strConcat(_outStr, ':', 
                                    planetCryptoUtils_interface.uint2str(latlngTokenID_zoomAll[zoom][lat_rows[y]][lng_columns[x]]), ']');
                    }
                    
                }
                //c = c+1;
                
            }
        }
        
        //return _out;
    }

    function queryPlotExists(uint8 zoom, int256[] lat_rows, int256[] lng_columns) public view returns(bool) {
        
        
        for(uint256 y=0; y< lat_rows.length; y++) {

            for(uint256 x=0; x< lng_columns.length; x++) {
                
                if(zoom == 0){
                    if(latlngTokenID_grids[lat_rows[y]][lng_columns[x]] > 0){
                        return true;
                    } 
                } else {
                    if(latlngTokenID_zoomAll[zoom][lat_rows[y]][lng_columns[x]] > 0){

                        return true;
                        
                    }                     
                }
           
                
            }
        }
        
        return false;
    }

    
    function roundLatLng(uint8 _zoomLvl, int256 _in) internal view returns(int256) {
        int256 multipler = 100000;
        if(_zoomLvl == 1)
            multipler = 100000;
        if(_zoomLvl == 2)
            multipler = 10000;
        if(_zoomLvl == 3)
            multipler = 1000;
        if(_zoomLvl == 4)
            multipler = 100;
        if(_zoomLvl == 5)
            multipler = 10;
        
        if(_in > 0){
            // round it
            _in = planetCryptoUtils_interface.ceil1(_in, multipler);
        } else {
            _in = _in * -1;
            _in = planetCryptoUtils_interface.ceil1(_in, multipler);
            _in = _in * -1;
        }
        
        return (_in);
        
    }
    

   




    // ERC721 overrides
    
    function safeTransferFrom(address from, address to, uint256 tokenId) public {
        safeTransferFrom(from, to, tokenId, "");
    }
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes _data) public {
        transferFrom(from, to, tokenId);
        // solium-disable-next-line arg-overflow
        require(_checkOnERC721Received(from, to, tokenId, _data));
    }
    
    function our_transferFrom(address from, address to, uint256 tokenId) internal {
        // permissions already checked on buycard
        process_swap(from,to,tokenId);
        
        internal_transferFrom(from, to, tokenId);
    }


    function transferFrom(address from, address to, uint256 tokenId) public {
        // check permission on the from address first
        require(_isApprovedOrOwner(msg.sender, tokenId));
        require(to != address(0));
        
        process_swap(from,to,tokenId);
        
        super.transferFrom(from, to, tokenId);

    }
    
    function process_swap(address from, address to, uint256 tokenId) internal {

        
        // remove the empire score & total land owned...
        uint256 _empireScore;
        uint256 _size;
        
        plotDetail memory _plotDetail = plotDetails[tokenIDplotdetailsIndexId[tokenId]];
        _empireScore = _plotDetail.empire_score;
        _size = _plotDetail.plots_lat.length;
        
        uint256 _playerObject_idx = playerAddressToPlayerObjectID[from];
        
        all_playerObjects[_playerObject_idx].totalEmpireScore
            = all_playerObjects[_playerObject_idx].totalEmpireScore - _empireScore;
            
        all_playerObjects[_playerObject_idx].totalLand
            = all_playerObjects[_playerObject_idx].totalLand - _size;
            
        // and increment on the other side...
        
        _playerObject_idx = playerAddressToPlayerObjectID[to];
        
        all_playerObjects[_playerObject_idx].totalEmpireScore
            = all_playerObjects[_playerObject_idx].totalEmpireScore + _empireScore;
            
        all_playerObjects[_playerObject_idx].totalLand
            = all_playerObjects[_playerObject_idx].totalLand + _size;
    }


    function burnToken(uint256 _tokenId) external onlyOwner {
        address _token_owner = ownerOf(_tokenId);
        _burn(_token_owner, _tokenId);
        
        
        // remove the empire score & total land owned...
        uint256 _empireScore;
        uint256 _size;
        
        plotDetail memory _plotDetail = plotDetails[tokenIDplotdetailsIndexId[_tokenId]];
        _empireScore = _plotDetail.empire_score;
        _size = _plotDetail.plots_lat.length;
        
        uint256 _playerObject_idx = playerAddressToPlayerObjectID[_token_owner];
        
        all_playerObjects[_playerObject_idx].totalEmpireScore
            = all_playerObjects[_playerObject_idx].totalEmpireScore - _empireScore;
            
        all_playerObjects[_playerObject_idx].totalLand
            = all_playerObjects[_playerObject_idx].totalLand - _size;
            
       
        
        for(uint256 c=0;c < tokenIDlatlngLookup[_tokenId].length; c++) {
            latlngTokenID_grids[
                    tokenIDlatlngLookup[_tokenId][c].lat
                ][tokenIDlatlngLookup[_tokenId][c].lng] = 0;
        }
        delete tokenIDlatlngLookup[_tokenId];
        
        
        
        //Same for tokenIDplotdetailsIndexId        
        // clear from plotDetails array... (Holds the detail of the card)
        uint256 oldIndex = tokenIDplotdetailsIndexId[_tokenId];
        if(oldIndex != plotDetails.length-1) {
            plotDetails[oldIndex] = plotDetails[plotDetails.length-1];
        }
        plotDetails.length--;
        

        delete tokenIDplotdetailsIndexId[_tokenId];



        for(uint8 zoom=1; zoom < 5; zoom++) {
            plotBasic[] storage _plotBasicList = tokenIDlatlngLookup_zoomAll[zoom][_tokenId];
            for(uint256 _plotsC=0; c< _plotBasicList.length; _plotsC++) {
                delete latlngTokenID_zoomAll[zoom][
                    _plotBasicList[_plotsC].lat
                    ][
                        _plotBasicList[_plotsC].lng
                        ];
                        
                delete _plotBasicList[_plotsC];
            }
            
        }
    
    



    }    



    // PRIVATE METHODS
    function p_update_action(uint256 _type, address _address) public onlyOwner {
        if(_type == 0){
            owner = _address;    
        }
        if(_type == 1){
            tokenBankAddress = _address;    
        }
        if(_type == 2) {
            devBankAddress = _address;
        }
    }


    function p_update_priceUpdateAmount(uint256 _price_update_amount) public onlyOwner {
        price_update_amount = _price_update_amount;
    }
    function p_update_currentPlotEmpireScore(uint256 _current_plot_empire_score) public onlyOwner {
        current_plot_empire_score = _current_plot_empire_score;
    }
    function p_update_planetCryptoCoinAddress(address _planetCryptoCoinAddress) public onlyOwner {
        planetCryptoCoinAddress = _planetCryptoCoinAddress;
        if(address(planetCryptoCoinAddress) != address(0)){ 
            planetCryptoCoin_interface = PlanetCryptoCoin_I(planetCryptoCoinAddress);
        }
    }
    function p_update_planetCryptoUtilsAddress(address _planetCryptoUtilsAddress) public onlyOwner {
        planetCryptoUtilsAddress = _planetCryptoUtilsAddress;
        if(address(planetCryptoUtilsAddress) != address(0)){ 
            planetCryptoUtils_interface = PlanetCryptoUtils_I(planetCryptoUtilsAddress);
        }
    }
    function p_update_mNewPlotDevPercent(uint256 _newPercent) onlyOwner public {
        m_newPlot_devPercent = Percent.percent(_newPercent,100);
    }
    function p_update_mNewPlotTaxPercent(uint256 _newPercent) onlyOwner public {
        m_newPlot_taxPercent = Percent.percent(_newPercent,100);
    }
    function p_update_mResalePlotDevPercent(uint256 _newPercent) onlyOwner public {
        m_resalePlot_devPercent = Percent.percent(_newPercent,100);
    }
    function p_update_mResalePlotTaxPercent(uint256 _newPercent) onlyOwner public {
        m_resalePlot_taxPercent = Percent.percent(_newPercent,100);
    }
    function p_update_mResalePlotOwnerPercent(uint256 _newPercent) onlyOwner public {
        m_resalePlot_ownerPercent = Percent.percent(_newPercent,100);
    }
    function p_update_mRefPercent(uint256 _newPercent) onlyOwner public {
        m_refPercent = Percent.percent(_newPercent,100);
    }
    function p_update_mEmpireScoreMultiplier(uint256 _newPercent) onlyOwner public {
        m_empireScoreMultiplier = Percent.percent(_newPercent, 100);
    }
    function p_update_mResaleMultipler(uint256 _newPercent) onlyOwner public {
        m_resaleMultipler = Percent.percent(_newPercent, 100);
    }
    function p_update_tokensRewardsAvailable(uint256 _tokens_rewards_available) onlyOwner public {
        tokens_rewards_available = _tokens_rewards_available;
    }
    function p_update_tokensRewardsAllocated(uint256 _tokens_rewards_allocated) onlyOwner public {
        tokens_rewards_allocated = _tokens_rewards_allocated;
    }
    function p_withdrawDevHoldings() public {
        require(msg.sender == devBankAddress);
        uint256 _t = devHoldings;
        devHoldings = 0;
        if(!devBankAddress.send(devHoldings)){
            devHoldings = _t;
        }
    }


    function stringToBytes32(string memory source) internal returns (bytes32 result) {
        bytes memory tempEmptyStringTest = bytes(source);
        if (tempEmptyStringTest.length == 0) {
            return 0x0;
        }
    
        assembly {
            result := mload(add(source, 32))
        }
    }

    function m() public {
        
    }
    
}

Contract Security Audit

Contract ABI

[{"constant":true,"inputs":[],"name":"min_plots_purchase_for_token_reward","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tokens_rewards_available","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"zoom","type":"uint8"},{"name":"lat_rows","type":"int256[]"},{"name":"lng_columns","type":"int256[]"}],"name":"queryPlotExists","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getAllPlayerObjectLen","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_plots_lat","type":"int256[]"},{"name":"_plots_lng","type":"int256[]"}],"name":"buyLandWithTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newPercent","type":"uint256"}],"name":"p_update_mResalePlotDevPercent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"price_update_amount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"all_playerObjects","outputs":[{"name":"playerAddress","type":"address"},{"name":"lastAccess","type":"uint256"},{"name":"totalEmpireScore","type":"uint256"},{"name":"totalLand","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tokens_rewards_available","type":"uint256"}],"name":"p_update_tokensRewardsAvailable","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newPercent","type":"uint256"}],"name":"p_update_mNewPlotTaxPercent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newPercent","type":"uint256"}],"name":"p_update_mRefPercent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_price_update_amount","type":"uint256"}],"name":"p_update_priceUpdateAmount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_current_plot_empire_score","type":"uint256"}],"name":"p_update_currentPlotEmpireScore","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"current_plot_price","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newPercent","type":"uint256"}],"name":"p_update_mResalePlotOwnerPercent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"tokens_rewards_allocated","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token_id","type":"uint256"},{"name":"_referrer","type":"address"}],"name":"buyCard","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"taxEarningsAvailable","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"m","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_planetCryptoUtilsAddress","type":"address"}],"name":"p_update_planetCryptoUtilsAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"withdrawTaxEarning","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newPercent","type":"uint256"}],"name":"p_update_mEmpireScoreMultiplier","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"burnToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_planetCryptoCoinAddress","type":"address"}],"name":"p_update_planetCryptoCoinAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"zoom","type":"uint8"},{"name":"lat_rows","type":"int256[]"},{"name":"lng_columns","type":"int256[]"}],"name":"queryMap","outputs":[{"name":"_outStr","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"total_empire_score","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"total_land_sold","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"tokenId","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"total_trades","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_type","type":"uint256"},{"name":"_address","type":"address"}],"name":"p_update_action","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_tokens_rewards_allocated","type":"uint256"}],"name":"p_update_tokensRewardsAllocated","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"current_plot_empire_score","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newPercent","type":"uint256"}],"name":"p_update_mResaleMultipler","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"},{"name":"isBasic","type":"bool"}],"name":"getToken","outputs":[{"name":"token_owner","type":"address"},{"name":"name","type":"bytes32"},{"name":"orig_value","type":"uint256"},{"name":"current_value","type":"uint256"},{"name":"empire_score","type":"uint256"},{"name":"plots_lat","type":"int256[]"},{"name":"plots_lng","type":"int256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"p_withdrawDevHoldings","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_plots_lat","type":"int256[]"},{"name":"_plots_lng","type":"int256[]"},{"name":"_referrer","type":"address"}],"name":"buyLand","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"tax_distributed","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"devHoldings","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tax_fund","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"plots_token_reward_divisor","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newPercent","type":"uint256"}],"name":"p_update_mNewPlotDevPercent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newPercent","type":"uint256"}],"name":"p_update_mResalePlotTaxPercent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"search_to","type":"address"},{"indexed":false,"name":"to","type":"address"},{"indexed":false,"name":"amnt","type":"uint256"},{"indexed":false,"name":"timestamp","type":"uint256"}],"name":"referralPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"searched_to","type":"address"},{"indexed":false,"name":"to","type":"address"},{"indexed":false,"name":"amnt","type":"uint256"},{"indexed":false,"name":"timestamp","type":"uint256"}],"name":"issueCoinTokens","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"search_token_id","type":"uint256"},{"indexed":true,"name":"search_buyer","type":"address"},{"indexed":false,"name":"token_id","type":"uint256"},{"indexed":false,"name":"buyer","type":"address"},{"indexed":false,"name":"name","type":"bytes32"},{"indexed":false,"name":"center_lat","type":"int256"},{"indexed":false,"name":"center_lng","type":"int256"},{"indexed":false,"name":"size","type":"uint256"},{"indexed":false,"name":"bought_at","type":"uint256"},{"indexed":false,"name":"empire_score","type":"uint256"},{"indexed":false,"name":"timestamp","type":"uint256"}],"name":"landPurchased","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amnt","type":"uint256"},{"indexed":false,"name":"total_players","type":"uint256"},{"indexed":false,"name":"timestamp","type":"uint256"}],"name":"taxDistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"search_token_id","type":"uint256"},{"indexed":true,"name":"search_from","type":"address"},{"indexed":true,"name":"search_to","type":"address"},{"indexed":false,"name":"token_id","type":"uint256"},{"indexed":false,"name":"from","type":"address"},{"indexed":false,"name":"to","type":"address"},{"indexed":false,"name":"name","type":"bytes32"},{"indexed":false,"name":"orig_value","type":"uint256"},{"indexed":false,"name":"new_value","type":"uint256"},{"indexed":false,"name":"empireScore","type":"uint256"},{"indexed":false,"name":"newEmpireScore","type":"uint256"},{"indexed":false,"name":"now","type":"uint256"}],"name":"cardBought","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":true,"name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"approved","type":"address"},{"indexed":true,"name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"operator","type":"address"},{"indexed":false,"name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"}]

600f8054600160a060020a031990811673a1c8031ef18272d8bfed22e1b61319d6d9d2881b17909155601180549091167319bfdf25542f1380790b6880ad85d6d5b02fee32179055604b6080819052606460a08190526013919091556014819055601960c081905260e082905260158190556016829055600a6101008190526101208390526017819055601883905561014081905261016083905290819055601a82905560506101808190526101a0839052601b55601c82905560056101c08190526101e0839052601d55601e8290556096610200819052610220839052601f55602082905561028060405260c8610240819052610260839052602155602282905560006023819055602782905560289190915566470de4df8200006029556501d1a94a2000602a55602b91909155602c819055602d819055602e819055602f8190556039553480156200015257600080fd5b50604080518082018252600c81527f506c616e657443727970746f00000000000000000000000000000000000000006020808301919091528251808401909352600383527f505443000000000000000000000000000000000000000000000000000000000090830152908181620001f27f01ffc9a7000000000000000000000000000000000000000000000000000000006401000000006200042a810204565b620002267f80ac58cd000000000000000000000000000000000000000000000000000000006401000000006200042a810204565b6200025a7f780e9d63000000000000000000000000000000000000000000000000000000006401000000006200042a810204565b81516200026f90600990602085019062000497565b5080516200028590600a90602084019062000497565b50620002ba7f5b5e139f000000000000000000000000000000000000000000000000000000006401000000006200042a810204565b5050600c8054600160a060020a0319908116331791829055600e80548216600160a060020a03938416908117909155600d805483169091179055600f5460108054831691841691909117905560115460128054831691841691909117905560408051608081018252600080825260208083018281529383018281526060840183815260318054600181018255908552945160049095027fc54045fa7c6ec765e825df7f9e9bf9dec12c5cef146f93a5eee56772ee647fbc8101805496909916959097169490941790965592517fc54045fa7c6ec765e825df7f9e9bf9dec12c5cef146f93a5eee56772ee647fbd85015593517fc54045fa7c6ec765e825df7f9e9bf9dec12c5cef146f93a5eee56772ee647fbe840155517fc54045fa7c6ec765e825df7f9e9bf9dec12c5cef146f93a5eee56772ee647fbf90920191909155818052603290527ebcd6ff29ae71d399fb597d99792fa72d0863bd723b9ab11f79d0b8d8ac5bc855506200053c9050565b7fffffffff0000000000000000000000000000000000000000000000000000000080821614156200045a57600080fd5b7fffffffff00000000000000000000000000000000000000000000000000000000166000908152602081905260409020805460ff19166001179055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620004da57805160ff19168380011785556200050a565b828001600101855582156200050a579182015b828111156200050a578251825591602001919060010190620004ed565b50620005189291506200051c565b5090565b6200053991905b8082111562000518576000815560010162000523565b90565b615f3b806200054c6000396000f30060806040526004361061028f5763ffffffff60e060020a60003504166301de168a811461029457806301ef74f1146102bb57806301ffc9a7146102d057806303a7b41f1461031b57806306fdde03146103b1578063081812fc1461043b578063095ea7b31461046f5780630cb9ee4b146104955780630d4ea316146104aa57806318160ddd1461053d5780631cbda93d14610552578063222d7c8a1461056a578063232720651461057f57806323b872dd146105c757806328ab7375146105f15780632f745c5914610609578063306a85891461062d578063312df32114610645578063368aa9ca1461065d57806337a74f7e146106755780633fadc3881461068d57806342842e0e146106a2578063478c4238146106cc5780634a22c7fb146106e45780634f6ccce7146106f957806350357beb14610711578063567c31f7146107285780635a2ee0191461073d5780636352211e1461075257806364cbfdd61461076a57806370a082311461078b5780637517b57e146107ac578063769988b3146107c15780637b47ec1a146107d957806382568a24146107f157806387dfc9091461081257806395d89b41146108a85780639ee837f5146108bd578063a22cb465146108d2578063aeaf5a37146108f8578063b88d4fde1461090d578063be3f34711461097c578063c112d52514610991578063c87b56dd146109b5578063cf28b18e146109cd578063d3f78cb4146109e5578063d67c7f35146109fa578063db737c7814610a12578063dbc933bc14610b05578063dc00adef14610b1a578063e1036f8614610bab578063e4fd6f8114610bc0578063e717dc3d14610bd5578063e985e9c514610bea578063f719db8e14610c11578063fa985a2f14610c26578063fc4116bb14610c3e575b600080fd5b3480156102a057600080fd5b506102a9610c56565b60408051918252519081900360200190f35b3480156102c757600080fd5b506102a9610c5c565b3480156102dc57600080fd5b506103077bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1960043516610c62565b604080519115158252519081900360200190f35b34801561032757600080fd5b5060408051602060046024803582810135848102808701860190975280865261030796843560ff1696369660449591949091019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750949750610c969650505050505050565b3480156103bd57600080fd5b506103c6610db7565b6040805160208082528351818301528351919283929083019185019080838360005b838110156104005781810151838201526020016103e8565b50505050905090810190601f16801561042d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561044757600080fd5b50610453600435610e4e565b60408051600160a060020a039092168252519081900360200190f35b34801561047b57600080fd5b50610493600160a060020a0360043516602435610e80565b005b3480156104a157600080fd5b506102a9610f29565b3480156104b657600080fd5b5060408051602060046024803582810135848102808701860190975280865261049396843596369660449591949091019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750949750610f2f9650505050505050565b34801561054957600080fd5b506102a96114a5565b34801561055e57600080fd5b506104936004356114ab565b34801561057657600080fd5b506102a96114e4565b34801561058b57600080fd5b506105976004356114ea565b60408051600160a060020a0390951685526020850193909352838301919091526060830152519081900360800190f35b3480156105d357600080fd5b50610493600160a060020a036004358116906024351660443561152c565b3480156105fd57600080fd5b50610493600435611571565b34801561061557600080fd5b506102a9600160a060020a036004351660243561158d565b34801561063957600080fd5b506104936004356115db565b34801561065157600080fd5b50610493600435611614565b34801561066957600080fd5b5061049360043561164d565b34801561068157600080fd5b50610493600435611669565b34801561069957600080fd5b506102a9611685565b3480156106ae57600080fd5b50610493600160a060020a036004358116906024351660443561168b565b3480156106d857600080fd5b506104936004356116a7565b3480156106f057600080fd5b506102a96116e0565b34801561070557600080fd5b506102a96004356116e6565b610493600435600160a060020a036024351661171b565b34801561073457600080fd5b506102a9611e5a565b34801561074957600080fd5b50610493611e6d565b34801561075e57600080fd5b50610453600435611e6f565b34801561077657600080fd5b50610493600160a060020a0360043516611e93565b34801561079757600080fd5b506102a9600160a060020a0360043516611ef7565b3480156107b857600080fd5b50610493611f2a565b3480156107cd57600080fd5b50610493600435611fa4565b3480156107e557600080fd5b50610493600435611fdb565b3480156107fd57600080fd5b50610493600160a060020a0360043516612480565b34801561081e57600080fd5b506040805160206004602480358281013584810280870186019097528086526103c696843560ff1696369660449591949091019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a9989019892975090820195509350839250850190849080828437509497506124e39650505050505050565b3480156108b457600080fd5b506103c661349d565b3480156108c957600080fd5b506102a96134fe565b3480156108de57600080fd5b50610493600160a060020a03600435166024351515613504565b34801561090457600080fd5b506102a9613588565b34801561091957600080fd5b50604080516020601f60643560048181013592830184900484028501840190955281845261049394600160a060020a03813581169560248035909216956044359536956084940191819084018382808284375094975061358e9650505050505050565b34801561098857600080fd5b506102a96135b6565b34801561099d57600080fd5b50610493600435600160a060020a03602435166135bc565b3480156109c157600080fd5b506103c6600435613644565b3480156109d957600080fd5b506104936004356136f9565b3480156109f157600080fd5b506102a9613715565b348015610a0657600080fd5b5061049360043561371b565b348015610a1e57600080fd5b50610a2f6004356024351515613754565b6040518088600160a060020a0316600160a060020a0316815260200187600019166000191681526020018681526020018581526020018481526020018060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015610aab578181015183820152602001610a93565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015610aea578181015183820152602001610ad2565b50505050905001995050505050505050505060405180910390f35b348015610b1157600080fd5b506104936138bc565b60408051602060046024803582810135848102808701860190975280865261049396843596369660449591949091019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a99890198929750908201955093508392508501908490808284375094975050509235600160a060020a0316935061391292505050565b348015610bb757600080fd5b506102a9613fea565b348015610bcc57600080fd5b506102a9613ff0565b348015610be157600080fd5b506102a9613ff6565b348015610bf657600080fd5b50610307600160a060020a0360043581169060243516613ffc565b348015610c1d57600080fd5b506102a961402a565b348015610c3257600080fd5b50610493600435614030565b348015610c4a57600080fd5b50610493600435614069565b60275481565b60255481565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191660009081526020819052604090205460ff1690565b600080805b8451821015610da9575060005b8351811015610d9e5760ff86161515610d24576000603560008785815181101515610ccf57fe5b90602001906020020151815260200190815260200160002060008684815181101515610cf757fe5b906020019060200201518152602001908152602001600020541115610d1f5760019250610dae565b610d96565b60ff8616600090815260376020526040812086518290889086908110610d4657fe5b90602001906020020151815260200190815260200160002060008684815181101515610d6e57fe5b906020019060200201518152602001908152602001600020541115610d965760019250610dae565b600101610ca8565b600190910190610c9b565b600092505b50509392505050565b60098054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610e435780601f10610e1857610100808354040283529160200191610e43565b820191906000526020600020905b815481529060010190602001808311610e2657829003601f168201915b505050505090505b90565b6000610e59826140a2565b1515610e6457600080fd5b50600090815260026020526040902054600160a060020a031690565b6000610e8b82611e6f565b9050600160a060020a038381169082161415610ea657600080fd5b33600160a060020a0382161480610ec25750610ec28133613ffc565b1515610ecd57600080fd5b6000828152600260205260408082208054600160a060020a031916600160a060020a0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b60315490565b6012546040517f05117e0d000000000000000000000000000000000000000000000000000000008152336004820181815260606024840190815286516064850152865187958795600160a060020a03909116946305117e0d9490938893889360448101916084909101906020808801910280838360005b83811015610fbe578181015183820152602001610fa6565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015610ffd578181015183820152602001610fe5565b5050505090500195505050505050602060405180830381600087803b15801561102557600080fd5b505af1158015611039573d6000803e3d6000fd5b505050506040513d602081101561104f57600080fd5b505115156001146110cf576040805160e560020a62461bcd028152602060048201526024808201527f4e6f7420656e6f75676820434f494e5320746f2062757920746865736520706c60448201527f6f74732100000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b601054600e548351604080517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a03938416602482015260448101929092525191909216916323b872dd9160648083019260209291908290030181600087803b15801561114957600080fd5b505af115801561115d573d6000803e3d6000fd5b505050506040513d602081101561117357600080fd5b505115156001146111ce576040805160e560020a62461bcd02815260206004820152601560248201527f546f6b656e207472616e73666572206661696c65640000000000000000000000604482015290519081900360640190fd5b6012546040517f62026229000000000000000000000000000000000000000000000000000000008152336004820181815260606024840190815288516064850152885189958995600160a060020a039091169463620262299490938893889360448101916084909101906020808801910280838360005b8381101561125d578181015183820152602001611245565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561129c578181015183820152602001611284565b5050505090500195505050505050602060405180830381600087803b1580156112c457600080fd5b505af11580156112d8573d6000803e3d6000fd5b505050506040513d60208110156112ee57600080fd5b50511515600114611349576040805160e560020a62461bcd02815260206004820181905260248201527f536f6d65206f662074686973206c616e6420616c7265616479206f776e656421604482015290519081900360640190fd5b3360009081526032602052604090205480151561146a5760408051608081018252338082524260208084019182526000848601818152606086018281526031805460018101825581855297517fc54045fa7c6ec765e825df7f9e9bf9dec12c5cef146f93a5eee56772ee647fbc60049099029889018054600160a060020a031916600160a060020a0390921691909117905594517fc54045fa7c6ec765e825df7f9e9bf9dec12c5cef146f93a5eee56772ee647fbd88015590517fc54045fa7c6ec765e825df7f9e9bf9dec12c5cef146f93a5eee56772ee647fbe870155517fc54045fa7c6ec765e825df7f9e9bf9dec12c5cef146f93a5eee56772ee647fbf90950194909455905491835260329052919020600019919091019055611490565b4260318281548110151561147a57fe5b9060005260206000209060040201600101819055505b61149b8888886140bf565b5050505050505050565b60075490565b600c54600160a060020a031633146114c257600080fd5b6040805180820190915281815260646020909101819052601791909155601855565b602a5481565b60318054829081106114f857fe5b60009182526020909120600490910201805460018201546002830154600390930154600160a060020a039092169350919084565b61153633826143e7565b151561154157600080fd5b600160a060020a038216151561155657600080fd5b611561838383614446565b61156c8383836146e1565b505050565b600c54600160a060020a0316331461158857600080fd5b602555565b600061159883611ef7565b82106115a357600080fd5b600160a060020a03831660009081526005602052604090208054839081106115c757fe5b906000526020600020015490505b92915050565b600c54600160a060020a031633146115f257600080fd5b6040805180820190915281815260646020909101819052601591909155601655565b600c54600160a060020a0316331461162b57600080fd5b6040805180820190915281815260646020909101819052601d91909155601e55565b600c54600160a060020a0316331461166457600080fd5b602a55565b600c54600160a060020a0316331461168057600080fd5b602b55565b60295481565b61156c838383602060405190810160405280600081525061358e565b600c54600160a060020a031633146116be57600080fd5b6040805180820190915281815260646020909101819052601b91909155601c55565b60265481565b60006116f06114a5565b82106116fb57600080fd5b600780548390811061170957fe5b90600052602060002001549050919050565b6000806000611728615cf1565b601254604080517e54438d0000000000000000000000000000000000000000000000000000000081523360048201523460248201526044810189905290516000928392839283928c92600160a060020a03909116916254438d9160648082019260209290919082900301818887803b1580156117a357600080fd5b505af11580156117b7573d6000803e3d6000fd5b505050506040513d60208110156117cd57600080fd5b50511515600114611828576040805160e560020a62461bcd02815260206004820181905260248201527f4e6f7420656e6f7567682045544820746f206275792074686973206361726421604482015290519081900360640190fd5b336000908152603260205260409020548015156119495760408051608081018252338082524260208084019182526000848601818152606086018281526031805460018101825581855297517fc54045fa7c6ec765e825df7f9e9bf9dec12c5cef146f93a5eee56772ee647fbc60049099029889018054600160a060020a031916600160a060020a0390921691909117905594517fc54045fa7c6ec765e825df7f9e9bf9dec12c5cef146f93a5eee56772ee647fbd88015590517fc54045fa7c6ec765e825df7f9e9bf9dec12c5cef146f93a5eee56772ee647fbe870155517fc54045fa7c6ec765e825df7f9e9bf9dec12c5cef146f93a5eee56772ee647fbf9095019490945590549183526032905291902060001991909101905561196f565b4260318281548110151561195957fe5b9060005260206000209060040201600101819055505b34995060009850600160a060020a038b1633148015906119975750600160a060020a038b1615155b15611a36576119ad601d3463ffffffff61476f16565b604051909950600160a060020a038c16908a156108fc02908b906000818181858888f1935050505015611a365760408051600160a060020a038d16808252602082018c9052428284015291517f500a1821a82e1e9951feb0c4eb0043d6f9d97be1a522ffa083f6a91b7b5c013d9181900360600190a2611a338a8a63ffffffff61479a16565b99505b611a59611a4a60198c63ffffffff61476f16565b602c549063ffffffff6147b116565b602c55600d54600160a060020a03166108fc611a7c60178d63ffffffff61476f16565b6040518115909202916000818181858888f193505050501515611ac057611abc611aad60178c63ffffffff61476f16565b6023549063ffffffff6147b116565b6023555b611ac98c611e6f565b9750600160a060020a0388166108fc611ae9601b8d63ffffffff61476f16565b6040518115909202916000818181858888f193505050501515611b5957611b3f611b1a601b8c63ffffffff61476f16565b600160a060020a038a166000908152602460205260409020549063ffffffff6147b116565b600160a060020a0389166000908152602460205260409020555b611b6488338e6147ca565b60008c815260346020526040902054603380549091908110611b8257fe5b60009182526020918290206040805160c0810182526006909302909101805483526001810154838501526002810154838301526003810154606084015260048101805483518187028101870190945280845293949193608086019392830182828015611c0d57602002820191906000526020600020905b815481526020019060010190808311611bf9575b5050505050815260200160058201805480602002602001604051908101604052809291908181526020018280548015611c6557602002820191906000526020600020905b815481526020019060010190808311611c51575b5050509190925250505060608101519097509550611c8a601f8763ffffffff61476f16565b604080890151336000908152603260205291909120546031805493985091965094508787039185908110611cba57fe5b90600052602060002090600402016002015401603184815481101515611cdc57fe5b906000526020600020906004020160020181905550846033603460008f815260200190815260200160002054815481101515611d1457fe5b90600052602060002090600602016003018190555085850360305401603081905550611d7d6033603460008f815260200190815260200160002054815481101515611d5b57fe5b906000526020600020906006020160020154602161476f90919063ffffffff16565b60008d815260346020526040902054603380549091908110611d9b57fe5b6000918252602090912060026006909202010155602f80546001019055611dd1611dcc60198c63ffffffff61476f16565b6147e0565b8651604080518e8152600160a060020a038b1660208201819052338284018190526060830194909452608082018890523460a083015260c082018a905260e082018990524261010083015291518f917fca6cef801d696b99880261abca3984a0cf932a69993676ef85130e9ce94e94da91908190036101200190a4505050505050505050505050565b3360009081526024602052604090205490565b565b600081815260016020526040812054600160a060020a03168015156115d557600080fd5b600c54600160a060020a03163314611eaa57600080fd5b60118054600160a060020a031916600160a060020a0383811691909117918290551615611ef45760115460128054600160a060020a031916600160a060020a039092169190911790555b50565b6000600160a060020a0382161515611f0e57600080fd5b50600160a060020a031660009081526003602052604090205490565b3360009081526024602052604081208054919055602c54611f51908263ffffffff61479a16565b602c55604051339082156108fc029083906000818181858888f193505050501515611ef457336000908152602460205260409020805482019055602c54611f9e908263ffffffff6147b116565b602c5550565b600c54600160a060020a03163314611fbb57600080fd5b6040805180820190915281815260646020918201819052601f9290925555565b6000806000611fe8615cf1565b600c5460009081908190819081908190600160a060020a0316331461200c57600080fd5b6120158b611e6f565b99506120218a8c614914565b60008b81526034602052604090205460338054909190811061203f57fe5b60009182526020918290206040805160c08101825260069093029091018054835260018101548385015260028101548383015260038101546060840152600481018054835181870281018701909452808452939491936080860193928301828280156120ca57602002820191906000526020600020905b8154815260200190600101908083116120b6575b505050505081526020016005820180548060200260200160405190810160405280929190818152602001828054801561212257602002820191906000526020600020905b81548152602001906001019080831161210e575b5050505050815250509650866060015198508660800151519750603260008b600160a060020a0316600160a060020a031681526020019081526020016000205495508860318781548110151561217457fe5b9060005260206000209060040201600201540360318781548110151561219657fe5b906000526020600020906004020160020181905550876031878154811015156121bb57fe5b906000526020600020906004020160030154036031878154811015156121dd57fe5b906000526020600020906004020160030181905550600094505b60008b81526036602052604090205485101561229f5760008b8152603660205260408120805460359183918990811061222c57fe5b90600052602060002090600202016000015481526020019081526020016000206000603660008f81526020019081526020016000208881548110151561226e57fe5b90600052602060002090600202016001015481526020019081526020016000208190555084806001019550506121f7565b60008b81526036602052604081206122b691615d2b565b60008b815260346020526040902054603354909450600019018414612364576033805460001981019081106122e757fe5b906000526020600020906006020160338581548110151561230457fe5b6000918252602090912082546006909202019081556001808301549082015560028083015490820155600380830154908201556004808301805461234b9284019190615d4c565b50600582810180546123609284019190615d4c565b5050505b6033805490612377906000198301615d9c565b5060008b815260346020526040812055600192505b60058360ff16101561247357505060ff811660009081526038602090815260408083208c84529091528120905b81548510156124685760ff8316600090815260376020526040812083549091908490849081106123e557fe5b90600052602060002090600202016000015481526020019081526020016000206000838381548110151561241557fe5b906000526020600020906002020160010154815260200190815260200160002060009055818181548110151561244757fe5b600091825260208220600290910201818155600190810191909155016123b9565b60019092019161238c565b5050505050505050505050565b600c54600160a060020a0316331461249757600080fd5b600f8054600160a060020a031916600160a060020a0383811691909117918290551615611ef457600f5460108054600160a060020a031916600160a060020a0390921691909117905550565b60606000805b8451821015610dae575060005b83518110156134925760ff86161515612cbd57600060356000878581518110151561251d57fe5b9060200190602002015181526020019081526020016000206000868481518110151561254557fe5b906020019060200201518152602001908152602001600020541115612cb8576012548551600160a060020a03909116906395978868908590839063997bc6c9908a908890811061259157fe5b906020019060200201516040518263ffffffff1660e060020a02815260040180828152602001915050600060405180830381600087803b1580156125d457600080fd5b505af11580156125e8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561261157600080fd5b81019080805164010000000081111561262957600080fd5b8201602081018481111561263c57600080fd5b815164010000000081118282018710171561265657600080fd5b50506012548b51919450600160a060020a0316925063997bc6c991508a908890811061267e57fe5b906020019060200201516040518263ffffffff1660e060020a02815260040180828152602001915050600060405180830381600087803b1580156126c157600080fd5b505af11580156126d5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156126fe57600080fd5b81019080805164010000000081111561271657600080fd5b8201602081018481111561272957600080fd5b815164010000000081118282018710171561274357600080fd5b50509291905050506040518463ffffffff1660e060020a028152600401808060200180602001806020018060200180602001868103865289818151815260200191508051906020019080838360005b838110156127aa578181015183820152602001612792565b50505050905090810190601f1680156127d75780820380516001836020036101000a031916815260200191505b50868103855260018152602001807f5b00000000000000000000000000000000000000000000000000000000000000815250602001868103845288818151815260200191508051906020019080838360005b83811015612841578181015183820152602001612829565b50505050905090810190601f16801561286e5780820380516001836020036101000a031916815260200191505b508681038352600181526020018060f960020a601d02815250602001868103825287818151815260200191508051906020019080838360005b838110156128bf5781810151838201526020016128a7565b50505050905090810190601f1680156128ec5780820380516001836020036101000a031916815260200191505b5098505050505050505050600060405180830381600087803b15801561291157600080fd5b505af1158015612925573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561294e57600080fd5b81019080805164010000000081111561296657600080fd5b8201602081018481111561297957600080fd5b815164010000000081118282018710171561299357600080fd5b50506012548951919750600160a060020a031693506345e965cd9250869150839063f76f950e906035906000908c908a9081106129cc57fe5b90602001906020020151815260200190815260200160002060008a888151811015156129f457fe5b906020019060200201518152602001908152602001600020546040518263ffffffff1660e060020a02815260040180828152602001915050600060405180830381600087803b158015612a4657600080fd5b505af1158015612a5a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015612a8357600080fd5b810190808051640100000000811115612a9b57600080fd5b82016020810184811115612aae57600080fd5b8151640100000000811182820187101715612ac857600080fd5b50509291905050506040518363ffffffff1660e060020a0281526004018080602001806020018060200180602001858103855287818151815260200191508051906020019080838360005b83811015612b2b578181015183820152602001612b13565b50505050905090810190601f168015612b585780820380516001836020036101000a031916815260200191505b508581038452600181526020018060f960020a601d02815250602001858103835286818151815260200191508051906020019080838360005b83811015612ba9578181015183820152602001612b91565b50505050905090810190601f168015612bd65780820380516001836020036101000a031916815260200191505b50858103825260018152602001807f5d000000000000000000000000000000000000000000000000000000000000008152506020019650505050505050600060405180830381600087803b158015612c2d57600080fd5b505af1158015612c41573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015612c6a57600080fd5b810190808051640100000000811115612c8257600080fd5b82016020810184811115612c9557600080fd5b8151640100000000811182820187101715612caf57600080fd5b50909650505050505b61348a565b60ff8616600090815260376020526040812086518290889086908110612cdf57fe5b90602001906020020151815260200190815260200160002060008684815181101515612d0757fe5b90602001906020020151815260200190815260200160002054111561348a576012548551600160a060020a03909116906395978868908590839063997bc6c9908a9088908110612d5357fe5b906020019060200201516040518263ffffffff1660e060020a02815260040180828152602001915050600060405180830381600087803b158015612d9657600080fd5b505af1158015612daa573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015612dd357600080fd5b810190808051640100000000811115612deb57600080fd5b82016020810184811115612dfe57600080fd5b8151640100000000811182820187101715612e1857600080fd5b50506012548b51919450600160a060020a0316925063997bc6c991508a9088908110612e4057fe5b906020019060200201516040518263ffffffff1660e060020a02815260040180828152602001915050600060405180830381600087803b158015612e8357600080fd5b505af1158015612e97573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015612ec057600080fd5b810190808051640100000000811115612ed857600080fd5b82016020810184811115612eeb57600080fd5b8151640100000000811182820187101715612f0557600080fd5b50509291905050506040518463ffffffff1660e060020a028152600401808060200180602001806020018060200180602001868103865289818151815260200191508051906020019080838360005b83811015612f6c578181015183820152602001612f54565b50505050905090810190601f168015612f995780820380516001836020036101000a031916815260200191505b50868103855260018152602001807f5b00000000000000000000000000000000000000000000000000000000000000815250602001868103845288818151815260200191508051906020019080838360005b83811015613003578181015183820152602001612feb565b50505050905090810190601f1680156130305780820380516001836020036101000a031916815260200191505b508681038352600181526020018060f960020a601d02815250602001868103825287818151815260200191508051906020019080838360005b83811015613081578181015183820152602001613069565b50505050905090810190601f1680156130ae5780820380516001836020036101000a031916815260200191505b5098505050505050505050600060405180830381600087803b1580156130d357600080fd5b505af11580156130e7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561311057600080fd5b81019080805164010000000081111561312857600080fd5b8201602081018481111561313b57600080fd5b815164010000000081118282018710171561315557600080fd5b505060125460ff8b1660009081526037602052604081208b51939950600160a060020a0390921695506345e965cd9450889350859263f76f950e9291908c908a90811061319e57fe5b90602001906020020151815260200190815260200160002060008a888151811015156131c657fe5b906020019060200201518152602001908152602001600020546040518263ffffffff1660e060020a02815260040180828152602001915050600060405180830381600087803b15801561321857600080fd5b505af115801561322c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561325557600080fd5b81019080805164010000000081111561326d57600080fd5b8201602081018481111561328057600080fd5b815164010000000081118282018710171561329a57600080fd5b50509291905050506040518363ffffffff1660e060020a0281526004018080602001806020018060200180602001858103855287818151815260200191508051906020019080838360005b838110156132fd5781810151838201526020016132e5565b50505050905090810190601f16801561332a5780820380516001836020036101000a031916815260200191505b508581038452600181526020018060f960020a601d02815250602001858103835286818151815260200191508051906020019080838360005b8381101561337b578181015183820152602001613363565b50505050905090810190601f1680156133a85780820380516001836020036101000a031916815260200191505b50858103825260018152602001807f5d000000000000000000000000000000000000000000000000000000000000008152506020019650505050505050600060405180830381600087803b1580156133ff57600080fd5b505af1158015613413573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561343c57600080fd5b81019080805164010000000081111561345457600080fd5b8201602081018481111561346757600080fd5b815164010000000081118282018710171561348157600080fd5b50909650505050505b6001016124f6565b6001909101906124e9565b600a8054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610e435780601f10610e1857610100808354040283529160200191610e43565b60305481565b600160a060020a03821633141561351a57600080fd5b336000818152600460209081526040808320600160a060020a03871680855290835292819020805460ff1916861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b602e5481565b61359984848461152c565b6135a58484848461495c565b15156135b057600080fd5b50505050565b602f5481565b600c54600160a060020a031633146135d357600080fd5b8115156135f657600c8054600160a060020a031916600160a060020a0383161790555b816001141561361b57600e8054600160a060020a031916600160a060020a0383161790555b816002141561364057600d8054600160a060020a031916600160a060020a0383161790555b5050565b606061364f826140a2565b151561365a57600080fd5b6000828152600b602090815260409182902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845290918301828280156136ed5780601f106136c2576101008083540402835291602001916136ed565b820191906000526020600020905b8154815290600101906020018083116136d057829003601f168201915b50505050509050919050565b600c54600160a060020a0316331461371057600080fd5b602655565b602b5481565b600c54600160a060020a0316331461373257600080fd5b6040805180820190915281815260646020909101819052602191909155602255565b6000806000806000606080613767615cf1565b6137708a611e6f565b60008b81526034602052604090205460338054929a5091811061378f57fe5b60009182526020918290206040805160c081018252600690930290910180548352600181015483850152600281015483830152600381015460608401526004810180548351818702810187019094528084529394919360808601939283018282801561381a57602002820191906000526020600020905b815481526020019060010190808311613806575b505050505081526020016005820180548060200260200160405190810160405280929190818152602001828054801561387257602002820191906000526020600020905b81548152602001906001019080831161385e575b5050505050815250509050806000015196508060600151935080602001519550806040015194508815156138af57806080015192508060a0015191505b5092959891949750929550565b600d54600090600160a060020a031633146138d657600080fd5b5060238054600091829055600d546040519192600160a060020a03909116916108fc919081818181818888f193505050501515611ef457602355565b60008060008585601260009054906101000a9004600160a060020a0316600160a060020a031663862c5e16333485856040518563ffffffff1660e060020a0281526004018085600160a060020a0316600160a060020a031681526020018481526020018060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156139b557818101518382015260200161399d565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156139f45781810151838201526020016139dc565b505050509050019650505050505050602060405180830381600087803b158015613a1d57600080fd5b505af1158015613a31573d6000803e3d6000fd5b505050506040513d6020811015613a4757600080fd5b50511515600114613aa2576040805160e560020a62461bcd02815260206004820152600f60248201527f4e6f7420656e6f75676820455448210000000000000000000000000000000000604482015290519081900360640190fd5b6012546040517f6202622900000000000000000000000000000000000000000000000000000000815233600482018181526060602484019081528c5160648501528c518d958d95600160a060020a039091169463620262299490938893889360448101916084909101906020808801910280838360005b83811015613b31578181015183820152602001613b19565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015613b70578181015183820152602001613b58565b5050505090500195505050505050602060405180830381600087803b158015613b9857600080fd5b505af1158015613bac573d6000803e3d6000fd5b505050506040513d6020811015613bc257600080fd5b50511515600114613c1d576040805160e560020a62461bcd02815260206004820181905260248201527f536f6d65206f662074686973206c616e6420616c7265616479206f776e656421604482015290519081900360640190fd5b33600090815260326020526040902054801515613d3e5760408051608081018252338082524260208084019182526000848601818152606086018281526031805460018101825581855297517fc54045fa7c6ec765e825df7f9e9bf9dec12c5cef146f93a5eee56772ee647fbc60049099029889018054600160a060020a031916600160a060020a0390921691909117905594517fc54045fa7c6ec765e825df7f9e9bf9dec12c5cef146f93a5eee56772ee647fbd88015590517fc54045fa7c6ec765e825df7f9e9bf9dec12c5cef146f93a5eee56772ee647fbe870155517fc54045fa7c6ec765e825df7f9e9bf9dec12c5cef146f93a5eee56772ee647fbf90950194909455905491835260329052919020600019919091019055613d64565b42603182815481101515613d4e57fe5b9060005260206000209060040201600101819055505b34975060009650600160a060020a0389163314801590613d8c5750600160a060020a03891615155b15613e2b57613da2601d3463ffffffff61476f16565b604051909750600160a060020a038a169088156108fc029089906000818181858888f1935050505015613e2b5760408051600160a060020a038b16808252602082018a9052428284015291517f500a1821a82e1e9951feb0c4eb0043d6f9d97be1a522ffa083f6a91b7b5c013d9181900360600190a2613e28888863ffffffff61479a16565b97505b613e3f611a4a60158a63ffffffff61476f16565b602c55600d54600160a060020a03166108fc613e6260138b63ffffffff61476f16565b6040518115909202916000818181858888f193505050501515613e9757613e93611aad60138a63ffffffff61476f16565b6023555b613ea28c8c8c6140bf565b613eb6611dcc60158a63ffffffff61476f16565b6027548b5110158015613ecb57506000602554115b15613fdc576028548b51811515613ede57fe5b049550602554861115613ef15760255495505b601054604080517fa9059cbb000000000000000000000000000000000000000000000000000000008152336004820152602481018990529051600160a060020a039092169163a9059cbb916044808201926020929091908290030181600087803b158015613f5e57600080fd5b505af1158015613f72573d6000803e3d6000fd5b505050506040513d6020811015613f8857600080fd5b5050604080513380825260208201899052428284015291517f4b4baca05c77f3008ba9b998920e58005aeb17a94101186b0a80f564075c043e9181900360600190a260268054870190556025805487900390555b505050505050505050505050565b602d5481565b60235481565b602c5481565b600160a060020a03918216600090815260046020908152604080832093909416825291909152205460ff1690565b60285481565b600c54600160a060020a0316331461404757600080fd5b6040805180820190915281815260646020909101819052601391909155601455565b600c54600160a060020a0316331461408057600080fd5b6040805180820190915281815260646020909101819052601991909155601a55565b600090815260016020526040902054600160a060020a0316151590565b60008060006140dd60016140d16114a5565b9063ffffffff6147b116565b92506140e93384614ade565b8351602b546040805160c081018252898152885160295490810260208084019182528b519092029383019384529390940260608201818152608083018b815260a084018b90526033805460018101808355600092909252855160069091027f82a75bdeeae8604d839476ae9efd8b0e15aa447e21bfd7f41283bb54e22c9a82810191825597517f82a75bdeeae8604d839476ae9efd8b0e15aa447e21bfd7f41283bb54e22c9a8389015595517f82a75bdeeae8604d839476ae9efd8b0e15aa447e21bfd7f41283bb54e22c9a8488015591517f82a75bdeeae8604d839476ae9efd8b0e15aa447e21bfd7f41283bb54e22c9a858701555180519298509095929461421a937f82a75bdeeae8604d839476ae9efd8b0e15aa447e21bfd7f41283bb54e22c9a8690910192910190615dc8565b5060a08201518051614236916005840191602090910190615dc8565b5050603354600086815260346020526040902060001990910190555061425f9050838686614b2d565b5033600090815260326020526040902054603180548391908390811061428157fe5b906000526020600020906004020160020154016031828154811015156142a357fe5b60009182526020909120600260049092020101556030805483019055845160318054839081106142cf57fe5b906000526020600020906004020160030154016031828154811015156142f157fe5b90600052602060002090600402016003018190555033600160a060020a0316837f807689f8da61b73f683c57d12d78610d2e69edfaa2feac878373d92ba25e273085338a8a600081518110151561434457fe5b906020019060200201518a600081518110151561435d57fe5b60209081029091018101518d5160295460408051988952600160a060020a0390971693880193909352868601949094526060860192909252608085019190915260a084019190915260c083015260e082018790524261010083015251908190036101200190a38451602a5402602954016029819055508451602e5401602e81905550505050505050565b6000806143f383611e6f565b905080600160a060020a031684600160a060020a0316148061442e575083600160a060020a031661442384610e4e565b600160a060020a0316145b8061443e575061443e8185613ffc565b949350505050565b600080614451615cf1565b60008481526034602052604081205460338054909190811061446f57fe5b60009182526020918290206040805160c08101825260069093029091018054835260018101548385015260028101548383015260038101546060840152600481018054835181870281018701909452808452939491936080860193928301828280156144fa57602002820191906000526020600020905b8154815260200190600101908083116144e6575b505050505081526020016005820180548060200260200160405190810160405280929190818152602001828054801561455257602002820191906000526020600020905b81548152602001906001019080831161453e575b50505050508152505091508160600151935081608001515192506032600088600160a060020a0316600160a060020a03168152602001908152602001600020549050836031828154811015156145a457fe5b906000526020600020906004020160020154036031828154811015156145c657fe5b906000526020600020906004020160020181905550826031828154811015156145eb57fe5b9060005260206000209060040201600301540360318281548110151561460d57fe5b9060005260206000209060040201600301819055506032600087600160a060020a0316600160a060020a031681526020019081526020016000205490508360318281548110151561465a57fe5b9060005260206000209060040201600201540160318281548110151561467c57fe5b906000526020600020906004020160020181905550826031828154811015156146a157fe5b906000526020600020906004020160030154016031828154811015156146c357fe5b90600052602060002090600402016003018190555050505050505050565b6146eb33826143e7565b15156146f657600080fd5b600160a060020a038216151561470b57600080fd5b6147158382614c89565b61471f8382614ceb565b6147298282614df2565b8082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000811515614780575060006115d5565b60018301548354830281151561479257fe5b049392505050565b600080838311156147aa57600080fd5b5050900390565b6000828201838110156147c357600080fd5b9392505050565b6147d5838383614446565b61156c838383614e3b565b60008060008060008060016147f36114a5565b111561490257600095506000945060395487019350600192505b6031548310156148b9576298968060305460318581548110151561482d57fe5b906000526020600020906004020160020154629896800281151561484d57fe5b04629896800281151561485c57fe5b04915050629896808304810260008111156148ae576148a360318481548110151561488357fe5b6000918252602090912060049091020154600160a060020a031682614ef2565b948501946001909401935b60019092019161480d565b60006039556040805187815260208101879052428183015290517f5fe10e72bed621bd9aa98489cd68e8ee3f0446c3472cea71de9c6c105c089f8f9181900360600190a161490b565b60398054880190555b50505050505050565b61491e8282614f4e565b6000818152600b60205260409020546002600019610100600184161502019091160415613640576000818152600b6020526040812061364091615e03565b60008061497185600160a060020a031661500a565b15156149805760019150614ad5565b6040517f150b7a020000000000000000000000000000000000000000000000000000000081523360048201818152600160a060020a03898116602485015260448401889052608060648501908152875160848601528751918a169463150b7a0294938c938b938b93909160a490910190602085019080838360005b83811015614a135781810151838201526020016149fb565b50505050905090810190601f168015614a405780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b158015614a6257600080fd5b505af1158015614a76573d6000803e3d6000fd5b505050506040513d6020811015614a8c57600080fd5b50517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1981167f150b7a020000000000000000000000000000000000000000000000000000000014925090505b50949350505050565b614ae88282615012565b600780546000838152600860205260408120829055600182018355919091527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688015550565b600080805b8451831015614c175785603560008786815181101515614b4e57fe5b90602001906020020151815260200190815260200160002060008686815181101515614b7657fe5b906020019060200201518152602001908152602001600020819055506036600087815260200190815260200160002060408051908101604052808786815181101515614bbe57fe5b9060200190602002015181526020018686815181101515614bdb57fe5b60209081029091018101519091528254600181810185556000948552938290208351600290920201908155910151908201559290920191614b32565b846000815181101515614c2657fe5b906020019060200201519150836000815181101515614c4157fe5b906020019060200201519050614c5a600183838961506d565b614c67600283838961506d565b614c74600383838961506d565b614c81600483838961506d565b505050505050565b81600160a060020a0316614c9c82611e6f565b600160a060020a031614614caf57600080fd5b600081815260026020526040902054600160a060020a0316156136405760009081526002602052604090208054600160a060020a031916905550565b6000806000614cfa85856159e2565b600084815260066020908152604080832054600160a060020a0389168452600590925290912054909350614d3590600163ffffffff61479a16565b600160a060020a038616600090815260056020526040902080549193509083908110614d5d57fe5b90600052602060002001549050806005600087600160a060020a0316600160a060020a0316815260200190815260200160002084815481101515614d9d57fe5b6000918252602080832090910192909255600160a060020a0387168152600590915260409020805490614dd4906000198301615e47565b50600093845260066020526040808520859055908452909220555050565b6000614dfe8383615a6b565b50600160a060020a039091166000908152600560209081526040808320805460018101825590845282842081018590559383526006909152902055565b600160a060020a0382161515614e5057600080fd5b600081815260026020526040902054600160a060020a031615614e8a5760008181526002602052604090208054600160a060020a03191690555b600160a060020a03831660009081526003602052604090205460011015614ecc57600160a060020a038316600090815260036020526040902080546000190190555b60008181526001602052604090208054600160a060020a03191690556147298282614df2565b600160a060020a038216600090815260246020526040902054614f1b908263ffffffff6147b116565b600160a060020a038316600090815260246020526040902055602d54614f47908263ffffffff6147b116565b602d555050565b6000806000614f5d8585615aee565b600084815260086020526040902054600754909350614f8390600163ffffffff61479a16565b9150600782815481101515614f9457fe5b9060005260206000200154905080600784815481101515614fb157fe5b60009182526020822001919091556007805484908110614fcd57fe5b6000918252602090912001556007805490614fec906000198301615e47565b50600093845260086020526040808520859055908452909220555050565b6000903b1190565b600160a060020a038216151561502757600080fd5b6150318282614df2565b6040518190600160a060020a038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000606080600061507e8888615b3e565b965061508a8887615b3e565b9550600593508760ff16600114156150a157600593505b8760ff16600214156150b257600493505b8760ff16600314156150c357600393505b8760ff16600414156150d457600293505b506000808712156150eb5760019050866000190296505b601254604080517f997bc6c9000000000000000000000000000000000000000000000000000000008152600481018a90529051600160a060020a039092169163997bc6c99160248082019260009290919082900301818387803b15801561515157600080fd5b505af1158015615165573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561518e57600080fd5b8101908080516401000000008111156151a657600080fd5b820160208101848111156151b957600080fd5b81516401000000008111828201871017156151d357600080fd5b50506012546040517f0326c06b000000000000000000000000000000000000000000000000000000008152602060048201818152845160248401528451949a50600160a060020a039093169650631dcd9b5595508994506000938b938893630326c06b9388938392604401918501908083838c5b8381101561525f578181015183820152602001615247565b50505050905090810190601f16801561528c5780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b1580156152ab57600080fd5b505af11580156152bf573d6000803e3d6000fd5b505050506040513d60208110156152d557600080fd5b505160405160e060020a63ffffffff8716028152602481018490529190036044820181905260606004830190815284516064840152845191929091829160840190602087019080838360005b83811015615339578181015183820152602001615321565b50505050905090810190601f1680156153665780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561538757600080fd5b505af115801561539b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156153c457600080fd5b8101908080516401000000008111156153dc57600080fd5b820160208101848111156153ef57600080fd5b815164010000000081118282018710171561540957600080fd5b5050601254604080517fbf4d89b500000000000000000000000000000000000000000000000000000000815260006024820181905260048201928352845160448301528451949a50600160a060020a03909316965063bf4d89b595508994509192909182916064909101906020860190808383885b8381101561549657818101518382015260200161547e565b50505050905090810190601f1680156154c35780820380516001836020036101000a031916815260200191505b509350505050602060405180830381600087803b1580156154e357600080fd5b505af11580156154f7573d6000803e3d6000fd5b505050506040513d602081101561550d57600080fd5b50519650801561551f57866000190296505b600086121561553857600190508560001902955061553c565b5060005b601254604080517f997bc6c9000000000000000000000000000000000000000000000000000000008152600481018990529051600160a060020a039092169163997bc6c99160248082019260009290919082900301818387803b1580156155a257600080fd5b505af11580156155b6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156155df57600080fd5b8101908080516401000000008111156155f757600080fd5b8201602081018481111561560a57600080fd5b815164010000000081118282018710171561562457600080fd5b50506012546040517f0326c06b000000000000000000000000000000000000000000000000000000008152602060048201818152845160248401528451949950600160a060020a039093169650631dcd9b5595508894506000938b938893630326c06b9388938392604401918501908083838c5b838110156156b0578181015183820152602001615698565b50505050905090810190601f1680156156dd5780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b1580156156fc57600080fd5b505af1158015615710573d6000803e3d6000fd5b505050506040513d602081101561572657600080fd5b505160405160e060020a63ffffffff8716028152602481018490529190036044820181905260606004830190815284516064840152845191929091829160840190602087019080838360005b8381101561578a578181015183820152602001615772565b50505050905090810190601f1680156157b75780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156157d857600080fd5b505af11580156157ec573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561581557600080fd5b81019080805164010000000081111561582d57600080fd5b8201602081018481111561584057600080fd5b815164010000000081118282018710171561585a57600080fd5b5050601254604080517fbf4d89b500000000000000000000000000000000000000000000000000000000815260006024820181905260048201928352845160448301528451949950600160a060020a03909316965063bf4d89b595508894509192909182916064909101906020860190808383885b838110156158e75781810151838201526020016158cf565b50505050905090810190601f1680156159145780820380516001836020036101000a031916815260200191505b509350505050602060405180830381600087803b15801561593457600080fd5b505af1158015615948573d6000803e3d6000fd5b505050506040513d602081101561595e57600080fd5b50519550801561597057856000190295505b50505060ff9094166000818152603760209081526040808320878452825280832086845282528083208590559282526038815282822093825292835281812082518084019093529482528183019384528454600181810187559582529290209051600290920201908155905191015550565b81600160a060020a03166159f582611e6f565b600160a060020a031614615a0857600080fd5b600160a060020a038216600090815260036020526040902054615a3290600163ffffffff61479a16565b600160a060020a039092166000908152600360209081526040808320949094559181526001909152208054600160a060020a0319169055565b600081815260016020526040902054600160a060020a031615615a8d57600080fd5b60008181526001602081815260408084208054600160a060020a031916600160a060020a0388169081179091558452600390915290912054615ace916147b1565b600160a060020a0390921660009081526003602052604090209190915550565b615af88282614c89565b615b028282614ceb565b6040518190600090600160a060020a038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6000620186a0600160ff85161415615b565750620186a05b8360ff1660021415615b6757506127105b8360ff1660031415615b7857506103e85b8360ff1660041415615b88575060645b8360ff1660051415615b985750600a5b6000831315615c4257601254604080517fda1eb54200000000000000000000000000000000000000000000000000000000815260048101869052602481018490529051600160a060020a039092169163da1eb542916044808201926020929091908290030181600087803b158015615c0f57600080fd5b505af1158015615c23573d6000803e3d6000fd5b505050506040513d6020811015615c3957600080fd5b50519250615ce9565b601254604080517fda1eb5420000000000000000000000000000000000000000000000000000000081526000958603600482018190526024820185905291519195600160a060020a039093169263da1eb542926044808401936020939083900390910190829087803b158015615cb757600080fd5b505af1158015615ccb573d6000803e3d6000fd5b505050506040513d6020811015615ce157600080fd5b505160000392505b509092915050565b60c0604051908101604052806000801916815260200160008152602001600081526020016000815260200160608152602001606081525090565b5080546000825560020290600052602060002090810190611ef49190615e6b565b828054828255906000526020600020908101928215615d8c5760005260206000209182015b82811115615d8c578254825591600101919060010190615d71565b50615d98929150615e8b565b5090565b81548183558181111561156c5760060281600602836000526020600020918201910161156c9190615ea5565b828054828255906000526020600020908101928215615d8c579160200282015b82811115615d8c578251825591602001919060010190615de8565b50805460018160011615610100020316600290046000825580601f10615e295750611ef4565b601f016020900490600052602060002090810190611ef49190615e8b565b81548183558181111561156c5760008381526020902061156c918101908301615e8b565b610e4b91905b80821115615d985760008082556001820155600201615e71565b610e4b91905b80821115615d985760008155600101615e91565b610e4b91905b80821115615d98576000808255600182018190556002820181905560038201819055615eda6004830182615ef1565b615ee8600583016000615ef1565b50600601615eab565b5080546000825590600052602060002090810190611ef49190615e8b5600a165627a7a7230582042badad37d7b5eed344c4ba6fd5492d81f93791345f3c9b6915c24b08962163b0029

Deployed Bytecode

0x60806040526004361061028f5763ffffffff60e060020a60003504166301de168a811461029457806301ef74f1146102bb57806301ffc9a7146102d057806303a7b41f1461031b57806306fdde03146103b1578063081812fc1461043b578063095ea7b31461046f5780630cb9ee4b146104955780630d4ea316146104aa57806318160ddd1461053d5780631cbda93d14610552578063222d7c8a1461056a578063232720651461057f57806323b872dd146105c757806328ab7375146105f15780632f745c5914610609578063306a85891461062d578063312df32114610645578063368aa9ca1461065d57806337a74f7e146106755780633fadc3881461068d57806342842e0e146106a2578063478c4238146106cc5780634a22c7fb146106e45780634f6ccce7146106f957806350357beb14610711578063567c31f7146107285780635a2ee0191461073d5780636352211e1461075257806364cbfdd61461076a57806370a082311461078b5780637517b57e146107ac578063769988b3146107c15780637b47ec1a146107d957806382568a24146107f157806387dfc9091461081257806395d89b41146108a85780639ee837f5146108bd578063a22cb465146108d2578063aeaf5a37146108f8578063b88d4fde1461090d578063be3f34711461097c578063c112d52514610991578063c87b56dd146109b5578063cf28b18e146109cd578063d3f78cb4146109e5578063d67c7f35146109fa578063db737c7814610a12578063dbc933bc14610b05578063dc00adef14610b1a578063e1036f8614610bab578063e4fd6f8114610bc0578063e717dc3d14610bd5578063e985e9c514610bea578063f719db8e14610c11578063fa985a2f14610c26578063fc4116bb14610c3e575b600080fd5b3480156102a057600080fd5b506102a9610c56565b60408051918252519081900360200190f35b3480156102c757600080fd5b506102a9610c5c565b3480156102dc57600080fd5b506103077bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1960043516610c62565b604080519115158252519081900360200190f35b34801561032757600080fd5b5060408051602060046024803582810135848102808701860190975280865261030796843560ff1696369660449591949091019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750949750610c969650505050505050565b3480156103bd57600080fd5b506103c6610db7565b6040805160208082528351818301528351919283929083019185019080838360005b838110156104005781810151838201526020016103e8565b50505050905090810190601f16801561042d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561044757600080fd5b50610453600435610e4e565b60408051600160a060020a039092168252519081900360200190f35b34801561047b57600080fd5b50610493600160a060020a0360043516602435610e80565b005b3480156104a157600080fd5b506102a9610f29565b3480156104b657600080fd5b5060408051602060046024803582810135848102808701860190975280865261049396843596369660449591949091019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750949750610f2f9650505050505050565b34801561054957600080fd5b506102a96114a5565b34801561055e57600080fd5b506104936004356114ab565b34801561057657600080fd5b506102a96114e4565b34801561058b57600080fd5b506105976004356114ea565b60408051600160a060020a0390951685526020850193909352838301919091526060830152519081900360800190f35b3480156105d357600080fd5b50610493600160a060020a036004358116906024351660443561152c565b3480156105fd57600080fd5b50610493600435611571565b34801561061557600080fd5b506102a9600160a060020a036004351660243561158d565b34801561063957600080fd5b506104936004356115db565b34801561065157600080fd5b50610493600435611614565b34801561066957600080fd5b5061049360043561164d565b34801561068157600080fd5b50610493600435611669565b34801561069957600080fd5b506102a9611685565b3480156106ae57600080fd5b50610493600160a060020a036004358116906024351660443561168b565b3480156106d857600080fd5b506104936004356116a7565b3480156106f057600080fd5b506102a96116e0565b34801561070557600080fd5b506102a96004356116e6565b610493600435600160a060020a036024351661171b565b34801561073457600080fd5b506102a9611e5a565b34801561074957600080fd5b50610493611e6d565b34801561075e57600080fd5b50610453600435611e6f565b34801561077657600080fd5b50610493600160a060020a0360043516611e93565b34801561079757600080fd5b506102a9600160a060020a0360043516611ef7565b3480156107b857600080fd5b50610493611f2a565b3480156107cd57600080fd5b50610493600435611fa4565b3480156107e557600080fd5b50610493600435611fdb565b3480156107fd57600080fd5b50610493600160a060020a0360043516612480565b34801561081e57600080fd5b506040805160206004602480358281013584810280870186019097528086526103c696843560ff1696369660449591949091019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a9989019892975090820195509350839250850190849080828437509497506124e39650505050505050565b3480156108b457600080fd5b506103c661349d565b3480156108c957600080fd5b506102a96134fe565b3480156108de57600080fd5b50610493600160a060020a03600435166024351515613504565b34801561090457600080fd5b506102a9613588565b34801561091957600080fd5b50604080516020601f60643560048181013592830184900484028501840190955281845261049394600160a060020a03813581169560248035909216956044359536956084940191819084018382808284375094975061358e9650505050505050565b34801561098857600080fd5b506102a96135b6565b34801561099d57600080fd5b50610493600435600160a060020a03602435166135bc565b3480156109c157600080fd5b506103c6600435613644565b3480156109d957600080fd5b506104936004356136f9565b3480156109f157600080fd5b506102a9613715565b348015610a0657600080fd5b5061049360043561371b565b348015610a1e57600080fd5b50610a2f6004356024351515613754565b6040518088600160a060020a0316600160a060020a0316815260200187600019166000191681526020018681526020018581526020018481526020018060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015610aab578181015183820152602001610a93565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015610aea578181015183820152602001610ad2565b50505050905001995050505050505050505060405180910390f35b348015610b1157600080fd5b506104936138bc565b60408051602060046024803582810135848102808701860190975280865261049396843596369660449591949091019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a99890198929750908201955093508392508501908490808284375094975050509235600160a060020a0316935061391292505050565b348015610bb757600080fd5b506102a9613fea565b348015610bcc57600080fd5b506102a9613ff0565b348015610be157600080fd5b506102a9613ff6565b348015610bf657600080fd5b50610307600160a060020a0360043581169060243516613ffc565b348015610c1d57600080fd5b506102a961402a565b348015610c3257600080fd5b50610493600435614030565b348015610c4a57600080fd5b50610493600435614069565b60275481565b60255481565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191660009081526020819052604090205460ff1690565b600080805b8451821015610da9575060005b8351811015610d9e5760ff86161515610d24576000603560008785815181101515610ccf57fe5b90602001906020020151815260200190815260200160002060008684815181101515610cf757fe5b906020019060200201518152602001908152602001600020541115610d1f5760019250610dae565b610d96565b60ff8616600090815260376020526040812086518290889086908110610d4657fe5b90602001906020020151815260200190815260200160002060008684815181101515610d6e57fe5b906020019060200201518152602001908152602001600020541115610d965760019250610dae565b600101610ca8565b600190910190610c9b565b600092505b50509392505050565b60098054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610e435780601f10610e1857610100808354040283529160200191610e43565b820191906000526020600020905b815481529060010190602001808311610e2657829003601f168201915b505050505090505b90565b6000610e59826140a2565b1515610e6457600080fd5b50600090815260026020526040902054600160a060020a031690565b6000610e8b82611e6f565b9050600160a060020a038381169082161415610ea657600080fd5b33600160a060020a0382161480610ec25750610ec28133613ffc565b1515610ecd57600080fd5b6000828152600260205260408082208054600160a060020a031916600160a060020a0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b60315490565b6012546040517f05117e0d000000000000000000000000000000000000000000000000000000008152336004820181815260606024840190815286516064850152865187958795600160a060020a03909116946305117e0d9490938893889360448101916084909101906020808801910280838360005b83811015610fbe578181015183820152602001610fa6565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015610ffd578181015183820152602001610fe5565b5050505090500195505050505050602060405180830381600087803b15801561102557600080fd5b505af1158015611039573d6000803e3d6000fd5b505050506040513d602081101561104f57600080fd5b505115156001146110cf576040805160e560020a62461bcd028152602060048201526024808201527f4e6f7420656e6f75676820434f494e5320746f2062757920746865736520706c60448201527f6f74732100000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b601054600e548351604080517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a03938416602482015260448101929092525191909216916323b872dd9160648083019260209291908290030181600087803b15801561114957600080fd5b505af115801561115d573d6000803e3d6000fd5b505050506040513d602081101561117357600080fd5b505115156001146111ce576040805160e560020a62461bcd02815260206004820152601560248201527f546f6b656e207472616e73666572206661696c65640000000000000000000000604482015290519081900360640190fd5b6012546040517f62026229000000000000000000000000000000000000000000000000000000008152336004820181815260606024840190815288516064850152885189958995600160a060020a039091169463620262299490938893889360448101916084909101906020808801910280838360005b8381101561125d578181015183820152602001611245565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561129c578181015183820152602001611284565b5050505090500195505050505050602060405180830381600087803b1580156112c457600080fd5b505af11580156112d8573d6000803e3d6000fd5b505050506040513d60208110156112ee57600080fd5b50511515600114611349576040805160e560020a62461bcd02815260206004820181905260248201527f536f6d65206f662074686973206c616e6420616c7265616479206f776e656421604482015290519081900360640190fd5b3360009081526032602052604090205480151561146a5760408051608081018252338082524260208084019182526000848601818152606086018281526031805460018101825581855297517fc54045fa7c6ec765e825df7f9e9bf9dec12c5cef146f93a5eee56772ee647fbc60049099029889018054600160a060020a031916600160a060020a0390921691909117905594517fc54045fa7c6ec765e825df7f9e9bf9dec12c5cef146f93a5eee56772ee647fbd88015590517fc54045fa7c6ec765e825df7f9e9bf9dec12c5cef146f93a5eee56772ee647fbe870155517fc54045fa7c6ec765e825df7f9e9bf9dec12c5cef146f93a5eee56772ee647fbf90950194909455905491835260329052919020600019919091019055611490565b4260318281548110151561147a57fe5b9060005260206000209060040201600101819055505b61149b8888886140bf565b5050505050505050565b60075490565b600c54600160a060020a031633146114c257600080fd5b6040805180820190915281815260646020909101819052601791909155601855565b602a5481565b60318054829081106114f857fe5b60009182526020909120600490910201805460018201546002830154600390930154600160a060020a039092169350919084565b61153633826143e7565b151561154157600080fd5b600160a060020a038216151561155657600080fd5b611561838383614446565b61156c8383836146e1565b505050565b600c54600160a060020a0316331461158857600080fd5b602555565b600061159883611ef7565b82106115a357600080fd5b600160a060020a03831660009081526005602052604090208054839081106115c757fe5b906000526020600020015490505b92915050565b600c54600160a060020a031633146115f257600080fd5b6040805180820190915281815260646020909101819052601591909155601655565b600c54600160a060020a0316331461162b57600080fd5b6040805180820190915281815260646020909101819052601d91909155601e55565b600c54600160a060020a0316331461166457600080fd5b602a55565b600c54600160a060020a0316331461168057600080fd5b602b55565b60295481565b61156c838383602060405190810160405280600081525061358e565b600c54600160a060020a031633146116be57600080fd5b6040805180820190915281815260646020909101819052601b91909155601c55565b60265481565b60006116f06114a5565b82106116fb57600080fd5b600780548390811061170957fe5b90600052602060002001549050919050565b6000806000611728615cf1565b601254604080517e54438d0000000000000000000000000000000000000000000000000000000081523360048201523460248201526044810189905290516000928392839283928c92600160a060020a03909116916254438d9160648082019260209290919082900301818887803b1580156117a357600080fd5b505af11580156117b7573d6000803e3d6000fd5b505050506040513d60208110156117cd57600080fd5b50511515600114611828576040805160e560020a62461bcd02815260206004820181905260248201527f4e6f7420656e6f7567682045544820746f206275792074686973206361726421604482015290519081900360640190fd5b336000908152603260205260409020548015156119495760408051608081018252338082524260208084019182526000848601818152606086018281526031805460018101825581855297517fc54045fa7c6ec765e825df7f9e9bf9dec12c5cef146f93a5eee56772ee647fbc60049099029889018054600160a060020a031916600160a060020a0390921691909117905594517fc54045fa7c6ec765e825df7f9e9bf9dec12c5cef146f93a5eee56772ee647fbd88015590517fc54045fa7c6ec765e825df7f9e9bf9dec12c5cef146f93a5eee56772ee647fbe870155517fc54045fa7c6ec765e825df7f9e9bf9dec12c5cef146f93a5eee56772ee647fbf9095019490945590549183526032905291902060001991909101905561196f565b4260318281548110151561195957fe5b9060005260206000209060040201600101819055505b34995060009850600160a060020a038b1633148015906119975750600160a060020a038b1615155b15611a36576119ad601d3463ffffffff61476f16565b604051909950600160a060020a038c16908a156108fc02908b906000818181858888f1935050505015611a365760408051600160a060020a038d16808252602082018c9052428284015291517f500a1821a82e1e9951feb0c4eb0043d6f9d97be1a522ffa083f6a91b7b5c013d9181900360600190a2611a338a8a63ffffffff61479a16565b99505b611a59611a4a60198c63ffffffff61476f16565b602c549063ffffffff6147b116565b602c55600d54600160a060020a03166108fc611a7c60178d63ffffffff61476f16565b6040518115909202916000818181858888f193505050501515611ac057611abc611aad60178c63ffffffff61476f16565b6023549063ffffffff6147b116565b6023555b611ac98c611e6f565b9750600160a060020a0388166108fc611ae9601b8d63ffffffff61476f16565b6040518115909202916000818181858888f193505050501515611b5957611b3f611b1a601b8c63ffffffff61476f16565b600160a060020a038a166000908152602460205260409020549063ffffffff6147b116565b600160a060020a0389166000908152602460205260409020555b611b6488338e6147ca565b60008c815260346020526040902054603380549091908110611b8257fe5b60009182526020918290206040805160c0810182526006909302909101805483526001810154838501526002810154838301526003810154606084015260048101805483518187028101870190945280845293949193608086019392830182828015611c0d57602002820191906000526020600020905b815481526020019060010190808311611bf9575b5050505050815260200160058201805480602002602001604051908101604052809291908181526020018280548015611c6557602002820191906000526020600020905b815481526020019060010190808311611c51575b5050509190925250505060608101519097509550611c8a601f8763ffffffff61476f16565b604080890151336000908152603260205291909120546031805493985091965094508787039185908110611cba57fe5b90600052602060002090600402016002015401603184815481101515611cdc57fe5b906000526020600020906004020160020181905550846033603460008f815260200190815260200160002054815481101515611d1457fe5b90600052602060002090600602016003018190555085850360305401603081905550611d7d6033603460008f815260200190815260200160002054815481101515611d5b57fe5b906000526020600020906006020160020154602161476f90919063ffffffff16565b60008d815260346020526040902054603380549091908110611d9b57fe5b6000918252602090912060026006909202010155602f80546001019055611dd1611dcc60198c63ffffffff61476f16565b6147e0565b8651604080518e8152600160a060020a038b1660208201819052338284018190526060830194909452608082018890523460a083015260c082018a905260e082018990524261010083015291518f917fca6cef801d696b99880261abca3984a0cf932a69993676ef85130e9ce94e94da91908190036101200190a4505050505050505050505050565b3360009081526024602052604090205490565b565b600081815260016020526040812054600160a060020a03168015156115d557600080fd5b600c54600160a060020a03163314611eaa57600080fd5b60118054600160a060020a031916600160a060020a0383811691909117918290551615611ef45760115460128054600160a060020a031916600160a060020a039092169190911790555b50565b6000600160a060020a0382161515611f0e57600080fd5b50600160a060020a031660009081526003602052604090205490565b3360009081526024602052604081208054919055602c54611f51908263ffffffff61479a16565b602c55604051339082156108fc029083906000818181858888f193505050501515611ef457336000908152602460205260409020805482019055602c54611f9e908263ffffffff6147b116565b602c5550565b600c54600160a060020a03163314611fbb57600080fd5b6040805180820190915281815260646020918201819052601f9290925555565b6000806000611fe8615cf1565b600c5460009081908190819081908190600160a060020a0316331461200c57600080fd5b6120158b611e6f565b99506120218a8c614914565b60008b81526034602052604090205460338054909190811061203f57fe5b60009182526020918290206040805160c08101825260069093029091018054835260018101548385015260028101548383015260038101546060840152600481018054835181870281018701909452808452939491936080860193928301828280156120ca57602002820191906000526020600020905b8154815260200190600101908083116120b6575b505050505081526020016005820180548060200260200160405190810160405280929190818152602001828054801561212257602002820191906000526020600020905b81548152602001906001019080831161210e575b5050505050815250509650866060015198508660800151519750603260008b600160a060020a0316600160a060020a031681526020019081526020016000205495508860318781548110151561217457fe5b9060005260206000209060040201600201540360318781548110151561219657fe5b906000526020600020906004020160020181905550876031878154811015156121bb57fe5b906000526020600020906004020160030154036031878154811015156121dd57fe5b906000526020600020906004020160030181905550600094505b60008b81526036602052604090205485101561229f5760008b8152603660205260408120805460359183918990811061222c57fe5b90600052602060002090600202016000015481526020019081526020016000206000603660008f81526020019081526020016000208881548110151561226e57fe5b90600052602060002090600202016001015481526020019081526020016000208190555084806001019550506121f7565b60008b81526036602052604081206122b691615d2b565b60008b815260346020526040902054603354909450600019018414612364576033805460001981019081106122e757fe5b906000526020600020906006020160338581548110151561230457fe5b6000918252602090912082546006909202019081556001808301549082015560028083015490820155600380830154908201556004808301805461234b9284019190615d4c565b50600582810180546123609284019190615d4c565b5050505b6033805490612377906000198301615d9c565b5060008b815260346020526040812055600192505b60058360ff16101561247357505060ff811660009081526038602090815260408083208c84529091528120905b81548510156124685760ff8316600090815260376020526040812083549091908490849081106123e557fe5b90600052602060002090600202016000015481526020019081526020016000206000838381548110151561241557fe5b906000526020600020906002020160010154815260200190815260200160002060009055818181548110151561244757fe5b600091825260208220600290910201818155600190810191909155016123b9565b60019092019161238c565b5050505050505050505050565b600c54600160a060020a0316331461249757600080fd5b600f8054600160a060020a031916600160a060020a0383811691909117918290551615611ef457600f5460108054600160a060020a031916600160a060020a0390921691909117905550565b60606000805b8451821015610dae575060005b83518110156134925760ff86161515612cbd57600060356000878581518110151561251d57fe5b9060200190602002015181526020019081526020016000206000868481518110151561254557fe5b906020019060200201518152602001908152602001600020541115612cb8576012548551600160a060020a03909116906395978868908590839063997bc6c9908a908890811061259157fe5b906020019060200201516040518263ffffffff1660e060020a02815260040180828152602001915050600060405180830381600087803b1580156125d457600080fd5b505af11580156125e8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561261157600080fd5b81019080805164010000000081111561262957600080fd5b8201602081018481111561263c57600080fd5b815164010000000081118282018710171561265657600080fd5b50506012548b51919450600160a060020a0316925063997bc6c991508a908890811061267e57fe5b906020019060200201516040518263ffffffff1660e060020a02815260040180828152602001915050600060405180830381600087803b1580156126c157600080fd5b505af11580156126d5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156126fe57600080fd5b81019080805164010000000081111561271657600080fd5b8201602081018481111561272957600080fd5b815164010000000081118282018710171561274357600080fd5b50509291905050506040518463ffffffff1660e060020a028152600401808060200180602001806020018060200180602001868103865289818151815260200191508051906020019080838360005b838110156127aa578181015183820152602001612792565b50505050905090810190601f1680156127d75780820380516001836020036101000a031916815260200191505b50868103855260018152602001807f5b00000000000000000000000000000000000000000000000000000000000000815250602001868103845288818151815260200191508051906020019080838360005b83811015612841578181015183820152602001612829565b50505050905090810190601f16801561286e5780820380516001836020036101000a031916815260200191505b508681038352600181526020018060f960020a601d02815250602001868103825287818151815260200191508051906020019080838360005b838110156128bf5781810151838201526020016128a7565b50505050905090810190601f1680156128ec5780820380516001836020036101000a031916815260200191505b5098505050505050505050600060405180830381600087803b15801561291157600080fd5b505af1158015612925573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561294e57600080fd5b81019080805164010000000081111561296657600080fd5b8201602081018481111561297957600080fd5b815164010000000081118282018710171561299357600080fd5b50506012548951919750600160a060020a031693506345e965cd9250869150839063f76f950e906035906000908c908a9081106129cc57fe5b90602001906020020151815260200190815260200160002060008a888151811015156129f457fe5b906020019060200201518152602001908152602001600020546040518263ffffffff1660e060020a02815260040180828152602001915050600060405180830381600087803b158015612a4657600080fd5b505af1158015612a5a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015612a8357600080fd5b810190808051640100000000811115612a9b57600080fd5b82016020810184811115612aae57600080fd5b8151640100000000811182820187101715612ac857600080fd5b50509291905050506040518363ffffffff1660e060020a0281526004018080602001806020018060200180602001858103855287818151815260200191508051906020019080838360005b83811015612b2b578181015183820152602001612b13565b50505050905090810190601f168015612b585780820380516001836020036101000a031916815260200191505b508581038452600181526020018060f960020a601d02815250602001858103835286818151815260200191508051906020019080838360005b83811015612ba9578181015183820152602001612b91565b50505050905090810190601f168015612bd65780820380516001836020036101000a031916815260200191505b50858103825260018152602001807f5d000000000000000000000000000000000000000000000000000000000000008152506020019650505050505050600060405180830381600087803b158015612c2d57600080fd5b505af1158015612c41573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015612c6a57600080fd5b810190808051640100000000811115612c8257600080fd5b82016020810184811115612c9557600080fd5b8151640100000000811182820187101715612caf57600080fd5b50909650505050505b61348a565b60ff8616600090815260376020526040812086518290889086908110612cdf57fe5b90602001906020020151815260200190815260200160002060008684815181101515612d0757fe5b90602001906020020151815260200190815260200160002054111561348a576012548551600160a060020a03909116906395978868908590839063997bc6c9908a9088908110612d5357fe5b906020019060200201516040518263ffffffff1660e060020a02815260040180828152602001915050600060405180830381600087803b158015612d9657600080fd5b505af1158015612daa573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015612dd357600080fd5b810190808051640100000000811115612deb57600080fd5b82016020810184811115612dfe57600080fd5b8151640100000000811182820187101715612e1857600080fd5b50506012548b51919450600160a060020a0316925063997bc6c991508a9088908110612e4057fe5b906020019060200201516040518263ffffffff1660e060020a02815260040180828152602001915050600060405180830381600087803b158015612e8357600080fd5b505af1158015612e97573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015612ec057600080fd5b810190808051640100000000811115612ed857600080fd5b82016020810184811115612eeb57600080fd5b8151640100000000811182820187101715612f0557600080fd5b50509291905050506040518463ffffffff1660e060020a028152600401808060200180602001806020018060200180602001868103865289818151815260200191508051906020019080838360005b83811015612f6c578181015183820152602001612f54565b50505050905090810190601f168015612f995780820380516001836020036101000a031916815260200191505b50868103855260018152602001807f5b00000000000000000000000000000000000000000000000000000000000000815250602001868103845288818151815260200191508051906020019080838360005b83811015613003578181015183820152602001612feb565b50505050905090810190601f1680156130305780820380516001836020036101000a031916815260200191505b508681038352600181526020018060f960020a601d02815250602001868103825287818151815260200191508051906020019080838360005b83811015613081578181015183820152602001613069565b50505050905090810190601f1680156130ae5780820380516001836020036101000a031916815260200191505b5098505050505050505050600060405180830381600087803b1580156130d357600080fd5b505af11580156130e7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561311057600080fd5b81019080805164010000000081111561312857600080fd5b8201602081018481111561313b57600080fd5b815164010000000081118282018710171561315557600080fd5b505060125460ff8b1660009081526037602052604081208b51939950600160a060020a0390921695506345e965cd9450889350859263f76f950e9291908c908a90811061319e57fe5b90602001906020020151815260200190815260200160002060008a888151811015156131c657fe5b906020019060200201518152602001908152602001600020546040518263ffffffff1660e060020a02815260040180828152602001915050600060405180830381600087803b15801561321857600080fd5b505af115801561322c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561325557600080fd5b81019080805164010000000081111561326d57600080fd5b8201602081018481111561328057600080fd5b815164010000000081118282018710171561329a57600080fd5b50509291905050506040518363ffffffff1660e060020a0281526004018080602001806020018060200180602001858103855287818151815260200191508051906020019080838360005b838110156132fd5781810151838201526020016132e5565b50505050905090810190601f16801561332a5780820380516001836020036101000a031916815260200191505b508581038452600181526020018060f960020a601d02815250602001858103835286818151815260200191508051906020019080838360005b8381101561337b578181015183820152602001613363565b50505050905090810190601f1680156133a85780820380516001836020036101000a031916815260200191505b50858103825260018152602001807f5d000000000000000000000000000000000000000000000000000000000000008152506020019650505050505050600060405180830381600087803b1580156133ff57600080fd5b505af1158015613413573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561343c57600080fd5b81019080805164010000000081111561345457600080fd5b8201602081018481111561346757600080fd5b815164010000000081118282018710171561348157600080fd5b50909650505050505b6001016124f6565b6001909101906124e9565b600a8054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610e435780601f10610e1857610100808354040283529160200191610e43565b60305481565b600160a060020a03821633141561351a57600080fd5b336000818152600460209081526040808320600160a060020a03871680855290835292819020805460ff1916861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b602e5481565b61359984848461152c565b6135a58484848461495c565b15156135b057600080fd5b50505050565b602f5481565b600c54600160a060020a031633146135d357600080fd5b8115156135f657600c8054600160a060020a031916600160a060020a0383161790555b816001141561361b57600e8054600160a060020a031916600160a060020a0383161790555b816002141561364057600d8054600160a060020a031916600160a060020a0383161790555b5050565b606061364f826140a2565b151561365a57600080fd5b6000828152600b602090815260409182902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845290918301828280156136ed5780601f106136c2576101008083540402835291602001916136ed565b820191906000526020600020905b8154815290600101906020018083116136d057829003601f168201915b50505050509050919050565b600c54600160a060020a0316331461371057600080fd5b602655565b602b5481565b600c54600160a060020a0316331461373257600080fd5b6040805180820190915281815260646020909101819052602191909155602255565b6000806000806000606080613767615cf1565b6137708a611e6f565b60008b81526034602052604090205460338054929a5091811061378f57fe5b60009182526020918290206040805160c081018252600690930290910180548352600181015483850152600281015483830152600381015460608401526004810180548351818702810187019094528084529394919360808601939283018282801561381a57602002820191906000526020600020905b815481526020019060010190808311613806575b505050505081526020016005820180548060200260200160405190810160405280929190818152602001828054801561387257602002820191906000526020600020905b81548152602001906001019080831161385e575b5050505050815250509050806000015196508060600151935080602001519550806040015194508815156138af57806080015192508060a0015191505b5092959891949750929550565b600d54600090600160a060020a031633146138d657600080fd5b5060238054600091829055600d546040519192600160a060020a03909116916108fc919081818181818888f193505050501515611ef457602355565b60008060008585601260009054906101000a9004600160a060020a0316600160a060020a031663862c5e16333485856040518563ffffffff1660e060020a0281526004018085600160a060020a0316600160a060020a031681526020018481526020018060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156139b557818101518382015260200161399d565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156139f45781810151838201526020016139dc565b505050509050019650505050505050602060405180830381600087803b158015613a1d57600080fd5b505af1158015613a31573d6000803e3d6000fd5b505050506040513d6020811015613a4757600080fd5b50511515600114613aa2576040805160e560020a62461bcd02815260206004820152600f60248201527f4e6f7420656e6f75676820455448210000000000000000000000000000000000604482015290519081900360640190fd5b6012546040517f6202622900000000000000000000000000000000000000000000000000000000815233600482018181526060602484019081528c5160648501528c518d958d95600160a060020a039091169463620262299490938893889360448101916084909101906020808801910280838360005b83811015613b31578181015183820152602001613b19565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015613b70578181015183820152602001613b58565b5050505090500195505050505050602060405180830381600087803b158015613b9857600080fd5b505af1158015613bac573d6000803e3d6000fd5b505050506040513d6020811015613bc257600080fd5b50511515600114613c1d576040805160e560020a62461bcd02815260206004820181905260248201527f536f6d65206f662074686973206c616e6420616c7265616479206f776e656421604482015290519081900360640190fd5b33600090815260326020526040902054801515613d3e5760408051608081018252338082524260208084019182526000848601818152606086018281526031805460018101825581855297517fc54045fa7c6ec765e825df7f9e9bf9dec12c5cef146f93a5eee56772ee647fbc60049099029889018054600160a060020a031916600160a060020a0390921691909117905594517fc54045fa7c6ec765e825df7f9e9bf9dec12c5cef146f93a5eee56772ee647fbd88015590517fc54045fa7c6ec765e825df7f9e9bf9dec12c5cef146f93a5eee56772ee647fbe870155517fc54045fa7c6ec765e825df7f9e9bf9dec12c5cef146f93a5eee56772ee647fbf90950194909455905491835260329052919020600019919091019055613d64565b42603182815481101515613d4e57fe5b9060005260206000209060040201600101819055505b34975060009650600160a060020a0389163314801590613d8c5750600160a060020a03891615155b15613e2b57613da2601d3463ffffffff61476f16565b604051909750600160a060020a038a169088156108fc029089906000818181858888f1935050505015613e2b5760408051600160a060020a038b16808252602082018a9052428284015291517f500a1821a82e1e9951feb0c4eb0043d6f9d97be1a522ffa083f6a91b7b5c013d9181900360600190a2613e28888863ffffffff61479a16565b97505b613e3f611a4a60158a63ffffffff61476f16565b602c55600d54600160a060020a03166108fc613e6260138b63ffffffff61476f16565b6040518115909202916000818181858888f193505050501515613e9757613e93611aad60138a63ffffffff61476f16565b6023555b613ea28c8c8c6140bf565b613eb6611dcc60158a63ffffffff61476f16565b6027548b5110158015613ecb57506000602554115b15613fdc576028548b51811515613ede57fe5b049550602554861115613ef15760255495505b601054604080517fa9059cbb000000000000000000000000000000000000000000000000000000008152336004820152602481018990529051600160a060020a039092169163a9059cbb916044808201926020929091908290030181600087803b158015613f5e57600080fd5b505af1158015613f72573d6000803e3d6000fd5b505050506040513d6020811015613f8857600080fd5b5050604080513380825260208201899052428284015291517f4b4baca05c77f3008ba9b998920e58005aeb17a94101186b0a80f564075c043e9181900360600190a260268054870190556025805487900390555b505050505050505050505050565b602d5481565b60235481565b602c5481565b600160a060020a03918216600090815260046020908152604080832093909416825291909152205460ff1690565b60285481565b600c54600160a060020a0316331461404757600080fd5b6040805180820190915281815260646020909101819052601391909155601455565b600c54600160a060020a0316331461408057600080fd5b6040805180820190915281815260646020909101819052601991909155601a55565b600090815260016020526040902054600160a060020a0316151590565b60008060006140dd60016140d16114a5565b9063ffffffff6147b116565b92506140e93384614ade565b8351602b546040805160c081018252898152885160295490810260208084019182528b519092029383019384529390940260608201818152608083018b815260a084018b90526033805460018101808355600092909252855160069091027f82a75bdeeae8604d839476ae9efd8b0e15aa447e21bfd7f41283bb54e22c9a82810191825597517f82a75bdeeae8604d839476ae9efd8b0e15aa447e21bfd7f41283bb54e22c9a8389015595517f82a75bdeeae8604d839476ae9efd8b0e15aa447e21bfd7f41283bb54e22c9a8488015591517f82a75bdeeae8604d839476ae9efd8b0e15aa447e21bfd7f41283bb54e22c9a858701555180519298509095929461421a937f82a75bdeeae8604d839476ae9efd8b0e15aa447e21bfd7f41283bb54e22c9a8690910192910190615dc8565b5060a08201518051614236916005840191602090910190615dc8565b5050603354600086815260346020526040902060001990910190555061425f9050838686614b2d565b5033600090815260326020526040902054603180548391908390811061428157fe5b906000526020600020906004020160020154016031828154811015156142a357fe5b60009182526020909120600260049092020101556030805483019055845160318054839081106142cf57fe5b906000526020600020906004020160030154016031828154811015156142f157fe5b90600052602060002090600402016003018190555033600160a060020a0316837f807689f8da61b73f683c57d12d78610d2e69edfaa2feac878373d92ba25e273085338a8a600081518110151561434457fe5b906020019060200201518a600081518110151561435d57fe5b60209081029091018101518d5160295460408051988952600160a060020a0390971693880193909352868601949094526060860192909252608085019190915260a084019190915260c083015260e082018790524261010083015251908190036101200190a38451602a5402602954016029819055508451602e5401602e81905550505050505050565b6000806143f383611e6f565b905080600160a060020a031684600160a060020a0316148061442e575083600160a060020a031661442384610e4e565b600160a060020a0316145b8061443e575061443e8185613ffc565b949350505050565b600080614451615cf1565b60008481526034602052604081205460338054909190811061446f57fe5b60009182526020918290206040805160c08101825260069093029091018054835260018101548385015260028101548383015260038101546060840152600481018054835181870281018701909452808452939491936080860193928301828280156144fa57602002820191906000526020600020905b8154815260200190600101908083116144e6575b505050505081526020016005820180548060200260200160405190810160405280929190818152602001828054801561455257602002820191906000526020600020905b81548152602001906001019080831161453e575b50505050508152505091508160600151935081608001515192506032600088600160a060020a0316600160a060020a03168152602001908152602001600020549050836031828154811015156145a457fe5b906000526020600020906004020160020154036031828154811015156145c657fe5b906000526020600020906004020160020181905550826031828154811015156145eb57fe5b9060005260206000209060040201600301540360318281548110151561460d57fe5b9060005260206000209060040201600301819055506032600087600160a060020a0316600160a060020a031681526020019081526020016000205490508360318281548110151561465a57fe5b9060005260206000209060040201600201540160318281548110151561467c57fe5b906000526020600020906004020160020181905550826031828154811015156146a157fe5b906000526020600020906004020160030154016031828154811015156146c357fe5b90600052602060002090600402016003018190555050505050505050565b6146eb33826143e7565b15156146f657600080fd5b600160a060020a038216151561470b57600080fd5b6147158382614c89565b61471f8382614ceb565b6147298282614df2565b8082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000811515614780575060006115d5565b60018301548354830281151561479257fe5b049392505050565b600080838311156147aa57600080fd5b5050900390565b6000828201838110156147c357600080fd5b9392505050565b6147d5838383614446565b61156c838383614e3b565b60008060008060008060016147f36114a5565b111561490257600095506000945060395487019350600192505b6031548310156148b9576298968060305460318581548110151561482d57fe5b906000526020600020906004020160020154629896800281151561484d57fe5b04629896800281151561485c57fe5b04915050629896808304810260008111156148ae576148a360318481548110151561488357fe5b6000918252602090912060049091020154600160a060020a031682614ef2565b948501946001909401935b60019092019161480d565b60006039556040805187815260208101879052428183015290517f5fe10e72bed621bd9aa98489cd68e8ee3f0446c3472cea71de9c6c105c089f8f9181900360600190a161490b565b60398054880190555b50505050505050565b61491e8282614f4e565b6000818152600b60205260409020546002600019610100600184161502019091160415613640576000818152600b6020526040812061364091615e03565b60008061497185600160a060020a031661500a565b15156149805760019150614ad5565b6040517f150b7a020000000000000000000000000000000000000000000000000000000081523360048201818152600160a060020a03898116602485015260448401889052608060648501908152875160848601528751918a169463150b7a0294938c938b938b93909160a490910190602085019080838360005b83811015614a135781810151838201526020016149fb565b50505050905090810190601f168015614a405780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b158015614a6257600080fd5b505af1158015614a76573d6000803e3d6000fd5b505050506040513d6020811015614a8c57600080fd5b50517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1981167f150b7a020000000000000000000000000000000000000000000000000000000014925090505b50949350505050565b614ae88282615012565b600780546000838152600860205260408120829055600182018355919091527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688015550565b600080805b8451831015614c175785603560008786815181101515614b4e57fe5b90602001906020020151815260200190815260200160002060008686815181101515614b7657fe5b906020019060200201518152602001908152602001600020819055506036600087815260200190815260200160002060408051908101604052808786815181101515614bbe57fe5b9060200190602002015181526020018686815181101515614bdb57fe5b60209081029091018101519091528254600181810185556000948552938290208351600290920201908155910151908201559290920191614b32565b846000815181101515614c2657fe5b906020019060200201519150836000815181101515614c4157fe5b906020019060200201519050614c5a600183838961506d565b614c67600283838961506d565b614c74600383838961506d565b614c81600483838961506d565b505050505050565b81600160a060020a0316614c9c82611e6f565b600160a060020a031614614caf57600080fd5b600081815260026020526040902054600160a060020a0316156136405760009081526002602052604090208054600160a060020a031916905550565b6000806000614cfa85856159e2565b600084815260066020908152604080832054600160a060020a0389168452600590925290912054909350614d3590600163ffffffff61479a16565b600160a060020a038616600090815260056020526040902080549193509083908110614d5d57fe5b90600052602060002001549050806005600087600160a060020a0316600160a060020a0316815260200190815260200160002084815481101515614d9d57fe5b6000918252602080832090910192909255600160a060020a0387168152600590915260409020805490614dd4906000198301615e47565b50600093845260066020526040808520859055908452909220555050565b6000614dfe8383615a6b565b50600160a060020a039091166000908152600560209081526040808320805460018101825590845282842081018590559383526006909152902055565b600160a060020a0382161515614e5057600080fd5b600081815260026020526040902054600160a060020a031615614e8a5760008181526002602052604090208054600160a060020a03191690555b600160a060020a03831660009081526003602052604090205460011015614ecc57600160a060020a038316600090815260036020526040902080546000190190555b60008181526001602052604090208054600160a060020a03191690556147298282614df2565b600160a060020a038216600090815260246020526040902054614f1b908263ffffffff6147b116565b600160a060020a038316600090815260246020526040902055602d54614f47908263ffffffff6147b116565b602d555050565b6000806000614f5d8585615aee565b600084815260086020526040902054600754909350614f8390600163ffffffff61479a16565b9150600782815481101515614f9457fe5b9060005260206000200154905080600784815481101515614fb157fe5b60009182526020822001919091556007805484908110614fcd57fe5b6000918252602090912001556007805490614fec906000198301615e47565b50600093845260086020526040808520859055908452909220555050565b6000903b1190565b600160a060020a038216151561502757600080fd5b6150318282614df2565b6040518190600160a060020a038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000606080600061507e8888615b3e565b965061508a8887615b3e565b9550600593508760ff16600114156150a157600593505b8760ff16600214156150b257600493505b8760ff16600314156150c357600393505b8760ff16600414156150d457600293505b506000808712156150eb5760019050866000190296505b601254604080517f997bc6c9000000000000000000000000000000000000000000000000000000008152600481018a90529051600160a060020a039092169163997bc6c99160248082019260009290919082900301818387803b15801561515157600080fd5b505af1158015615165573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561518e57600080fd5b8101908080516401000000008111156151a657600080fd5b820160208101848111156151b957600080fd5b81516401000000008111828201871017156151d357600080fd5b50506012546040517f0326c06b000000000000000000000000000000000000000000000000000000008152602060048201818152845160248401528451949a50600160a060020a039093169650631dcd9b5595508994506000938b938893630326c06b9388938392604401918501908083838c5b8381101561525f578181015183820152602001615247565b50505050905090810190601f16801561528c5780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b1580156152ab57600080fd5b505af11580156152bf573d6000803e3d6000fd5b505050506040513d60208110156152d557600080fd5b505160405160e060020a63ffffffff8716028152602481018490529190036044820181905260606004830190815284516064840152845191929091829160840190602087019080838360005b83811015615339578181015183820152602001615321565b50505050905090810190601f1680156153665780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561538757600080fd5b505af115801561539b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156153c457600080fd5b8101908080516401000000008111156153dc57600080fd5b820160208101848111156153ef57600080fd5b815164010000000081118282018710171561540957600080fd5b5050601254604080517fbf4d89b500000000000000000000000000000000000000000000000000000000815260006024820181905260048201928352845160448301528451949a50600160a060020a03909316965063bf4d89b595508994509192909182916064909101906020860190808383885b8381101561549657818101518382015260200161547e565b50505050905090810190601f1680156154c35780820380516001836020036101000a031916815260200191505b509350505050602060405180830381600087803b1580156154e357600080fd5b505af11580156154f7573d6000803e3d6000fd5b505050506040513d602081101561550d57600080fd5b50519650801561551f57866000190296505b600086121561553857600190508560001902955061553c565b5060005b601254604080517f997bc6c9000000000000000000000000000000000000000000000000000000008152600481018990529051600160a060020a039092169163997bc6c99160248082019260009290919082900301818387803b1580156155a257600080fd5b505af11580156155b6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156155df57600080fd5b8101908080516401000000008111156155f757600080fd5b8201602081018481111561560a57600080fd5b815164010000000081118282018710171561562457600080fd5b50506012546040517f0326c06b000000000000000000000000000000000000000000000000000000008152602060048201818152845160248401528451949950600160a060020a039093169650631dcd9b5595508894506000938b938893630326c06b9388938392604401918501908083838c5b838110156156b0578181015183820152602001615698565b50505050905090810190601f1680156156dd5780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b1580156156fc57600080fd5b505af1158015615710573d6000803e3d6000fd5b505050506040513d602081101561572657600080fd5b505160405160e060020a63ffffffff8716028152602481018490529190036044820181905260606004830190815284516064840152845191929091829160840190602087019080838360005b8381101561578a578181015183820152602001615772565b50505050905090810190601f1680156157b75780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156157d857600080fd5b505af11580156157ec573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561581557600080fd5b81019080805164010000000081111561582d57600080fd5b8201602081018481111561584057600080fd5b815164010000000081118282018710171561585a57600080fd5b5050601254604080517fbf4d89b500000000000000000000000000000000000000000000000000000000815260006024820181905260048201928352845160448301528451949950600160a060020a03909316965063bf4d89b595508894509192909182916064909101906020860190808383885b838110156158e75781810151838201526020016158cf565b50505050905090810190601f1680156159145780820380516001836020036101000a031916815260200191505b509350505050602060405180830381600087803b15801561593457600080fd5b505af1158015615948573d6000803e3d6000fd5b505050506040513d602081101561595e57600080fd5b50519550801561597057856000190295505b50505060ff9094166000818152603760209081526040808320878452825280832086845282528083208590559282526038815282822093825292835281812082518084019093529482528183019384528454600181810187559582529290209051600290920201908155905191015550565b81600160a060020a03166159f582611e6f565b600160a060020a031614615a0857600080fd5b600160a060020a038216600090815260036020526040902054615a3290600163ffffffff61479a16565b600160a060020a039092166000908152600360209081526040808320949094559181526001909152208054600160a060020a0319169055565b600081815260016020526040902054600160a060020a031615615a8d57600080fd5b60008181526001602081815260408084208054600160a060020a031916600160a060020a0388169081179091558452600390915290912054615ace916147b1565b600160a060020a0390921660009081526003602052604090209190915550565b615af88282614c89565b615b028282614ceb565b6040518190600090600160a060020a038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6000620186a0600160ff85161415615b565750620186a05b8360ff1660021415615b6757506127105b8360ff1660031415615b7857506103e85b8360ff1660041415615b88575060645b8360ff1660051415615b985750600a5b6000831315615c4257601254604080517fda1eb54200000000000000000000000000000000000000000000000000000000815260048101869052602481018490529051600160a060020a039092169163da1eb542916044808201926020929091908290030181600087803b158015615c0f57600080fd5b505af1158015615c23573d6000803e3d6000fd5b505050506040513d6020811015615c3957600080fd5b50519250615ce9565b601254604080517fda1eb5420000000000000000000000000000000000000000000000000000000081526000958603600482018190526024820185905291519195600160a060020a039093169263da1eb542926044808401936020939083900390910190829087803b158015615cb757600080fd5b505af1158015615ccb573d6000803e3d6000fd5b505050506040513d6020811015615ce157600080fd5b505160000392505b509092915050565b60c0604051908101604052806000801916815260200160008152602001600081526020016000815260200160608152602001606081525090565b5080546000825560020290600052602060002090810190611ef49190615e6b565b828054828255906000526020600020908101928215615d8c5760005260206000209182015b82811115615d8c578254825591600101919060010190615d71565b50615d98929150615e8b565b5090565b81548183558181111561156c5760060281600602836000526020600020918201910161156c9190615ea5565b828054828255906000526020600020908101928215615d8c579160200282015b82811115615d8c578251825591602001919060010190615de8565b50805460018160011615610100020316600290046000825580601f10615e295750611ef4565b601f016020900490600052602060002090810190611ef49190615e8b565b81548183558181111561156c5760008381526020902061156c918101908301615e8b565b610e4b91905b80821115615d985760008082556001820155600201615e71565b610e4b91905b80821115615d985760008155600101615e91565b610e4b91905b80821115615d98576000808255600182018190556002820181905560038201819055615eda6004830182615ef1565b615ee8600583016000615ef1565b50600601615eab565b5080546000825590600052602060002090810190611ef49190615e8b5600a165627a7a7230582042badad37d7b5eed344c4ba6fd5492d81f93791345f3c9b6915c24b08962163b0029

Swarm Source

bzzr://42badad37d7b5eed344c4ba6fd5492d81f93791345f3c9b6915c24b08962163b
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.