Address Details
contract

0xB325A8E12344953E8b8B1AfbF1D5580d36c26245

Contract Name
AddressSortedLinkedList
Creator
0xe23a4c–2b2dee at 0x277f65–9790aa
Balance
0 CELO ( )
Locked CELO Balance
0.00 CELO
Voting CELO Balance
0.00 CELO
Pending Unlocked Gold
0.00 CELO
Tokens
Fetching tokens...
Transactions
0 Transactions
Transfers
0 Transfers
Gas Used
Fetching gas used...
Last Balance Update
3618666
Contract name:
AddressSortedLinkedList




Optimization enabled
false
Compiler version
v0.5.8+commit.23d335f2




Verified at
2020-04-22T22:48:16.400053Z

Contract source code

pragma solidity ^0.5.3;


library Math {
    
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a >= b ? a : b;
    }

    
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        
        return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
    }
}

library SafeMath {
    
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

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

        return c;
    }

    
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        
        
        
        if (a == 0) {
            return 0;
        }

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

        return c;
    }

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

    
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        
        require(b > 0, errorMessage);
        uint256 c = a / b;
        

        return c;
    }

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

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

library LinkedList {
  using SafeMath for uint256;

  struct Element {
    bytes32 previousKey;
    bytes32 nextKey;
    bool exists;
  }

  struct List {
    bytes32 head;
    bytes32 tail;
    uint256 numElements;
    mapping(bytes32 => Element) elements;
  }

  
  function insert(List storage list, bytes32 key, bytes32 previousKey, bytes32 nextKey) public {
    require(key != bytes32(0), "Key must be defined");
    require(!contains(list, key), "Can't insert an existing element");
    require(
      previousKey != key && nextKey != key,
      "Key cannot be the same as previousKey or nextKey"
    );

    Element storage element = list.elements[key];
    element.exists = true;

    if (list.numElements == 0) {
      list.tail = key;
      list.head = key;
    } else {
      require(
        previousKey != bytes32(0) || nextKey != bytes32(0),
        "Either previousKey or nextKey must be defined"
      );

      element.previousKey = previousKey;
      element.nextKey = nextKey;

      if (previousKey != bytes32(0)) {
        require(
          contains(list, previousKey),
          "If previousKey is defined, it must exist in the list"
        );
        Element storage previousElement = list.elements[previousKey];
        require(previousElement.nextKey == nextKey, "previousKey must be adjacent to nextKey");
        previousElement.nextKey = key;
      } else {
        list.tail = key;
      }

      if (nextKey != bytes32(0)) {
        require(contains(list, nextKey), "If nextKey is defined, it must exist in the list");
        Element storage nextElement = list.elements[nextKey];
        require(nextElement.previousKey == previousKey, "previousKey must be adjacent to nextKey");
        nextElement.previousKey = key;
      } else {
        list.head = key;
      }
    }

    list.numElements = list.numElements.add(1);
  }

  
  function push(List storage list, bytes32 key) public {
    insert(list, key, bytes32(0), list.tail);
  }

  
  function remove(List storage list, bytes32 key) public {
    Element storage element = list.elements[key];
    require(key != bytes32(0) && contains(list, key), "key not in list");
    if (element.previousKey != bytes32(0)) {
      Element storage previousElement = list.elements[element.previousKey];
      previousElement.nextKey = element.nextKey;
    } else {
      list.tail = element.nextKey;
    }

    if (element.nextKey != bytes32(0)) {
      Element storage nextElement = list.elements[element.nextKey];
      nextElement.previousKey = element.previousKey;
    } else {
      list.head = element.previousKey;
    }

    delete list.elements[key];
    list.numElements = list.numElements.sub(1);
  }

  
  function update(List storage list, bytes32 key, bytes32 previousKey, bytes32 nextKey) public {
    require(
      key != bytes32(0) && key != previousKey && key != nextKey && contains(list, key),
      "key on in list"
    );
    remove(list, key);
    insert(list, key, previousKey, nextKey);
  }

  
  function contains(List storage list, bytes32 key) public view returns (bool) {
    return list.elements[key].exists;
  }

  
  function headN(List storage list, uint256 n) public view returns (bytes32[] memory) {
    require(n <= list.numElements, "not enough elements");
    bytes32[] memory keys = new bytes32[](n);
    bytes32 key = list.head;
    for (uint256 i = 0; i < n; i = i.add(1)) {
      keys[i] = key;
      key = list.elements[key].previousKey;
    }
    return keys;
  }

  
  function getKeys(List storage list) public view returns (bytes32[] memory) {
    return headN(list, list.numElements);
  }
}

