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:18.177917Z
Contract source code
// All rights reserved. // SPDX-License-Identifier: No License (None) pragma solidity ^0.8.16; interface IContractDeposits { function withdraw(address _token, address _owner, uint _value) external; function withdrawFee(address _token, 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 - помечен пользователем для удаления из системы. 9 - ордер закрыт (полное выполнение), закрыт по причине достижения лимита исполняемых ордеров, остаток меняемого токена владельцу разблокирован. } struct OwnerListID{ uint256 next; // указатель на следующий id ордера uint256 prev; // указатель на предыдущий id ордера } struct OrderBook{ uint256 price; // цена ордера uint256 next; // указатель на следующий id ордера uint256 prev; // указатель на предыдущий id ордера } struct Variables { // структура переменных для исполнения ордера (обходим ошибку глубины стека) uint _hash_pair; uint _opposite_id; uint _opposite_price; uint _opposite_value_out; uint _val_in_diff; uint _temp; uint _commission; uint _value_add; uint _fee_in; uint _fee_out; address _recipient; } uint256 public id; // уникальный идентификатор ордера mapping(uint256 => mapping(uint256 => OrderBook)) private order_book; // упорядоченный список ордеров по ценам (первый параметр это хэш двух токенов без сортировки) mapping(address => mapping(uint256 => OwnerListID)) private all_open_order; // список всех открытых ордеров владельца mapping(uint256 => mapping(uint256 => OwnerListID)) private open_order; // открытые ордера трейдера по парам mapping(uint256 => mapping(uint256 => OwnerListID)) private close_order; // закрытые ордера трейдера по парам mapping(uint256 => uint256[51]) private exec_order_book; // выполненые/частично выполненые ордера на бирже. Цикличный буфер через массив, 0 - элемент указывает на текущую позицию. (первый параметр это хэш двух токенов с сортировкой) mapping(uint256 => Orders) private orders; // все ордера на бирже address public owner = 0xeBE894814554c8382EA6a24CcDdf1527407A24f6; // Владелец address public constant contractDeposits = 0x45c881B36fC357d80A715Da36d79B845303796c1; // Контракт с депозитами 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 hash2Address(address _a1, address _a2, bool _sort) private pure returns (uint256) // Возвращаем хэш по 2-м адресам, при неодходимости первоначально сортируем их { if(_sort){ (_a1, _a2) = _a1 < _a2 ? (_a1, _a2) : (_a2, _a1); // сортируем токены } return (uint256(keccak256(abi.encodePacked(_a1, _a2)))); } function hash3Address(address _a1, address _a2, address _a3) private pure returns (uint256) // Возвращаем хэш по 3-м адресам { uint256 _hash = hash2Address(_a1, _a2, true); // получаем хэш первых 2-х токенов с их обязательной сортировкой return (uint256(keccak256(abi.encodePacked(_hash, _a3)))); } // *************************** // ФУНКЦИИ ДЛЯ РАБОТЫ С ОРДЕРАМИ function createOrder(address _owner, address _token_in, uint _value_in, address _token_out, uint _value_out, uint8 _order_type, uint _price, uint _order_position, uint _dex_fee, uint _dex_num_exec_ord) external returns (uint256) // создание ордера (возвращаем ID ордера) { require(msg.sender == contractDeposits); // Только контракт депозитов имеет право на создание ордеров 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 = _order_type; _ord.price = _price; _ord.token_in = _token_in; _ord.token_out = _token_out; _ord.owner = _owner; _ord.order_status = 1; ++id; // ID нового ордера uint _id = id; // Найдем позицию нового ордера в стакане, а также определим является ли новый ордер вершиной стакана bool top; (_order_position, top) = searchPositionInOrderBook(hash2Address(_token_in, _token_out, false), _order_position, _price, _order_type); if(top){ // новый ордер размещается на вершине стакана, надо проверить возможность его исполнения Variables memory variable; variable._hash_pair = hash2Address(_token_out, _token_in, false); // получаем хэш по выходящему и входящему токену variable._opposite_id = order_book[variable._hash_pair][0].prev; // вершина противоположного стакана while(variable._opposite_id > 0){ // перебираем подходящие встречные ордера с вершины стакана в глубину variable._opposite_price = order_book[variable._hash_pair][variable._opposite_id].price; // получаем цену ордера if(_order_type == 1){ // новый ордер продажи if(_price > variable._opposite_price) break; // если нет пересекающийся цены ордеров, то выполнять нечего } else{ // новый ордер покупки if(_price < variable._opposite_price) break; // если нет пересекающийся цены ордеров, то выполнять нечего } // Контролируем лимит исполняемых ордеров if(_dex_num_exec_ord == 0){ // если было исполнено максимальное количество ордеров установленное биржей _ord.order_status = 9; IContractDeposits(contractDeposits).withdraw(_token_in, _ord.owner, _ord.value_in); // не исполненый остаток от ордера возвращаем владельцу break; } --_dex_num_exec_ord; // выполняем ордера 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 * _dex_fee / (100 * 1e18); // фактически отдает ордер из книги, комиссию бирже variable._fee_in += variable._commission; // накапливаем выплату комиссии биржи variable._recipient = orders[variable._opposite_id].owner; // владелец чей ордер исполняется (из книги ордеров) IContractDeposits(contractDeposits).withdraw(_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 * _dex_fee / (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; // фактически обменяно от всего ордера 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(variable._hash_pair, 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[variable._hash_pair][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_add > 0) IContractDeposits(contractDeposits).withdraw(_token_out, _ord.owner, variable._value_add); // создатель ордера должен получить второй токен // переводим всю собранную комиссию (комиссия копится в контракте комиссий) if(variable._fee_in > 0) IContractDeposits(contractDeposits).withdrawFee(_token_in, variable._fee_in); if(variable._fee_out > 0) IContractDeposits(contractDeposits).withdrawFee(_token_out, variable._fee_out); } orders[_id] = _ord; // сохраняем ордер целиком под уникальным номером if ((_ord.order_status == 1) || (_ord.order_status == 6)) { // создание ордера или частичное исполнение add_ID_order_book(hash2Address(_token_in, _token_out, false), _order_position, _id, _price); // Добавляем новый ордер в книгу ордеров add_ID_open_order(_token_in, _token_out, _ord.owner, _id); // добавление нового ордера в открытые ордера трейдера } else { // 7 - ордер полностью исполнен или 9 - ордер полностью исполнен (с разблокировкой оставщейся необменяной суммой) add_ID_close_order(_token_in, _token_out, _ord.owner, _id); // добавление нового ордера в закрытые ордера трейдера add_ID_exec_order_book(_token_in, _token_out, _id); } emit CreateOrder(_id); return _id; } function add_ID_order_book(uint256 _hash_pair, uint _id_prev, uint _id_new, uint _price) private { // добавление нового ордера в книгу ордеров uint _id_next = order_book[_hash_pair][_id_prev].next; // _id_new будет расположен между _id_prev и _id_next order_book[_hash_pair][_id_prev].next = _id_new; order_book[_hash_pair][_id_next].prev = _id_new; order_book[_hash_pair][_id_new] = OrderBook(_price, _id_next, _id_prev); } function add_ID_open_order(address _token1, address _token2, address _owner, uint _id_new) private { // добавление нового ордера в открытые ордера трейдера uint _id_last = all_open_order[_owner][0].prev; // получаем последний открытый ордер трейдера all_open_order[_owner][_id_last].next = _id_new; all_open_order[_owner][0].prev = _id_new; all_open_order[_owner][_id_new].prev = _id_last; // более оптимальная запись, так как next последнего элемента всегда указывает на 0 uint256 _hash_pair_owner = hash3Address(_token1, _token2, _owner); // _hash_pair_owner - при получении хэша пары, токены были отсортированы _id_last = open_order[_hash_pair_owner][0].prev; // получаем последний открытый ордер трейдера open_order[_hash_pair_owner][_id_last].next = _id_new; open_order[_hash_pair_owner][0].prev = _id_new; open_order[_hash_pair_owner][_id_new].prev = _id_last; // более оптимальная запись, так как next последнего элемента всегда указывает на 0 } function add_ID_close_order(address _token1, address _token2, address _owner, uint _id_new) private { // добавление нового ордера в закрытые ордера трейдера uint256 _hash_pair_owner = hash3Address(_token1, _token2, _owner); // _hash_pair_owner - при получении хэша пары, токены были отсортированы uint _id_last = close_order[_hash_pair_owner][0].prev; // получаем последний закрытый ордер трейдера close_order[_hash_pair_owner][_id_last].next = _id_new; close_order[_hash_pair_owner][0].prev = _id_new; close_order[_hash_pair_owner][_id_new].prev = _id_last; // более оптимальная запись, так как next последнего элемента всегда указывает на 0 } function add_ID_exec_order_book(address _token1, address _token2, uint _id_new) private { // добавление ордера в список исполненых ордеров uint256 _hash_pair = hash2Address(_token1, _token2, true); // _hash_pair - при получении хэша пары, токены были отсортированы uint _index = exec_order_book[_hash_pair][0]; // получаем последний элемент цикличного буфера if(_index == 50) _index = 0; // если текущий элемент это последний элемент списка ++_index; exec_order_book[_hash_pair][_index] = _id_new; // добавляем выполненый ордер exec_order_book[_hash_pair][0] = _index; // запоминаем индекс последнего добавленного ордера } function del_ID_order_book(uint256 _hash_pair, uint _id_del) private { // удаление ордера из книги ордеров uint _id_next = order_book[_hash_pair][_id_del].next; uint _id_prev = order_book[_hash_pair][_id_del].prev; order_book[_hash_pair][_id_prev].next = _id_next; order_book[_hash_pair][_id_next].prev = _id_prev; delete order_book[_hash_pair][_id_del]; } function del_ID_open_order(address _token1, address _token2, address _owner, uint _id_del) private { // удаление ордера из открытых ордеров трейдера uint _id_next = all_open_order[_owner][_id_del].next; uint _id_prev = all_open_order[_owner][_id_del].prev; all_open_order[_owner][_id_prev].next = _id_next; all_open_order[_owner][_id_next].prev = _id_prev; delete all_open_order[_owner][_id_del]; uint256 _hash_pair_owner = hash3Address(_token1, _token2, _owner); // _hash_pair_owner - при получении хэша пары, токены были отсортированы _id_next = open_order[_hash_pair_owner][_id_del].next; _id_prev = open_order[_hash_pair_owner][_id_del].prev; open_order[_hash_pair_owner][_id_prev].next = _id_next; open_order[_hash_pair_owner][_id_next].prev = _id_prev; delete open_order[_hash_pair_owner][_id_del]; } function del_ID_close_order(uint256 _hash_pair_owner, uint _id_del) private { // удаление ордера из закрытых ордеров трейдера // сортировка токенов была выполнена в функции deleteCloseOrders uint _id_next = close_order[_hash_pair_owner][_id_del].next; uint _id_prev = close_order[_hash_pair_owner][_id_del].prev; close_order[_hash_pair_owner][_id_prev].next = _id_next; close_order[_hash_pair_owner][_id_next].prev = _id_prev; delete close_order[_hash_pair_owner][_id_del]; } function cancelOrders(uint[] memory _id_arr) external returns (uint [] memory) { // отмена ордеров, возвращаем массив с отмененными ордерами (если ордер не был отменен, то вместо его ID в массив записывается 0) uint8 _status; // текущий статус ордера из массива uint256 _id; // ID текущего ордера uint _pay; // Вернуть владельцу оставшиеся токены address _token_in; address _token_out; for(uint i; i < _id_arr.length; i++){ // перебираем весь массив с ордерами на отмену _id = _id_arr[i]; _status = orders[_id].order_status; if((orders[_id].owner == msg.sender) && ((_status == 1) || (_status == 6))){ _pay = orders[_id].value_in; // Вернуть владельцу оставшиеся токены _token_in = orders[_id].token_in; _token_out = orders[_id].token_out; IContractDeposits(contractDeposits).withdraw(_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(hash2Address(_token_in, _token_out, false), _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); } else{ // ордер не может быть отменен (другой владелец или не подходящий статус ордера) _id_arr[i] = 0; // убираем ID ордера из массива отменяемых ордеров } } return (_id_arr); } function deleteCloseOrders(uint[] memory _id_arr) external returns (uint [] memory) { // удаление закрытых пользовательских ордеров, возвращаем массив с удаленными ордерами (если ордер не был удален, то вместо его ID в массив записывается 0) uint8 _status; // текущий статус ордера из массива uint256 _id; // ID текущего ордера for(uint i; i < _id_arr.length; i++){ // перебираем весь массив с ордерами на удаление _id = _id_arr[i]; _status = orders[_id].order_status; if((orders[_id].owner == msg.sender) && ((_status == 4) || (_status == 7) || (_status == 9))){ del_ID_close_order(hash3Address(orders[_id].token_in, orders[_id].token_out, msg.sender), _id); // удаляем ордер из списка закрытых ордеров пользователя orders[_id].order_status = 8; // глобально помечаем ордер для удаления из системы emit DeleteOrder(_id); } else{ // ордер не может быть удален (другой владелец или не подходящий статус ордера) _id_arr[i] = 0; // убираем ID ордера из массива удаляемых ордеров } } return (_id_arr); } 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(uint256 _hash_pair, uint _startID, uint _price, uint8 _order_type) private view returns (uint256, bool) // вернуть ID ордера после которого будет размещен новый ордер, а также вернуть true если новый ордер это вершина стакана { uint256 tek_price; uint256 next_id; _startID = order_book[_hash_pair][_startID].price > 0 ? _startID : order_book[_hash_pair][0].prev; // определяем стартовую позицию ордера, если такого ордера нет в книге, то стартавая позиция это последний ордер в книге tek_price = order_book[_hash_pair][_startID].price; if(tek_price == 0){ // если книга ордеров пуста return (0, true); } else{ // надо искать позицию if(_order_type == 1){ // новый ордер продажи if(_price < tek_price){ // поиск к вершине стакана next_id = order_book[_hash_pair][_startID].next; while(_price < tek_price){ if(next_id == 0) return (_startID, true); _startID = next_id; tek_price = order_book[_hash_pair][_startID].price; next_id = order_book[_hash_pair][_startID].next; } return (order_book[_hash_pair][_startID].prev, false); } else{ // поиск в глубь стакана next_id = order_book[_hash_pair][_startID].prev; while(_price >= tek_price){ if(next_id == 0) return (0, false); _startID = next_id; tek_price = order_book[_hash_pair][_startID].price; next_id = order_book[_hash_pair][_startID].prev; } return (_startID, false); } } else{ // новый ордер покупки if(_price > tek_price){ // поиск к вершине стакана next_id = order_book[_hash_pair][_startID].next; while(_price > tek_price){ if(next_id == 0) return (_startID, true); _startID = next_id; tek_price = order_book[_hash_pair][_startID].price; next_id = order_book[_hash_pair][_startID].next; } return (order_book[_hash_pair][_startID].prev, false); } else{ // поиск в глубь стакана next_id = order_book[_hash_pair][_startID].prev; while(_price <= tek_price){ if(next_id == 0) return (0, false); _startID = next_id; tek_price = order_book[_hash_pair][_startID].price; next_id = order_book[_hash_pair][_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 и цены из книги ордеров (для фронта). Фронт учавствует в поиске позиции для ордера { uint256 _hash_pair = hash2Address(_token_in, _token_out, false); // получаем хэш пары по входящему и выходящему токену _id_start = order_book[_hash_pair][_id_start].price > 0 ? _id_start : order_book[_hash_pair][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[_hash_pair][_id_start].price; _id_start = order_book[_hash_pair][_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) // Возвращаем ордера стакана от вершины стакана в глубину { uint256 _hash_pair = hash2Address(_token_in, _token_out, false); // получаем хэш пары по входящему и выходящему токену uint _index; uint _id = order_book[_hash_pair][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[_hash_pair][_id].prev; } return (result); } function getExecOrderBook(address _token1, address _token2) public view returns (uint [] memory) // Возвращаем выполненые ордера в данной торговой паре { uint256 _hash_pair = hash2Address(_token1, _token2, true); // _hash_pair - при получении хэша пары, токены были отсортированы uint _index_top = exec_order_book[_hash_pair][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[_hash_pair][_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[_hash_pair][_index_top] == 0) break; // обрываем цикл если исполнено менее 50 ордеров } } return (result); } function getAllOpenOrders(address _owner, uint _id, uint _amount) public view returns (uint [] memory) // Возвращаем указанное количество открытых ордеров пользователя, со сдедующего ордера от стартового ID { // если _id = 0, тогда открытые ордера формируются с самого последнего ордера _id = all_open_order[_owner][_id].prev; if(_id == 0) return (new uint[](1)); // если открытых ордеров еще не существует, либо если это первый ордер в списке, который уже был обработан, вернем [0] uint _index; uint[] memory result = new uint[](_amount * 9); // [id, время, цена, осталось_отдать, адрес_токена_IN, осталось_получить, адрес_токена_OUT, тип_ордера, статус...] for(uint i; i < _amount; i++){ if(_id == 0) break; result[_index++] = _id; result[_index++] = orders[_id].time; result[_index++] = orders[_id].price; result[_index++] = orders[_id].value_in; result[_index++] = uint256(uint160(orders[_id].token_in)); result[_index++] = orders[_id].value_out; result[_index++] = uint256(uint160(orders[_id].token_out)); result[_index++] = orders[_id].order_type; result[_index++] = orders[_id].order_status; _id = all_open_order[_owner][_id].prev; } return (result); } function getOpenOrders(address _token1, address _token2, address _owner, uint _id, uint _amount) public view returns (uint [] memory) // Возвращаем указанное количество открытых ордеров пользователя, со сдедующего ордера от стартового ID, в данной торговой паре { // если _id = 0, тогда открытые ордера формируются с самого последнего ордера uint256 _hash_pair_owner = hash3Address(_token1, _token2, _owner); // _hash_pair_owner - при получении хэша пары, токены были отсортированы _id = open_order[_hash_pair_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[_hash_pair_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, тогда закрытые ордера формируются с самого последнего ордера uint256 _hash_pair_owner = hash3Address(_token1, _token2, _owner); // _hash_pair_owner - при получении хэша пары, токены были отсортированы _id = close_order[_hash_pair_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].exec_in; result[_index++] = orders[_id].exec_out; _id = close_order[_hash_pair_owner][_id].prev; } 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":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"cancelOrders","inputs":[{"type":"uint256[]","name":"_id_arr","internalType":"uint256[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"contractDeposits","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"createOrder","inputs":[{"type":"address","name":"_owner","internalType":"address"},{"type":"address","name":"_token_in","internalType":"address"},{"type":"uint256","name":"_value_in","internalType":"uint256"},{"type":"address","name":"_token_out","internalType":"address"},{"type":"uint256","name":"_value_out","internalType":"uint256"},{"type":"uint8","name":"_order_type","internalType":"uint8"},{"type":"uint256","name":"_price","internalType":"uint256"},{"type":"uint256","name":"_order_position","internalType":"uint256"},{"type":"uint256","name":"_dex_fee","internalType":"uint256"},{"type":"uint256","name":"_dex_num_exec_ord","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"deleteCloseOrders","inputs":[{"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":"getAllOpenOrders","inputs":[{"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":"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":"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":"uint256","name":"","internalType":"uint256"}],"name":"id","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]}]
Contract Creation Code
0x608060405273ebe894814554c8382ea6a24ccddf1527407a24f6600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555034801561006557600080fd5b506144dc806100756000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c806375b024051161008c5780638da5cb5b116100665780638da5cb5b146102a95780639435298b146102c7578063af640d0f146102f7578063b55fb57414610315576100ea565b806375b02405146102195780637e9da7a214610249578063809741ed14610279576100ea565b8063299821f6116100c8578063299821f61461016d578063334503bf1461018957806347402bea146101b95780635eb2088e146101e9576100ea565b80630e0578f5146100ef578063127e11971461011f57806318df23881461013d575b600080fd5b610109600480360381019061010491906138fe565b610345565b6040516101169190613a8d565b60405180910390f35b6101276104f5565b6040516101349190613ab8565b60405180910390f35b61015760048036038101906101529190613aff565b61050d565b6040516101649190613c15565b60405180910390f35b61018760048036038101906101829190613c9c565b6106b8565b005b6101a3600480360381019061019e9190613ce9565b6108ba565b6040516101b09190613c15565b60405180910390f35b6101d360048036038101906101ce9190613d90565b610b91565b6040516101e09190613e7e565b60405180910390f35b61020360048036038101906101fe9190613e99565b61187b565b6040516102109190613c15565b60405180910390f35b610233600480360381019061022e919061403b565b611cd9565b6040516102409190613c15565b60405180910390f35b610263600480360381019061025e9190613ce9565b611ee4565b6040516102709190613c15565b60405180910390f35b610293600480360381019061028e9190614084565b6121bb565b6040516102a09190613c15565b60405180910390f35b6102b16124cc565b6040516102be9190613ab8565b60405180910390f35b6102e160048036038101906102dc91906140c4565b6124f2565b6040516102ee9190613c15565b60405180910390f35b6102ff6126b0565b60405161030c9190613e7e565b60405180910390f35b61032f600480360381019061032a919061403b565b6126b6565b60405161033c9190613c15565b60405180910390f35b61034d61379b565b6006600083815260200190815260200160002060405180610180016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016008820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016009820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016009820160149054906101000a900460ff1660ff1660ff1681526020016009820160159054906101000a900460ff1660ff1660ff16815250509050919050565b7345c881b36fc357d80a715da36d79b845303796c181565b6060600061051d868660006129c8565b90506000600160008381526020019081526020016000206000868152602001908152602001600020600001541161057b576001600082815260200190815260200160002060008081526020019081526020016000206002015461057d565b835b935060008060028561058f9190614146565b67ffffffffffffffff8111156105a8576105a7613efd565b5b6040519080825280602002602001820160405280156105d65781602001602082028036833780820191505090505b50905060005b858110156106a95760008703156106a957868284806105fa906141a0565b95508151811061060d5761060c6141e8565b5b6020026020010181815250506001600085815260200190815260200160002060008881526020019081526020016000206000015482848061064d906141a0565b9550815181106106605761065f6141e8565b5b60200260200101818152505060016000858152602001908152602001600020600088815260200190815260200160002060020154965080806106a1906141a0565b9150506105dc565b50809350505050949350505050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610748576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073f90614274565b60405180910390fd5b60005b828290508110156108b55760086006600085858581811061076f5761076e6141e8565b5b90506020020135815260200190815260200160002060090160159054906101000a900460ff1660ff16036108a257600660008484848181106107b4576107b36141e8565b5b9050602002013581526020019081526020016000206000808201600090556001820160009055600282016000905560038201600090556004820160009055600582016000905560068201600090556007820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556008820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556009820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556009820160146101000a81549060ff02191690556009820160156101000a81549060ff021916905550505b80806108ad906141a0565b91505061074b565b505050565b606060006108c9878787612a4b565b90506003600082815260200190815260200160002060008581526020019081526020016000206001015493506000840361094f57600167ffffffffffffffff81111561091857610917613efd565b5b6040519080825280602002602001820160405280156109465781602001602082028036833780820191505090505b50915050610b88565b60008060068561095f9190614146565b67ffffffffffffffff81111561097857610977613efd565b5b6040519080825280602002602001820160405280156109a65781602001602082028036833780820191505090505b50905060005b85811015610b80576000870315610b8057868284806109ca906141a0565b9550815181106109dd576109dc6141e8565b5b6020026020010181815250506006600088815260200190815260200160002060090160149054906101000a900460ff1660ff16828480610a1c906141a0565b955081518110610a2f57610a2e6141e8565b5b6020026020010181815250506006600088815260200190815260200160002060000154828480610a5e906141a0565b955081518110610a7157610a706141e8565b5b6020026020010181815250506006600088815260200190815260200160002060030154828480610aa0906141a0565b955081518110610ab357610ab26141e8565b5b6020026020010181815250506006600088815260200190815260200160002060020154828480610ae2906141a0565b955081518110610af557610af46141e8565b5b6020026020010181815250506006600088815260200190815260200160002060040154828480610b24906141a0565b955081518110610b3757610b366141e8565b5b6020026020010181815250506003600085815260200190815260200160002060008881526020019081526020016000206001015496508080610b78906141a0565b9150506109ac565b508093505050505b95945050505050565b60007345c881b36fc357d80a715da36d79b845303796c173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610bdf57600080fd5b610be761379b565b4281600001818152505089816040018181525050878160800181815250508681610140019060ff16908160ff1681525050858160600181815250508a8160e0019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508881610100019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508b81610120019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600181610160019060ff16908160ff16815250506000808154610cee906141a0565b919050819055506000805490506000610d14610d0c8e8d60006129c8565b888a8c612a92565b8092508198505050801561165457610d2a613844565b610d368c8f60006129c8565b81600001818152505060016000826000015181526020019081526020016000206000808152602001908152602001600020600201548160200181815250505b60008160200151111561148e5760016000826000015181526020019081526020016000206000826020015181526020019081526020016000206000015481604001818152505060018a60ff1603610dd6578060400151891161148e57610de2565b8060400151891061148e575b60008603610e8f57600984610160019060ff16908160ff16815250507345c881b36fc357d80a715da36d79b845303796c173ffffffffffffffffffffffffffffffffffffffff1663d9caed128f86610120015187604001516040518463ffffffff1660e01b8152600401610e5893929190614294565b600060405180830381600087803b158015610e7257600080fd5b505af1158015610e86573d6000803e3d6000fd5b5050505061148e565b85610e99906142cb565b95506006600082602001518152602001908152602001600020600401548160600181815250508060600151846040015110610ed8578060600151610ede565b83604001515b8160800181815250508360400151846080015182608001518660400151610f0591906142f4565b610f0f9190614146565b610f199190614357565b8460800181815250506000846080015114610f38578060800151610f3e565b83604001515b8160a00181815250508060a0015184604001818151610f5d91906142f4565b915081815250508060a001518460a001818151610f7a9190614388565b9150818152505068056bc75e2d63100000878260a00151610f9b9190614146565b610fa59190614357565b8160c00181815250508060c001518161010001818151610fc59190614388565b91508181525050600660008260200151815260200190815260200160002060090160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681610140019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250507345c881b36fc357d80a715da36d79b845303796c173ffffffffffffffffffffffffffffffffffffffff1663d9caed128f8361014001518460c001518560a0015161108a91906142f4565b6040518463ffffffff1660e01b81526004016110a893929190614294565b600060405180830381600087803b1580156110c257600080fd5b505af11580156110d6573d6000803e3d6000fd5b505050508060c001518160a001516110ee91906142f4565b600660008360200151815260200190815260200160002060060160008282546111179190614388565b925050819055508060c001516006600083602001518152602001908152602001600020600101600082825461114c9190614388565b92505081905550806060015160066000836020015181526020019081526020016000206002015482608001516111829190614146565b61118c9190614357565b8160a001818152505068056bc75e2d63100000878260a001516111af9190614146565b6111b99190614357565b8160c00181815250508060a00151600660008360200151815260200190815260200160002060020160008282546111f091906142f4565b925050819055508060800151816060015161120b91906142f4565b6006600083602001518152602001908152602001600020600401819055508060a00151600660008360200151815260200190815260200160002060050160008282546112579190614388565b925050819055508060c0015181610120018181516112759190614388565b915081815250508060c001518160a0015161129091906142f4565b8160e0018181516112a19190614388565b915081815250508060c001518160a001516112bc91906142f4565b8460c0018181516112cd9190614388565b915081815250508060c00151846020018181516112ea9190614388565b915081815250504260066000836020015181526020019081526020016000206000018190555080602001517f271adf7ca5026da9466c7e2ee50294432b6518106821bb0baa27adfbe5203bad60405160405180910390a260006006600083602001518152602001908152602001600020600201540361141c576007600660008360200151815260200190815260200160002060090160156101000a81548160ff021916908360ff1602179055506113a981600001518260200151612e71565b6113be8c8f8361014001518460200151612f66565b6113d38c8f8361014001518460200151613224565b6113e28c8f83602001516132eb565b6001600082600001518152602001908152602001600020600080815260200190815260200160002060020154816020018181525050611450565b60068060008360200151815260200190815260200160002060090160156101000a81548160ff021916908360ff1602179055505b600084604001510361147557600784610160019060ff16908160ff168152505061148e565b600684610160019060ff16908160ff1681525050610d75565b60008160e001511115611528577345c881b36fc357d80a715da36d79b845303796c173ffffffffffffffffffffffffffffffffffffffff1663d9caed128d8661012001518460e001516040518463ffffffff1660e01b81526004016114f593929190614294565b600060405180830381600087803b15801561150f57600080fd5b505af1158015611523573d6000803e3d6000fd5b505050505b600081610100015111156115bd577345c881b36fc357d80a715da36d79b845303796c173ffffffffffffffffffffffffffffffffffffffff1663fd9be5228f8361010001516040518363ffffffff1660e01b815260040161158a9291906143bc565b600060405180830381600087803b1580156115a457600080fd5b505af11580156115b8573d6000803e3d6000fd5b505050505b60008161012001511115611652577345c881b36fc357d80a715da36d79b845303796c173ffffffffffffffffffffffffffffffffffffffff1663fd9be5228d8361012001516040518363ffffffff1660e01b815260040161161f9291906143bc565b600060405180830381600087803b15801561163957600080fd5b505af115801561164d573d6000803e3d6000fd5b505050505b505b8260066000848152602001908152602001600020600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e08201518160070160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101008201518160080160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101208201518160090160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101408201518160090160146101000a81548160ff021916908360ff1602179055506101608201518160090160156101000a81548160ff021916908360ff160217905550905050600183610160015160ff1614806117eb5750600683610160015160ff16145b1561181d576118076117ff8e8d60006129c8565b88848b61339e565b6118188d8c85610120015185613489565b61183a565b61182e8d8c85610120015185613224565b6118398d8c846132eb565b5b817f2f539bcf68b0eef24f9fef1ae5ad7dd5a37f80a2fab34f406ad2b92c779d606460405160405180910390a28193505050509a9950505050505050505050565b6060600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008481526020019081526020016000206001015492506000830361192c57600167ffffffffffffffff8111156118f6576118f5613efd565b5b6040519080825280602002602001820160405280156119245781602001602082028036833780820191505090505b509050611cd2565b60008060098461193c9190614146565b67ffffffffffffffff81111561195557611954613efd565b5b6040519080825280602002602001820160405280156119835781602001602082028036833780820191505090505b50905060005b84811015611ccb576000860315611ccb57858284806119a7906141a0565b9550815181106119ba576119b96141e8565b5b60200260200101818152505060066000878152602001908152602001600020600001548284806119e9906141a0565b9550815181106119fc576119fb6141e8565b5b6020026020010181815250506006600087815260200190815260200160002060030154828480611a2b906141a0565b955081518110611a3e57611a3d6141e8565b5b6020026020010181815250506006600087815260200190815260200160002060020154828480611a6d906141a0565b955081518110611a8057611a7f6141e8565b5b6020026020010181815250506006600087815260200190815260200160002060070160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16828480611ae5906141a0565b955081518110611af857611af76141e8565b5b6020026020010181815250506006600087815260200190815260200160002060040154828480611b27906141a0565b955081518110611b3a57611b396141e8565b5b6020026020010181815250506006600087815260200190815260200160002060080160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16828480611b9f906141a0565b955081518110611bb257611bb16141e8565b5b6020026020010181815250506006600087815260200190815260200160002060090160149054906101000a900460ff1660ff16828480611bf1906141a0565b955081518110611c0457611c036141e8565b5b6020026020010181815250506006600087815260200190815260200160002060090160159054906101000a900460ff1660ff16828480611c43906141a0565b955081518110611c5657611c556141e8565b5b602002602001018181525050600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008781526020019081526020016000206001015495508080611cc3906141a0565b915050611989565b5080925050505b9392505050565b606060008060005b8451811015611ed957848181518110611cfd57611cfc6141e8565b5b602002602001015191506006600083815260200190815260200160002060090160159054906101000a900460ff1692503373ffffffffffffffffffffffffffffffffffffffff166006600084815260200190815260200160002060090160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16148015611dbd575060048360ff161480611dae575060078360ff16145b80611dbc575060098360ff16145b5b15611ea457611e42611e3c6006600085815260200190815260200160002060070160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166006600086815260200190815260200160002060080160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1633612a4b565b836136ae565b60086006600084815260200190815260200160002060090160156101000a81548160ff021916908360ff160217905550817fbd000546857b596b03c884060c13e7d8c7a7ce52366d2f116f76688e6f000f6660405160405180910390a2611ec6565b6000858281518110611eb957611eb86141e8565b5b6020026020010181815250505b8080611ed1906141a0565b915050611ce1565b508392505050919050565b60606000611ef3878787612a4b565b905060046000828152602001908152602001600020600085815260200190815260200160002060010154935060008403611f7957600167ffffffffffffffff811115611f4257611f41613efd565b5b604051908082528060200260200182016040528015611f705781602001602082028036833780820191505090505b509150506121b2565b600080600685611f899190614146565b67ffffffffffffffff811115611fa257611fa1613efd565b5b604051908082528060200260200182016040528015611fd05781602001602082028036833780820191505090505b50905060005b858110156121aa5760008703156121aa5786828480611ff4906141a0565b955081518110612007576120066141e8565b5b6020026020010181815250506006600088815260200190815260200160002060090160149054906101000a900460ff1660ff16828480612046906141a0565b955081518110612059576120586141e8565b5b6020026020010181815250506006600088815260200190815260200160002060000154828480612088906141a0565b95508151811061209b5761209a6141e8565b5b60200260200101818152505060066000888152602001908152602001600020600301548284806120ca906141a0565b9550815181106120dd576120dc6141e8565b5b602002602001018181525050600660008881526020019081526020016000206005015482848061210c906141a0565b95508151811061211f5761211e6141e8565b5b602002602001018181525050600660008881526020019081526020016000206006015482848061214e906141a0565b955081518110612161576121606141e8565b5b60200260200101818152505060046000858152602001908152602001600020600088815260200190815260200160002060010154965080806121a2906141a0565b915050611fd6565b508093505050505b95945050505050565b606060006121cb848460016129c8565b90506000600560008381526020019081526020016000206000603381106121f5576121f46141e8565b5b015490506000810361225457600167ffffffffffffffff81111561221c5761221b613efd565b5b60405190808252806020026020018201604052801561224a5781602001602082028036833780820191505090505b50925050506124c6565b600080600061012c67ffffffffffffffff81111561227557612274613efd565b5b6040519080825280602002602001820160405280156122a35781602001602082028036833780820191505090505b50905060005b60328110156124bc576005600087815260200190815260200160002085603381106122d7576122d66141e8565b5b01549250828285806122e8906141a0565b9650815181106122fb576122fa6141e8565b5b6020026020010181815250506006600084815260200190815260200160002060090160149054906101000a900460ff1660ff1682858061233a906141a0565b96508151811061234d5761234c6141e8565b5b602002602001018181525050600660008481526020019081526020016000206000015482858061237c906141a0565b96508151811061238f5761238e6141e8565b5b60200260200101818152505060066000848152602001908152602001600020600301548285806123be906141a0565b9650815181106123d1576123d06141e8565b5b6020026020010181815250506006600084815260200190815260200160002060050154828580612400906141a0565b965081518110612413576124126141e8565b5b6020026020010181815250506006600084815260200190815260200160002060060154828580612442906141a0565b965081518110612455576124546141e8565b5b60200260200101818152505060008561246d906142cb565b955085036124a9576032945060006005600088815260200190815260200160002086603381106124a05761249f6141e8565b5b015403156124bc575b80806124b4906141a0565b9150506122a9565b5080955050505050505b92915050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60606000612502858560006129c8565b905060008060016000848152602001908152602001600020600080815260200190815260200160002060020154905060006003866125409190614146565b67ffffffffffffffff81111561255957612558613efd565b5b6040519080825280602002602001820160405280156125875781602001602082028036833780820191505090505b50905060005b868110156126a15760008303156126a15760066000848152602001908152602001600020600301548285806125c1906141a0565b9650815181106125d4576125d36141e8565b5b6020026020010181815250506006600084815260200190815260200160002060020154828580612603906141a0565b965081518110612616576126156141e8565b5b6020026020010181815250506006600084815260200190815260200160002060040154828580612645906141a0565b965081518110612658576126576141e8565b5b6020026020010181815250506001600086815260200190815260200160002060008481526020019081526020016000206002015492508080612699906141a0565b91505061258d565b50809450505050509392505050565b60005481565b60606000806000806000805b87518110156129ba578781815181106126de576126dd6141e8565b5b602002602001015194506006600086815260200190815260200160002060090160159054906101000a900460ff1695503373ffffffffffffffffffffffffffffffffffffffff166006600087815260200190815260200160002060090160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16148015612790575060018660ff16148061278f575060068660ff16145b5b1561298557600660008681526020019081526020016000206002015493506006600086815260200190815260200160002060070160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1692506006600086815260200190815260200160002060080160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691507345c881b36fc357d80a715da36d79b845303796c173ffffffffffffffffffffffffffffffffffffffff1663d9caed128433876040518463ffffffff1660e01b815260040161287193929190614294565b600060405180830381600087803b15801561288b57600080fd5b505af115801561289f573d6000803e3d6000fd5b50505050426006600087815260200190815260200160002060000181905550600060066000878152602001908152602001600020600201819055506000600660008781526020019081526020016000206004018190555060046006600087815260200190815260200160002060090160156101000a81548160ff021916908360ff16021790555061293b612935848460006129c8565b86612e71565b61294783833388612f66565b61295383833388613224565b847f935c9ad2f1fda9d7eae0d2a512f1521cb7190ee06165414e722366a65975fb6b60405160405180910390a26129a7565b600088828151811061299a576129996141e8565b5b6020026020010181815250505b80806129b2906141a0565b9150506126c2565b508695505050505050919050565b60008115612a16578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610612a0a578284612a0d565b83835b80945081955050505b8383604051602001612a2992919061442d565b6040516020818303038152906040528051906020012060001c90509392505050565b600080612a5a858560016129c8565b90508083604051602001612a6f92919061447a565b6040516020818303038152906040528051906020012060001c9150509392505050565b6000806000806000600160008a815260200190815260200160002060008981526020019081526020016000206000015411612af45760016000898152602001908152602001600020600080815260200190815260200160002060020154612af6565b865b965060016000898152602001908152602001600020600088815260200190815260200160002060000154915060008203612b395760006001935093505050612e68565b60018560ff1603612cd85781861015612c26576001600089815260200190815260200160002060008881526020019081526020016000206001015490505b81861015612bf15760008103612b9557866001935093505050612e68565b809650600160008981526020019081526020016000206000888152602001908152602001600020600001549150600160008981526020019081526020016000206000888152602001908152602001600020600101549050612b77565b600160008981526020019081526020016000206000888152602001908152602001600020600201546000935093505050612e68565b6001600089815260200190815260200160002060008881526020019081526020016000206002015490505b818610612cca5760008103612c6e57600080935093505050612e68565b809650600160008981526020019081526020016000206000888152602001908152602001600020600001549150600160008981526020019081526020016000206000888152602001908152602001600020600201549050612c51565b866000935093505050612e68565b81861115612dba576001600089815260200190815260200160002060008881526020019081526020016000206001015490505b81861115612d855760008103612d2957866001935093505050612e68565b809650600160008981526020019081526020016000206000888152602001908152602001600020600001549150600160008981526020019081526020016000206000888152602001908152602001600020600101549050612d0b565b600160008981526020019081526020016000206000888152602001908152602001600020600201546000935093505050612e68565b6001600089815260200190815260200160002060008881526020019081526020016000206002015490505b818611612e5e5760008103612e0257600080935093505050612e68565b809650600160008981526020019081526020016000206000888152602001908152602001600020600001549150600160008981526020019081526020016000206000888152602001908152602001600020600201549050612de5565b8660009350935050505b94509492505050565b600060016000848152602001908152602001600020600083815260200190815260200160002060010154905060006001600085815260200190815260200160002060008481526020019081526020016000206002015490508160016000868152602001908152602001600020600083815260200190815260200160002060010181905550806001600086815260200190815260200160002060008481526020019081526020016000206002018190555060016000858152602001908152602001600020600084815260200190815260200160002060008082016000905560018201600090556002820160009055505050505050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000015490506000600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060010154905081600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000018190555080600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060010181905550600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000848152602001908152602001600020600080820160009055600182016000905550506000613136878787612a4b565b9050600360008281526020019081526020016000206000858152602001908152602001600020600001549250600360008281526020019081526020016000206000858152602001908152602001600020600101549150826003600083815260200190815260200160002060008481526020019081526020016000206000018190555081600360008381526020019081526020016000206000858152602001908152602001600020600101819055506003600082815260200190815260200160002060008581526020019081526020016000206000808201600090556001820160009055505050505050505050565b6000613231858585612a4b565b90506000600460008381526020019081526020016000206000808152602001908152602001600020600101549050826004600084815260200190815260200160002060008381526020019081526020016000206000018190555082600460008481526020019081526020016000206000808152602001908152602001600020600101819055508060046000848152602001908152602001600020600085815260200190815260200160002060010181905550505050505050565b60006132f9848460016129c8565b9050600060056000838152602001908152602001600020600060338110613323576133226141e8565b5b015490506032810361333457600090505b8061333e906141a0565b905082600560008481526020019081526020016000208260338110613366576133656141e8565b5b01819055508060056000848152602001908152602001600020600060338110613392576133916141e8565b5b01819055505050505050565b6000600160008681526020019081526020016000206000858152602001908152602001600020600101549050826001600087815260200190815260200160002060008681526020019081526020016000206001018190555082600160008781526020019081526020016000206000838152602001908152602001600020600201819055506040518060600160405280838152602001828152602001858152506001600087815260200190815260200160002060008581526020019081526020016000206000820151816000015560208201518160010155604082015181600201559050505050505050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600080815260200190815260200160002060010154905081600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000018190555081600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008081526020019081526020016000206001018190555080600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008481526020019081526020016000206001018190555060006135f6868686612a4b565b9050600360008281526020019081526020016000206000808152602001908152602001600020600101549150826003600083815260200190815260200160002060008481526020019081526020016000206000018190555082600360008381526020019081526020016000206000808152602001908152602001600020600101819055508160036000838152602001908152602001600020600085815260200190815260200160002060010181905550505050505050565b60006004600084815260200190815260200160002060008381526020019081526020016000206000015490506000600460008581526020019081526020016000206000848152602001908152602001600020600101549050816004600086815260200190815260200160002060008381526020019081526020016000206000018190555080600460008681526020019081526020016000206000848152602001908152602001600020600101819055506004600085815260200190815260200160002060008481526020019081526020016000206000808201600090556001820160009055505050505050565b60405180610180016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600060ff168152602001600060ff1681525090565b60405180610160016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b6138db816138c8565b81146138e657600080fd5b50565b6000813590506138f8816138d2565b92915050565b600060208284031215613914576139136138be565b5b6000613922848285016138e9565b91505092915050565b613934816138c8565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006139658261393a565b9050919050565b6139758161395a565b82525050565b600060ff82169050919050565b6139918161397b565b82525050565b610180820160008201516139ae600085018261392b565b5060208201516139c1602085018261392b565b5060408201516139d4604085018261392b565b5060608201516139e7606085018261392b565b5060808201516139fa608085018261392b565b5060a0820151613a0d60a085018261392b565b5060c0820151613a2060c085018261392b565b5060e0820151613a3360e085018261396c565b50610100820151613a4861010085018261396c565b50610120820151613a5d61012085018261396c565b50610140820151613a72610140850182613988565b50610160820151613a87610160850182613988565b50505050565b600061018082019050613aa36000830184613997565b92915050565b613ab28161395a565b82525050565b6000602082019050613acd6000830184613aa9565b92915050565b613adc8161395a565b8114613ae757600080fd5b50565b600081359050613af981613ad3565b92915050565b60008060008060808587031215613b1957613b186138be565b5b6000613b2787828801613aea565b9450506020613b3887828801613aea565b9350506040613b49878288016138e9565b9250506060613b5a878288016138e9565b91505092959194509250565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000613b9e838361392b565b60208301905092915050565b6000602082019050919050565b6000613bc282613b66565b613bcc8185613b71565b9350613bd783613b82565b8060005b83811015613c08578151613bef8882613b92565b9750613bfa83613baa565b925050600181019050613bdb565b5085935050505092915050565b60006020820190508181036000830152613c2f8184613bb7565b905092915050565b600080fd5b600080fd5b600080fd5b60008083601f840112613c5c57613c5b613c37565b5b8235905067ffffffffffffffff811115613c7957613c78613c3c565b5b602083019150836020820283011115613c9557613c94613c41565b5b9250929050565b60008060208385031215613cb357613cb26138be565b5b600083013567ffffffffffffffff811115613cd157613cd06138c3565b5b613cdd85828601613c46565b92509250509250929050565b600080600080600060a08688031215613d0557613d046138be565b5b6000613d1388828901613aea565b9550506020613d2488828901613aea565b9450506040613d3588828901613aea565b9350506060613d46888289016138e9565b9250506080613d57888289016138e9565b9150509295509295909350565b613d6d8161397b565b8114613d7857600080fd5b50565b600081359050613d8a81613d64565b92915050565b6000806000806000806000806000806101408b8d031215613db457613db36138be565b5b6000613dc28d828e01613aea565b9a50506020613dd38d828e01613aea565b9950506040613de48d828e016138e9565b9850506060613df58d828e01613aea565b9750506080613e068d828e016138e9565b96505060a0613e178d828e01613d7b565b95505060c0613e288d828e016138e9565b94505060e0613e398d828e016138e9565b935050610100613e4b8d828e016138e9565b925050610120613e5d8d828e016138e9565b9150509295989b9194979a5092959850565b613e78816138c8565b82525050565b6000602082019050613e936000830184613e6f565b92915050565b600080600060608486031215613eb257613eb16138be565b5b6000613ec086828701613aea565b9350506020613ed1868287016138e9565b9250506040613ee2868287016138e9565b9150509250925092565b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613f3582613eec565b810181811067ffffffffffffffff82111715613f5457613f53613efd565b5b80604052505050565b6000613f676138b4565b9050613f738282613f2c565b919050565b600067ffffffffffffffff821115613f9357613f92613efd565b5b602082029050602081019050919050565b6000613fb7613fb284613f78565b613f5d565b90508083825260208201905060208402830185811115613fda57613fd9613c41565b5b835b818110156140035780613fef88826138e9565b845260208401935050602081019050613fdc565b5050509392505050565b600082601f83011261402257614021613c37565b5b8135614032848260208601613fa4565b91505092915050565b600060208284031215614051576140506138be565b5b600082013567ffffffffffffffff81111561406f5761406e6138c3565b5b61407b8482850161400d565b91505092915050565b6000806040838503121561409b5761409a6138be565b5b60006140a985828601613aea565b92505060206140ba85828601613aea565b9150509250929050565b6000806000606084860312156140dd576140dc6138be565b5b60006140eb86828701613aea565b93505060206140fc86828701613aea565b925050604061410d868287016138e9565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614151826138c8565b915061415c836138c8565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561419557614194614117565b5b828202905092915050565b60006141ab826138c8565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036141dd576141dc614117565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082825260208201905092915050565b7f4f6e6c79206f776e65722063616e2063616c6c20746869732e00000000000000600082015250565b600061425e601983614217565b915061426982614228565b602082019050919050565b6000602082019050818103600083015261428d81614251565b9050919050565b60006060820190506142a96000830186613aa9565b6142b66020830185613aa9565b6142c36040830184613e6f565b949350505050565b60006142d6826138c8565b9150600082036142e9576142e8614117565b5b600182039050919050565b60006142ff826138c8565b915061430a836138c8565b925082820390508181111561432257614321614117565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614362826138c8565b915061436d836138c8565b92508261437d5761437c614328565b5b828204905092915050565b6000614393826138c8565b915061439e836138c8565b92508282019050808211156143b6576143b5614117565b5b92915050565b60006040820190506143d16000830185613aa9565b6143de6020830184613e6f565b9392505050565b60008160601b9050919050565b60006143fd826143e5565b9050919050565b600061440f826143f2565b9050919050565b6144276144228261395a565b614404565b82525050565b60006144398285614416565b6014820191506144498284614416565b6014820191508190509392505050565b6000819050919050565b61447461446f826138c8565b614459565b82525050565b60006144868285614463565b6020820191506144968284614416565b601482019150819050939250505056fea2646970667358221220ee3e7c09638282ee602ed582ad36395384b19887eb2d75d72cbab9a67ee1496664736f6c63430008100033
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c806375b024051161008c5780638da5cb5b116100665780638da5cb5b146102a95780639435298b146102c7578063af640d0f146102f7578063b55fb57414610315576100ea565b806375b02405146102195780637e9da7a214610249578063809741ed14610279576100ea565b8063299821f6116100c8578063299821f61461016d578063334503bf1461018957806347402bea146101b95780635eb2088e146101e9576100ea565b80630e0578f5146100ef578063127e11971461011f57806318df23881461013d575b600080fd5b610109600480360381019061010491906138fe565b610345565b6040516101169190613a8d565b60405180910390f35b6101276104f5565b6040516101349190613ab8565b60405180910390f35b61015760048036038101906101529190613aff565b61050d565b6040516101649190613c15565b60405180910390f35b61018760048036038101906101829190613c9c565b6106b8565b005b6101a3600480360381019061019e9190613ce9565b6108ba565b6040516101b09190613c15565b60405180910390f35b6101d360048036038101906101ce9190613d90565b610b91565b6040516101e09190613e7e565b60405180910390f35b61020360048036038101906101fe9190613e99565b61187b565b6040516102109190613c15565b60405180910390f35b610233600480360381019061022e919061403b565b611cd9565b6040516102409190613c15565b60405180910390f35b610263600480360381019061025e9190613ce9565b611ee4565b6040516102709190613c15565b60405180910390f35b610293600480360381019061028e9190614084565b6121bb565b6040516102a09190613c15565b60405180910390f35b6102b16124cc565b6040516102be9190613ab8565b60405180910390f35b6102e160048036038101906102dc91906140c4565b6124f2565b6040516102ee9190613c15565b60405180910390f35b6102ff6126b0565b60405161030c9190613e7e565b60405180910390f35b61032f600480360381019061032a919061403b565b6126b6565b60405161033c9190613c15565b60405180910390f35b61034d61379b565b6006600083815260200190815260200160002060405180610180016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016008820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016009820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016009820160149054906101000a900460ff1660ff1660ff1681526020016009820160159054906101000a900460ff1660ff1660ff16815250509050919050565b7345c881b36fc357d80a715da36d79b845303796c181565b6060600061051d868660006129c8565b90506000600160008381526020019081526020016000206000868152602001908152602001600020600001541161057b576001600082815260200190815260200160002060008081526020019081526020016000206002015461057d565b835b935060008060028561058f9190614146565b67ffffffffffffffff8111156105a8576105a7613efd565b5b6040519080825280602002602001820160405280156105d65781602001602082028036833780820191505090505b50905060005b858110156106a95760008703156106a957868284806105fa906141a0565b95508151811061060d5761060c6141e8565b5b6020026020010181815250506001600085815260200190815260200160002060008881526020019081526020016000206000015482848061064d906141a0565b9550815181106106605761065f6141e8565b5b60200260200101818152505060016000858152602001908152602001600020600088815260200190815260200160002060020154965080806106a1906141a0565b9150506105dc565b50809350505050949350505050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610748576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073f90614274565b60405180910390fd5b60005b828290508110156108b55760086006600085858581811061076f5761076e6141e8565b5b90506020020135815260200190815260200160002060090160159054906101000a900460ff1660ff16036108a257600660008484848181106107b4576107b36141e8565b5b9050602002013581526020019081526020016000206000808201600090556001820160009055600282016000905560038201600090556004820160009055600582016000905560068201600090556007820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556008820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556009820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556009820160146101000a81549060ff02191690556009820160156101000a81549060ff021916905550505b80806108ad906141a0565b91505061074b565b505050565b606060006108c9878787612a4b565b90506003600082815260200190815260200160002060008581526020019081526020016000206001015493506000840361094f57600167ffffffffffffffff81111561091857610917613efd565b5b6040519080825280602002602001820160405280156109465781602001602082028036833780820191505090505b50915050610b88565b60008060068561095f9190614146565b67ffffffffffffffff81111561097857610977613efd565b5b6040519080825280602002602001820160405280156109a65781602001602082028036833780820191505090505b50905060005b85811015610b80576000870315610b8057868284806109ca906141a0565b9550815181106109dd576109dc6141e8565b5b6020026020010181815250506006600088815260200190815260200160002060090160149054906101000a900460ff1660ff16828480610a1c906141a0565b955081518110610a2f57610a2e6141e8565b5b6020026020010181815250506006600088815260200190815260200160002060000154828480610a5e906141a0565b955081518110610a7157610a706141e8565b5b6020026020010181815250506006600088815260200190815260200160002060030154828480610aa0906141a0565b955081518110610ab357610ab26141e8565b5b6020026020010181815250506006600088815260200190815260200160002060020154828480610ae2906141a0565b955081518110610af557610af46141e8565b5b6020026020010181815250506006600088815260200190815260200160002060040154828480610b24906141a0565b955081518110610b3757610b366141e8565b5b6020026020010181815250506003600085815260200190815260200160002060008881526020019081526020016000206001015496508080610b78906141a0565b9150506109ac565b508093505050505b95945050505050565b60007345c881b36fc357d80a715da36d79b845303796c173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610bdf57600080fd5b610be761379b565b4281600001818152505089816040018181525050878160800181815250508681610140019060ff16908160ff1681525050858160600181815250508a8160e0019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508881610100019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508b81610120019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600181610160019060ff16908160ff16815250506000808154610cee906141a0565b919050819055506000805490506000610d14610d0c8e8d60006129c8565b888a8c612a92565b8092508198505050801561165457610d2a613844565b610d368c8f60006129c8565b81600001818152505060016000826000015181526020019081526020016000206000808152602001908152602001600020600201548160200181815250505b60008160200151111561148e5760016000826000015181526020019081526020016000206000826020015181526020019081526020016000206000015481604001818152505060018a60ff1603610dd6578060400151891161148e57610de2565b8060400151891061148e575b60008603610e8f57600984610160019060ff16908160ff16815250507345c881b36fc357d80a715da36d79b845303796c173ffffffffffffffffffffffffffffffffffffffff1663d9caed128f86610120015187604001516040518463ffffffff1660e01b8152600401610e5893929190614294565b600060405180830381600087803b158015610e7257600080fd5b505af1158015610e86573d6000803e3d6000fd5b5050505061148e565b85610e99906142cb565b95506006600082602001518152602001908152602001600020600401548160600181815250508060600151846040015110610ed8578060600151610ede565b83604001515b8160800181815250508360400151846080015182608001518660400151610f0591906142f4565b610f0f9190614146565b610f199190614357565b8460800181815250506000846080015114610f38578060800151610f3e565b83604001515b8160a00181815250508060a0015184604001818151610f5d91906142f4565b915081815250508060a001518460a001818151610f7a9190614388565b9150818152505068056bc75e2d63100000878260a00151610f9b9190614146565b610fa59190614357565b8160c00181815250508060c001518161010001818151610fc59190614388565b91508181525050600660008260200151815260200190815260200160002060090160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681610140019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250507345c881b36fc357d80a715da36d79b845303796c173ffffffffffffffffffffffffffffffffffffffff1663d9caed128f8361014001518460c001518560a0015161108a91906142f4565b6040518463ffffffff1660e01b81526004016110a893929190614294565b600060405180830381600087803b1580156110c257600080fd5b505af11580156110d6573d6000803e3d6000fd5b505050508060c001518160a001516110ee91906142f4565b600660008360200151815260200190815260200160002060060160008282546111179190614388565b925050819055508060c001516006600083602001518152602001908152602001600020600101600082825461114c9190614388565b92505081905550806060015160066000836020015181526020019081526020016000206002015482608001516111829190614146565b61118c9190614357565b8160a001818152505068056bc75e2d63100000878260a001516111af9190614146565b6111b99190614357565b8160c00181815250508060a00151600660008360200151815260200190815260200160002060020160008282546111f091906142f4565b925050819055508060800151816060015161120b91906142f4565b6006600083602001518152602001908152602001600020600401819055508060a00151600660008360200151815260200190815260200160002060050160008282546112579190614388565b925050819055508060c0015181610120018181516112759190614388565b915081815250508060c001518160a0015161129091906142f4565b8160e0018181516112a19190614388565b915081815250508060c001518160a001516112bc91906142f4565b8460c0018181516112cd9190614388565b915081815250508060c00151846020018181516112ea9190614388565b915081815250504260066000836020015181526020019081526020016000206000018190555080602001517f271adf7ca5026da9466c7e2ee50294432b6518106821bb0baa27adfbe5203bad60405160405180910390a260006006600083602001518152602001908152602001600020600201540361141c576007600660008360200151815260200190815260200160002060090160156101000a81548160ff021916908360ff1602179055506113a981600001518260200151612e71565b6113be8c8f8361014001518460200151612f66565b6113d38c8f8361014001518460200151613224565b6113e28c8f83602001516132eb565b6001600082600001518152602001908152602001600020600080815260200190815260200160002060020154816020018181525050611450565b60068060008360200151815260200190815260200160002060090160156101000a81548160ff021916908360ff1602179055505b600084604001510361147557600784610160019060ff16908160ff168152505061148e565b600684610160019060ff16908160ff1681525050610d75565b60008160e001511115611528577345c881b36fc357d80a715da36d79b845303796c173ffffffffffffffffffffffffffffffffffffffff1663d9caed128d8661012001518460e001516040518463ffffffff1660e01b81526004016114f593929190614294565b600060405180830381600087803b15801561150f57600080fd5b505af1158015611523573d6000803e3d6000fd5b505050505b600081610100015111156115bd577345c881b36fc357d80a715da36d79b845303796c173ffffffffffffffffffffffffffffffffffffffff1663fd9be5228f8361010001516040518363ffffffff1660e01b815260040161158a9291906143bc565b600060405180830381600087803b1580156115a457600080fd5b505af11580156115b8573d6000803e3d6000fd5b505050505b60008161012001511115611652577345c881b36fc357d80a715da36d79b845303796c173ffffffffffffffffffffffffffffffffffffffff1663fd9be5228d8361012001516040518363ffffffff1660e01b815260040161161f9291906143bc565b600060405180830381600087803b15801561163957600080fd5b505af115801561164d573d6000803e3d6000fd5b505050505b505b8260066000848152602001908152602001600020600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e08201518160070160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101008201518160080160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101208201518160090160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101408201518160090160146101000a81548160ff021916908360ff1602179055506101608201518160090160156101000a81548160ff021916908360ff160217905550905050600183610160015160ff1614806117eb5750600683610160015160ff16145b1561181d576118076117ff8e8d60006129c8565b88848b61339e565b6118188d8c85610120015185613489565b61183a565b61182e8d8c85610120015185613224565b6118398d8c846132eb565b5b817f2f539bcf68b0eef24f9fef1ae5ad7dd5a37f80a2fab34f406ad2b92c779d606460405160405180910390a28193505050509a9950505050505050505050565b6060600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008481526020019081526020016000206001015492506000830361192c57600167ffffffffffffffff8111156118f6576118f5613efd565b5b6040519080825280602002602001820160405280156119245781602001602082028036833780820191505090505b509050611cd2565b60008060098461193c9190614146565b67ffffffffffffffff81111561195557611954613efd565b5b6040519080825280602002602001820160405280156119835781602001602082028036833780820191505090505b50905060005b84811015611ccb576000860315611ccb57858284806119a7906141a0565b9550815181106119ba576119b96141e8565b5b60200260200101818152505060066000878152602001908152602001600020600001548284806119e9906141a0565b9550815181106119fc576119fb6141e8565b5b6020026020010181815250506006600087815260200190815260200160002060030154828480611a2b906141a0565b955081518110611a3e57611a3d6141e8565b5b6020026020010181815250506006600087815260200190815260200160002060020154828480611a6d906141a0565b955081518110611a8057611a7f6141e8565b5b6020026020010181815250506006600087815260200190815260200160002060070160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16828480611ae5906141a0565b955081518110611af857611af76141e8565b5b6020026020010181815250506006600087815260200190815260200160002060040154828480611b27906141a0565b955081518110611b3a57611b396141e8565b5b6020026020010181815250506006600087815260200190815260200160002060080160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16828480611b9f906141a0565b955081518110611bb257611bb16141e8565b5b6020026020010181815250506006600087815260200190815260200160002060090160149054906101000a900460ff1660ff16828480611bf1906141a0565b955081518110611c0457611c036141e8565b5b6020026020010181815250506006600087815260200190815260200160002060090160159054906101000a900460ff1660ff16828480611c43906141a0565b955081518110611c5657611c556141e8565b5b602002602001018181525050600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008781526020019081526020016000206001015495508080611cc3906141a0565b915050611989565b5080925050505b9392505050565b606060008060005b8451811015611ed957848181518110611cfd57611cfc6141e8565b5b602002602001015191506006600083815260200190815260200160002060090160159054906101000a900460ff1692503373ffffffffffffffffffffffffffffffffffffffff166006600084815260200190815260200160002060090160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16148015611dbd575060048360ff161480611dae575060078360ff16145b80611dbc575060098360ff16145b5b15611ea457611e42611e3c6006600085815260200190815260200160002060070160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166006600086815260200190815260200160002060080160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1633612a4b565b836136ae565b60086006600084815260200190815260200160002060090160156101000a81548160ff021916908360ff160217905550817fbd000546857b596b03c884060c13e7d8c7a7ce52366d2f116f76688e6f000f6660405160405180910390a2611ec6565b6000858281518110611eb957611eb86141e8565b5b6020026020010181815250505b8080611ed1906141a0565b915050611ce1565b508392505050919050565b60606000611ef3878787612a4b565b905060046000828152602001908152602001600020600085815260200190815260200160002060010154935060008403611f7957600167ffffffffffffffff811115611f4257611f41613efd565b5b604051908082528060200260200182016040528015611f705781602001602082028036833780820191505090505b509150506121b2565b600080600685611f899190614146565b67ffffffffffffffff811115611fa257611fa1613efd565b5b604051908082528060200260200182016040528015611fd05781602001602082028036833780820191505090505b50905060005b858110156121aa5760008703156121aa5786828480611ff4906141a0565b955081518110612007576120066141e8565b5b6020026020010181815250506006600088815260200190815260200160002060090160149054906101000a900460ff1660ff16828480612046906141a0565b955081518110612059576120586141e8565b5b6020026020010181815250506006600088815260200190815260200160002060000154828480612088906141a0565b95508151811061209b5761209a6141e8565b5b60200260200101818152505060066000888152602001908152602001600020600301548284806120ca906141a0565b9550815181106120dd576120dc6141e8565b5b602002602001018181525050600660008881526020019081526020016000206005015482848061210c906141a0565b95508151811061211f5761211e6141e8565b5b602002602001018181525050600660008881526020019081526020016000206006015482848061214e906141a0565b955081518110612161576121606141e8565b5b60200260200101818152505060046000858152602001908152602001600020600088815260200190815260200160002060010154965080806121a2906141a0565b915050611fd6565b508093505050505b95945050505050565b606060006121cb848460016129c8565b90506000600560008381526020019081526020016000206000603381106121f5576121f46141e8565b5b015490506000810361225457600167ffffffffffffffff81111561221c5761221b613efd565b5b60405190808252806020026020018201604052801561224a5781602001602082028036833780820191505090505b50925050506124c6565b600080600061012c67ffffffffffffffff81111561227557612274613efd565b5b6040519080825280602002602001820160405280156122a35781602001602082028036833780820191505090505b50905060005b60328110156124bc576005600087815260200190815260200160002085603381106122d7576122d66141e8565b5b01549250828285806122e8906141a0565b9650815181106122fb576122fa6141e8565b5b6020026020010181815250506006600084815260200190815260200160002060090160149054906101000a900460ff1660ff1682858061233a906141a0565b96508151811061234d5761234c6141e8565b5b602002602001018181525050600660008481526020019081526020016000206000015482858061237c906141a0565b96508151811061238f5761238e6141e8565b5b60200260200101818152505060066000848152602001908152602001600020600301548285806123be906141a0565b9650815181106123d1576123d06141e8565b5b6020026020010181815250506006600084815260200190815260200160002060050154828580612400906141a0565b965081518110612413576124126141e8565b5b6020026020010181815250506006600084815260200190815260200160002060060154828580612442906141a0565b965081518110612455576124546141e8565b5b60200260200101818152505060008561246d906142cb565b955085036124a9576032945060006005600088815260200190815260200160002086603381106124a05761249f6141e8565b5b015403156124bc575b80806124b4906141a0565b9150506122a9565b5080955050505050505b92915050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60606000612502858560006129c8565b905060008060016000848152602001908152602001600020600080815260200190815260200160002060020154905060006003866125409190614146565b67ffffffffffffffff81111561255957612558613efd565b5b6040519080825280602002602001820160405280156125875781602001602082028036833780820191505090505b50905060005b868110156126a15760008303156126a15760066000848152602001908152602001600020600301548285806125c1906141a0565b9650815181106125d4576125d36141e8565b5b6020026020010181815250506006600084815260200190815260200160002060020154828580612603906141a0565b965081518110612616576126156141e8565b5b6020026020010181815250506006600084815260200190815260200160002060040154828580612645906141a0565b965081518110612658576126576141e8565b5b6020026020010181815250506001600086815260200190815260200160002060008481526020019081526020016000206002015492508080612699906141a0565b91505061258d565b50809450505050509392505050565b60005481565b60606000806000806000805b87518110156129ba578781815181106126de576126dd6141e8565b5b602002602001015194506006600086815260200190815260200160002060090160159054906101000a900460ff1695503373ffffffffffffffffffffffffffffffffffffffff166006600087815260200190815260200160002060090160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16148015612790575060018660ff16148061278f575060068660ff16145b5b1561298557600660008681526020019081526020016000206002015493506006600086815260200190815260200160002060070160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1692506006600086815260200190815260200160002060080160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691507345c881b36fc357d80a715da36d79b845303796c173ffffffffffffffffffffffffffffffffffffffff1663d9caed128433876040518463ffffffff1660e01b815260040161287193929190614294565b600060405180830381600087803b15801561288b57600080fd5b505af115801561289f573d6000803e3d6000fd5b50505050426006600087815260200190815260200160002060000181905550600060066000878152602001908152602001600020600201819055506000600660008781526020019081526020016000206004018190555060046006600087815260200190815260200160002060090160156101000a81548160ff021916908360ff16021790555061293b612935848460006129c8565b86612e71565b61294783833388612f66565b61295383833388613224565b847f935c9ad2f1fda9d7eae0d2a512f1521cb7190ee06165414e722366a65975fb6b60405160405180910390a26129a7565b600088828151811061299a576129996141e8565b5b6020026020010181815250505b80806129b2906141a0565b9150506126c2565b508695505050505050919050565b60008115612a16578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610612a0a578284612a0d565b83835b80945081955050505b8383604051602001612a2992919061442d565b6040516020818303038152906040528051906020012060001c90509392505050565b600080612a5a858560016129c8565b90508083604051602001612a6f92919061447a565b6040516020818303038152906040528051906020012060001c9150509392505050565b6000806000806000600160008a815260200190815260200160002060008981526020019081526020016000206000015411612af45760016000898152602001908152602001600020600080815260200190815260200160002060020154612af6565b865b965060016000898152602001908152602001600020600088815260200190815260200160002060000154915060008203612b395760006001935093505050612e68565b60018560ff1603612cd85781861015612c26576001600089815260200190815260200160002060008881526020019081526020016000206001015490505b81861015612bf15760008103612b9557866001935093505050612e68565b809650600160008981526020019081526020016000206000888152602001908152602001600020600001549150600160008981526020019081526020016000206000888152602001908152602001600020600101549050612b77565b600160008981526020019081526020016000206000888152602001908152602001600020600201546000935093505050612e68565b6001600089815260200190815260200160002060008881526020019081526020016000206002015490505b818610612cca5760008103612c6e57600080935093505050612e68565b809650600160008981526020019081526020016000206000888152602001908152602001600020600001549150600160008981526020019081526020016000206000888152602001908152602001600020600201549050612c51565b866000935093505050612e68565b81861115612dba576001600089815260200190815260200160002060008881526020019081526020016000206001015490505b81861115612d855760008103612d2957866001935093505050612e68565b809650600160008981526020019081526020016000206000888152602001908152602001600020600001549150600160008981526020019081526020016000206000888152602001908152602001600020600101549050612d0b565b600160008981526020019081526020016000206000888152602001908152602001600020600201546000935093505050612e68565b6001600089815260200190815260200160002060008881526020019081526020016000206002015490505b818611612e5e5760008103612e0257600080935093505050612e68565b809650600160008981526020019081526020016000206000888152602001908152602001600020600001549150600160008981526020019081526020016000206000888152602001908152602001600020600201549050612de5565b8660009350935050505b94509492505050565b600060016000848152602001908152602001600020600083815260200190815260200160002060010154905060006001600085815260200190815260200160002060008481526020019081526020016000206002015490508160016000868152602001908152602001600020600083815260200190815260200160002060010181905550806001600086815260200190815260200160002060008481526020019081526020016000206002018190555060016000858152602001908152602001600020600084815260200190815260200160002060008082016000905560018201600090556002820160009055505050505050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000015490506000600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060010154905081600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000018190555080600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060010181905550600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000848152602001908152602001600020600080820160009055600182016000905550506000613136878787612a4b565b9050600360008281526020019081526020016000206000858152602001908152602001600020600001549250600360008281526020019081526020016000206000858152602001908152602001600020600101549150826003600083815260200190815260200160002060008481526020019081526020016000206000018190555081600360008381526020019081526020016000206000858152602001908152602001600020600101819055506003600082815260200190815260200160002060008581526020019081526020016000206000808201600090556001820160009055505050505050505050565b6000613231858585612a4b565b90506000600460008381526020019081526020016000206000808152602001908152602001600020600101549050826004600084815260200190815260200160002060008381526020019081526020016000206000018190555082600460008481526020019081526020016000206000808152602001908152602001600020600101819055508060046000848152602001908152602001600020600085815260200190815260200160002060010181905550505050505050565b60006132f9848460016129c8565b9050600060056000838152602001908152602001600020600060338110613323576133226141e8565b5b015490506032810361333457600090505b8061333e906141a0565b905082600560008481526020019081526020016000208260338110613366576133656141e8565b5b01819055508060056000848152602001908152602001600020600060338110613392576133916141e8565b5b01819055505050505050565b6000600160008681526020019081526020016000206000858152602001908152602001600020600101549050826001600087815260200190815260200160002060008681526020019081526020016000206001018190555082600160008781526020019081526020016000206000838152602001908152602001600020600201819055506040518060600160405280838152602001828152602001858152506001600087815260200190815260200160002060008581526020019081526020016000206000820151816000015560208201518160010155604082015181600201559050505050505050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600080815260200190815260200160002060010154905081600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000018190555081600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008081526020019081526020016000206001018190555080600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008481526020019081526020016000206001018190555060006135f6868686612a4b565b9050600360008281526020019081526020016000206000808152602001908152602001600020600101549150826003600083815260200190815260200160002060008481526020019081526020016000206000018190555082600360008381526020019081526020016000206000808152602001908152602001600020600101819055508160036000838152602001908152602001600020600085815260200190815260200160002060010181905550505050505050565b60006004600084815260200190815260200160002060008381526020019081526020016000206000015490506000600460008581526020019081526020016000206000848152602001908152602001600020600101549050816004600086815260200190815260200160002060008381526020019081526020016000206000018190555080600460008681526020019081526020016000206000848152602001908152602001600020600101819055506004600085815260200190815260200160002060008481526020019081526020016000206000808201600090556001820160009055505050505050565b60405180610180016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600060ff168152602001600060ff1681525090565b60405180610160016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b6138db816138c8565b81146138e657600080fd5b50565b6000813590506138f8816138d2565b92915050565b600060208284031215613914576139136138be565b5b6000613922848285016138e9565b91505092915050565b613934816138c8565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006139658261393a565b9050919050565b6139758161395a565b82525050565b600060ff82169050919050565b6139918161397b565b82525050565b610180820160008201516139ae600085018261392b565b5060208201516139c1602085018261392b565b5060408201516139d4604085018261392b565b5060608201516139e7606085018261392b565b5060808201516139fa608085018261392b565b5060a0820151613a0d60a085018261392b565b5060c0820151613a2060c085018261392b565b5060e0820151613a3360e085018261396c565b50610100820151613a4861010085018261396c565b50610120820151613a5d61012085018261396c565b50610140820151613a72610140850182613988565b50610160820151613a87610160850182613988565b50505050565b600061018082019050613aa36000830184613997565b92915050565b613ab28161395a565b82525050565b6000602082019050613acd6000830184613aa9565b92915050565b613adc8161395a565b8114613ae757600080fd5b50565b600081359050613af981613ad3565b92915050565b60008060008060808587031215613b1957613b186138be565b5b6000613b2787828801613aea565b9450506020613b3887828801613aea565b9350506040613b49878288016138e9565b9250506060613b5a878288016138e9565b91505092959194509250565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000613b9e838361392b565b60208301905092915050565b6000602082019050919050565b6000613bc282613b66565b613bcc8185613b71565b9350613bd783613b82565b8060005b83811015613c08578151613bef8882613b92565b9750613bfa83613baa565b925050600181019050613bdb565b5085935050505092915050565b60006020820190508181036000830152613c2f8184613bb7565b905092915050565b600080fd5b600080fd5b600080fd5b60008083601f840112613c5c57613c5b613c37565b5b8235905067ffffffffffffffff811115613c7957613c78613c3c565b5b602083019150836020820283011115613c9557613c94613c41565b5b9250929050565b60008060208385031215613cb357613cb26138be565b5b600083013567ffffffffffffffff811115613cd157613cd06138c3565b5b613cdd85828601613c46565b92509250509250929050565b600080600080600060a08688031215613d0557613d046138be565b5b6000613d1388828901613aea565b9550506020613d2488828901613aea565b9450506040613d3588828901613aea565b9350506060613d46888289016138e9565b9250506080613d57888289016138e9565b9150509295509295909350565b613d6d8161397b565b8114613d7857600080fd5b50565b600081359050613d8a81613d64565b92915050565b6000806000806000806000806000806101408b8d031215613db457613db36138be565b5b6000613dc28d828e01613aea565b9a50506020613dd38d828e01613aea565b9950506040613de48d828e016138e9565b9850506060613df58d828e01613aea565b9750506080613e068d828e016138e9565b96505060a0613e178d828e01613d7b565b95505060c0613e288d828e016138e9565b94505060e0613e398d828e016138e9565b935050610100613e4b8d828e016138e9565b925050610120613e5d8d828e016138e9565b9150509295989b9194979a5092959850565b613e78816138c8565b82525050565b6000602082019050613e936000830184613e6f565b92915050565b600080600060608486031215613eb257613eb16138be565b5b6000613ec086828701613aea565b9350506020613ed1868287016138e9565b9250506040613ee2868287016138e9565b9150509250925092565b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613f3582613eec565b810181811067ffffffffffffffff82111715613f5457613f53613efd565b5b80604052505050565b6000613f676138b4565b9050613f738282613f2c565b919050565b600067ffffffffffffffff821115613f9357613f92613efd565b5b602082029050602081019050919050565b6000613fb7613fb284613f78565b613f5d565b90508083825260208201905060208402830185811115613fda57613fd9613c41565b5b835b818110156140035780613fef88826138e9565b845260208401935050602081019050613fdc565b5050509392505050565b600082601f83011261402257614021613c37565b5b8135614032848260208601613fa4565b91505092915050565b600060208284031215614051576140506138be565b5b600082013567ffffffffffffffff81111561406f5761406e6138c3565b5b61407b8482850161400d565b91505092915050565b6000806040838503121561409b5761409a6138be565b5b60006140a985828601613aea565b92505060206140ba85828601613aea565b9150509250929050565b6000806000606084860312156140dd576140dc6138be565b5b60006140eb86828701613aea565b93505060206140fc86828701613aea565b925050604061410d868287016138e9565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614151826138c8565b915061415c836138c8565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561419557614194614117565b5b828202905092915050565b60006141ab826138c8565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036141dd576141dc614117565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082825260208201905092915050565b7f4f6e6c79206f776e65722063616e2063616c6c20746869732e00000000000000600082015250565b600061425e601983614217565b915061426982614228565b602082019050919050565b6000602082019050818103600083015261428d81614251565b9050919050565b60006060820190506142a96000830186613aa9565b6142b66020830185613aa9565b6142c36040830184613e6f565b949350505050565b60006142d6826138c8565b9150600082036142e9576142e8614117565b5b600182039050919050565b60006142ff826138c8565b915061430a836138c8565b925082820390508181111561432257614321614117565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614362826138c8565b915061436d836138c8565b92508261437d5761437c614328565b5b828204905092915050565b6000614393826138c8565b915061439e836138c8565b92508282019050808211156143b6576143b5614117565b5b92915050565b60006040820190506143d16000830185613aa9565b6143de6020830184613e6f565b9392505050565b60008160601b9050919050565b60006143fd826143e5565b9050919050565b600061440f826143f2565b9050919050565b6144276144228261395a565b614404565b82525050565b60006144398285614416565b6014820191506144498284614416565b6014820191508190509392505050565b6000819050919050565b61447461446f826138c8565b614459565b82525050565b60006144868285614463565b6020820191506144968284614416565b601482019150819050939250505056fea2646970667358221220ee3e7c09638282ee602ed582ad36395384b19887eb2d75d72cbab9a67ee1496664736f6c63430008100033