Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- TwoBearsBalances
- Optimization enabled
- false
- Compiler version
- v0.8.16+commit.07a7930e
- EVM Version
- default
- Verified at
- 2024-09-26T15:34:55.616328Z
Contract source code
// All rights reserved. // SPDX-License-Identifier: No License (None) pragma solidity ^0.8.16; interface IContractOrders { function createOrder(address _owner, address _token_in, uint _value_in, address _token_out, uint _value_out, uint8 _order_type, uint _price, uint _order_position, uint _dex_fee, uint _dex_num_exec_ord) external returns (uint256); } interface IERC20 { function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function transfer(address to, uint256 value) external returns (bool); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 value) external returns (bool); function transferFrom(address from, address to, uint256 value) external returns (bool); } interface IWCLO { function deposit() external payable; function withdraw(uint wad) external; } contract TwoBearsBalances { struct Tokens { uint256 minValue; // 32 байта - минимальное количество токена, доступное для торговли (ограничивает создание пылевых ордеров) uint8 standart; // 1 байта - стандарт токена uint8 decimal; // 1 байт - количество десятичных знаков uint16 priority; // 2 байта - приоритет токена для определения ценообразования (цена - отношение к токену с максимальным приоритетом) bytes8 symb; // 8 байт - аббревиатура токена address next; // 20 байт - адрес следующего токена (последний токен указывает на нулевой адрес) } uint256 commission = 4 * 1e17; // комиссионный процент взымаемый с каждого выполняемого ордера (оплачивается получаемым токеном, в процессе исполнения ордера) uint256 numExecutedOrders = 30; // максимальное количество ордеров которое можно выполнить за 1 транзакцию uint256 gasPrice = 1002 * 1e9; // максимальная цена газа для оплаты оракула (Gwei) uint256 gaslimit = 15000000; // максимальный лимит газа для оракула uint256 gasAdd = 90000; // добавочный газ который не может быть расчитан (вызов функции + вызов transferFrom в котором происходит оплата оракула). Так же этот газ должен оплатить владелец бота за разблокировку заблокированного бота mapping(address => Tokens) private tokens; // Односвязный список всех токенов на бирже address public owner = 0xeBE894814554c8382EA6a24CcDdf1527407A24f6; // Владелец address public constant contractOrders = 0x951D1F73f30716fE0d3E9f9998486fd1F48b68A1; // Контракт с книгами ордеров address public constant contractCommission = 0x469A2f6604b456110b486dA4950D032958FDE447; // Контракт куда поступают комиссии address public constant contractBots = 0x8cBe0B85F49933d81a9d964531A5e5EC68157604; // Контракт ботов //address private constant firstToken = 0xbd2D3BCe975FD72E44A73cC8e834aD1B8441BdDa; // первый адрес в списке токенов это WCLO address private constant firstToken = 0xF5AD6F6EDeC824C7fD54A66d241a227F6503aD3a; // первый адрес в списке токенов это WCLO address private endToken = firstToken; // всегда указывает на последний токен в списке токенов modifier onlyOwner() { require(msg.sender == owner, "Only owner can call this"); _; } modifier onlyContractOrders() { require(msg.sender == contractOrders, "Only contract orders can call"); _; } constructor() { tokens[firstToken] = Tokens(1000 * 1e18, 223, 18, 50000, "WCLO", address(0x00)); IERC20(firstToken).approve(address(this), uint(int(-1))); //Даем разрешение нашему контракту тратить токен на своем балансе через TransferFrom } // Функции обработки поступающих средств (создание ордеров) receive() external payable { // принимаем нативную монету только от контракта, который ее оборачивал require(msg.sender == firstToken); } function createOrderNative(address _token_out, uint _value_out, uint _order_position) external payable { // создаем ордер через нативную монету IWCLO(firstToken).deposit{value: msg.value}(); // оборачиваем нативную монету от пользователя createOrderUser(msg.sender, firstToken, msg.value, _token_out, _value_out, _order_position); } function createOrderERC20(address _token_in, uint _value_in, address _token_out, uint _value_out, uint _order_position) external { //require(tokens[_token_in].standart > 0); // токен должен присутствовать в списке токенов IERC20(_token_in).transferFrom(msg.sender, address(this), _value_in); // контракт принимает входящий токен от пользователя createOrderUser(msg.sender, _token_in, _value_in, _token_out, _value_out, _order_position); } function tokenReceived(address _from, uint _value, bytes memory _data) public returns (bytes4) { // новый ERC223 //require(tokens[msg.sender].standart == 223); // токен должен присутствовать в списке токенов (address _token_out, uint _value_out, uint _order_position) = abi.decode(_data, (address, uint, uint)); createOrderUser(_from, msg.sender, _value, _token_out, _value_out, _order_position); return this.tokenReceived.selector; // возвращаем селектор этой функции } function createOrderUser(address _owner, address _token_in, uint _value_in, address _token_out, uint _value_out, uint _order_position) private returns (uint256){ // создание ордера от имени пользователя require((tokens[_token_in].standart > 0) && (tokens[_token_out].standart > 0)); // токены должны присутствовать в списке токенов require((_value_in > 0) && (_value_out > 0)); // количество входящего и получаемого токена должно быть больше 0 require(_token_in != _token_out); // токены не должны быть одинаковыми if(tokens[_token_in].priority < tokens[_token_out].priority){ // делаем проверку что ордера не пылевые - соответствуют минимальному значению по токену с максимальным приоритетом require(_value_out >= tokens[_token_out].minValue); } else{ require(_value_in >= tokens[_token_in].minValue); } (uint8 _order_type, uint256 _price) = getTypeAndPriceOrder(_token_in, _value_in, _token_out, _value_out); // Определяем тип ордера и его цену require(_price > 0); // запрещено ордеру иметь нулевую цену uint _id = IContractOrders(contractOrders).createOrder(_owner, _token_in, _value_in, _token_out, _value_out, _order_type, _price, _order_position, commission, numExecutedOrders); return _id; } function withdraw(address _token, address _owner, uint _value) external onlyContractOrders // Выплата токена указанному владельцу { uint256 _size; assembly { _size := extcodesize(_owner) } // проверяем является ли адрес получателя контрактом if(_size > 0){ // если получатель это контракт, то выплачиваем токенами (нативная монета не разворачивается) if(_owner == contractBots){ IERC20(_token).transfer(_owner, _value); } else{ IERC20(_token).transferFrom(address(this), _owner, _value); } } else{ // пользователи (EOA) ордеров нативную монету получают в развернутом виде if(_token == firstToken){ // вывод нативного CLO IWCLO(_token).withdraw(_value); payable(_owner).transfer(_value); } else{ // вывод токена //IERC20(_token).transferFrom(address(this), _owner, _value); IERC20(_token).transfer(_owner, _value); } } } function withdrawFee(address _token, uint _value) external onlyContractOrders // Выплата комиссии за исполнение ордера { //IERC20(_token).approve(address(this), _value); //Даем разрешение нашему контракту тратить токен на своем балансе через TransferFrom //IERC20(_token).transferFrom(address(this), contractCommission, _value); IERC20(_token).transfer(contractCommission, _value); } // ФУНКЦИИ ВЛАДЕЛЬЦА function setFeesExchange(uint256 _newCommission) external onlyOwner // установить новый процент биржи { commission = _newCommission; } function setNumExecutedOrders(uint256 _numExecutedOrders) external onlyOwner // установить максимальное количество исполняемых ордеров в пределах 1 транзакции { numExecutedOrders = _numExecutedOrders; } function setGasPriceGasLimitGasAdd(uint256 _gasPrice, uint256 _gaslimit, uint256 _gasAdd) external onlyOwner // установить новую цену газа, максимальный лимит газа и добавочный газ (для оракула) { gasPrice = _gasPrice; gaslimit = _gaslimit; gasAdd = _gasAdd; } function approveToken(address _token) external onlyOwner // Дать безлимитное разрешение нашему контракту тратить токен на своем балансе через TransferFrom { require(tokens[_token].standart > 0); IERC20(_token).approve(address(this), uint(int(-1))); // Даем разрешение нашему контракту тратить токен на своем балансе через TransferFrom } function addToken(address _newToken, uint8 _standart, uint16 _priority, uint256 _minValue) external onlyOwner // Добавление нового токена на dex { require(tokens[_newToken].standart == 0, "err: token exists"); // токен должен отсутствовать в списке токенов bytes8 _newSymb; string memory str = IERC20(_newToken).symbol(); assembly { _newSymb := mload(add(str, 32)) } tokens[_newToken] = Tokens(_minValue, _standart, IERC20(_newToken).decimals(), _priority, _newSymb, address(0x00)); tokens[endToken].next = _newToken; // связываем последний токен с новым токеном endToken = _newToken; // новый токен становится последним IERC20(_newToken).approve(address(this), uint(int(-1))); //Даем разрешение нашему контракту тратить токен на своем балансе через TransferFrom } function changeTokenMinValue(address _token, uint256 _minValue) external onlyOwner // Изменить минимальное количество токена, доступное для торговли { require(tokens[_token].standart > 0); // токен должен присутствовать в списке токенов tokens[_token].minValue = _minValue; } function delToken(address _delToken, address _prevToken) external onlyOwner // Делистинг токена { // _delToken - удаляемый токен, _prevToken - токен в списке перед удаляемым токеном require((_delToken != address(0)) && (_delToken != firstToken)); // Удаляемый токен не может быть нулевым адресом и WCLO require(tokens[_prevToken].next == _delToken); // предыдущий токен в списке должен указывать на удаляемый токен require(IERC20(_delToken).balanceOf(address(this)) == 0); // контракт не должен иметь баланс в удаляемом токене if(_delToken == endToken) endToken = _prevToken; // если удаляется последний токен в списке tokens[_prevToken].next = tokens[_delToken].next; // исключаем удаляемый токен из списка delete tokens[_delToken]; // чистим память, данная операция поощрается EVM и будет возвращено часть газа } function getTokensInfo(address _startToken, uint _elem) public view returns (Tokens[] memory) // Возвращаем _elem токенов на бирже от указанного адреса { Tokens[] memory result = new Tokens[](_elem); _startToken = tokens[_startToken].standart > 0 ? _startToken : firstToken; // определяем стартовую позицию address _nextToken; for(uint i; i < _elem; i++){ _nextToken = tokens[_startToken].next; result[i] = Tokens(tokens[_startToken].minValue, tokens[_startToken].standart, tokens[_startToken].decimal, tokens[_startToken].priority, tokens[_startToken].symb, tokens[_startToken].next); if(_nextToken == address(0x00)){ break; // достигли конца списка } else { _startToken = _nextToken; } } return (result); // возвращаем массив с инфой по токенам } function getTokenMinValue(address _token) public view returns (uint256) // вернуть минимальное количество токена, доступное для торговли { return (tokens[_token].minValue); } function getTokenPriority(address _token) public view returns (uint256) // вернуть приоритет токена { return (tokens[_token].priority); } function getBalancesByTokens(address[] calldata _tokens, address _owner) public view returns (uint [] memory) // вернуть баланс всех токенов из массива и в конец массива добавить баланс нативной монеты { uint[] memory result = new uint[](_tokens.length + 1); // Добавочный элемент для хранения баланса нативной монеты for(uint i; i < _tokens.length; i++){ result[i] = IERC20(_tokens[i]).balanceOf(_owner); } result[_tokens.length] = _owner.balance; // получаем баланс адреса в нативной монете return (result); } function getFeesAndNumExecOrd() public view returns (uint256, uint256) // вернуть процент биржи и максимальное количество исполняемых ордеров за 1 транзакцию { return (commission, numExecutedOrders); } function getTypeAndPriceOrder(address _token_in, uint _value_in, address _token_out, uint _value_out) public view returns (uint8, uint256) // вернуть тип ордера и цену ордера { uint8 _order_type = tokens[_token_in].priority < tokens[_token_out].priority ? 1 : 2; // тип ордера (1 - продажа, 2 - покупка) uint256 res = _order_type == 1 ? _value_out * (10**tokens[_token_in].decimal) / _value_in : _value_in * (10**tokens[_token_out].decimal) / _value_out; // расчет цены ордера return (_order_type, res); } // ФУНКЦИИ БОТОВ function getTypeAndValue(address _token_in, address _token_out, uint _value, uint _price) public view returns (uint8, uint256) // вернуть тип ордера и объем токена с наивысшим приоритетом { // _value - объем токена с наименьшим приоритетом // _price - цена в токене с максимальным приоритетом uint8 _order_type = tokens[_token_in].priority < tokens[_token_out].priority ? 1 : 2; // тип ордера (1 - продажа, 2 - покупка) uint256 res = _order_type == 1 ? _price * _value / (10**tokens[_token_in].decimal) : _price * _value / (10**tokens[_token_out].decimal); // расчет входящего / выходящего объема return (_order_type, res); } function getWrappedAndPricelimit() public view returns (address, uint256, uint256) // функция возвращает адрес обернутой нативной монеты, цену газа и лимит газа (максималка для оракула) { return (firstToken, gasPrice, gaslimit); } function getPriceAndGasAdd() public view returns (uint256, uint256) // функция возвращает цену газа и добавочный газ (это газ за создание транзакции + выплата оракулу). Также столько газа надо передать оракулу за разблокировку бота { return (gasPrice, gasAdd); } function payTheOracle(address _owner, address _oracle, uint _gasUsed) external returns (uint256){ // оплатить работу оракула. Возвращает количество нативной монеты что была выплачена оракулу require(msg.sender == contractBots); // Только контракт ботов имеет право вызывать эту функцию uint _value; // оплата работы бота if(_owner != _oracle){ // Владелец бота должен оплатить газ создателю транзакции (оплата обернутой нативной монетой) _value = (_gasUsed + gasAdd) * gasPrice; // (газ затраченый оракулом + добавочный газ) * цену газа IERC20(firstToken).transferFrom(_owner, _oracle, _value); } return _value; // возвращаем сколько обернутой нативной монеты выплачено оракулу } function createOrderBot(address _owner, address _token_in, uint _value_in, address _token_out, uint _value_out, uint _order_position) external returns (uint256){ // создание ордера от имени бота require(msg.sender == contractBots); // Только контракт ботов имеет право на создание ордеров IERC20(_token_in).transferFrom(_owner, address(this), _value_in); // контракт принимает входящий токен от владельца бота (uint8 _order_type, uint256 _price) = getTypeAndPriceOrder(_token_in, _value_in, _token_out, _value_out); // Определяем тип ордера и его цену uint _id = IContractOrders(contractOrders).createOrder(msg.sender, _token_in, _value_in, _token_out, _value_out, _order_type, _price, _order_position, commission, numExecutedOrders); return _id; } }
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addToken","inputs":[{"type":"address","name":"_newToken","internalType":"address"},{"type":"uint8","name":"_standart","internalType":"uint8"},{"type":"uint16","name":"_priority","internalType":"uint16"},{"type":"uint256","name":"_minValue","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"approveToken","inputs":[{"type":"address","name":"_token","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeTokenMinValue","inputs":[{"type":"address","name":"_token","internalType":"address"},{"type":"uint256","name":"_minValue","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"contractBots","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"contractCommission","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"contractOrders","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"createOrderBot","inputs":[{"type":"address","name":"_owner","internalType":"address"},{"type":"address","name":"_token_in","internalType":"address"},{"type":"uint256","name":"_value_in","internalType":"uint256"},{"type":"address","name":"_token_out","internalType":"address"},{"type":"uint256","name":"_value_out","internalType":"uint256"},{"type":"uint256","name":"_order_position","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"createOrderERC20","inputs":[{"type":"address","name":"_token_in","internalType":"address"},{"type":"uint256","name":"_value_in","internalType":"uint256"},{"type":"address","name":"_token_out","internalType":"address"},{"type":"uint256","name":"_value_out","internalType":"uint256"},{"type":"uint256","name":"_order_position","internalType":"uint256"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"createOrderNative","inputs":[{"type":"address","name":"_token_out","internalType":"address"},{"type":"uint256","name":"_value_out","internalType":"uint256"},{"type":"uint256","name":"_order_position","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"delToken","inputs":[{"type":"address","name":"_delToken","internalType":"address"},{"type":"address","name":"_prevToken","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"getBalancesByTokens","inputs":[{"type":"address[]","name":"_tokens","internalType":"address[]"},{"type":"address","name":"_owner","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"}],"name":"getFeesAndNumExecOrd","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"}],"name":"getPriceAndGasAdd","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getTokenMinValue","inputs":[{"type":"address","name":"_token","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getTokenPriority","inputs":[{"type":"address","name":"_token","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[]","name":"","internalType":"struct TwoBearsBalances.Tokens[]","components":[{"type":"uint256","name":"minValue","internalType":"uint256"},{"type":"uint8","name":"standart","internalType":"uint8"},{"type":"uint8","name":"decimal","internalType":"uint8"},{"type":"uint16","name":"priority","internalType":"uint16"},{"type":"bytes8","name":"symb","internalType":"bytes8"},{"type":"address","name":"next","internalType":"address"}]}],"name":"getTokensInfo","inputs":[{"type":"address","name":"_startToken","internalType":"address"},{"type":"uint256","name":"_elem","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"},{"type":"uint256","name":"","internalType":"uint256"}],"name":"getTypeAndPriceOrder","inputs":[{"type":"address","name":"_token_in","internalType":"address"},{"type":"uint256","name":"_value_in","internalType":"uint256"},{"type":"address","name":"_token_out","internalType":"address"},{"type":"uint256","name":"_value_out","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"},{"type":"uint256","name":"","internalType":"uint256"}],"name":"getTypeAndValue","inputs":[{"type":"address","name":"_token_in","internalType":"address"},{"type":"address","name":"_token_out","internalType":"address"},{"type":"uint256","name":"_value","internalType":"uint256"},{"type":"uint256","name":"_price","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"},{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"}],"name":"getWrappedAndPricelimit","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"payTheOracle","inputs":[{"type":"address","name":"_owner","internalType":"address"},{"type":"address","name":"_oracle","internalType":"address"},{"type":"uint256","name":"_gasUsed","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setFeesExchange","inputs":[{"type":"uint256","name":"_newCommission","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setGasPriceGasLimitGasAdd","inputs":[{"type":"uint256","name":"_gasPrice","internalType":"uint256"},{"type":"uint256","name":"_gaslimit","internalType":"uint256"},{"type":"uint256","name":"_gasAdd","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setNumExecutedOrders","inputs":[{"type":"uint256","name":"_numExecutedOrders","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes4","name":"","internalType":"bytes4"}],"name":"tokenReceived","inputs":[{"type":"address","name":"_from","internalType":"address"},{"type":"uint256","name":"_value","internalType":"uint256"},{"type":"bytes","name":"_data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdraw","inputs":[{"type":"address","name":"_token","internalType":"address"},{"type":"address","name":"_owner","internalType":"address"},{"type":"uint256","name":"_value","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdrawFee","inputs":[{"type":"address","name":"_token","internalType":"address"},{"type":"uint256","name":"_value","internalType":"uint256"}]},{"type":"receive","stateMutability":"payable"}]
Contract Creation Code
0x608060405267058d15e176280000600055601e60015564e94bdaa40060025562e4e1c060035562015f9060045573ebe894814554c8382ea6a24ccddf1527407a24f6600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555073f5ad6f6edec824c7fd54a66d241a227f6503ad3a600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550348015620000e357600080fd5b506040518060c00160405280683635c9adc5dea00000815260200160df60ff168152602001601260ff16815260200161c35061ffff1681526020017f57434c4f0000000000000000000000000000000000000000000000000000000077ffffffffffffffffffffffffffffffffffffffffffffffff19168152602001600073ffffffffffffffffffffffffffffffffffffffff168152506005600073f5ad6f6edec824c7fd54a66d241a227f6503ad3a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000820151816000015560208201518160010160006101000a81548160ff021916908360ff16021790555060408201518160010160016101000a81548160ff021916908360ff16021790555060608201518160010160026101000a81548161ffff021916908361ffff16021790555060808201518160010160046101000a81548167ffffffffffffffff021916908360c01c021790555060a082015181600101600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505073f5ad6f6edec824c7fd54a66d241a227f6503ad3a73ffffffffffffffffffffffffffffffffffffffff1663095ea7b3307fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6040518363ffffffff1660e01b81526004016200031f929190620003cc565b6020604051808303816000875af11580156200033f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200036591906200043b565b506200046d565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062000399826200036c565b9050919050565b620003ab816200038c565b82525050565b6000819050919050565b620003c681620003b1565b82525050565b6000604082019050620003e36000830185620003a0565b620003f26020830184620003bb565b9392505050565b600080fd5b60008115159050919050565b6200041581620003fe565b81146200042157600080fd5b50565b60008151905062000435816200040a565b92915050565b600060208284031215620004545762000453620003f9565b5b6000620004648482850162000424565b91505092915050565b613ff2806200047d6000396000f3fe6080604052600436106101a05760003560e01c80637c0b052a116100ec578063944d44ab1161008a578063e06b440011610064578063e06b440014610638578063f3f9d41a14610663578063f41a710d146106a0578063fd9be522146106dd576101f3565b8063944d44ab146105bd578063bfdf0bd7146105e6578063d9caed121461060f576101f3565b80638943ec02116100c65780638943ec02146105105780638a6cea2c1461054d5780638b43f445146105765780638da5cb5b14610592576101f3565b80637c0b052a1461048157806380b2edd8146104be57806381e1c10b146104e7576101f3565b80632709275e11610159578063508784051161013357806350878405146103ad578063624ff298146103d957806365593d7b146104055780636655580414610443576101f3565b80632709275e1461032a5780634b4265a3146103555780634c1129bc14610382576101f3565b80631a180bb6146101f85780631f2bff681461022157806322fe7c6f1461025e57806323c5036b1461029b57806324bd3e8f146102c457806326c28edf146102ed576101f3565b366101f35773f5ad6f6edec824c7fd54a66d241a227f6503ad3a73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101f157600080fd5b005b600080fd5b34801561020457600080fd5b5061021f600480360381019061021a9190612cfd565b610706565b005b34801561022d57600080fd5b5061024860048036038101906102439190612cfd565b610840565b6040516102559190612ef9565b60405180910390f35b34801561026a57600080fd5b5061028560048036038101906102809190612f1b565b610c41565b6040516102929190612fb7565b60405180910390f35b3480156102a757600080fd5b506102c260048036038101906102bd9190612fd2565b610ddd565b005b3480156102d057600080fd5b506102eb60048036038101906102e6919061304d565b610e74565b005b3480156102f957600080fd5b50610314600480360381019061030f91906130df565b610f0e565b60405161032191906131ee565b60405180910390f35b34801561033657600080fd5b5061033f611093565b60405161034c919061321f565b60405180910390f35b34801561036157600080fd5b5061036a6110ab565b6040516103799392919061323a565b60405180910390f35b34801561038e57600080fd5b506103976110d6565b6040516103a4919061321f565b60405180910390f35b3480156103b957600080fd5b506103c26110ee565b6040516103d0929190613271565b60405180910390f35b3480156103e557600080fd5b506103ee6110ff565b6040516103fc929190613271565b60405180910390f35b34801561041157600080fd5b5061042c6004803603810190610427919061329a565b611110565b60405161043a929190613310565b60405180910390f35b34801561044f57600080fd5b5061046a60048036038101906104659190613339565b6112da565b604051610478929190613310565b60405180910390f35b34801561048d57600080fd5b506104a860048036038101906104a391906133a0565b6114a4565b6040516104b59190612fb7565b60405180910390f35b3480156104ca57600080fd5b506104e560048036038101906104e091906133f3565b6115e5565b005b3480156104f357600080fd5b5061050e60048036038101906105099190613420565b611776565b005b34801561051c57600080fd5b50610537600480360381019061053291906135a1565b611bf3565b604051610544919061364b565b60405180910390f35b34801561055957600080fd5b50610574600480360381019061056f919061304d565b611c36565b005b610590600480360381019061058b9190613666565b611cd0565b005b34801561059e57600080fd5b506105a7611d6d565b6040516105b4919061321f565b60405180910390f35b3480156105c957600080fd5b506105e460048036038101906105df91906136b9565b611d93565b005b3480156105f257600080fd5b5061060d60048036038101906106089190613764565b611e3d565b005b34801561061b57600080fd5b50610636600480360381019061063191906133a0565b612364565b005b34801561064457600080fd5b5061064d6126cc565b60405161065a919061321f565b60405180910390f35b34801561066f57600080fd5b5061068a600480360381019061068591906133f3565b6126e4565b6040516106979190612fb7565b60405180910390f35b3480156106ac57600080fd5b506106c760048036038101906106c291906133f3565b612742565b6040516106d49190612fb7565b60405180910390f35b3480156106e957600080fd5b5061070460048036038101906106ff9190612cfd565b61278e565b005b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610796576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161078d90613828565b60405180910390fd5b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff1660ff16116107f557600080fd5b80600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001819055505050565b606060008267ffffffffffffffff81111561085e5761085d613476565b5b60405190808252806020026020018201604052801561089757816020015b610884612be4565b81526020019060019003908161087c5790505b5090506000600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff1660ff161161090e5773f5ad6f6edec824c7fd54a66d241a227f6503ad3a610910565b835b93506000805b84811015610c3557600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691506040518060c00160405280600560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001548152602001600560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff1660ff168152602001600560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900460ff1660ff168152602001600560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160029054906101000a900461ffff1661ffff168152602001600560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160049054906101000a900460c01b77ffffffffffffffffffffffffffffffffffffffffffffffff19168152602001600560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250838281518110610bdf57610bde613848565b5b6020026020010181905250600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160315610c35578195508080610c2d906138a6565b915050610916565b50819250505092915050565b6000738cbe0b85f49933d81a9d964531a5e5ec6815760473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610c8f57600080fd5b8573ffffffffffffffffffffffffffffffffffffffff166323b872dd8830886040518463ffffffff1660e01b8152600401610ccc939291906138ee565b6020604051808303816000875af1158015610ceb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d0f919061395d565b50600080610d1f888888886112da565b91509150600073951d1f73f30716fe0d3e9f9998486fd1f48b68a173ffffffffffffffffffffffffffffffffffffffff166347402bea338b8b8b8b89898d6000546001546040518b63ffffffff1660e01b8152600401610d889a9998979695949392919061398a565b6020604051808303816000875af1158015610da7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dcb9190613a3b565b90508093505050509695505050505050565b8473ffffffffffffffffffffffffffffffffffffffff166323b872dd3330876040518463ffffffff1660e01b8152600401610e1a939291906138ee565b6020604051808303816000875af1158015610e39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e5d919061395d565b50610e6c3386868686866128a7565b505050505050565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f04576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610efb90613828565b60405180910390fd5b8060018190555050565b60606000600185859050610f229190613a68565b67ffffffffffffffff811115610f3b57610f3a613476565b5b604051908082528060200260200182016040528015610f695781602001602082028036833780820191505090505b50905060005b8585905081101561104d57858582818110610f8d57610f8c613848565b5b9050602002016020810190610fa291906133f3565b73ffffffffffffffffffffffffffffffffffffffff166370a08231856040518263ffffffff1660e01b8152600401610fda919061321f565b602060405180830381865afa158015610ff7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061101b9190613a3b565b82828151811061102e5761102d613848565b5b6020026020010181815250508080611045906138a6565b915050610f6f565b508273ffffffffffffffffffffffffffffffffffffffff163181868690508151811061107c5761107b613848565b5b602002602001018181525050809150509392505050565b73469a2f6604b456110b486da4950d032958fde44781565b600080600073f5ad6f6edec824c7fd54a66d241a227f6503ad3a600254600354925092509250909192565b738cbe0b85f49933d81a9d964531a5e5ec6815760481565b600080600054600154915091509091565b600080600254600454915091509091565b6000806000600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160029054906101000a900461ffff1661ffff16600560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160029054906101000a900461ffff1661ffff16106111cb5760026111ce565b60015b9050600060018260ff161461125457600560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900460ff16600a6112399190613bcf565b86866112459190613c1a565b61124f9190613ca3565b6112c7565b600560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900460ff16600a6112b09190613bcf565b86866112bc9190613c1a565b6112c69190613ca3565b5b9050818193509350505094509492505050565b6000806000600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160029054906101000a900461ffff1661ffff16600560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160029054906101000a900461ffff1661ffff1610611395576002611398565b60015b9050600060018260ff161461141e5784600560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900460ff16600a6114049190613bcf565b8861140f9190613c1a565b6114199190613ca3565b611491565b86600560008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900460ff16600a61147b9190613bcf565b866114869190613c1a565b6114909190613ca3565b5b9050818193509350505094509492505050565b6000738cbe0b85f49933d81a9d964531a5e5ec6815760473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146114f257600080fd5b60008373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16146115da57600254600454846115389190613a68565b6115429190613c1a565b905073f5ad6f6edec824c7fd54a66d241a227f6503ad3a73ffffffffffffffffffffffffffffffffffffffff166323b872dd8686846040518463ffffffff1660e01b8152600401611595939291906138ee565b6020604051808303816000875af11580156115b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115d8919061395d565b505b809150509392505050565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611675576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161166c90613828565b60405180910390fd5b6000600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff1660ff16116116d457600080fd5b8073ffffffffffffffffffffffffffffffffffffffff1663095ea7b3307fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6040518363ffffffff1660e01b815260040161172f929190613cd4565b6020604051808303816000875af115801561174e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611772919061395d565b5050565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611806576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117fd90613828565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015611883575073f5ad6f6edec824c7fd54a66d241a227f6503ad3a73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b61188c57600080fd5b8173ffffffffffffffffffffffffffffffffffffffff16600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461192657600080fd5b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611961919061321f565b602060405180830381865afa15801561197e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119a29190613a3b565b146119ac57600080fd5b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611a435780600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000808201600090556001820160006101000a81549060ff02191690556001820160016101000a81549060ff02191690556001820160026101000a81549061ffff02191690556001820160046101000a81549067ffffffffffffffff021916905560018201600c6101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550505050565b60008060008084806020019051810190611c0d9190613d3b565b925092509250611c218733888686866128a7565b50638943ec0260e01b93505050509392505050565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611cc6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cbd90613828565b60405180910390fd5b8060008190555050565b73f5ad6f6edec824c7fd54a66d241a227f6503ad3a73ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015611d2c57600080fd5b505af1158015611d40573d6000803e3d6000fd5b5050505050611d673373f5ad6f6edec824c7fd54a66d241a227f6503ad3a348686866128a7565b50505050565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611e23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e1a90613828565b60405180910390fd5b826002819055508160038190555080600481905550505050565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611ecd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ec490613828565b60405180910390fd5b6000600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff1660ff1614611f62576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f5990613dda565b60405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611fb0573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611fd99190613ec5565b9050602081015191506040518060c001604052808481526020018660ff1681526020018773ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612047573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061206b9190613f23565b60ff1681526020018561ffff1681526020018377ffffffffffffffffffffffffffffffffffffffffffffffff19168152602001600073ffffffffffffffffffffffffffffffffffffffff16815250600560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000820151816000015560208201518160010160006101000a81548160ff021916908360ff16021790555060408201518160010160016101000a81548160ff021916908360ff16021790555060608201518160010160026101000a81548161ffff021916908361ffff16021790555060808201518160010160046101000a81548167ffffffffffffffff021916908360c01c021790555060a082015181600101600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050508560056000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555085600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508573ffffffffffffffffffffffffffffffffffffffff1663095ea7b3307fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6040518363ffffffff1660e01b8152600401612318929190613cd4565b6020604051808303816000875af1158015612337573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061235b919061395d565b50505050505050565b73951d1f73f30716fe0d3e9f9998486fd1f48b68a173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146123e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123dd90613f9c565b60405180910390fd5b6000823b9050600081111561254757738cbe0b85f49933d81a9d964531a5e5ec6815760473ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036124c0578373ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846040518363ffffffff1660e01b8152600401612477929190613cd4565b6020604051808303816000875af1158015612496573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124ba919061395d565b50612542565b8373ffffffffffffffffffffffffffffffffffffffff166323b872dd3085856040518463ffffffff1660e01b81526004016124fd939291906138ee565b6020604051808303816000875af115801561251c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612540919061395d565b505b6126c6565b73f5ad6f6edec824c7fd54a66d241a227f6503ad3a73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612645578373ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d836040518263ffffffff1660e01b81526004016125c79190612fb7565b600060405180830381600087803b1580156125e157600080fd5b505af11580156125f5573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f1935050505015801561263f573d6000803e3d6000fd5b506126c5565b8373ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846040518363ffffffff1660e01b8152600401612680929190613cd4565b6020604051808303816000875af115801561269f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126c3919061395d565b505b5b50505050565b73951d1f73f30716fe0d3e9f9998486fd1f48b68a181565b6000600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160029054906101000a900461ffff1661ffff169050919050565b6000600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001549050919050565b73951d1f73f30716fe0d3e9f9998486fd1f48b68a173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612810576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161280790613f9c565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb73469a2f6604b456110b486da4950d032958fde447836040518363ffffffff1660e01b815260040161285f929190613cd4565b6020604051808303816000875af115801561287e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128a2919061395d565b505050565b600080600560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff1660ff1611801561295c57506000600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff1660ff16115b61296557600080fd5b6000851180156129755750600083115b61297e57600080fd5b8373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16036129b657600080fd5b600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160029054906101000a900461ffff1661ffff16600560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160029054906101000a900461ffff1661ffff161015612aba57600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154831015612ab557600080fd5b612b0a565b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154851015612b0957600080fd5b5b600080612b19888888886112da565b9150915060008111612b2a57600080fd5b600073951d1f73f30716fe0d3e9f9998486fd1f48b68a173ffffffffffffffffffffffffffffffffffffffff166347402bea8b8b8b8b8b89898d6000546001546040518b63ffffffff1660e01b8152600401612b8f9a9998979695949392919061398a565b6020604051808303816000875af1158015612bae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bd29190613a3b565b90508093505050509695505050505050565b6040518060c0016040528060008152602001600060ff168152602001600060ff168152602001600061ffff168152602001600077ffffffffffffffffffffffffffffffffffffffffffffffff19168152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612c9482612c69565b9050919050565b612ca481612c89565b8114612caf57600080fd5b50565b600081359050612cc181612c9b565b92915050565b6000819050919050565b612cda81612cc7565b8114612ce557600080fd5b50565b600081359050612cf781612cd1565b92915050565b60008060408385031215612d1457612d13612c5f565b5b6000612d2285828601612cb2565b9250506020612d3385828601612ce8565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b612d7281612cc7565b82525050565b600060ff82169050919050565b612d8e81612d78565b82525050565b600061ffff82169050919050565b612dab81612d94565b82525050565b60007fffffffffffffffff00000000000000000000000000000000000000000000000082169050919050565b612de681612db1565b82525050565b612df581612c89565b82525050565b60c082016000820151612e116000850182612d69565b506020820151612e246020850182612d85565b506040820151612e376040850182612d85565b506060820151612e4a6060850182612da2565b506080820151612e5d6080850182612ddd565b5060a0820151612e7060a0850182612dec565b50505050565b6000612e828383612dfb565b60c08301905092915050565b6000602082019050919050565b6000612ea682612d3d565b612eb08185612d48565b9350612ebb83612d59565b8060005b83811015612eec578151612ed38882612e76565b9750612ede83612e8e565b925050600181019050612ebf565b5085935050505092915050565b60006020820190508181036000830152612f138184612e9b565b905092915050565b60008060008060008060c08789031215612f3857612f37612c5f565b5b6000612f4689828a01612cb2565b9650506020612f5789828a01612cb2565b9550506040612f6889828a01612ce8565b9450506060612f7989828a01612cb2565b9350506080612f8a89828a01612ce8565b92505060a0612f9b89828a01612ce8565b9150509295509295509295565b612fb181612cc7565b82525050565b6000602082019050612fcc6000830184612fa8565b92915050565b600080600080600060a08688031215612fee57612fed612c5f565b5b6000612ffc88828901612cb2565b955050602061300d88828901612ce8565b945050604061301e88828901612cb2565b935050606061302f88828901612ce8565b925050608061304088828901612ce8565b9150509295509295909350565b60006020828403121561306357613062612c5f565b5b600061307184828501612ce8565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261309f5761309e61307a565b5b8235905067ffffffffffffffff8111156130bc576130bb61307f565b5b6020830191508360208202830111156130d8576130d7613084565b5b9250929050565b6000806000604084860312156130f8576130f7612c5f565b5b600084013567ffffffffffffffff81111561311657613115612c64565b5b61312286828701613089565b9350935050602061313586828701612cb2565b9150509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006131778383612d69565b60208301905092915050565b6000602082019050919050565b600061319b8261313f565b6131a5818561314a565b93506131b08361315b565b8060005b838110156131e15781516131c8888261316b565b97506131d383613183565b9250506001810190506131b4565b5085935050505092915050565b600060208201905081810360008301526132088184613190565b905092915050565b61321981612c89565b82525050565b60006020820190506132346000830184613210565b92915050565b600060608201905061324f6000830186613210565b61325c6020830185612fa8565b6132696040830184612fa8565b949350505050565b60006040820190506132866000830185612fa8565b6132936020830184612fa8565b9392505050565b600080600080608085870312156132b4576132b3612c5f565b5b60006132c287828801612cb2565b94505060206132d387828801612cb2565b93505060406132e487828801612ce8565b92505060606132f587828801612ce8565b91505092959194509250565b61330a81612d78565b82525050565b60006040820190506133256000830185613301565b6133326020830184612fa8565b9392505050565b6000806000806080858703121561335357613352612c5f565b5b600061336187828801612cb2565b945050602061337287828801612ce8565b935050604061338387828801612cb2565b925050606061339487828801612ce8565b91505092959194509250565b6000806000606084860312156133b9576133b8612c5f565b5b60006133c786828701612cb2565b93505060206133d886828701612cb2565b92505060406133e986828701612ce8565b9150509250925092565b60006020828403121561340957613408612c5f565b5b600061341784828501612cb2565b91505092915050565b6000806040838503121561343757613436612c5f565b5b600061344585828601612cb2565b925050602061345685828601612cb2565b9150509250929050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6134ae82613465565b810181811067ffffffffffffffff821117156134cd576134cc613476565b5b80604052505050565b60006134e0612c55565b90506134ec82826134a5565b919050565b600067ffffffffffffffff82111561350c5761350b613476565b5b61351582613465565b9050602081019050919050565b82818337600083830152505050565b600061354461353f846134f1565b6134d6565b9050828152602081018484840111156135605761355f613460565b5b61356b848285613522565b509392505050565b600082601f8301126135885761358761307a565b5b8135613598848260208601613531565b91505092915050565b6000806000606084860312156135ba576135b9612c5f565b5b60006135c886828701612cb2565b93505060206135d986828701612ce8565b925050604084013567ffffffffffffffff8111156135fa576135f9612c64565b5b61360686828701613573565b9150509250925092565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61364581613610565b82525050565b6000602082019050613660600083018461363c565b92915050565b60008060006060848603121561367f5761367e612c5f565b5b600061368d86828701612cb2565b935050602061369e86828701612ce8565b92505060406136af86828701612ce8565b9150509250925092565b6000806000606084860312156136d2576136d1612c5f565b5b60006136e086828701612ce8565b93505060206136f186828701612ce8565b925050604061370286828701612ce8565b9150509250925092565b61371581612d78565b811461372057600080fd5b50565b6000813590506137328161370c565b92915050565b61374181612d94565b811461374c57600080fd5b50565b60008135905061375e81613738565b92915050565b6000806000806080858703121561377e5761377d612c5f565b5b600061378c87828801612cb2565b945050602061379d87828801613723565b93505060406137ae8782880161374f565b92505060606137bf87828801612ce8565b91505092959194509250565b600082825260208201905092915050565b7f4f6e6c79206f776e65722063616e2063616c6c20746869730000000000000000600082015250565b60006138126018836137cb565b915061381d826137dc565b602082019050919050565b6000602082019050818103600083015261384181613805565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006138b182612cc7565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036138e3576138e2613877565b5b600182019050919050565b60006060820190506139036000830186613210565b6139106020830185613210565b61391d6040830184612fa8565b949350505050565b60008115159050919050565b61393a81613925565b811461394557600080fd5b50565b60008151905061395781613931565b92915050565b60006020828403121561397357613972612c5f565b5b600061398184828501613948565b91505092915050565b6000610140820190506139a0600083018d613210565b6139ad602083018c613210565b6139ba604083018b612fa8565b6139c7606083018a613210565b6139d46080830189612fa8565b6139e160a0830188613301565b6139ee60c0830187612fa8565b6139fb60e0830186612fa8565b613a09610100830185612fa8565b613a17610120830184612fa8565b9b9a5050505050505050505050565b600081519050613a3581612cd1565b92915050565b600060208284031215613a5157613a50612c5f565b5b6000613a5f84828501613a26565b91505092915050565b6000613a7382612cc7565b9150613a7e83612cc7565b9250828201905080821115613a9657613a95613877565b5b92915050565b60008160011c9050919050565b6000808291508390505b6001851115613af357808604811115613acf57613ace613877565b5b6001851615613ade5780820291505b8081029050613aec85613a9c565b9450613ab3565b94509492505050565b600082613b0c5760019050613bc8565b81613b1a5760009050613bc8565b8160018114613b305760028114613b3a57613b69565b6001915050613bc8565b60ff841115613b4c57613b4b613877565b5b8360020a915084821115613b6357613b62613877565b5b50613bc8565b5060208310610133831016604e8410600b8410161715613b9e5782820a905083811115613b9957613b98613877565b5b613bc8565b613bab8484846001613aa9565b92509050818404811115613bc257613bc1613877565b5b81810290505b9392505050565b6000613bda82612cc7565b9150613be583612d78565b9250613c127fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484613afc565b905092915050565b6000613c2582612cc7565b9150613c3083612cc7565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613c6957613c68613877565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613cae82612cc7565b9150613cb983612cc7565b925082613cc957613cc8613c74565b5b828204905092915050565b6000604082019050613ce96000830185613210565b613cf66020830184612fa8565b9392505050565b6000613d0882612c69565b9050919050565b613d1881613cfd565b8114613d2357600080fd5b50565b600081519050613d3581613d0f565b92915050565b600080600060608486031215613d5457613d53612c5f565b5b6000613d6286828701613d26565b9350506020613d7386828701613a26565b9250506040613d8486828701613a26565b9150509250925092565b7f6572723a20746f6b656e20657869737473000000000000000000000000000000600082015250565b6000613dc46011836137cb565b9150613dcf82613d8e565b602082019050919050565b60006020820190508181036000830152613df381613db7565b9050919050565b600067ffffffffffffffff821115613e1557613e14613476565b5b613e1e82613465565b9050602081019050919050565b60005b83811015613e49578082015181840152602081019050613e2e565b60008484015250505050565b6000613e68613e6384613dfa565b6134d6565b905082815260208101848484011115613e8457613e83613460565b5b613e8f848285613e2b565b509392505050565b600082601f830112613eac57613eab61307a565b5b8151613ebc848260208601613e55565b91505092915050565b600060208284031215613edb57613eda612c5f565b5b600082015167ffffffffffffffff811115613ef957613ef8612c64565b5b613f0584828501613e97565b91505092915050565b600081519050613f1d8161370c565b92915050565b600060208284031215613f3957613f38612c5f565b5b6000613f4784828501613f0e565b91505092915050565b7f4f6e6c7920636f6e7472616374206f72646572732063616e2063616c6c000000600082015250565b6000613f86601d836137cb565b9150613f9182613f50565b602082019050919050565b60006020820190508181036000830152613fb581613f79565b905091905056fea26469706673582212209106b991195801a7c067ce150318db61653eb344bb79901365f2d6742f513a6d64736f6c63430008100033
Deployed ByteCode
0x6080604052600436106101a05760003560e01c80637c0b052a116100ec578063944d44ab1161008a578063e06b440011610064578063e06b440014610638578063f3f9d41a14610663578063f41a710d146106a0578063fd9be522146106dd576101f3565b8063944d44ab146105bd578063bfdf0bd7146105e6578063d9caed121461060f576101f3565b80638943ec02116100c65780638943ec02146105105780638a6cea2c1461054d5780638b43f445146105765780638da5cb5b14610592576101f3565b80637c0b052a1461048157806380b2edd8146104be57806381e1c10b146104e7576101f3565b80632709275e11610159578063508784051161013357806350878405146103ad578063624ff298146103d957806365593d7b146104055780636655580414610443576101f3565b80632709275e1461032a5780634b4265a3146103555780634c1129bc14610382576101f3565b80631a180bb6146101f85780631f2bff681461022157806322fe7c6f1461025e57806323c5036b1461029b57806324bd3e8f146102c457806326c28edf146102ed576101f3565b366101f35773f5ad6f6edec824c7fd54a66d241a227f6503ad3a73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101f157600080fd5b005b600080fd5b34801561020457600080fd5b5061021f600480360381019061021a9190612cfd565b610706565b005b34801561022d57600080fd5b5061024860048036038101906102439190612cfd565b610840565b6040516102559190612ef9565b60405180910390f35b34801561026a57600080fd5b5061028560048036038101906102809190612f1b565b610c41565b6040516102929190612fb7565b60405180910390f35b3480156102a757600080fd5b506102c260048036038101906102bd9190612fd2565b610ddd565b005b3480156102d057600080fd5b506102eb60048036038101906102e6919061304d565b610e74565b005b3480156102f957600080fd5b50610314600480360381019061030f91906130df565b610f0e565b60405161032191906131ee565b60405180910390f35b34801561033657600080fd5b5061033f611093565b60405161034c919061321f565b60405180910390f35b34801561036157600080fd5b5061036a6110ab565b6040516103799392919061323a565b60405180910390f35b34801561038e57600080fd5b506103976110d6565b6040516103a4919061321f565b60405180910390f35b3480156103b957600080fd5b506103c26110ee565b6040516103d0929190613271565b60405180910390f35b3480156103e557600080fd5b506103ee6110ff565b6040516103fc929190613271565b60405180910390f35b34801561041157600080fd5b5061042c6004803603810190610427919061329a565b611110565b60405161043a929190613310565b60405180910390f35b34801561044f57600080fd5b5061046a60048036038101906104659190613339565b6112da565b604051610478929190613310565b60405180910390f35b34801561048d57600080fd5b506104a860048036038101906104a391906133a0565b6114a4565b6040516104b59190612fb7565b60405180910390f35b3480156104ca57600080fd5b506104e560048036038101906104e091906133f3565b6115e5565b005b3480156104f357600080fd5b5061050e60048036038101906105099190613420565b611776565b005b34801561051c57600080fd5b50610537600480360381019061053291906135a1565b611bf3565b604051610544919061364b565b60405180910390f35b34801561055957600080fd5b50610574600480360381019061056f919061304d565b611c36565b005b610590600480360381019061058b9190613666565b611cd0565b005b34801561059e57600080fd5b506105a7611d6d565b6040516105b4919061321f565b60405180910390f35b3480156105c957600080fd5b506105e460048036038101906105df91906136b9565b611d93565b005b3480156105f257600080fd5b5061060d60048036038101906106089190613764565b611e3d565b005b34801561061b57600080fd5b50610636600480360381019061063191906133a0565b612364565b005b34801561064457600080fd5b5061064d6126cc565b60405161065a919061321f565b60405180910390f35b34801561066f57600080fd5b5061068a600480360381019061068591906133f3565b6126e4565b6040516106979190612fb7565b60405180910390f35b3480156106ac57600080fd5b506106c760048036038101906106c291906133f3565b612742565b6040516106d49190612fb7565b60405180910390f35b3480156106e957600080fd5b5061070460048036038101906106ff9190612cfd565b61278e565b005b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610796576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161078d90613828565b60405180910390fd5b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff1660ff16116107f557600080fd5b80600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001819055505050565b606060008267ffffffffffffffff81111561085e5761085d613476565b5b60405190808252806020026020018201604052801561089757816020015b610884612be4565b81526020019060019003908161087c5790505b5090506000600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff1660ff161161090e5773f5ad6f6edec824c7fd54a66d241a227f6503ad3a610910565b835b93506000805b84811015610c3557600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691506040518060c00160405280600560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001548152602001600560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff1660ff168152602001600560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900460ff1660ff168152602001600560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160029054906101000a900461ffff1661ffff168152602001600560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160049054906101000a900460c01b77ffffffffffffffffffffffffffffffffffffffffffffffff19168152602001600560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250838281518110610bdf57610bde613848565b5b6020026020010181905250600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160315610c35578195508080610c2d906138a6565b915050610916565b50819250505092915050565b6000738cbe0b85f49933d81a9d964531a5e5ec6815760473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610c8f57600080fd5b8573ffffffffffffffffffffffffffffffffffffffff166323b872dd8830886040518463ffffffff1660e01b8152600401610ccc939291906138ee565b6020604051808303816000875af1158015610ceb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d0f919061395d565b50600080610d1f888888886112da565b91509150600073951d1f73f30716fe0d3e9f9998486fd1f48b68a173ffffffffffffffffffffffffffffffffffffffff166347402bea338b8b8b8b89898d6000546001546040518b63ffffffff1660e01b8152600401610d889a9998979695949392919061398a565b6020604051808303816000875af1158015610da7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dcb9190613a3b565b90508093505050509695505050505050565b8473ffffffffffffffffffffffffffffffffffffffff166323b872dd3330876040518463ffffffff1660e01b8152600401610e1a939291906138ee565b6020604051808303816000875af1158015610e39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e5d919061395d565b50610e6c3386868686866128a7565b505050505050565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f04576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610efb90613828565b60405180910390fd5b8060018190555050565b60606000600185859050610f229190613a68565b67ffffffffffffffff811115610f3b57610f3a613476565b5b604051908082528060200260200182016040528015610f695781602001602082028036833780820191505090505b50905060005b8585905081101561104d57858582818110610f8d57610f8c613848565b5b9050602002016020810190610fa291906133f3565b73ffffffffffffffffffffffffffffffffffffffff166370a08231856040518263ffffffff1660e01b8152600401610fda919061321f565b602060405180830381865afa158015610ff7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061101b9190613a3b565b82828151811061102e5761102d613848565b5b6020026020010181815250508080611045906138a6565b915050610f6f565b508273ffffffffffffffffffffffffffffffffffffffff163181868690508151811061107c5761107b613848565b5b602002602001018181525050809150509392505050565b73469a2f6604b456110b486da4950d032958fde44781565b600080600073f5ad6f6edec824c7fd54a66d241a227f6503ad3a600254600354925092509250909192565b738cbe0b85f49933d81a9d964531a5e5ec6815760481565b600080600054600154915091509091565b600080600254600454915091509091565b6000806000600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160029054906101000a900461ffff1661ffff16600560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160029054906101000a900461ffff1661ffff16106111cb5760026111ce565b60015b9050600060018260ff161461125457600560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900460ff16600a6112399190613bcf565b86866112459190613c1a565b61124f9190613ca3565b6112c7565b600560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900460ff16600a6112b09190613bcf565b86866112bc9190613c1a565b6112c69190613ca3565b5b9050818193509350505094509492505050565b6000806000600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160029054906101000a900461ffff1661ffff16600560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160029054906101000a900461ffff1661ffff1610611395576002611398565b60015b9050600060018260ff161461141e5784600560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900460ff16600a6114049190613bcf565b8861140f9190613c1a565b6114199190613ca3565b611491565b86600560008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900460ff16600a61147b9190613bcf565b866114869190613c1a565b6114909190613ca3565b5b9050818193509350505094509492505050565b6000738cbe0b85f49933d81a9d964531a5e5ec6815760473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146114f257600080fd5b60008373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16146115da57600254600454846115389190613a68565b6115429190613c1a565b905073f5ad6f6edec824c7fd54a66d241a227f6503ad3a73ffffffffffffffffffffffffffffffffffffffff166323b872dd8686846040518463ffffffff1660e01b8152600401611595939291906138ee565b6020604051808303816000875af11580156115b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115d8919061395d565b505b809150509392505050565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611675576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161166c90613828565b60405180910390fd5b6000600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff1660ff16116116d457600080fd5b8073ffffffffffffffffffffffffffffffffffffffff1663095ea7b3307fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6040518363ffffffff1660e01b815260040161172f929190613cd4565b6020604051808303816000875af115801561174e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611772919061395d565b5050565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611806576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117fd90613828565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015611883575073f5ad6f6edec824c7fd54a66d241a227f6503ad3a73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b61188c57600080fd5b8173ffffffffffffffffffffffffffffffffffffffff16600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461192657600080fd5b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611961919061321f565b602060405180830381865afa15801561197e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119a29190613a3b565b146119ac57600080fd5b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611a435780600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000808201600090556001820160006101000a81549060ff02191690556001820160016101000a81549060ff02191690556001820160026101000a81549061ffff02191690556001820160046101000a81549067ffffffffffffffff021916905560018201600c6101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550505050565b60008060008084806020019051810190611c0d9190613d3b565b925092509250611c218733888686866128a7565b50638943ec0260e01b93505050509392505050565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611cc6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cbd90613828565b60405180910390fd5b8060008190555050565b73f5ad6f6edec824c7fd54a66d241a227f6503ad3a73ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015611d2c57600080fd5b505af1158015611d40573d6000803e3d6000fd5b5050505050611d673373f5ad6f6edec824c7fd54a66d241a227f6503ad3a348686866128a7565b50505050565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611e23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e1a90613828565b60405180910390fd5b826002819055508160038190555080600481905550505050565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611ecd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ec490613828565b60405180910390fd5b6000600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff1660ff1614611f62576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f5990613dda565b60405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611fb0573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611fd99190613ec5565b9050602081015191506040518060c001604052808481526020018660ff1681526020018773ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612047573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061206b9190613f23565b60ff1681526020018561ffff1681526020018377ffffffffffffffffffffffffffffffffffffffffffffffff19168152602001600073ffffffffffffffffffffffffffffffffffffffff16815250600560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000820151816000015560208201518160010160006101000a81548160ff021916908360ff16021790555060408201518160010160016101000a81548160ff021916908360ff16021790555060608201518160010160026101000a81548161ffff021916908361ffff16021790555060808201518160010160046101000a81548167ffffffffffffffff021916908360c01c021790555060a082015181600101600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050508560056000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555085600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508573ffffffffffffffffffffffffffffffffffffffff1663095ea7b3307fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6040518363ffffffff1660e01b8152600401612318929190613cd4565b6020604051808303816000875af1158015612337573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061235b919061395d565b50505050505050565b73951d1f73f30716fe0d3e9f9998486fd1f48b68a173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146123e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123dd90613f9c565b60405180910390fd5b6000823b9050600081111561254757738cbe0b85f49933d81a9d964531a5e5ec6815760473ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036124c0578373ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846040518363ffffffff1660e01b8152600401612477929190613cd4565b6020604051808303816000875af1158015612496573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124ba919061395d565b50612542565b8373ffffffffffffffffffffffffffffffffffffffff166323b872dd3085856040518463ffffffff1660e01b81526004016124fd939291906138ee565b6020604051808303816000875af115801561251c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612540919061395d565b505b6126c6565b73f5ad6f6edec824c7fd54a66d241a227f6503ad3a73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612645578373ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d836040518263ffffffff1660e01b81526004016125c79190612fb7565b600060405180830381600087803b1580156125e157600080fd5b505af11580156125f5573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f1935050505015801561263f573d6000803e3d6000fd5b506126c5565b8373ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846040518363ffffffff1660e01b8152600401612680929190613cd4565b6020604051808303816000875af115801561269f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126c3919061395d565b505b5b50505050565b73951d1f73f30716fe0d3e9f9998486fd1f48b68a181565b6000600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160029054906101000a900461ffff1661ffff169050919050565b6000600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001549050919050565b73951d1f73f30716fe0d3e9f9998486fd1f48b68a173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612810576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161280790613f9c565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb73469a2f6604b456110b486da4950d032958fde447836040518363ffffffff1660e01b815260040161285f929190613cd4565b6020604051808303816000875af115801561287e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128a2919061395d565b505050565b600080600560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff1660ff1611801561295c57506000600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff1660ff16115b61296557600080fd5b6000851180156129755750600083115b61297e57600080fd5b8373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16036129b657600080fd5b600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160029054906101000a900461ffff1661ffff16600560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160029054906101000a900461ffff1661ffff161015612aba57600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154831015612ab557600080fd5b612b0a565b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154851015612b0957600080fd5b5b600080612b19888888886112da565b9150915060008111612b2a57600080fd5b600073951d1f73f30716fe0d3e9f9998486fd1f48b68a173ffffffffffffffffffffffffffffffffffffffff166347402bea8b8b8b8b8b89898d6000546001546040518b63ffffffff1660e01b8152600401612b8f9a9998979695949392919061398a565b6020604051808303816000875af1158015612bae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bd29190613a3b565b90508093505050509695505050505050565b6040518060c0016040528060008152602001600060ff168152602001600060ff168152602001600061ffff168152602001600077ffffffffffffffffffffffffffffffffffffffffffffffff19168152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612c9482612c69565b9050919050565b612ca481612c89565b8114612caf57600080fd5b50565b600081359050612cc181612c9b565b92915050565b6000819050919050565b612cda81612cc7565b8114612ce557600080fd5b50565b600081359050612cf781612cd1565b92915050565b60008060408385031215612d1457612d13612c5f565b5b6000612d2285828601612cb2565b9250506020612d3385828601612ce8565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b612d7281612cc7565b82525050565b600060ff82169050919050565b612d8e81612d78565b82525050565b600061ffff82169050919050565b612dab81612d94565b82525050565b60007fffffffffffffffff00000000000000000000000000000000000000000000000082169050919050565b612de681612db1565b82525050565b612df581612c89565b82525050565b60c082016000820151612e116000850182612d69565b506020820151612e246020850182612d85565b506040820151612e376040850182612d85565b506060820151612e4a6060850182612da2565b506080820151612e5d6080850182612ddd565b5060a0820151612e7060a0850182612dec565b50505050565b6000612e828383612dfb565b60c08301905092915050565b6000602082019050919050565b6000612ea682612d3d565b612eb08185612d48565b9350612ebb83612d59565b8060005b83811015612eec578151612ed38882612e76565b9750612ede83612e8e565b925050600181019050612ebf565b5085935050505092915050565b60006020820190508181036000830152612f138184612e9b565b905092915050565b60008060008060008060c08789031215612f3857612f37612c5f565b5b6000612f4689828a01612cb2565b9650506020612f5789828a01612cb2565b9550506040612f6889828a01612ce8565b9450506060612f7989828a01612cb2565b9350506080612f8a89828a01612ce8565b92505060a0612f9b89828a01612ce8565b9150509295509295509295565b612fb181612cc7565b82525050565b6000602082019050612fcc6000830184612fa8565b92915050565b600080600080600060a08688031215612fee57612fed612c5f565b5b6000612ffc88828901612cb2565b955050602061300d88828901612ce8565b945050604061301e88828901612cb2565b935050606061302f88828901612ce8565b925050608061304088828901612ce8565b9150509295509295909350565b60006020828403121561306357613062612c5f565b5b600061307184828501612ce8565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261309f5761309e61307a565b5b8235905067ffffffffffffffff8111156130bc576130bb61307f565b5b6020830191508360208202830111156130d8576130d7613084565b5b9250929050565b6000806000604084860312156130f8576130f7612c5f565b5b600084013567ffffffffffffffff81111561311657613115612c64565b5b61312286828701613089565b9350935050602061313586828701612cb2565b9150509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006131778383612d69565b60208301905092915050565b6000602082019050919050565b600061319b8261313f565b6131a5818561314a565b93506131b08361315b565b8060005b838110156131e15781516131c8888261316b565b97506131d383613183565b9250506001810190506131b4565b5085935050505092915050565b600060208201905081810360008301526132088184613190565b905092915050565b61321981612c89565b82525050565b60006020820190506132346000830184613210565b92915050565b600060608201905061324f6000830186613210565b61325c6020830185612fa8565b6132696040830184612fa8565b949350505050565b60006040820190506132866000830185612fa8565b6132936020830184612fa8565b9392505050565b600080600080608085870312156132b4576132b3612c5f565b5b60006132c287828801612cb2565b94505060206132d387828801612cb2565b93505060406132e487828801612ce8565b92505060606132f587828801612ce8565b91505092959194509250565b61330a81612d78565b82525050565b60006040820190506133256000830185613301565b6133326020830184612fa8565b9392505050565b6000806000806080858703121561335357613352612c5f565b5b600061336187828801612cb2565b945050602061337287828801612ce8565b935050604061338387828801612cb2565b925050606061339487828801612ce8565b91505092959194509250565b6000806000606084860312156133b9576133b8612c5f565b5b60006133c786828701612cb2565b93505060206133d886828701612cb2565b92505060406133e986828701612ce8565b9150509250925092565b60006020828403121561340957613408612c5f565b5b600061341784828501612cb2565b91505092915050565b6000806040838503121561343757613436612c5f565b5b600061344585828601612cb2565b925050602061345685828601612cb2565b9150509250929050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6134ae82613465565b810181811067ffffffffffffffff821117156134cd576134cc613476565b5b80604052505050565b60006134e0612c55565b90506134ec82826134a5565b919050565b600067ffffffffffffffff82111561350c5761350b613476565b5b61351582613465565b9050602081019050919050565b82818337600083830152505050565b600061354461353f846134f1565b6134d6565b9050828152602081018484840111156135605761355f613460565b5b61356b848285613522565b509392505050565b600082601f8301126135885761358761307a565b5b8135613598848260208601613531565b91505092915050565b6000806000606084860312156135ba576135b9612c5f565b5b60006135c886828701612cb2565b93505060206135d986828701612ce8565b925050604084013567ffffffffffffffff8111156135fa576135f9612c64565b5b61360686828701613573565b9150509250925092565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61364581613610565b82525050565b6000602082019050613660600083018461363c565b92915050565b60008060006060848603121561367f5761367e612c5f565b5b600061368d86828701612cb2565b935050602061369e86828701612ce8565b92505060406136af86828701612ce8565b9150509250925092565b6000806000606084860312156136d2576136d1612c5f565b5b60006136e086828701612ce8565b93505060206136f186828701612ce8565b925050604061370286828701612ce8565b9150509250925092565b61371581612d78565b811461372057600080fd5b50565b6000813590506137328161370c565b92915050565b61374181612d94565b811461374c57600080fd5b50565b60008135905061375e81613738565b92915050565b6000806000806080858703121561377e5761377d612c5f565b5b600061378c87828801612cb2565b945050602061379d87828801613723565b93505060406137ae8782880161374f565b92505060606137bf87828801612ce8565b91505092959194509250565b600082825260208201905092915050565b7f4f6e6c79206f776e65722063616e2063616c6c20746869730000000000000000600082015250565b60006138126018836137cb565b915061381d826137dc565b602082019050919050565b6000602082019050818103600083015261384181613805565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006138b182612cc7565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036138e3576138e2613877565b5b600182019050919050565b60006060820190506139036000830186613210565b6139106020830185613210565b61391d6040830184612fa8565b949350505050565b60008115159050919050565b61393a81613925565b811461394557600080fd5b50565b60008151905061395781613931565b92915050565b60006020828403121561397357613972612c5f565b5b600061398184828501613948565b91505092915050565b6000610140820190506139a0600083018d613210565b6139ad602083018c613210565b6139ba604083018b612fa8565b6139c7606083018a613210565b6139d46080830189612fa8565b6139e160a0830188613301565b6139ee60c0830187612fa8565b6139fb60e0830186612fa8565b613a09610100830185612fa8565b613a17610120830184612fa8565b9b9a5050505050505050505050565b600081519050613a3581612cd1565b92915050565b600060208284031215613a5157613a50612c5f565b5b6000613a5f84828501613a26565b91505092915050565b6000613a7382612cc7565b9150613a7e83612cc7565b9250828201905080821115613a9657613a95613877565b5b92915050565b60008160011c9050919050565b6000808291508390505b6001851115613af357808604811115613acf57613ace613877565b5b6001851615613ade5780820291505b8081029050613aec85613a9c565b9450613ab3565b94509492505050565b600082613b0c5760019050613bc8565b81613b1a5760009050613bc8565b8160018114613b305760028114613b3a57613b69565b6001915050613bc8565b60ff841115613b4c57613b4b613877565b5b8360020a915084821115613b6357613b62613877565b5b50613bc8565b5060208310610133831016604e8410600b8410161715613b9e5782820a905083811115613b9957613b98613877565b5b613bc8565b613bab8484846001613aa9565b92509050818404811115613bc257613bc1613877565b5b81810290505b9392505050565b6000613bda82612cc7565b9150613be583612d78565b9250613c127fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484613afc565b905092915050565b6000613c2582612cc7565b9150613c3083612cc7565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613c6957613c68613877565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613cae82612cc7565b9150613cb983612cc7565b925082613cc957613cc8613c74565b5b828204905092915050565b6000604082019050613ce96000830185613210565b613cf66020830184612fa8565b9392505050565b6000613d0882612c69565b9050919050565b613d1881613cfd565b8114613d2357600080fd5b50565b600081519050613d3581613d0f565b92915050565b600080600060608486031215613d5457613d53612c5f565b5b6000613d6286828701613d26565b9350506020613d7386828701613a26565b9250506040613d8486828701613a26565b9150509250925092565b7f6572723a20746f6b656e20657869737473000000000000000000000000000000600082015250565b6000613dc46011836137cb565b9150613dcf82613d8e565b602082019050919050565b60006020820190508181036000830152613df381613db7565b9050919050565b600067ffffffffffffffff821115613e1557613e14613476565b5b613e1e82613465565b9050602081019050919050565b60005b83811015613e49578082015181840152602081019050613e2e565b60008484015250505050565b6000613e68613e6384613dfa565b6134d6565b905082815260208101848484011115613e8457613e83613460565b5b613e8f848285613e2b565b509392505050565b600082601f830112613eac57613eab61307a565b5b8151613ebc848260208601613e55565b91505092915050565b600060208284031215613edb57613eda612c5f565b5b600082015167ffffffffffffffff811115613ef957613ef8612c64565b5b613f0584828501613e97565b91505092915050565b600081519050613f1d8161370c565b92915050565b600060208284031215613f3957613f38612c5f565b5b6000613f4784828501613f0e565b91505092915050565b7f4f6e6c7920636f6e7472616374206f72646572732063616e2063616c6c000000600082015250565b6000613f86601d836137cb565b9150613f9182613f50565b602082019050919050565b60006020820190508181036000830152613fb581613f79565b905091905056fea26469706673582212209106b991195801a7c067ce150318db61653eb344bb79901365f2d6742f513a6d64736f6c63430008100033