library SortedLinkedList {
  using SafeMath for uint256;
  using LinkedList for LinkedList.List;

  struct List {
    LinkedList.List list;
    mapping(bytes32 => uint256) values;
  }

  
  function insert(
    List storage list,
    bytes32 key,
    uint256 value,
    bytes32 lesserKey,
    bytes32 greaterKey
  ) public {
    require(
      key != bytes32(0) && key != lesserKey && key != greaterKey && !contains(list, key),
      "invalid key"
    );
    require(
      (lesserKey != bytes32(0) || greaterKey != bytes32(0)) || list.list.numElements == 0,
      "greater and lesser key zero"
    );
    require(contains(list, lesserKey) || lesserKey == bytes32(0), "invalid lesser key");
    require(contains(list, greaterKey) || greaterKey == bytes32(0), "invalid greater key");
    (lesserKey, greaterKey) = getLesserAndGreater(list, value, lesserKey, greaterKey);
    list.list.insert(key, lesserKey, greaterKey);
    list.values[key] = value;
  }

  
  function remove(List storage list, bytes32 key) public {
    list.list.remove(key);
    list.values[key] = 0;
  }

  
  function update(
    List storage list,
    bytes32 key,
    uint256 value,
    bytes32 lesserKey,
    bytes32 greaterKey
  ) public {
    
    
    
    remove(list, key);
    insert(list, key, value, lesserKey, greaterKey);
  }

  
  function push(List storage list, bytes32 key) public {
    insert(list, key, 0, bytes32(0), list.list.tail);
  }

  
  function popN(List storage list, uint256 n) public returns (bytes32[] memory) {
    require(n <= list.list.numElements, "not enough elements");
    bytes32[] memory keys = new bytes32[](n);
    for (uint256 i = 0; i < n; i = i.add(1)) {
      bytes32 key = list.list.head;
      keys[i] = key;
      remove(list, key);
    }
    return keys;
  }

  
  function contains(List storage list, bytes32 key) public view returns (bool) {
    return list.list.contains(key);
  }

  
  function getValue(List storage list, bytes32 key) public view returns (uint256) {
    return list.values[key];
  }

  
  function getElements(List storage list) public view returns (bytes32[] memory, uint256[] memory) {
    bytes32[] memory keys = getKeys(list);
    uint256[] memory values = new uint256[](keys.length);
    for (uint256 i = 0; i < keys.length; i = i.add(1)) {
      values[i] = list.values[keys[i]];
    }
    return (keys, values);
  }

  
  function getKeys(List storage list) public view returns (bytes32[] memory) {
    return list.list.getKeys();
  }

  
  function headN(List storage list, uint256 n) public view returns (bytes32[] memory) {
    return list.list.headN(n);
  }

  
  
  function getLesserAndGreater(
    List storage list,
    uint256 value,
    bytes32 lesserKey,
    bytes32 greaterKey
  ) private view returns (bytes32, bytes32) {
    
    
    
    
    
    if (lesserKey == bytes32(0) && isValueBetween(list, value, lesserKey, list.list.tail)) {
      return (lesserKey, list.list.tail);
    } else if (
      greaterKey == bytes32(0) && isValueBetween(list, value, list.list.head, greaterKey)
    ) {
      return (list.list.head, greaterKey);
    } else if (
      lesserKey != bytes32(0) &&
      isValueBetween(list, value, lesserKey, list.list.elements[lesserKey].nextKey)
    ) {
      return (lesserKey, list.list.elements[lesserKey].nextKey);
    } else if (
      greaterKey != bytes32(0) &&
      isValueBetween(list, value, list.list.elements[greaterKey].previousKey, greaterKey)
    ) {
      return (list.list.elements[greaterKey].previousKey, greaterKey);
    } else {
      require(false, "get lesser and greater failure");
    }
  }

  
  function isValueBetween(List storage list, uint256 value, bytes32 lesserKey, bytes32 greaterKey)
    private
    view
    returns (bool)
  {
    bool isLesser = lesserKey == bytes32(0) || list.values[lesserKey] <= value;
    bool isGreater = greaterKey == bytes32(0) || list.values[greaterKey] >= value;
    return isLesser && isGreater;
  }
}

