false
false
0

Contract Address Details

0x56067F64F4EDEc5F665853de4bAFB024a3DA0701

Contract Name
TwoBearsOrders
Creator
0xebe894–7a24f6 at 0x7c35af–170f1e
Balance
0 CLO
Tokens
Fetching tokens...
Transactions
Fetching transactions...
Transfers
Fetching transfers...
Gas Used
Fetching gas used...
Last Balance Update
16292071
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
TwoBearsOrders




Optimization enabled
false
Compiler version
v0.8.16+commit.07a7930e




EVM Version
default




Verified at
2024-09-26T15:35:20.006153Z

Contract source code

// All rights reserved.
// SPDX-License-Identifier: No License (None)

pragma solidity ^0.8.16;

interface IContractDeposits {
    function lockInOrder(address _token_in, address _token_out, address _owner, uint _value_in) external;
    function getTypeAndPriceOrder(address _token_in, uint _value_in, address _token_out, uint _value_out) external view returns (uint8, uint256);
    function operSub(address _token, address _owner, uint _value) external;
    function operAdd(address _token, address _owner, uint _value) external;
}

contract TwoBearsOrders {

    struct Orders {
        uint256 time; // время обновляется при изменении статуса ордер
        uint256 commission; // комиссия биржи за исполнение данного ордера, выплачивается в момент исполнения ордера получаемым токеном
        uint256 value_in; // количество которое отдает владелец ордера (остаток обмена) (когда это значение дойдет до 0, ордер будет закрыт)
        uint256 price; // цена исполнения ордера
        uint256 value_out; // количество которое должен получить владелец ордера (остаток к получению) (когда это значение дойдет до 0, ордер будет закрыт)
        uint256 exec_in; // количество уже обменено
        uint256 exec_out; // количество уже получено
        address token_in; // адрес токена который отдает владелец ордера
        address token_out; // адрес токена который получает владелец ордера
        address owner; // адрес владельца ордера
        uint8 order_type; // тип ордера. 1 - продажа, 2 - покупка
        uint8 order_status; // стутус ордера. 1 - ордер создан. 4 - ордер отменен. 6 - ордер частично выполнен. 7 - ордер закрыт (полное выполнение). 8 - помечен пользователем для удаления из системы
    }

    struct OwnerListID{
        uint256 next; // указатель на следующий id ордера
        uint256 prev; // указатель на предыдущий id ордера       
    }

    struct OrderBook{
        uint256 price; // цена ордера
        uint256 next; // указатель на следующий id ордера
        uint256 prev; // указатель на предыдущий id ордера
    }

    struct Variables { // структура переменных для исполнения ордера (обходим ошибку глубины стека)
        uint _opposite_id;
        uint _opposite_price;
        uint _opposite_value_out;
        uint _val_in_diff;
        uint _temp;
        uint _commission;
        uint _value_sub;
        uint _value_add;
        uint _fee_in;
        uint _fee_out;
        address _recipient;
    }

    uint256 commission = 4 * 1e17; // комиссионный процент взымаемый с каждого выполняемого ордера (оплачивается получаемым токеном, в процессе исполнения ордера)
    uint256 id; // уникальный идентификатор ордера

    mapping(address => mapping(address => mapping(uint256 => OrderBook))) private order_book; // упорядоченный список ордеров по ценам
    mapping(address => mapping(address => mapping(address => mapping(uint256 => OwnerListID)))) private open_order; // открытые ордера трейдера по парам
    mapping(address => mapping(address => mapping(address => mapping(uint256 => OwnerListID)))) private close_order; // закрытые ордера трейдера по парам
    mapping(address => mapping(address => uint256[51])) private exec_order_book; // выполненые/частично выполненые ордера на бирже. Цикличный буфер через массив, 0 - элемент указывает на текущую позицию
    mapping(uint256 => Orders) private orders; // все ордера на бирже

    address public owner = msg.sender; // Владелец
    address public constant contractDeposits = 0x9bF4dc50f8C11206554de8FddaF4cdE5FAB332cc; // Контракт с депозитами
    
    event CreateOrder(uint indexed ID);
    event CancelOrder(uint indexed ID);
    event DeleteOrder(uint indexed ID);
    event ExecutableOrder(uint indexed ID);

    modifier onlyOwner() {
        require(msg.sender == owner, "Only owner can call this.");
        _;
    }


    function getFeesExchange() public view returns (uint256) // вернуть процент биржи
    {
        return commission;
    }

    function setFeesExchange(uint256 _newCommission) public onlyOwner // установить новый процент биржи
    {
        commission = _newCommission;
    }

    // ФУНКЦИИ ДЛЯ РАБОТЫ С ОРДЕРАМИ

    function createOrder(address _token_in, uint _value_in, address _token_out, uint _value_out, uint _order_position) external { // создание ордера
        require((_value_in > 0) && (_value_out > 0)); // количество входящего и получаемого токена должно быть больше 0  

        IContractDeposits(contractDeposits).lockInOrder(_token_in, _token_out, msg.sender, _value_in); // блокируем количество входящего токена в ордере

        Orders memory _ord;
        _ord.time = block.timestamp;
        //_ord.commission = _value_in * commission / (100 * 1e18); // комиссия биржи во входящем токене
        _ord.value_in = _value_in;
        _ord.value_out = _value_out;
        //_ord.exec_in = 0;
        //_ord.exec_out = 0;
        (_ord.order_type, _ord.price) = IContractDeposits(contractDeposits).getTypeAndPriceOrder(_token_in, _value_in, _token_out, _value_out);
        require(_ord.price > 0); // запрещено ордеру иметь нулевую цену
        _ord.token_in = _token_in;
        _ord.token_out = _token_out;
        _ord.owner = msg.sender;
        _ord.order_status = 1;

        ++id; // ID нового ордера
        uint _id = id;

        // Найдем позицию нового ордера в стакане, а также определим является ли новый ордер вершиной стакана
        bool top;
        (_order_position, top) = searchPositionInOrderBook(_token_in, _token_out, _order_position, _ord.price, _ord.order_type);

        if(top){ // новый ордер размещается на вершине стакана, надо проверить возможность его исполнения
            Variables memory variable;
            variable._opposite_id = order_book[_token_out][_token_in][0].prev; // вершина противоположного стакана
            while(variable._opposite_id > 0){ // перебираем подходящие встречные ордера с вершины стакана в глубину
                variable._opposite_price = order_book[_token_out][_token_in][variable._opposite_id].price; // получаем цену ордера
                if(_ord.order_type == 1){ // новый ордер продажи
                    if(_ord.price > variable._opposite_price) break; // если нет пересекающийся цены ордеров, то выполнять нечего
                }
                else{ // новый ордер покупки
                    if(_ord.price < variable._opposite_price) break; // если нет пересекающийся цены ордеров, то выполнять нечего
                }
                // выполняем ордера
                variable._opposite_value_out = orders[variable._opposite_id].value_out; // получаем значение выходящего токена из книги ордеров
                variable._val_in_diff = _ord.value_in < variable._opposite_value_out ? _ord.value_in : variable._opposite_value_out; // найдем объем входящего токена, у создающегося ордере, который надо исполнить

                _ord.value_out = (_ord.value_in - variable._val_in_diff) * _ord.value_out / _ord.value_in; // остаток получения в создаваемом ордере
                variable._temp = _ord.value_out == 0 ? _ord.value_in : variable._val_in_diff; // если остаток получения = 0, тогда отдаем весь вход с пылью (фактически отдает трейдер, создающий ордер)
                _ord.value_in -= variable._temp; // осталось на обмен в создаваемом ордере
                _ord.exec_in += variable._temp; // фактически обменяно от всего ордера
                variable._commission = variable._temp * commission / (100 * 1e18); // фактически отдает ордер из книги, комиссию бирже
                variable._value_sub += variable._temp; // забираем сумму обмена с баланса пользователя
                variable._fee_in += variable._commission; // накапливаем выплату комиссии биржи

                variable._recipient = orders[variable._opposite_id].owner; // владелец чей ордер исполняется (из книги ордеров)
                IContractDeposits(contractDeposits).operAdd(_token_in, variable._recipient, variable._temp - variable._commission);
                orders[variable._opposite_id].exec_out += (variable._temp - variable._commission);
                orders[variable._opposite_id].commission += variable._commission;

                
                variable._temp = variable._val_in_diff * orders[variable._opposite_id].value_in / variable._opposite_value_out; // фактически отдает трейдер из книги ордеров
                variable._commission = variable._temp * commission / (100 * 1e18); // фактически отдает трейдер комиссию бирже
                orders[variable._opposite_id].value_in -= variable._temp; // осталось на обмен в ордере
                orders[variable._opposite_id].value_out = variable._opposite_value_out - variable._val_in_diff; // осталось на обмен в ордере
                orders[variable._opposite_id].exec_in += variable._temp; // фактически обменяно от всего ордера
                IContractDeposits(contractDeposits).operSub(_token_out, variable._recipient, variable._temp); // забираем сумму обмена с баланса пользователя
                variable._fee_out += variable._commission; // накапливаем выплату комиссии биржи

                variable._value_add += (variable._temp - variable._commission);
                _ord.exec_out += (variable._temp - variable._commission);
                _ord.commission += variable._commission;


                orders[variable._opposite_id].time = block.timestamp; // обновляем время последнего исполнения

                // перекрестные ордера отработали
                emit ExecutableOrder(variable._opposite_id);

                if(orders[variable._opposite_id].value_in == 0){ // ордер из книги ордеров полностью отработал
                    orders[variable._opposite_id].order_status = 7; // статус закрытого ордера (полностью отработал)
                    del_ID_order_book(_token_out, _token_in, variable._opposite_id); // удаляем ордер из книги ордеров
                    del_ID_open_order(_token_out, _token_in, variable._recipient, variable._opposite_id); // удаляем ордер в открытых ордерах
                    add_ID_close_order(_token_out, _token_in, variable._recipient, variable._opposite_id); // Добавить ордер в закрытые ордера
                    add_ID_exec_order_book(_token_out, _token_in, variable._opposite_id); // Добавляем в исполненые
                    variable._opposite_id = order_book[_token_out][_token_in][0].prev;
                }
                else{ // ордер отработал частично
                    orders[variable._opposite_id].order_status = 6; // ордер выполнен частично
                }

                if(_ord.value_in == 0){ // создаваемый ордер полностью отработал
                    _ord.order_status = 7;
                    break;
                }
                else{
                    _ord.order_status = 6; // создаваемый ордер отработал частично
                }
            }

            // Переводы создателю ордера
            if(variable._value_sub > 0) IContractDeposits(contractDeposits).operSub(_token_in, msg.sender, variable._value_sub); // создатель ордера должен отдать первый токен (in_order)
            if(variable._value_add > 0) IContractDeposits(contractDeposits).operAdd(_token_out, msg.sender, variable._value_add); // создатель ордера должен получить второй токен (free)
            // переводим бирже все собранную комиссию (комиссия копится на контракте с депозитами)
            if(variable._fee_in > 0) IContractDeposits(contractDeposits).operAdd(_token_in, contractDeposits, variable._fee_in);
            if(variable._fee_out > 0) IContractDeposits(contractDeposits).operAdd(_token_out, contractDeposits, variable._fee_out);
        }

        orders[_id] = _ord; // сохраняем ордер целиком под уникальным номером

        if ((_ord.order_status == 1) || (_ord.order_status == 6)) { // создание ордера или частичное исполнение
            add_ID_order_book(_token_in, _token_out, _order_position, _id, _ord.price); // Добавляем новый ордер в книгу ордеров
            add_ID_open_order(_token_in, _token_out, _id); // добавление нового ордера в открытые ордера трейдера
        } else { // 7 - ордер полностью исполнен
            add_ID_close_order(_token_in, _token_out, msg.sender, _id); // добавление нового ордера в закрытые ордера трейдера
            add_ID_exec_order_book(_token_in, _token_out, _id);
        }

        emit CreateOrder(_id);
    }



    function add_ID_order_book(address _token_in, address _token_out, uint _id_prev, uint _id_new, uint _price) private { // добавление нового ордера в книгу ордеров
        uint _id_next = order_book[_token_in][_token_out][_id_prev].next; // _id_new будет расположен между _id_prev и _id_next
        order_book[_token_in][_token_out][_id_prev].next = _id_new;
        order_book[_token_in][_token_out][_id_next].prev = _id_new;
        order_book[_token_in][_token_out][_id_new] = OrderBook(_price, _id_next, _id_prev);
    }

    function add_ID_open_order(address _token1, address _token2, uint _id_new) private { // добавление нового ордера в открытые ордера трейдера
        (_token1, _token2) = _token1 < _token2 ? (_token1, _token2) : (_token2, _token1); // сортируем токены
        uint _id_last = open_order[_token1][_token2][msg.sender][0].prev; // получаем последний открытый ордер трейдера
        open_order[_token1][_token2][msg.sender][_id_last].next = _id_new;
        open_order[_token1][_token2][msg.sender][0].prev = _id_new;
        open_order[_token1][_token2][msg.sender][_id_new].prev = _id_last; // более оптимальная запись, так как next последнего элемента всегда указывает на 0
    }

    function add_ID_close_order(address _token1, address _token2, address _owner, uint _id_new) private { // добавление нового ордера в закрытые ордера трейдера
        (_token1, _token2) = _token1 < _token2 ? (_token1, _token2) : (_token2, _token1); // сортируем токены
        uint _id_last = close_order[_token1][_token2][_owner][0].prev; // получаем последний закрытый ордер трейдера
        close_order[_token1][_token2][_owner][_id_last].next = _id_new;
        close_order[_token1][_token2][_owner][0].prev = _id_new;
        close_order[_token1][_token2][_owner][_id_new].prev = _id_last; // более оптимальная запись, так как next последнего элемента всегда указывает на 0
    }

    function add_ID_exec_order_book(address _token1, address _token2, uint _id_new) private { // добавление ордера в список исполненых ордеров
        (_token1, _token2) = _token1 < _token2 ? (_token1, _token2) : (_token2, _token1); // сортируем токены
        uint _index = exec_order_book[_token1][_token2][0]; // получаем последний элемент цикличного буфера
        if(_index == 50) _index = 0; // если текущий элемент это последний элемент списка
        ++_index;
        exec_order_book[_token1][_token2][_index] = _id_new; // добавляем выполненый ордер
        exec_order_book[_token1][_token2][0] = _index; // запоминаем индекс последнего добавленного ордера
    }

    function del_ID_order_book(address _token_in, address _token_out, uint _id_del) private { // удаление ордера из книги ордеров
        uint _id_next = order_book[_token_in][_token_out][_id_del].next;
        uint _id_prev = order_book[_token_in][_token_out][_id_del].prev;
        order_book[_token_in][_token_out][_id_prev].next = _id_next;
        order_book[_token_in][_token_out][_id_next].prev = _id_prev;
        delete order_book[_token_in][_token_out][_id_del];
    }

    function del_ID_open_order(address _token1, address _token2, address _owner, uint _id_del) private { // удаление ордера из открытых ордеров трейдера
        (_token1, _token2) = _token1 < _token2 ? (_token1, _token2) : (_token2, _token1); // сортируем токены
        uint _id_next = open_order[_token1][_token2][_owner][_id_del].next;
        uint _id_prev = open_order[_token1][_token2][_owner][_id_del].prev;
        open_order[_token1][_token2][_owner][_id_prev].next = _id_next;
        open_order[_token1][_token2][_owner][_id_next].prev = _id_prev;
        delete open_order[_token1][_token2][_owner][_id_del];
    }

    function del_ID_close_order(address _token1, address _token2, address _owner, uint _id_del) private { // удаление ордера из закрытых ордеров трейдера
        // сортировка токенов была выполнена в функции deleteCloseOrders
        uint _id_next = close_order[_token1][_token2][_owner][_id_del].next;
        uint _id_prev = close_order[_token1][_token2][_owner][_id_del].prev;
        close_order[_token1][_token2][_owner][_id_prev].next = _id_next;
        close_order[_token1][_token2][_owner][_id_next].prev = _id_prev;
        delete close_order[_token1][_token2][_owner][_id_del];
    }


    function cancelOrder(uint _id) external { // отмена ордера
        require(orders[_id].owner == msg.sender);
        require((orders[_id].order_status == 1) || (orders[_id].order_status == 6)); // ордер создан или частично выполнен
        uint _pay = orders[_id].value_in; // Вернуть владельцу оставшиеся токены
        address _token_in = orders[_id].token_in;
        address _token_out = orders[_id].token_out;
        IContractDeposits(contractDeposits).operSub(_token_in, msg.sender, _pay);
        IContractDeposits(contractDeposits).operAdd(_token_in, msg.sender, _pay);
        orders[_id].time = block.timestamp;
        orders[_id].value_in = 0;
        orders[_id].value_out = 0;
        orders[_id].order_status = 4;

        del_ID_order_book(_token_in, _token_out, _id); // удаляем ордер из книги ордеров
        del_ID_open_order(_token_in, _token_out, msg.sender, _id); // удаляем ордер в открытых ордерах
        add_ID_close_order(_token_in, _token_out, msg.sender, _id); // Добавить ордер в закрытые ордера

        emit CancelOrder(_id);
    }


    function deleteCloseOrders(address _token1, address _token2, uint[] calldata _id_arr) external { // удаление списка закрытых пользовательских ордеров
        (_token1, _token2) = _token1 < _token2 ? (_token1, _token2) : (_token2, _token1); // сортируем токены
        uint8 _status; // текущий статус ордера из массива
        for(uint i; i < _id_arr.length; i++){ // перебираем весь массив с ордерами на удаление
            _status = orders[_id_arr[i]].order_status;
            if((orders[_id_arr[i]].owner == msg.sender) && ((_status == 4) || (_status == 7))){
                del_ID_close_order(_token1, _token2, msg.sender, _id_arr[i]); // удаляем ордер из списка закрытых ордеров пользователя
                orders[_id_arr[i]].order_status = 8; // глобально помечаем ордер для удаления из системы
                emit DeleteOrder(_id_arr[i]);
            }
        }
    }


    function deleteGlobalOrders(uint[] calldata _id_arr) external onlyOwner // Удаление списка ордеров из системы. Только тех ордеров, что пользователи пометили как удаляемые
    {
        for(uint i; i < _id_arr.length; i++){ // перебираем весь массив с ордерами на удаление
            if(orders[_id_arr[i]].order_status == 8){ // можно удалять только если пользователь отметил данный ордер как удаляемый
                delete orders[_id_arr[i]];
            }
        }
    }



    function searchPositionInOrderBook(address _token_in, address _token_out, uint _startID, uint _price, uint8 _order_type) public view returns (uint256, bool) // вернуть ID ордера после которого будет размещен новый ордер, а также вернуть true если новый ордер это вершина стакана
    {
        uint256 tek_price;
        uint256 next_id;

        _startID = order_book[_token_in][_token_out][_startID].price > 0 ? _startID : order_book[_token_in][_token_out][0].prev; // определяем стартовую позицию ордера, если такого ордера нет в книге, то стартавая позиция это последний ордер в книге

        tek_price = order_book[_token_in][_token_out][_startID].price;

        if(tek_price == 0){ // если книга ордеров пуста
            return (0, true);
        }
        else{ // надо искать позицию
            if(_order_type == 1){ // новый ордер продажи
                if(_price < tek_price){ // поиск к вершине стакана
                    next_id = order_book[_token_in][_token_out][_startID].next;
                    while(_price < tek_price){
                        if(next_id == 0) return (_startID, true);
                        _startID = next_id;
                        tek_price = order_book[_token_in][_token_out][_startID].price;
                        next_id = order_book[_token_in][_token_out][_startID].next;
                    }
                    return (order_book[_token_in][_token_out][_startID].prev, false);
                }
                else{ // поиск в глубь стакана
                    next_id = order_book[_token_in][_token_out][_startID].prev;
                    while(_price >= tek_price){
                        if(next_id == 0) return (0, false);
                        _startID = next_id;
                        tek_price = order_book[_token_in][_token_out][_startID].price;
                        next_id = order_book[_token_in][_token_out][_startID].prev;
                    }
                    return (_startID, false);
                }
            }
            else{ // новый ордер покупки
                if(_price > tek_price){ // поиск к вершине стакана
                    next_id = order_book[_token_in][_token_out][_startID].next;
                    while(_price > tek_price){
                        if(next_id == 0) return (_startID, true);
                        _startID = next_id;
                        tek_price = order_book[_token_in][_token_out][_startID].price;
                        next_id = order_book[_token_in][_token_out][_startID].next;
                    }
                    return (order_book[_token_in][_token_out][_startID].prev, false);
                }
                else{ // поиск в глубь стакана
                    next_id = order_book[_token_in][_token_out][_startID].prev;
                    while(_price <= tek_price){
                        if(next_id == 0) return (0, false);
                        _startID = next_id;
                        tek_price = order_book[_token_in][_token_out][_startID].price;
                        next_id = order_book[_token_in][_token_out][_startID].prev;
                    }
                    return (_startID, false);
                }
            }
        }
    }


    function get_ID_and_Prices_from_OrderBook(address _token_in, address _token_out, uint _id_start, uint _amount) public view returns (uint [] memory) // Возвращает ID и цены из книги ордеров (для фронта). Фронт учавствует в поиске позиции для ордера
    {   
        _id_start = order_book[_token_in][_token_out][_id_start].price > 0 ? _id_start : order_book[_token_in][_token_out][0].prev; // определяем стартовую позицию ордера, если такого ордера нет в книге, то стартавая позиция это последний ордер в книге
        uint _index;
        uint[] memory result = new uint[](_amount * 2); // [ID, цена...]

        for(uint i; i < _amount; i++){
            if(_id_start == 0) break;
            result[_index++] = _id_start;
            result[_index++] = order_book[_token_in][_token_out][_id_start].price;
            _id_start = order_book[_token_in][_token_out][_id_start].prev;
        }

        return (result);
    }

    function getOrderByID(uint _id) public view returns (Orders memory) // Возвращаем ордер по ID
    {   
        return (orders[_id]);
    }

    function getOrderBook(address _token_in, address _token_out, uint _amount) public view returns (uint [] memory) // Возвращаем ордера стакана от вершины стакана в глубину
    {   
        uint _index;
        uint _id = order_book[_token_in][_token_out][0].prev;
        uint[] memory result = new uint[](_amount * 3); // [цена, отдаю, получаю...]

        for(uint i; i < _amount; i++){
            if(_id == 0) break;
            result[_index++] = orders[_id].price;
            result[_index++] = orders[_id].value_in;
            result[_index++] = orders[_id].value_out;
            _id = order_book[_token_in][_token_out][_id].prev;
        }
        return (result);
    }

    function getExecOrderBook(address _token1, address _token2) public view returns (uint [] memory) // Возвращаем выполненые ордера в данной торговой паре
    {   
        (_token1, _token2) = _token1 < _token2 ? (_token1, _token2) : (_token2, _token1); // сортируем токены
        uint _index_top = exec_order_book[_token1][_token2][0];
        if(_index_top == 0) return (new uint[](1)); // если исполненых ордеров еще не существует, вернем [0]

        uint _index;
        uint _id;
        uint[] memory result = new uint[](50 * 6); // [id, тип_ордера, время, цена, отдал, получил...]        

        for(uint i = 0; i < 50; i++){
            _id = exec_order_book[_token1][_token2][_index_top];
            result[_index++] = _id;
            result[_index++] = orders[_id].order_type;
            result[_index++] = orders[_id].time;
            result[_index++] = orders[_id].price;
            result[_index++] = orders[_id].exec_in;
            result[_index++] = orders[_id].exec_out;
            if(--_index_top == 0){
                _index_top = 50;
                if(exec_order_book[_token1][_token2][_index_top] == 0) break; // обрываем цикл если исполнено менее 50 ордеров
            } 
        }

        return (result);
    }

    function getOpenOrders(address _token1, address _token2, address _owner, uint _id, uint _amount) public view returns (uint [] memory) // Возвращаем указанное количество открытых ордеров пользователя, со сдедующего ордера от стартового ID, в данной торговой паре
    {   // если _id = 0, тогда открытые ордера формируются с самого последнего ордера
        (_token1, _token2) = _token1 < _token2 ? (_token1, _token2) : (_token2, _token1); // сортируем токены
        _id = open_order[_token1][_token2][_owner][_id].prev;

        if(_id == 0) return (new uint[](1)); // если открытых ордеров еще не существует, либо если это первый ордер в списке, который уже был обработан, вернем [0]

        uint _index;
        uint[] memory result = new uint[](_amount * 6); // [id, тип_ордера, время, цена, осталось_отдать, осталось_получить...]

        for(uint i; i < _amount; i++){
            if(_id == 0) break;
            result[_index++] = _id;
            result[_index++] = orders[_id].order_type;
            result[_index++] = orders[_id].time;
            result[_index++] = orders[_id].price;
            result[_index++] = orders[_id].value_in;
            result[_index++] = orders[_id].value_out;
            _id = open_order[_token1][_token2][_owner][_id].prev;
        }
        return (result);
    }

    function getCloseOrders(address _token1, address _token2, address _owner, uint _id, uint _amount) public view returns (uint [] memory) // Возвращаем указанное количество закрытых ордеров пользователя, со сдедующего ордера от стартового ID, в данной торговой паре
    {   // если _id = 0, тогда закрытые ордера формируются с самого первого ордера
        (_token1, _token2) = _token1 < _token2 ? (_token1, _token2) : (_token2, _token1); // сортируем токены
        _id = close_order[_token1][_token2][_owner][_id].next;

        if(_id == 0) return (new uint[](1)); // если закрытых ордеров еще не существует, либо если это первый ордер в списке, который уже был обработан, вернем [0]

        uint _index;
        uint[] memory result = new uint[](_amount * 6); // [id, тип_ордера, время, цена, отдал, получил...]

        for(uint i; i < _amount; i++){
            if(_id == 0) break;
            result[_index++] = _id;
            result[_index++] = orders[_id].order_type;
            result[_index++] = orders[_id].time;
            result[_index++] = orders[_id].price;
            result[_index++] = orders[_id].exec_in;
            result[_index++] = orders[_id].exec_out;
            _id = close_order[_token1][_token2][_owner][_id].next;
        }
        return (result);
    }
}
        