library AddressSortedLinkedList {
  using SafeMath for uint256;
  using SortedLinkedList for SortedLinkedList.List;

  function toBytes(address a) public pure returns (bytes32) {
    return bytes32(uint256(a) << 96);
  }

  function toAddress(bytes32 b) public pure returns (address) {
    return address(uint256(b) >> 96);
  }

  
  function insert(
    SortedLinkedList.List storage list,
    address key,
    uint256 value,
    address lesserKey,
    address greaterKey
  ) public {
    list.insert(toBytes(key), value, toBytes(lesserKey), toBytes(greaterKey));
  }

  
  function remove(SortedLinkedList.List storage list, address key) public {
    list.remove(toBytes(key));
  }

  
  function update(
    SortedLinkedList.List storage list,
    address key,
    uint256 value,
    address lesserKey,
    address greaterKey
  ) public {
    list.update(toBytes(key), value, toBytes(lesserKey), toBytes(greaterKey));
  }

  
  function contains(SortedLinkedList.List storage list, address key) public view returns (bool) {
    return list.contains(toBytes(key));
  }

  
  function getValue(SortedLinkedList.List storage list, address key) public view returns (uint256) {
    return list.getValue(toBytes(key));
  }

  
  function getElements(SortedLinkedList.List storage list)
    public
    view
    returns (address[] memory, uint256[] memory)
  {
    bytes32[] memory byteKeys = list.getKeys();
    address[] memory keys = new address[](byteKeys.length);
    uint256[] memory values = new uint256[](byteKeys.length);
    for (uint256 i = 0; i < byteKeys.length; i = i.add(1)) {
      keys[i] = toAddress(byteKeys[i]);
      values[i] = list.values[byteKeys[i]];
    }
    return (keys, values);
  }

  
  function numElementsGreaterThan(
    SortedLinkedList.List storage list,
    uint256 threshold,
    uint256 max
  ) public view returns (uint256) {
    uint256 revisedMax = Math.min(max, list.list.numElements);
    bytes32 key = list.list.head;
    for (uint256 i = 0; i < revisedMax; i = i.add(1)) {
      if (list.getValue(key) < threshold) {
        return i;
      }
      key = list.list.elements[key].previousKey;
    }
    return revisedMax;
  }

  
  function headN(SortedLinkedList.List storage list, uint256 n)
    public
    view
    returns (address[] memory)
  {
    bytes32[] memory byteKeys = list.headN(n);
    address[] memory keys = new address[](n);
    for (uint256 i = 0; i < n; i = i.add(1)) {
      keys[i] = toAddress(byteKeys[i]);
    }
    return keys;
  }

  
  function getKeys(SortedLinkedList.List storage list) public view returns (address[] memory) {
    return headN(list, list.list.numElements);
  }
}
        

Contract ABI

[{"type":"function","stateMutability":"pure","payable":false,"outputs":[{"type":"address","name":""}],"name":"toAddress","inputs":[{"type":"bytes32","name":"b"}],"constant":true},{"type":"function","stateMutability":"pure","payable":false,"outputs":[{"type":"bytes32","name":""}],"name":"toBytes","inputs":[{"type":"address","name":"a"}],"constant":true}]
              

Contract Creation Code

0x610f5a610026600b82828239805160001a60731461001957fe5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100b35760003560e01c806342b6351a1161007b57806342b6351a1461030f578063593b79fe1461036557806369b317e3146103bd578063cab455ae14610488578063dcb2a4dd1461052d578063e0fe44b3146105ba576100b3565b806302f13028146100b8578063281359291461011e5780632dedbbf014610179578063341f66231461021e5780633a72e8021461028c575b600080fd5b610104600480360360408110156100ce57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061061c565b604051808215151515815260200191505060405180910390f35b81801561012a57600080fd5b506101776004803603604081101561014157600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506106c2565b005b81801561018557600080fd5b5061021c600480360360a081101561019c57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061073f565b005b61024a6004803603602081101561023457600080fd5b81019080803590602001909291905050506107e7565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102b8600480360360208110156102a257600080fd5b81019080803590602001909291905050506107f8565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156102fb5780820151818401526020810190506102e0565b505050509050019250505060405180910390f35b61034f6004803603606081101561032557600080fd5b81019080803590602001909291908035906020019092919080359060200190929190505050610812565b6040518082815260200191505060405180910390f35b6103a76004803603602081101561037b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061092f565b6040518082815260200191505060405180910390f35b6103e9600480360360208110156103d357600080fd5b8101908080359060200190929190505050610956565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015610430578082015181840152602081019050610415565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015610472578082015181840152602081019050610457565b5050505090500194505050505060405180910390f35b81801561049457600080fd5b5061052b600480360360a08110156104ab57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610b85565b005b6105636004803603604081101561054357600080fd5b810190808035906020019092919080359060200190929190505050610c2d565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156105a657808201518184015260208101905061058b565b505050509050019250505060405180910390f35b610606600480360360408110156105d057600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610de7565b6040518082815260200191505060405180910390f35b600082737c68b5647fb5624cb1f83209a5d828111f26496963809a6bfd90916106448561092f565b6040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b15801561067f57600080fd5b505af4158015610693573d6000803e3d6000fd5b505050506040513d60208110156106a957600080fd5b8101908080519060200190929190505050905092915050565b81737c68b5647fb5624cb1f83209a5d828111f26496963530c2c8490916106e88461092f565b6040518363ffffffff1660e01b8152600401808381526020018281526020019250505060006040518083038186803b15801561072357600080fd5b505af4158015610737573d6000803e3d6000fd5b505050505050565b84737c68b5647fb5624cb1f83209a5d828111f26496963caf2014d90916107658761092f565b8661076f8761092f565b6107788761092f565b6040518663ffffffff1660e01b8152600401808681526020018581526020018481526020018381526020018281526020019550505050505060006040518083038186803b1580156107c857600080fd5b505af41580156107dc573d6000803e3d6000fd5b505050505050505050565b600060608260001c901c9050919050565b606061080b828360000160020154610c2d565b9050919050565b600080610826838660000160020154610e8d565b905060008560000160000154905060008090505b82811015610921578587737c68b5647fb5624cb1f83209a5d828111f264969630d48ec0c9091856040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b15801561089c57600080fd5b505af41580156108b0573d6000803e3d6000fd5b505050506040513d60208110156108c657600080fd5b810190808051906020019092919050505010156108e857809350505050610928565b86600001600301600083815260200190815260200160002060000154915061091a600182610ea690919063ffffffff16565b905061083a565b5081925050505b9392505050565b600060608273ffffffffffffffffffffffffffffffffffffffff16901b60001b9050919050565b606080606083737c68b5647fb5624cb1f83209a5d828111f264969633a72e80290916040518263ffffffff1660e01b81526004018082815260200191505060006040518083038186803b1580156109ac57600080fd5b505af41580156109c0573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525060208110156109ea57600080fd5b810190808051640100000000811115610a0257600080fd5b82810190506020810184811115610a1857600080fd5b8151856020820283011164010000000082111715610a3557600080fd5b5050929190505050905060608151604051908082528060200260200182016040528015610a715781602001602082028038833980820191505090505b50905060608251604051908082528060200260200182016040528015610aa65781602001602082028038833980820191505090505b50905060008090505b8351811015610b7657610ad4848281518110610ac757fe5b60200260200101516107e7565b838281518110610ae057fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050866004016000858381518110610b2c57fe5b6020026020010151815260200190815260200160002054828281518110610b4f57fe5b602002602001018181525050610b6f600182610ea690919063ffffffff16565b9050610aaf565b50818194509450505050915091565b84737c68b5647fb5624cb1f83209a5d828111f264969631fd6b4f89091610bab8761092f565b86610bb58761092f565b610bbe8761092f565b6040518663ffffffff1660e01b8152600401808681526020018581526020018481526020018381526020018281526020019550505050505060006040518083038186803b158015610c0e57600080fd5b505af4158015610c22573d6000803e3d6000fd5b505050505050505050565b60608083737c68b5647fb5624cb1f83209a5d828111f26496963dcb2a4dd9091856040518363ffffffff1660e01b8152600401808381526020018281526020019250505060006040518083038186803b158015610c8957600080fd5b505af4158015610c9d573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052506020811015610cc757600080fd5b810190808051640100000000811115610cdf57600080fd5b82810190506020810184811115610cf557600080fd5b8151856020820283011164010000000082111715610d1257600080fd5b50509291905050509050606083604051908082528060200260200182016040528015610d4d5781602001602082028038833980820191505090505b50905060008090505b84811015610ddb57610d7a838281518110610d6d57fe5b60200260200101516107e7565b828281518110610d8657fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050610dd4600182610ea690919063ffffffff16565b9050610d56565b50809250505092915050565b600082737c68b5647fb5624cb1f83209a5d828111f264969630d48ec0c9091610e0f8561092f565b6040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b158015610e4a57600080fd5b505af4158015610e5e573d6000803e3d6000fd5b505050506040513d6020811015610e7457600080fd5b8101908080519060200190929190505050905092915050565b6000818310610e9c5781610e9e565b825b905092915050565b600080828401905083811015610f24576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b809150509291505056fea165627a7a72305820c9e7012264748b512bcedae1bf6ad00428ceb74ae17c2898414b944e239ba4a40029