Contract ABI

[{"type":"event","name":"CancelOrder","inputs":[{"type":"uint256","name":"ID","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"CreateOrder","inputs":[{"type":"uint256","name":"ID","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"DeleteOrder","inputs":[{"type":"uint256","name":"ID","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"ExecutableOrder","inputs":[{"type":"uint256","name":"ID","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"cancelOrder","inputs":[{"type":"uint256","name":"_id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"contractDeposits","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"createOrder","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":"nonpayable","outputs":[],"name":"deleteCloseOrders","inputs":[{"type":"address","name":"_token1","internalType":"address"},{"type":"address","name":"_token2","internalType":"address"},{"type":"uint256[]","name":"_id_arr","internalType":"uint256[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"deleteGlobalOrders","inputs":[{"type":"uint256[]","name":"_id_arr","internalType":"uint256[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"getCloseOrders","inputs":[{"type":"address","name":"_token1","internalType":"address"},{"type":"address","name":"_token2","internalType":"address"},{"type":"address","name":"_owner","internalType":"address"},{"type":"uint256","name":"_id","internalType":"uint256"},{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"getExecOrderBook","inputs":[{"type":"address","name":"_token1","internalType":"address"},{"type":"address","name":"_token2","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getFeesExchange","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"getOpenOrders","inputs":[{"type":"address","name":"_token1","internalType":"address"},{"type":"address","name":"_token2","internalType":"address"},{"type":"address","name":"_owner","internalType":"address"},{"type":"uint256","name":"_id","internalType":"uint256"},{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"getOrderBook","inputs":[{"type":"address","name":"_token_in","internalType":"address"},{"type":"address","name":"_token_out","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct TwoBearsOrders.Orders","components":[{"type":"uint256","name":"time","internalType":"uint256"},{"type":"uint256","name":"commission","internalType":"uint256"},{"type":"uint256","name":"value_in","internalType":"uint256"},{"type":"uint256","name":"price","internalType":"uint256"},{"type":"uint256","name":"value_out","internalType":"uint256"},{"type":"uint256","name":"exec_in","internalType":"uint256"},{"type":"uint256","name":"exec_out","internalType":"uint256"},{"type":"address","name":"token_in","internalType":"address"},{"type":"address","name":"token_out","internalType":"address"},{"type":"address","name":"owner","internalType":"address"},{"type":"uint8","name":"order_type","internalType":"uint8"},{"type":"uint8","name":"order_status","internalType":"uint8"}]}],"name":"getOrderByID","inputs":[{"type":"uint256","name":"_id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"get_ID_and_Prices_from_OrderBook","inputs":[{"type":"address","name":"_token_in","internalType":"address"},{"type":"address","name":"_token_out","internalType":"address"},{"type":"uint256","name":"_id_start","internalType":"uint256"},{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"},{"type":"bool","name":"","internalType":"bool"}],"name":"searchPositionInOrderBook","inputs":[{"type":"address","name":"_token_in","internalType":"address"},{"type":"address","name":"_token_out","internalType":"address"},{"type":"uint256","name":"_startID","internalType":"uint256"},{"type":"uint256","name":"_price","internalType":"uint256"},{"type":"uint8","name":"_order_type","internalType":"uint8"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setFeesExchange","inputs":[{"type":"uint256","name":"_newCommission","internalType":"uint256"}]}]
              

Contract Creation Code

Verify & Publish
0x608060405267058d15e17628000060005533600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555034801561005d57600080fd5b50615e2e806200006e6000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80637e9da7a2116100975780638a6cea2c116100665780638a6cea2c146102ab5780638da5cb5b146102c75780639435298b146102e557806396d4f64014610315576100f5565b80637e9da7a214610211578063809741ed14610241578063867443d414610271578063894557381461028d576100f5565b80631f5edaf6116100d35780631f5edaf614610178578063299821f6146101a9578063334503bf146101c5578063514fcac7146101f5576100f5565b80630e0578f5146100fa578063127e11971461012a57806318df238814610148575b600080fd5b610114600480360381019061010f9190615333565b610331565b60405161012191906154c2565b60405180910390f35b6101326104e1565b60405161013f91906154ed565b60405180910390f35b610162600480360381019061015d9190615534565b6104f9565b60405161016f919061564a565b60405180910390f35b610192600480360381019061018d9190615698565b610837565b6040516101a092919061573d565b60405180910390f35b6101c360048036038101906101be91906157cb565b611310565b005b6101df60048036038101906101da9190615818565b611512565b6040516101ec919061564a565b60405180910390f35b61020f600480360381019061020a9190615333565b611969565b005b61022b60048036038101906102269190615818565b611caa565b604051610238919061564a565b60405180910390f35b61025b60048036038101906102569190615893565b612101565b604051610268919061564a565b60405180910390f35b61028b600480360381019061028691906158d3565b612580565b005b610295612783565b6040516102a29190615947565b60405180910390f35b6102c560048036038101906102c09190615333565b61278c565b005b6102cf612826565b6040516102dc91906154ed565b60405180910390f35b6102ff60048036038101906102fa9190615962565b61284c565b60405161030c919061564a565b60405180910390f35b61032f600480360381019061032a91906159b5565b612acb565b005b6103396151da565b6006600083815260200190815260200160002060405180610180016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016008820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016009820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016009820160149054906101000a900460ff1660ff1660ff1681526020016009820160159054906101000a900460ff1660ff1660ff16815250509050919050565b739bf4dc50f8c11206554de8fddaf4cde5fab332cc81565b60606000600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000858152602001908152602001600020600001541161062957600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008081526020019081526020016000206002015461062b565b825b925060008060028461063d9190615a5f565b67ffffffffffffffff81111561065657610655615ab9565b5b6040519080825280602002602001820160405280156106845781602001602082028036833780820191505090505b50905060005b8481101561082957600086031561082957858284806106a890615ae8565b9550815181106106bb576106ba615b30565b5b602002602001018181525050600260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008781526020019081526020016000206000015482848061076490615ae8565b95508151811061077757610776615b30565b5b602002602001018181525050600260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000878152602001908152602001600020600201549550808061082190615ae8565b91505061068a565b508092505050949350505050565b6000806000806000600260008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000898152602001908152602001600020600001541161096b57600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008081526020019081526020016000206002015461096d565b865b9650600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600088815260200190815260200160002060000154915060008203610a195760006001935093505050611306565b60018560ff1603610e975781861015610caa57600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008881526020019081526020016000206001015490505b81861015610c0c5760008103610ade57866001935093505050611306565b809650600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000888152602001908152602001600020600001549150600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000888152602001908152602001600020600101549050610ac0565b600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000888152602001908152602001600020600201546000935093505050611306565b600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008881526020019081526020016000206002015490505b818610610e895760008103610d5b57600080935093505050611306565b809650600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000888152602001908152602001600020600001549150600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000888152602001908152602001600020600201549050610d3e565b866000935093505050611306565b8186111561111d57600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008881526020019081526020016000206001015490505b8186111561107f5760008103610f5157866001935093505050611306565b809650600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000888152602001908152602001600020600001549150600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000888152602001908152602001600020600101549050610f33565b600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000888152602001908152602001600020600201546000935093505050611306565b600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008881526020019081526020016000206002015490505b8186116112fc57600081036111ce57600080935093505050611306565b809650600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000888152602001908152602001600020600001549150600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008881526020019081526020016000206002015490506111b1565b8660009350935050505b9550959350505050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146113a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139790615bbc565b60405180910390fd5b60005b8282905081101561150d576008600660008585858181106113c7576113c6615b30565b5b90506020020135815260200190815260200160002060090160159054906101000a900460ff1660ff16036114fa576006600084848481811061140c5761140b615b30565b5b9050602002013581526020019081526020016000206000808201600090556001820160009055600282016000905560038201600090556004820160009055600582016000905560068201600090556007820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556008820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556009820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556009820160146101000a81549060ff02191690556009820160156101000a81549060ff021916905550505b808061150590615ae8565b9150506113a3565b505050565b60608473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161061154e578486611551565b85855b8096508197505050600360008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008481526020019081526020016000206001015492506000830361168257600167ffffffffffffffff81111561164c5761164b615ab9565b5b60405190808252806020026020018201604052801561167a5781602001602082028036833780820191505090505b509050611960565b6000806006846116929190615a5f565b67ffffffffffffffff8111156116ab576116aa615ab9565b5b6040519080825280602002602001820160405280156116d95781602001602082028036833780820191505090505b50905060005b8481101561195957600086031561195957858284806116fd90615ae8565b9550815181106117105761170f615b30565b5b6020026020010181815250506006600087815260200190815260200160002060090160149054906101000a900460ff1660ff1682848061174f90615ae8565b95508151811061176257611761615b30565b5b602002602001018181525050600660008781526020019081526020016000206000015482848061179190615ae8565b9550815181106117a4576117a3615b30565b5b60200260200101818152505060066000878152602001908152602001600020600301548284806117d390615ae8565b9550815181106117e6576117e5615b30565b5b602002602001018181525050600660008781526020019081526020016000206002015482848061181590615ae8565b95508151811061182857611827615b30565b5b602002602001018181525050600660008781526020019081526020016000206004015482848061185790615ae8565b95508151811061186a57611869615b30565b5b602002602001018181525050600360008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000878152602001908152602001600020600101549550808061195190615ae8565b9150506116df565b5080925050505b95945050505050565b3373ffffffffffffffffffffffffffffffffffffffff166006600083815260200190815260200160002060090160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146119d757600080fd5b60016006600083815260200190815260200160002060090160159054906101000a900460ff1660ff161480611a315750600680600083815260200190815260200160002060090160159054906101000a900460ff1660ff16145b611a3a57600080fd5b60006006600083815260200190815260200160002060020154905060006006600084815260200190815260200160002060070160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060006006600085815260200190815260200160002060080160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050739bf4dc50f8c11206554de8fddaf4cde5fab332cc73ffffffffffffffffffffffffffffffffffffffff166367579e218333866040518463ffffffff1660e01b8152600401611b1c93929190615bdc565b600060405180830381600087803b158015611b3657600080fd5b505af1158015611b4a573d6000803e3d6000fd5b50505050739bf4dc50f8c11206554de8fddaf4cde5fab332cc73ffffffffffffffffffffffffffffffffffffffff16630da529b68333866040518463ffffffff1660e01b8152600401611b9f93929190615bdc565b600060405180830381600087803b158015611bb957600080fd5b505af1158015611bcd573d6000803e3d6000fd5b50505050426006600086815260200190815260200160002060000181905550600060066000868152602001908152602001600020600201819055506000600660008681526020019081526020016000206004018190555060046006600086815260200190815260200160002060090160156101000a81548160ff021916908360ff160217905550611c5f828286613a5f565b611c6b82823387613d62565b611c77828233876141d4565b837f935c9ad2f1fda9d7eae0d2a512f1521cb7190ee06165414e722366a65975fb6b60405160405180910390a250505050565b60608473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1610611ce6578486611ce9565b85855b8096508197505050600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060000154925060008303611e1a57600167ffffffffffffffff811115611de457611de3615ab9565b5b604051908082528060200260200182016040528015611e125781602001602082028036833780820191505090505b5090506120f8565b600080600684611e2a9190615a5f565b67ffffffffffffffff811115611e4357611e42615ab9565b5b604051908082528060200260200182016040528015611e715781602001602082028036833780820191505090505b50905060005b848110156120f15760008603156120f15785828480611e9590615ae8565b955081518110611ea857611ea7615b30565b5b6020026020010181815250506006600087815260200190815260200160002060090160149054906101000a900460ff1660ff16828480611ee790615ae8565b955081518110611efa57611ef9615b30565b5b6020026020010181815250506006600087815260200190815260200160002060000154828480611f2990615ae8565b955081518110611f3c57611f3b615b30565b5b6020026020010181815250506006600087815260200190815260200160002060030154828480611f6b90615ae8565b955081518110611f7e57611f7d615b30565b5b6020026020010181815250506006600087815260200190815260200160002060050154828480611fad90615ae8565b955081518110611fc057611fbf615b30565b5b6020026020010181815250506006600087815260200190815260200160002060060154828480611fef90615ae8565b95508151811061200257612001615b30565b5b602002602001018181525050600460008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600087815260200190815260200160002060000154955080806120e990615ae8565b915050611e77565b5080925050505b95945050505050565b60608173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161061213d578183612140565b82825b80935081945050506000600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000603381106121d9576121d8615b30565b5b015490506000810361223757600167ffffffffffffffff811115612200576121ff615ab9565b5b60405190808252806020026020018201604052801561222e5781602001602082028036833780820191505090505b5091505061257a565b600080600061012c67ffffffffffffffff81111561225857612257615ab9565b5b6040519080825280602002602001820160405280156122865781602001602082028036833780820191505090505b50905060005b603281101561257157600560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020856033811061232357612322615b30565b5b015492508282858061233490615ae8565b96508151811061234757612346615b30565b5b6020026020010181815250506006600084815260200190815260200160002060090160149054906101000a900460ff1660ff1682858061238690615ae8565b96508151811061239957612398615b30565b5b60200260200101818152505060066000848152602001908152602001600020600001548285806123c890615ae8565b9650815181106123db576123da615b30565b5b602002602001018181525050600660008481526020019081526020016000206003015482858061240a90615ae8565b96508151811061241d5761241c615b30565b5b602002602001018181525050600660008481526020019081526020016000206005015482858061244c90615ae8565b96508151811061245f5761245e615b30565b5b602002602001018181525050600660008481526020019081526020016000206006015482858061248e90615ae8565b9650815181106124a1576124a0615b30565b5b6020026020010181815250506000856124b990615c13565b9550850361255e57603294506000600560008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020866033811061255557612554615b30565b5b01540315612571575b808061256990615ae8565b91505061228c565b50809450505050505b92915050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16106125ba5782846125bd565b83835b80945081955050506000805b8383905081101561277b57600660008585848181106125eb576125ea615b30565b5b90506020020135815260200190815260200160002060090160159054906101000a900460ff1691503373ffffffffffffffffffffffffffffffffffffffff166006600086868581811061264157612640615b30565b5b90506020020135815260200190815260200160002060090160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161480156126ae575060048260ff1614806126ad575060078260ff16145b5b15612768576126d88686338787868181106126cc576126cb615b30565b5b90506020020135614568565b6008600660008686858181106126f1576126f0615b30565b5b90506020020135815260200190815260200160002060090160156101000a81548160ff021916908360ff16021790555083838281811061273457612733615b30565b5b905060200201357fbd000546857b596b03c884060c13e7d8c7a7ce52366d2f116f76688e6f000f6660405160405180910390a25b808061277390615ae8565b9150506125c9565b505050505050565b60008054905090565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461281c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161281390615bbc565b60405180910390fd5b8060008190555050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6060600080600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600080815260200190815260200160002060020154905060006003856128f39190615a5f565b67ffffffffffffffff81111561290c5761290b615ab9565b5b60405190808252806020026020018201604052801561293a5781602001602082028036833780820191505090505b50905060005b85811015612abd576000830315612abd57600660008481526020019081526020016000206003015482858061297490615ae8565b96508151811061298757612986615b30565b5b60200260200101818152505060066000848152602001908152602001600020600201548285806129b690615ae8565b9650815181106129c9576129c8615b30565b5b60200260200101818152505060066000848152602001908152602001600020600401548285806129f890615ae8565b965081518110612a0b57612a0a615b30565b5b602002602001018181525050600260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008481526020019081526020016000206002015492508080612ab590615ae8565b915050612940565b508093505050509392505050565b600084118015612adb5750600082115b612ae457600080fd5b739bf4dc50f8c11206554de8fddaf4cde5fab332cc73ffffffffffffffffffffffffffffffffffffffff16635dd70a51868533886040518563ffffffff1660e01b8152600401612b379493929190615c3c565b600060405180830381600087803b158015612b5157600080fd5b505af1158015612b65573d6000803e3d6000fd5b50505050612b716151da565b428160000181815250508481604001818152505082816080018181525050739bf4dc50f8c11206554de8fddaf4cde5fab332cc73ffffffffffffffffffffffffffffffffffffffff166366555804878787876040518563ffffffff1660e01b8152600401612be29493929190615c81565b6040805180830381865afa158015612bfe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c229190615cf0565b826101400183606001828152508260ff1660ff1681525050506000816060015111612c4c57600080fd5b858160e0019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508381610100019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250503381610120019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600181610160019060ff16908160ff1681525050600160008154612d1990615ae8565b91905081905550600060015490506000612d3f8887868660600151876101400151610837565b8092508195505050801561385357612d55615283565b600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000808152602001908152602001600020600201548160000181815250505b6000816000015111156135d157600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008260000151815260200190815260200160002060000154816020018181525050600184610140015160ff1603612ebf5780602001518460600151116135d157612ecf565b80602001518460600151106135d1575b6006600082600001518152602001908152602001600020600401548160400181815250508060400151846040015110612f0c578060400151612f12565b83604001515b8160600181815250508360400151846080015182606001518660400151612f399190615d30565b612f439190615a5f565b612f4d9190615d93565b8460800181815250506000846080015114612f6c578060600151612f72565b83604001515b816080018181525050806080015184604001818151612f919190615d30565b9150818152505080608001518460a001818151612fae9190615dc4565b9150818152505068056bc75e2d631000006000548260800151612fd19190615a5f565b612fdb9190615d93565b8160a001818152505080608001518160c001818151612ffa9190615dc4565b915081815250508060a0015181610100018181516130189190615dc4565b91508181525050600660008260000151815260200190815260200160002060090160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681610140019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050739bf4dc50f8c11206554de8fddaf4cde5fab332cc73ffffffffffffffffffffffffffffffffffffffff16630da529b68a8361014001518460a0015185608001516130dd9190615d30565b6040518463ffffffff1660e01b81526004016130fb93929190615bdc565b600060405180830381600087803b15801561311557600080fd5b505af1158015613129573d6000803e3d6000fd5b505050508060a0015181608001516131419190615d30565b6006600083600001518152602001908152602001600020600601600082825461316a9190615dc4565b925050819055508060a001516006600083600001518152602001908152602001600020600101600082825461319f9190615dc4565b92505081905550806040015160066000836000015181526020019081526020016000206002015482606001516131d59190615a5f565b6131df9190615d93565b81608001818152505068056bc75e2d6310000060005482608001516132049190615a5f565b61320e9190615d93565b8160a00181815250508060800151600660008360000151815260200190815260200160002060020160008282546132459190615d30565b92505081905550806060015181604001516132609190615d30565b6006600083600001518152602001908152602001600020600401819055508060800151600660008360000151815260200190815260200160002060050160008282546132ac9190615dc4565b92505081905550739bf4dc50f8c11206554de8fddaf4cde5fab332cc73ffffffffffffffffffffffffffffffffffffffff166367579e218883610140015184608001516040518463ffffffff1660e01b815260040161330d93929190615bdc565b600060405180830381600087803b15801561332757600080fd5b505af115801561333b573d6000803e3d6000fd5b505050508060a0015181610120018181516133569190615dc4565b915081815250508060a0015181608001516133719190615d30565b8160e0018181516133829190615dc4565b915081815250508060a00151816080015161339d9190615d30565b8460c0018181516133ae9190615dc4565b915081815250508060a00151846020018181516133cb9190615dc4565b915081815250504260066000836000015181526020019081526020016000206000018190555080600001517f271adf7ca5026da9466c7e2ee50294432b6518106821bb0baa27adfbe5203bad60405160405180910390a260006006600083600001518152602001908152602001600020600201540361355f576007600660008360000151815260200190815260200160002060090160156101000a81548160ff021916908360ff160217905550613487878a8360000151613a5f565b61349c878a8361014001518460000151613d62565b6134b1878a83610140015184600001516141d4565b6134c0878a8360000151614995565b600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600080815260200190815260200160002060020154816000018181525050613593565b60068060008360000151815260200190815260200160002060090160156101000a81548160ff021916908360ff1602179055505b60008460400151036135b857600784610160019060ff16908160ff16815250506135d1565b600684610160019060ff16908160ff1681525050612df0565b60008160c00151111561366657739bf4dc50f8c11206554de8fddaf4cde5fab332cc73ffffffffffffffffffffffffffffffffffffffff166367579e218a338460c001516040518463ffffffff1660e01b815260040161363393929190615bdc565b600060405180830381600087803b15801561364d57600080fd5b505af1158015613661573d6000803e3d6000fd5b505050505b60008160e0015111156136fb57739bf4dc50f8c11206554de8fddaf4cde5fab332cc73ffffffffffffffffffffffffffffffffffffffff16630da529b688338460e001516040518463ffffffff1660e01b81526004016136c893929190615bdc565b600060405180830381600087803b1580156136e257600080fd5b505af11580156136f6573d6000803e3d6000fd5b505050505b600081610100015111156137a657739bf4dc50f8c11206554de8fddaf4cde5fab332cc73ffffffffffffffffffffffffffffffffffffffff16630da529b68a739bf4dc50f8c11206554de8fddaf4cde5fab332cc8461010001516040518463ffffffff1660e01b815260040161377393929190615bdc565b600060405180830381600087803b15801561378d57600080fd5b505af11580156137a1573d6000803e3d6000fd5b505050505b6000816101200151111561385157739bf4dc50f8c11206554de8fddaf4cde5fab332cc73ffffffffffffffffffffffffffffffffffffffff16630da529b688739bf4dc50f8c11206554de8fddaf4cde5fab332cc8461012001516040518463ffffffff1660e01b815260040161381e93929190615bdc565b600060405180830381600087803b15801561383857600080fd5b505af115801561384c573d6000803e3d6000fd5b505050505b505b8260066000848152602001908152602001600020600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e08201518160070160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101008201518160080160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101208201518160090160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101408201518160090160146101000a81548160ff021916908360ff1602179055506101608201518160090160156101000a81548160ff021916908360ff160217905550905050600183610160015160ff1614806139ea5750600683610160015160ff16145b15613a1057613a00888786858760600151614bb7565b613a0b888784614e47565b613a28565b613a1c888733856141d4565b613a27888784614995565b5b817f2f539bcf68b0eef24f9fef1ae5ad7dd5a37f80a2fab34f406ad2b92c779d606460405160405180910390a25050505050505050565b6000600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206001015490506000600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060020154905081600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206001018190555080600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060020181905550600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008481526020019081526020016000206000808201600090556001820160009055600282016000905550505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610613d9c578284613d9f565b83835b80945081955050506000600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000015490506000600360008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060010154905081600360008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000018190555080600360008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060010181905550600360008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060008082016000905560018201600090555050505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161061420e578284614211565b83835b80945081955050506000600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600080815260200190815260200160002060010154905081600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000018190555081600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008081526020019081526020016000206001018190555080600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000848152602001908152602001600020600101819055505050505050565b6000600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000015490506000600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060010154905081600460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000018190555080600460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060010181905550600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060008082016000905560018201600090555050505050505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16106149cf5781836149d2565b82825b80935081945050506000600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600060338110614a6b57614a6a615b30565b5b0154905060328103614a7c57600090505b80614a8690615ae8565b905081600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208260338110614b1757614b16615b30565b5b018190555080600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600060338110614bac57614bab615b30565b5b018190555050505050565b6000600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600085815260200190815260200160002060010154905082600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008681526020019081526020016000206001018190555082600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002060020181905550604051806060016040528083815260200182815260200185815250600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000858152602001908152602001600020600082015181600001556020820151816001015560408201518160020155905050505050505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1610614e81578183614e84565b82825b80935081945050506000600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600080815260200190815260200160002060010154905081600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000018190555081600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008081526020019081526020016000206001018190555080600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008481526020019081526020016000206001018190555050505050565b60405180610180016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600060ff168152602001600060ff1681525090565b60405180610160016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b600080fd5b600080fd5b6000819050919050565b615310816152fd565b811461531b57600080fd5b50565b60008135905061532d81615307565b92915050565b600060208284031215615349576153486152f3565b5b60006153578482850161531e565b91505092915050565b615369816152fd565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061539a8261536f565b9050919050565b6153aa8161538f565b82525050565b600060ff82169050919050565b6153c6816153b0565b82525050565b610180820160008201516153e36000850182615360565b5060208201516153f66020850182615360565b5060408201516154096040850182615360565b50606082015161541c6060850182615360565b50608082015161542f6080850182615360565b5060a082015161544260a0850182615360565b5060c082015161545560c0850182615360565b5060e082015161546860e08501826153a1565b5061010082015161547d6101008501826153a1565b506101208201516154926101208501826153a1565b506101408201516154a76101408501826153bd565b506101608201516154bc6101608501826153bd565b50505050565b6000610180820190506154d860008301846153cc565b92915050565b6154e78161538f565b82525050565b600060208201905061550260008301846154de565b92915050565b6155118161538f565b811461551c57600080fd5b50565b60008135905061552e81615508565b92915050565b6000806000806080858703121561554e5761554d6152f3565b5b600061555c8782880161551f565b945050602061556d8782880161551f565b935050604061557e8782880161531e565b925050606061558f8782880161531e565b91505092959194509250565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006155d38383615360565b60208301905092915050565b6000602082019050919050565b60006155f78261559b565b61560181856155a6565b935061560c836155b7565b8060005b8381101561563d57815161562488826155c7565b975061562f836155df565b925050600181019050615610565b5085935050505092915050565b6000602082019050818103600083015261566481846155ec565b905092915050565b615675816153b0565b811461568057600080fd5b50565b6000813590506156928161566c565b92915050565b600080600080600060a086880312156156b4576156b36152f3565b5b60006156c28882890161551f565b95505060206156d38882890161551f565b94505060406156e48882890161531e565b93505060606156f58882890161531e565b925050608061570688828901615683565b9150509295509295909350565b61571c816152fd565b82525050565b60008115159050919050565b61573781615722565b82525050565b60006040820190506157526000830185615713565b61575f602083018461572e565b9392505050565b600080fd5b600080fd5b600080fd5b60008083601f84011261578b5761578a615766565b5b8235905067ffffffffffffffff8111156157a8576157a761576b565b5b6020830191508360208202830111156157c4576157c3615770565b5b9250929050565b600080602083850312156157e2576157e16152f3565b5b600083013567ffffffffffffffff811115615800576157ff6152f8565b5b61580c85828601615775565b92509250509250929050565b600080600080600060a08688031215615834576158336152f3565b5b60006158428882890161551f565b95505060206158538882890161551f565b94505060406158648882890161551f565b93505060606158758882890161531e565b92505060806158868882890161531e565b9150509295509295909350565b600080604083850312156158aa576158a96152f3565b5b60006158b88582860161551f565b92505060206158c98582860161551f565b9150509250929050565b600080600080606085870312156158ed576158ec6152f3565b5b60006158fb8782880161551f565b945050602061590c8782880161551f565b935050604085013567ffffffffffffffff81111561592d5761592c6152f8565b5b61593987828801615775565b925092505092959194509250565b600060208201905061595c6000830184615713565b92915050565b60008060006060848603121561597b5761597a6152f3565b5b60006159898682870161551f565b935050602061599a8682870161551f565b92505060406159ab8682870161531e565b9150509250925092565b600080600080600060a086880312156159d1576159d06152f3565b5b60006159df8882890161551f565b95505060206159f08882890161531e565b9450506040615a018882890161551f565b9350506060615a128882890161531e565b9250506080615a238882890161531e565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000615a6a826152fd565b9150615a75836152fd565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615aae57615aad615a30565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000615af3826152fd565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615b2557615b24615a30565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082825260208201905092915050565b7f4f6e6c79206f776e65722063616e2063616c6c20746869732e00000000000000600082015250565b6000615ba6601983615b5f565b9150615bb182615b70565b602082019050919050565b60006020820190508181036000830152615bd581615b99565b9050919050565b6000606082019050615bf160008301866154de565b615bfe60208301856154de565b615c0b6040830184615713565b949350505050565b6000615c1e826152fd565b915060008203615c3157615c30615a30565b5b600182039050919050565b6000608082019050615c5160008301876154de565b615c5e60208301866154de565b615c6b60408301856154de565b615c786060830184615713565b95945050505050565b6000608082019050615c9660008301876154de565b615ca36020830186615713565b615cb060408301856154de565b615cbd6060830184615713565b95945050505050565b600081519050615cd58161566c565b92915050565b600081519050615cea81615307565b92915050565b60008060408385031215615d0757615d066152f3565b5b6000615d1585828601615cc6565b9250506020615d2685828601615cdb565b9150509250929050565b6000615d3b826152fd565b9150615d46836152fd565b9250828203905081811115615d5e57615d5d615a30565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000615d9e826152fd565b9150615da9836152fd565b925082615db957615db8615d64565b5b828204905092915050565b6000615dcf826152fd565b9150615dda836152fd565b9250828201905080821115615df257615df1615a30565b5b9291505056fea2646970667358221220e56c2b15ee5f42419985b327a2bcdb849253dca7eb4e494387ef155435d7301964736f6c63430008100033

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106100f55760003560e01c80637e9da7a2116100975780638a6cea2c116100665780638a6cea2c146102ab5780638da5cb5b146102c75780639435298b146102e557806396d4f64014610315576100f5565b80637e9da7a214610211578063809741ed14610241578063867443d414610271578063894557381461028d576100f5565b80631f5edaf6116100d35780631f5edaf614610178578063299821f6146101a9578063334503bf146101c5578063514fcac7146101f5576100f5565b80630e0578f5146100fa578063127e11971461012a57806318df238814610148575b600080fd5b610114600480360381019061010f9190615333565b610331565b60405161012191906154c2565b60405180910390f35b6101326104e1565b60405161013f91906154ed565b60405180910390f35b610162600480360381019061015d9190615534565b6104f9565b60405161016f919061564a565b60405180910390f35b610192600480360381019061018d9190615698565b610837565b6040516101a092919061573d565b60405180910390f35b6101c360048036038101906101be91906157cb565b611310565b005b6101df60048036038101906101da9190615818565b611512565b6040516101ec919061564a565b60405180910390f35b61020f600480360381019061020a9190615333565b611969565b005b61022b60048036038101906102269190615818565b611caa565b604051610238919061564a565b60405180910390f35b61025b60048036038101906102569190615893565b612101565b604051610268919061564a565b60405180910390f35b61028b600480360381019061028691906158d3565b612580565b005b610295612783565b6040516102a29190615947565b60405180910390f35b6102c560048036038101906102c09190615333565b61278c565b005b6102cf612826565b6040516102dc91906154ed565b60405180910390f35b6102ff60048036038101906102fa9190615962565b61284c565b60405161030c919061564a565b60405180910390f35b61032f600480360381019061032a91906159b5565b612acb565b005b6103396151da565b6006600083815260200190815260200160002060405180610180016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016008820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016009820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016009820160149054906101000a900460ff1660ff1660ff1681526020016009820160159054906101000a900460ff1660ff1660ff16815250509050919050565b739bf4dc50f8c11206554de8fddaf4cde5fab332cc81565b60606000600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000858152602001908152602001600020600001541161062957600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008081526020019081526020016000206002015461062b565b825b925060008060028461063d9190615a5f565b67ffffffffffffffff81111561065657610655615ab9565b5b6040519080825280602002602001820160405280156106845781602001602082028036833780820191505090505b50905060005b8481101561082957600086031561082957858284806106a890615ae8565b9550815181106106bb576106ba615b30565b5b602002602001018181525050600260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008781526020019081526020016000206000015482848061076490615ae8565b95508151811061077757610776615b30565b5b602002602001018181525050600260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000878152602001908152602001600020600201549550808061082190615ae8565b91505061068a565b508092505050949350505050565b6000806000806000600260008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000898152602001908152602001600020600001541161096b57600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008081526020019081526020016000206002015461096d565b865b9650600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600088815260200190815260200160002060000154915060008203610a195760006001935093505050611306565b60018560ff1603610e975781861015610caa57600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008881526020019081526020016000206001015490505b81861015610c0c5760008103610ade57866001935093505050611306565b809650600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000888152602001908152602001600020600001549150600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000888152602001908152602001600020600101549050610ac0565b600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000888152602001908152602001600020600201546000935093505050611306565b600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008881526020019081526020016000206002015490505b818610610e895760008103610d5b57600080935093505050611306565b809650600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000888152602001908152602001600020600001549150600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000888152602001908152602001600020600201549050610d3e565b866000935093505050611306565b8186111561111d57600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008881526020019081526020016000206001015490505b8186111561107f5760008103610f5157866001935093505050611306565b809650600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000888152602001908152602001600020600001549150600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000888152602001908152602001600020600101549050610f33565b600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000888152602001908152602001600020600201546000935093505050611306565b600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008881526020019081526020016000206002015490505b8186116112fc57600081036111ce57600080935093505050611306565b809650600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000888152602001908152602001600020600001549150600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008881526020019081526020016000206002015490506111b1565b8660009350935050505b9550959350505050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146113a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139790615bbc565b60405180910390fd5b60005b8282905081101561150d576008600660008585858181106113c7576113c6615b30565b5b90506020020135815260200190815260200160002060090160159054906101000a900460ff1660ff16036114fa576006600084848481811061140c5761140b615b30565b5b9050602002013581526020019081526020016000206000808201600090556001820160009055600282016000905560038201600090556004820160009055600582016000905560068201600090556007820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556008820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556009820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556009820160146101000a81549060ff02191690556009820160156101000a81549060ff021916905550505b808061150590615ae8565b9150506113a3565b505050565b60608473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161061154e578486611551565b85855b8096508197505050600360008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008481526020019081526020016000206001015492506000830361168257600167ffffffffffffffff81111561164c5761164b615ab9565b5b60405190808252806020026020018201604052801561167a5781602001602082028036833780820191505090505b509050611960565b6000806006846116929190615a5f565b67ffffffffffffffff8111156116ab576116aa615ab9565b5b6040519080825280602002602001820160405280156116d95781602001602082028036833780820191505090505b50905060005b8481101561195957600086031561195957858284806116fd90615ae8565b9550815181106117105761170f615b30565b5b6020026020010181815250506006600087815260200190815260200160002060090160149054906101000a900460ff1660ff1682848061174f90615ae8565b95508151811061176257611761615b30565b5b602002602001018181525050600660008781526020019081526020016000206000015482848061179190615ae8565b9550815181106117a4576117a3615b30565b5b60200260200101818152505060066000878152602001908152602001600020600301548284806117d390615ae8565b9550815181106117e6576117e5615b30565b5b602002602001018181525050600660008781526020019081526020016000206002015482848061181590615ae8565b95508151811061182857611827615b30565b5b602002602001018181525050600660008781526020019081526020016000206004015482848061185790615ae8565b95508151811061186a57611869615b30565b5b602002602001018181525050600360008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000878152602001908152602001600020600101549550808061195190615ae8565b9150506116df565b5080925050505b95945050505050565b3373ffffffffffffffffffffffffffffffffffffffff166006600083815260200190815260200160002060090160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146119d757600080fd5b60016006600083815260200190815260200160002060090160159054906101000a900460ff1660ff161480611a315750600680600083815260200190815260200160002060090160159054906101000a900460ff1660ff16145b611a3a57600080fd5b60006006600083815260200190815260200160002060020154905060006006600084815260200190815260200160002060070160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060006006600085815260200190815260200160002060080160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050739bf4dc50f8c11206554de8fddaf4cde5fab332cc73ffffffffffffffffffffffffffffffffffffffff166367579e218333866040518463ffffffff1660e01b8152600401611b1c93929190615bdc565b600060405180830381600087803b158015611b3657600080fd5b505af1158015611b4a573d6000803e3d6000fd5b50505050739bf4dc50f8c11206554de8fddaf4cde5fab332cc73ffffffffffffffffffffffffffffffffffffffff16630da529b68333866040518463ffffffff1660e01b8152600401611b9f93929190615bdc565b600060405180830381600087803b158015611bb957600080fd5b505af1158015611bcd573d6000803e3d6000fd5b50505050426006600086815260200190815260200160002060000181905550600060066000868152602001908152602001600020600201819055506000600660008681526020019081526020016000206004018190555060046006600086815260200190815260200160002060090160156101000a81548160ff021916908360ff160217905550611c5f828286613a5f565b611c6b82823387613d62565b611c77828233876141d4565b837f935c9ad2f1fda9d7eae0d2a512f1521cb7190ee06165414e722366a65975fb6b60405160405180910390a250505050565b60608473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1610611ce6578486611ce9565b85855b8096508197505050600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060000154925060008303611e1a57600167ffffffffffffffff811115611de457611de3615ab9565b5b604051908082528060200260200182016040528015611e125781602001602082028036833780820191505090505b5090506120f8565b600080600684611e2a9190615a5f565b67ffffffffffffffff811115611e4357611e42615ab9565b5b604051908082528060200260200182016040528015611e715781602001602082028036833780820191505090505b50905060005b848110156120f15760008603156120f15785828480611e9590615ae8565b955081518110611ea857611ea7615b30565b5b6020026020010181815250506006600087815260200190815260200160002060090160149054906101000a900460ff1660ff16828480611ee790615ae8565b955081518110611efa57611ef9615b30565b5b6020026020010181815250506006600087815260200190815260200160002060000154828480611f2990615ae8565b955081518110611f3c57611f3b615b30565b5b6020026020010181815250506006600087815260200190815260200160002060030154828480611f6b90615ae8565b955081518110611f7e57611f7d615b30565b5b6020026020010181815250506006600087815260200190815260200160002060050154828480611fad90615ae8565b955081518110611fc057611fbf615b30565b5b6020026020010181815250506006600087815260200190815260200160002060060154828480611fef90615ae8565b95508151811061200257612001615b30565b5b602002602001018181525050600460008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600087815260200190815260200160002060000154955080806120e990615ae8565b915050611e77565b5080925050505b95945050505050565b60608173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161061213d578183612140565b82825b80935081945050506000600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000603381106121d9576121d8615b30565b5b015490506000810361223757600167ffffffffffffffff811115612200576121ff615ab9565b5b60405190808252806020026020018201604052801561222e5781602001602082028036833780820191505090505b5091505061257a565b600080600061012c67ffffffffffffffff81111561225857612257615ab9565b5b6040519080825280602002602001820160405280156122865781602001602082028036833780820191505090505b50905060005b603281101561257157600560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020856033811061232357612322615b30565b5b015492508282858061233490615ae8565b96508151811061234757612346615b30565b5b6020026020010181815250506006600084815260200190815260200160002060090160149054906101000a900460ff1660ff1682858061238690615ae8565b96508151811061239957612398615b30565b5b60200260200101818152505060066000848152602001908152602001600020600001548285806123c890615ae8565b9650815181106123db576123da615b30565b5b602002602001018181525050600660008481526020019081526020016000206003015482858061240a90615ae8565b96508151811061241d5761241c615b30565b5b602002602001018181525050600660008481526020019081526020016000206005015482858061244c90615ae8565b96508151811061245f5761245e615b30565b5b602002602001018181525050600660008481526020019081526020016000206006015482858061248e90615ae8565b9650815181106124a1576124a0615b30565b5b6020026020010181815250506000856124b990615c13565b9550850361255e57603294506000600560008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020866033811061255557612554615b30565b5b01540315612571575b808061256990615ae8565b91505061228c565b50809450505050505b92915050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16106125ba5782846125bd565b83835b80945081955050506000805b8383905081101561277b57600660008585848181106125eb576125ea615b30565b5b90506020020135815260200190815260200160002060090160159054906101000a900460ff1691503373ffffffffffffffffffffffffffffffffffffffff166006600086868581811061264157612640615b30565b5b90506020020135815260200190815260200160002060090160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161480156126ae575060048260ff1614806126ad575060078260ff16145b5b15612768576126d88686338787868181106126cc576126cb615b30565b5b90506020020135614568565b6008600660008686858181106126f1576126f0615b30565b5b90506020020135815260200190815260200160002060090160156101000a81548160ff021916908360ff16021790555083838281811061273457612733615b30565b5b905060200201357fbd000546857b596b03c884060c13e7d8c7a7ce52366d2f116f76688e6f000f6660405160405180910390a25b808061277390615ae8565b9150506125c9565b505050505050565b60008054905090565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461281c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161281390615bbc565b60405180910390fd5b8060008190555050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6060600080600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600080815260200190815260200160002060020154905060006003856128f39190615a5f565b67ffffffffffffffff81111561290c5761290b615ab9565b5b60405190808252806020026020018201604052801561293a5781602001602082028036833780820191505090505b50905060005b85811015612abd576000830315612abd57600660008481526020019081526020016000206003015482858061297490615ae8565b96508151811061298757612986615b30565b5b60200260200101818152505060066000848152602001908152602001600020600201548285806129b690615ae8565b9650815181106129c9576129c8615b30565b5b60200260200101818152505060066000848152602001908152602001600020600401548285806129f890615ae8565b965081518110612a0b57612a0a615b30565b5b602002602001018181525050600260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008481526020019081526020016000206002015492508080612ab590615ae8565b915050612940565b508093505050509392505050565b600084118015612adb5750600082115b612ae457600080fd5b739bf4dc50f8c11206554de8fddaf4cde5fab332cc73ffffffffffffffffffffffffffffffffffffffff16635dd70a51868533886040518563ffffffff1660e01b8152600401612b379493929190615c3c565b600060405180830381600087803b158015612b5157600080fd5b505af1158015612b65573d6000803e3d6000fd5b50505050612b716151da565b428160000181815250508481604001818152505082816080018181525050739bf4dc50f8c11206554de8fddaf4cde5fab332cc73ffffffffffffffffffffffffffffffffffffffff166366555804878787876040518563ffffffff1660e01b8152600401612be29493929190615c81565b6040805180830381865afa158015612bfe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c229190615cf0565b826101400183606001828152508260ff1660ff1681525050506000816060015111612c4c57600080fd5b858160e0019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508381610100019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250503381610120019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600181610160019060ff16908160ff1681525050600160008154612d1990615ae8565b91905081905550600060015490506000612d3f8887868660600151876101400151610837565b8092508195505050801561385357612d55615283565b600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000808152602001908152602001600020600201548160000181815250505b6000816000015111156135d157600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008260000151815260200190815260200160002060000154816020018181525050600184610140015160ff1603612ebf5780602001518460600151116135d157612ecf565b80602001518460600151106135d1575b6006600082600001518152602001908152602001600020600401548160400181815250508060400151846040015110612f0c578060400151612f12565b83604001515b8160600181815250508360400151846080015182606001518660400151612f399190615d30565b612f439190615a5f565b612f4d9190615d93565b8460800181815250506000846080015114612f6c578060600151612f72565b83604001515b816080018181525050806080015184604001818151612f919190615d30565b9150818152505080608001518460a001818151612fae9190615dc4565b9150818152505068056bc75e2d631000006000548260800151612fd19190615a5f565b612fdb9190615d93565b8160a001818152505080608001518160c001818151612ffa9190615dc4565b915081815250508060a0015181610100018181516130189190615dc4565b91508181525050600660008260000151815260200190815260200160002060090160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681610140019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050739bf4dc50f8c11206554de8fddaf4cde5fab332cc73ffffffffffffffffffffffffffffffffffffffff16630da529b68a8361014001518460a0015185608001516130dd9190615d30565b6040518463ffffffff1660e01b81526004016130fb93929190615bdc565b600060405180830381600087803b15801561311557600080fd5b505af1158015613129573d6000803e3d6000fd5b505050508060a0015181608001516131419190615d30565b6006600083600001518152602001908152602001600020600601600082825461316a9190615dc4565b925050819055508060a001516006600083600001518152602001908152602001600020600101600082825461319f9190615dc4565b92505081905550806040015160066000836000015181526020019081526020016000206002015482606001516131d59190615a5f565b6131df9190615d93565b81608001818152505068056bc75e2d6310000060005482608001516132049190615a5f565b61320e9190615d93565b8160a00181815250508060800151600660008360000151815260200190815260200160002060020160008282546132459190615d30565b92505081905550806060015181604001516132609190615d30565b6006600083600001518152602001908152602001600020600401819055508060800151600660008360000151815260200190815260200160002060050160008282546132ac9190615dc4565b92505081905550739bf4dc50f8c11206554de8fddaf4cde5fab332cc73ffffffffffffffffffffffffffffffffffffffff166367579e218883610140015184608001516040518463ffffffff1660e01b815260040161330d93929190615bdc565b600060405180830381600087803b15801561332757600080fd5b505af115801561333b573d6000803e3d6000fd5b505050508060a0015181610120018181516133569190615dc4565b915081815250508060a0015181608001516133719190615d30565b8160e0018181516133829190615dc4565b915081815250508060a00151816080015161339d9190615d30565b8460c0018181516133ae9190615dc4565b915081815250508060a00151846020018181516133cb9190615dc4565b915081815250504260066000836000015181526020019081526020016000206000018190555080600001517f271adf7ca5026da9466c7e2ee50294432b6518106821bb0baa27adfbe5203bad60405160405180910390a260006006600083600001518152602001908152602001600020600201540361355f576007600660008360000151815260200190815260200160002060090160156101000a81548160ff021916908360ff160217905550613487878a8360000151613a5f565b61349c878a8361014001518460000151613d62565b6134b1878a83610140015184600001516141d4565b6134c0878a8360000151614995565b600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600080815260200190815260200160002060020154816000018181525050613593565b60068060008360000151815260200190815260200160002060090160156101000a81548160ff021916908360ff1602179055505b60008460400151036135b857600784610160019060ff16908160ff16815250506135d1565b600684610160019060ff16908160ff1681525050612df0565b60008160c00151111561366657739bf4dc50f8c11206554de8fddaf4cde5fab332cc73ffffffffffffffffffffffffffffffffffffffff166367579e218a338460c001516040518463ffffffff1660e01b815260040161363393929190615bdc565b600060405180830381600087803b15801561364d57600080fd5b505af1158015613661573d6000803e3d6000fd5b505050505b60008160e0015111156136fb57739bf4dc50f8c11206554de8fddaf4cde5fab332cc73ffffffffffffffffffffffffffffffffffffffff16630da529b688338460e001516040518463ffffffff1660e01b81526004016136c893929190615bdc565b600060405180830381600087803b1580156136e257600080fd5b505af11580156136f6573d6000803e3d6000fd5b505050505b600081610100015111156137a657739bf4dc50f8c11206554de8fddaf4cde5fab332cc73ffffffffffffffffffffffffffffffffffffffff16630da529b68a739bf4dc50f8c11206554de8fddaf4cde5fab332cc8461010001516040518463ffffffff1660e01b815260040161377393929190615bdc565b600060405180830381600087803b15801561378d57600080fd5b505af11580156137a1573d6000803e3d6000fd5b505050505b6000816101200151111561385157739bf4dc50f8c11206554de8fddaf4cde5fab332cc73ffffffffffffffffffffffffffffffffffffffff16630da529b688739bf4dc50f8c11206554de8fddaf4cde5fab332cc8461012001516040518463ffffffff1660e01b815260040161381e93929190615bdc565b600060405180830381600087803b15801561383857600080fd5b505af115801561384c573d6000803e3d6000fd5b505050505b505b8260066000848152602001908152602001600020600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e08201518160070160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101008201518160080160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101208201518160090160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101408201518160090160146101000a81548160ff021916908360ff1602179055506101608201518160090160156101000a81548160ff021916908360ff160217905550905050600183610160015160ff1614806139ea5750600683610160015160ff16145b15613a1057613a00888786858760600151614bb7565b613a0b888784614e47565b613a28565b613a1c888733856141d4565b613a27888784614995565b5b817f2f539bcf68b0eef24f9fef1ae5ad7dd5a37f80a2fab34f406ad2b92c779d606460405160405180910390a25050505050505050565b6000600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206001015490506000600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060020154905081600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206001018190555080600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060020181905550600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008481526020019081526020016000206000808201600090556001820160009055600282016000905550505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610613d9c578284613d9f565b83835b80945081955050506000600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000015490506000600360008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060010154905081600360008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000018190555080600360008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060010181905550600360008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060008082016000905560018201600090555050505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161061420e578284614211565b83835b80945081955050506000600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600080815260200190815260200160002060010154905081600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000018190555081600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008081526020019081526020016000206001018190555080600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000848152602001908152602001600020600101819055505050505050565b6000600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000015490506000600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060010154905081600460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000018190555080600460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060010181905550600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060008082016000905560018201600090555050505050505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16106149cf5781836149d2565b82825b80935081945050506000600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600060338110614a6b57614a6a615b30565b5b0154905060328103614a7c57600090505b80614a8690615ae8565b905081600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208260338110614b1757614b16615b30565b5b018190555080600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600060338110614bac57614bab615b30565b5b018190555050505050565b6000600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600085815260200190815260200160002060010154905082600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008681526020019081526020016000206001018190555082600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002060020181905550604051806060016040528083815260200182815260200185815250600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000858152602001908152602001600020600082015181600001556020820151816001015560408201518160020155905050505050505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1610614e81578183614e84565b82825b80935081945050506000600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600080815260200190815260200160002060010154905081600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000018190555081600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008081526020019081526020016000206001018190555080600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008481526020019081526020016000206001018190555050505050565b60405180610180016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600060ff168152602001600060ff1681525090565b60405180610160016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b600080fd5b600080fd5b6000819050919050565b615310816152fd565b811461531b57600080fd5b50565b60008135905061532d81615307565b92915050565b600060208284031215615349576153486152f3565b5b60006153578482850161531e565b91505092915050565b615369816152fd565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061539a8261536f565b9050919050565b6153aa8161538f565b82525050565b600060ff82169050919050565b6153c6816153b0565b82525050565b610180820160008201516153e36000850182615360565b5060208201516153f66020850182615360565b5060408201516154096040850182615360565b50606082015161541c6060850182615360565b50608082015161542f6080850182615360565b5060a082015161544260a0850182615360565b5060c082015161545560c0850182615360565b5060e082015161546860e08501826153a1565b5061010082015161547d6101008501826153a1565b506101208201516154926101208501826153a1565b506101408201516154a76101408501826153bd565b506101608201516154bc6101608501826153bd565b50505050565b6000610180820190506154d860008301846153cc565b92915050565b6154e78161538f565b82525050565b600060208201905061550260008301846154de565b92915050565b6155118161538f565b811461551c57600080fd5b50565b60008135905061552e81615508565b92915050565b6000806000806080858703121561554e5761554d6152f3565b5b600061555c8782880161551f565b945050602061556d8782880161551f565b935050604061557e8782880161531e565b925050606061558f8782880161531e565b91505092959194509250565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006155d38383615360565b60208301905092915050565b6000602082019050919050565b60006155f78261559b565b61560181856155a6565b935061560c836155b7565b8060005b8381101561563d57815161562488826155c7565b975061562f836155df565b925050600181019050615610565b5085935050505092915050565b6000602082019050818103600083015261566481846155ec565b905092915050565b615675816153b0565b811461568057600080fd5b50565b6000813590506156928161566c565b92915050565b600080600080600060a086880312156156b4576156b36152f3565b5b60006156c28882890161551f565b95505060206156d38882890161551f565b94505060406156e48882890161531e565b93505060606156f58882890161531e565b925050608061570688828901615683565b9150509295509295909350565b61571c816152fd565b82525050565b60008115159050919050565b61573781615722565b82525050565b60006040820190506157526000830185615713565b61575f602083018461572e565b9392505050565b600080fd5b600080fd5b600080fd5b60008083601f84011261578b5761578a615766565b5b8235905067ffffffffffffffff8111156157a8576157a761576b565b5b6020830191508360208202830111156157c4576157c3615770565b5b9250929050565b600080602083850312156157e2576157e16152f3565b5b600083013567ffffffffffffffff811115615800576157ff6152f8565b5b61580c85828601615775565b92509250509250929050565b600080600080600060a08688031215615834576158336152f3565b5b60006158428882890161551f565b95505060206158538882890161551f565b94505060406158648882890161551f565b93505060606158758882890161531e565b92505060806158868882890161531e565b9150509295509295909350565b600080604083850312156158aa576158a96152f3565b5b60006158b88582860161551f565b92505060206158c98582860161551f565b9150509250929050565b600080600080606085870312156158ed576158ec6152f3565b5b60006158fb8782880161551f565b945050602061590c8782880161551f565b935050604085013567ffffffffffffffff81111561592d5761592c6152f8565b5b61593987828801615775565b925092505092959194509250565b600060208201905061595c6000830184615713565b92915050565b60008060006060848603121561597b5761597a6152f3565b5b60006159898682870161551f565b935050602061599a8682870161551f565b92505060406159ab8682870161531e565b9150509250925092565b600080600080600060a086880312156159d1576159d06152f3565b5b60006159df8882890161551f565b95505060206159f08882890161531e565b9450506040615a018882890161551f565b9350506060615a128882890161531e565b9250506080615a238882890161531e565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000615a6a826152fd565b9150615a75836152fd565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615aae57615aad615a30565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000615af3826152fd565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615b2557615b24615a30565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082825260208201905092915050565b7f4f6e6c79206f776e65722063616e2063616c6c20746869732e00000000000000600082015250565b6000615ba6601983615b5f565b9150615bb182615b70565b602082019050919050565b60006020820190508181036000830152615bd581615b99565b9050919050565b6000606082019050615bf160008301866154de565b615bfe60208301856154de565b615c0b6040830184615713565b949350505050565b6000615c1e826152fd565b915060008203615c3157615c30615a30565b5b600182039050919050565b6000608082019050615c5160008301876154de565b615c5e60208301866154de565b615c6b60408301856154de565b615c786060830184615713565b95945050505050565b6000608082019050615c9660008301876154de565b615ca36020830186615713565b615cb060408301856154de565b615cbd6060830184615713565b95945050505050565b600081519050615cd58161566c565b92915050565b600081519050615cea81615307565b92915050565b60008060408385031215615d0757615d066152f3565b5b6000615d1585828601615cc6565b9250506020615d2685828601615cdb565b9150509250929050565b6000615d3b826152fd565b9150615d46836152fd565b9250828203905081811115615d5e57615d5d615a30565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000615d9e826152fd565b9150615da9836152fd565b925082615db957615db8615d64565b5b828204905092915050565b6000615dcf826152fd565b9150615dda836152fd565b9250828201905080821115615df257615df1615a30565b5b9291505056fea2646970667358221220e56c2b15ee5f42419985b327a2bcdb849253dca7eb4e494387ef155435d7301964736f6c63430008100033