Deployed ByteCode

0x73b325a8e12344953e8b8b1afbf1d5580d36c2624530146080604052600436106100b35760003560e01c806342b6351a1161007b57806342b6351a1461030f578063593b79fe1461036557806369b317e3146103bd578063cab455ae14610488578063dcb2a4dd1461052d578063e0fe44b3146105ba576100b3565b806302f13028146100b8578063281359291461011e5780632dedbbf014610179578063341f66231461021e5780633a72e8021461028c575b600080fd5b610104600480360360408110156100ce57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061061c565b604051808215151515815260200191505060405180910390f35b81801561012a57600080fd5b506101776004803603604081101561014157600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506106c2565b005b81801561018557600080fd5b5061021c600480360360a081101561019c57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061073f565b005b61024a6004803603602081101561023457600080fd5b81019080803590602001909291905050506107e7565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102b8600480360360208110156102a257600080fd5b81019080803590602001909291905050506107f8565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156102fb5780820151818401526020810190506102e0565b505050509050019250505060405180910390f35b61034f6004803603606081101561032557600080fd5b81019080803590602001909291908035906020019092919080359060200190929190505050610812565b6040518082815260200191505060405180910390f35b6103a76004803603602081101561037b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061092f565b6040518082815260200191505060405180910390f35b6103e9600480360360208110156103d357600080fd5b8101908080359060200190929190505050610956565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015610430578082015181840152602081019050610415565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015610472578082015181840152602081019050610457565b5050505090500194505050505060405180910390f35b81801561049457600080fd5b5061052b600480360360a08110156104ab57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610b85565b005b6105636004803603604081101561054357600080fd5b810190808035906020019092919080359060200190929190505050610c2d565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156105a657808201518184015260208101905061058b565b505050509050019250505060405180910390f35b610606600480360360408110156105d057600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610de7565b6040518082815260200191505060405180910390f35b600082737c68b5647fb5624cb1f83209a5d828111f26496963809a6bfd90916106448561092f565b6040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b15801561067f57600080fd5b505af4158015610693573d6000803e3d6000fd5b505050506040513d60208110156106a957600080fd5b8101908080519060200190929190505050905092915050565b81737c68b5647fb5624cb1f83209a5d828111f26496963530c2c8490916106e88461092f565b6040518363ffffffff1660e01b8152600401808381526020018281526020019250505060006040518083038186803b15801561072357600080fd5b505af4158015610737573d6000803e3d6000fd5b505050505050565b84737c68b5647fb5624cb1f83209a5d828111f26496963caf2014d90916107658761092f565b8661076f8761092f565b6107788761092f565b6040518663ffffffff1660e01b8152600401808681526020018581526020018481526020018381526020018281526020019550505050505060006040518083038186803b1580156107c857600080fd5b505af41580156107dc573d6000803e3d6000fd5b505050505050505050565b600060608260001c901c9050919050565b606061080b828360000160020154610c2d565b9050919050565b600080610826838660000160020154610e8d565b905060008560000160000154905060008090505b82811015610921578587737c68b5647fb5624cb1f83209a5d828111f264969630d48ec0c9091856040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b15801561089c57600080fd5b505af41580156108b0573d6000803e3d6000fd5b505050506040513d60208110156108c657600080fd5b810190808051906020019092919050505010156108e857809350505050610928565b86600001600301600083815260200190815260200160002060000154915061091a600182610ea690919063ffffffff16565b905061083a565b5081925050505b9392505050565b600060608273ffffffffffffffffffffffffffffffffffffffff16901b60001b9050919050565b606080606083737c68b5647fb5624cb1f83209a5d828111f264969633a72e80290916040518263ffffffff1660e01b81526004018082815260200191505060006040518083038186803b1580156109ac57600080fd5b505af41580156109c0573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525060208110156109ea57600080fd5b810190808051640100000000811115610a0257600080fd5b82810190506020810184811115610a1857600080fd5b8151856020820283011164010000000082111715610a3557600080fd5b5050929190505050905060608151604051908082528060200260200182016040528015610a715781602001602082028038833980820191505090505b50905060608251604051908082528060200260200182016040528015610aa65781602001602082028038833980820191505090505b50905060008090505b8351811015610b7657610ad4848281518110610ac757fe5b60200260200101516107e7565b838281518110610ae057fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050866004016000858381518110610b2c57fe5b6020026020010151815260200190815260200160002054828281518110610b4f57fe5b602002602001018181525050610b6f600182610ea690919063ffffffff16565b9050610aaf565b50818194509450505050915091565b84737c68b5647fb5624cb1f83209a5d828111f264969631fd6b4f89091610bab8761092f565b86610bb58761092f565b610bbe8761092f565b6040518663ffffffff1660e01b8152600401808681526020018581526020018481526020018381526020018281526020019550505050505060006040518083038186803b158015610c0e57600080fd5b505af4158015610c22573d6000803e3d6000fd5b505050505050505050565b60608083737c68b5647fb5624cb1f83209a5d828111f26496963dcb2a4dd9091856040518363ffffffff1660e01b8152600401808381526020018281526020019250505060006040518083038186803b158015610c8957600080fd5b505af4158015610c9d573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052506020811015610cc757600080fd5b810190808051640100000000811115610cdf57600080fd5b82810190506020810184811115610cf557600080fd5b8151856020820283011164010000000082111715610d1257600080fd5b50509291905050509050606083604051908082528060200260200182016040528015610d4d5781602001602082028038833980820191505090505b50905060008090505b84811015610ddb57610d7a838281518110610d6d57fe5b60200260200101516107e7565b828281518110610d8657fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050610dd4600182610ea690919063ffffffff16565b9050610d56565b50809250505092915050565b600082737c68b5647fb5624cb1f83209a5d828111f264969630d48ec0c9091610e0f8561092f565b6040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b158015610e4a57600080fd5b505af4158015610e5e573d6000803e3d6000fd5b505050506040513d6020811015610e7457600080fd5b8101908080519060200190929190505050905092915050565b6000818310610e9c5781610e9e565b825b905092915050565b600080828401905083811015610f24576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b809150509291505056fea165627a7a72305820c9e7012264748b512bcedae1bf6ad00428ceb74ae17c2898414b944e239ba4a40029

External libraries