Feature Tip: Add private address tag to any address under My Name Tag !
ERC-721
Overview
Max Total Supply
225 MMPLS
Holders
118
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
2 MMPLSLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
LWMempools
Compiler Version
v0.8.4+commit.c7e474f2
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
//SPDX-License-Identifier: Unlicense pragma solidity ^0.8.4; import './LTNT.sol'; import './lib/Rando.sol'; import '@openzeppelin/contracts/security/ReentrancyGuard.sol'; /** ___ ___ ___ __ __ __ | /\ | |__ |\ | | | | / \ |__) |__/ /__` |___ /~~\ | |___ | \| | .|/\| \__/ | \ | \ .__/ "mempools", latent.works, 2022 */ /// @title Mempools /// @author troels_a /// @notice latent.works/mempools contract LWMempools is ERC721, LTNTIssuer, Ownable, ReentrancyGuard { /// @dev main bank struct struct Bank { string _name; // name of bank string[4] _parts; // parts of the bank string _filter; uint[15] _pools; } uint public constant PRICE = 0.15 ether; // The price of one mempool uint private _pool_ids; // Tracks the current pool id Bank[15] private _banks; // Holds banks mapping(uint => uint) private _pool_timestamps; // Holds the timestamp of when a pool was created mapping(uint => uint) private _pool_banks; // Holds the bank id of a pool - id => bank_index mapping(uint => uint) private _pool_fixed_epochs; // Holds the fixed epoch of a pool - id => epoch LTNT public immutable _ltnt; // The LTNT token contract LWMempools_Gen public immutable _generator; // The generator contract LWMempools_Meta private _meta; // The meta contract ////////////////////////// /// CONTRACT ////////////////////////// constructor(address ltnt_) ERC721("Mempools", "MMPLS"){ _ltnt = LTNT(ltnt_); // Set the LTNT token contract _generator = new LWMempools_Gen(); // Deploy the generator contract _meta = new LWMempools_Meta(); // Deploy the meta contract } /// @dev declare issuer info for LTNT /// @return LTNT.IssuerInfo struct with issuer info /// @param param_ the LTNT token params struct function issuerInfo(uint, LTNT.Param memory param_) public view override returns(LTNT.IssuerInfo memory){ return LTNT.IssuerInfo('mempools', getPoolImage(param_._uint, true)); } /// @dev get the address of the _meta contract /// @return address of the _meta contract function getMeta() public view returns (address){ return address(_meta); } /// @dev set the address of the _meta contract /// @param meta_ the address of the new _meta contract function setMeta(address meta_) public onlyOwner { _meta = LWMempools_Meta(meta_); } ///////////////////////////// /// MINTING ///////////////////////////// /// @dev mint a new mempool /// @param bank_index_ the bank id of the mempool /// @param pool_index_ the pool id of the mempool function mint(uint bank_index_, uint pool_index_) public payable nonReentrant { uint bank_count_ = getBankCount(); require(msg.value == PRICE, 'INVALID_PRICE'); // Check price require(bank_count_ > 0 && bank_index_ < bank_count_, 'INVALID_BANK'); // Check bank index require(_banks[bank_index_]._pools[pool_index_] == 0, 'POOL_INDEX_USED'); // Check pool index _mintFor(msg.sender, bank_index_, pool_index_); // Mint the mempool } /// @dev mint a new mempool holding a LTNT token /// @param ltnt_id_ the id of the LTNT token to hold /// @param bank_index_ the bank id of the mempool /// @param pool_index_ the pool id of the mempool function mintWithLTNT(uint ltnt_id_, uint bank_index_, uint pool_index_) public payable nonReentrant { uint bank_count_ = getBankCount(); require(msg.value == (PRICE/3)*2, 'INVALID_PRICE'); // Check price require(_ltnt.ownerOf(ltnt_id_) == msg.sender, 'NOT_LTNT_HOLDER'); // Check LTNT ownership require(!_ltnt.hasStamp(ltnt_id_, address(this)), 'ALREADY_STAMPED'); // Check if LTNT is already stamped require(bank_count_ > 0 && bank_index_ < bank_count_, 'INVALID_BANK'); // Check bank index require(_banks[bank_index_]._pools[pool_index_] == 0, 'POOL_INDEX_USED'); // Check pool index uint id_ = _mintFor(msg.sender, bank_index_, pool_index_); // Mint the mempool _ltnt.stamp(ltnt_id_, LTNT.Param(id_, address(0), '', false)); // Stamp the LTNT token } /// @dev internal mint function function _mintFor(address for_, uint bank_, uint index_) private returns(uint) { _pool_ids++; // Increment the pool id _mint(for_, _pool_ids); // Mint the token _pool_timestamps[_pool_ids] = block.timestamp; // Set the timestamp of the pool _pool_banks[_pool_ids] = bank_; // Set the bank of the pool _banks[bank_]._pools[index_] = _pool_ids; // Set the pool id of the bank return _pool_ids; } /// @dev get the total supply of mempools /// @return uint total supply of mempools function totalSupply() public view returns (uint) { return _pool_ids; } ///////////////////////////// /// BANKS ///////////////////////////// /// @dev add a bank to the contract /// @param name_ the name of the bank /// @param parts_ the parts of the bank /// @param filter_ the filter of the bank function addBank(string memory name_, string[4] memory parts_, string memory filter_) public onlyOwner { uint next_index_ = getBankCount(); // Current count should be equal to next index since we start at 0 require(next_index_ < _banks.length, "MAX_BANKS"); // Make sure we don't exceed the max banks _banks[next_index_]._name = name_; // Set the name _banks[next_index_]._parts = parts_; // Set the parts _banks[next_index_]._filter = filter_; // Set the filter } /// @dev get a specific bank /// @return Bank struct /// @param index_ the index of the bank in _banks function getBank(uint index_) public view returns(Bank memory){ return _banks[index_]; } /// @dev get array of added banks /// @return array of Bank structs function getBanks() public view returns(Bank[] memory){ uint count = getBankCount(); // Get the bank count Bank[] memory banks_ = new Bank[](count); // Create a new array of banks with the correct length for(uint i = 0; i < count; i++) // Copy the banks to the new array banks_[i] = _banks[i]; return banks_; } /// @dev get the cuurent count of banks /// @return uint the count function getBankCount() public view returns(uint) { uint count_; // Init the count for(uint i = 0; i < _banks.length; i++) // Loop through the banks if(bytes(_banks[i]._name).length > 0) // If the name is not empty count_++; // Increment the count return count_; } ///////////////////////////// /// POOLS ///////////////////////////// /// @dev check if a pool exists /// @return bool if the pool exists /// @param pool_id_ the id of the pool function poolExists(uint pool_id_) public view returns(bool) { return _exists(pool_id_); } /// @dev get the filter for a given pool /// @return string the name of the filter function getPoolFilter(uint pool_id_) public view returns(string memory){ return _banks[_pool_banks[pool_id_]]._filter; } /// @dev get the bank index for a given pool /// @return uint the index of the bank /// @param pool_id_ the id of the pool function getPoolBankIndex(uint pool_id_) public view returns(uint){ return _pool_banks[pool_id_]; } /// @dev get the Bank struct for a given pool /// @return Bank the bank struct /// @param pool_id_ the id of the pool function getPoolBank(uint pool_id_) public view returns(LWMempools.Bank memory){ return getBank(getPoolBankIndex(pool_id_)); } /// @dev get the part index for a given pool /// @return uint the index of the part /// @param pool_id_ the id of the pool function getPoolPartIndex(uint pool_id_) public view returns(uint){ Bank memory bank_ = getPoolBank(pool_id_); string memory seed_part_ = getPoolSeed(pool_id_, 'part'); return Rando.number(seed_part_, 0, bank_._parts.length-1); } /// @dev get the part for a given pool /// @return string the part /// @param pool_id_ the id of the pool function getPoolPart(uint pool_id_) public view returns(string memory){ LWMempools.Bank memory bank_ = getPoolBank(pool_id_); return bank_._parts[getPoolPartIndex(pool_id_)]; } /// @dev get the seed for a given pool /// @return string the seed /// @param pool_id_ the id of the pool /// @param append_ a string to append to the seed function getPoolSeed(uint pool_id_, string memory append_) public view returns(string memory){ return string(abi.encodePacked(Strings.toString(_pool_timestamps[pool_id_]), Strings.toString(pool_id_), append_)); } ///////////////////////////// /// EPOCHS ///////////////////////////// /// @dev get epoch length for a given pool in seconds /// @return uint the epoch length /// @param pool_id_ the id of the pool function getEpochLength(uint pool_id_) public view returns(uint){ return Rando.number(getPoolSeed(pool_id_, 'epoch'), 1, 6)*7776000; } /// @dev get the current epoch for a given pool /// @return uint the epoch number /// @param pool_id_ the id of the pool function getCurrentEpoch(uint pool_id_) public view returns(uint){ uint epoch = (((block.timestamp - _pool_timestamps[pool_id_]) / getEpochLength(pool_id_))+1); return epoch; } /// @dev get the fixed epoch for a given pool /// @return uint the epoch number - 0 means the pool epoch is not fixed /// @param pool_id_ the id of the pool function getFixedEpoch(uint pool_id_) public view returns(uint){ return _pool_fixed_epochs[pool_id_]; } /// @dev allow pool owner to fix the epoch for a given pool /// @param pool_id_ the id of the pool /// @param epoch_ the epoch to fix the pool to function fixEpoch(uint pool_id_, uint epoch_) public { require(ownerOf(pool_id_) == msg.sender, 'NOT_OWNER'); require(getCurrentEpoch(pool_id_) <= epoch_, 'EPOCH_NOT_REACHED'); _pool_fixed_epochs[pool_id_] = epoch_; } /// @dev get the generated image for a pool /// @return string the image /// @param pool_id_ the id of the pool function getPoolImage(uint pool_id_, bool encode_) public view returns(string memory){ if(!poolExists(pool_id_)) // If the pool doesn't exist... return ''; // ...return empty string uint epoch_ = _pool_fixed_epochs[pool_id_]; // Get the fixed epoch if(epoch_ < 1) // Fixed epoch is 0, go to current epoch epoch_ = getCurrentEpoch(pool_id_); // Get the current epoch return _generator.generateImage(pool_id_, epoch_, encode_); // Get the image based on id and epoch } /// @dev get the metadat data uri for a given pool /// @return string the uri /// @param pool_id_ the id of the pool function tokenURI(uint pool_id_) override public view returns(string memory) { return _meta.getJSON(pool_id_, true); } ////////////////////////// /// BALANCE ////////////////////////// function withdrawAllTo(address to_) public payable onlyOwner { require(payable(to_).send(address(this).balance)); } } /// @title Mempools meta /// @author troels_a /// @notice This contract handles the metadata for the mempools contract contract LWMempools_Meta { using Strings for string; LWMempools public _pools; // The mempools contract constructor() { _pools = LWMempools(msg.sender); // Set the mempools contract } /// @dev get the metadata for a given pool /// @return string the metadata /// @param pool_id_ the id of the pool function getJSON(uint pool_id_, bool encode_) public view returns(string memory) { if(!_pools.poolExists(pool_id_)) // If the pool doesn't exist... return ''; // ...return empty string LWMempools.Bank memory bank_ = _pools.getPoolBank(pool_id_); // Get the bank for the pool // Create the JSON string bytes memory json_ = abi.encodePacked( '{', '"name":"mempool #',Strings.toString(pool_id_),'",', '"image": "', _pools.getPoolImage(pool_id_, true),'",', '"description": "latent.works",', '"attributes": [', '{"trait_type": "bank", "value": "',bank_._name,'"},', '{"trait_type": "bank_index", "value": "',bank_._name,'-',Strings.toString(_pools.getPoolPartIndex(pool_id_)),'"},', '{"trait_type": "epoch", "value": ', Strings.toString(_pools.getCurrentEpoch(pool_id_)), '},', '{"trait_type": "fixed_epoch", "value": ', Strings.toString(_pools.getFixedEpoch(pool_id_)), '},', '{"trait_type": "epoch_length", "value": ', Strings.toString(_pools.getEpochLength(pool_id_)), '}', ']', '}' ); if(encode_) // If encode_ is true return string(abi.encodePacked('data:application/json;base64,', Base64.encode(json_))); // ...encode the json string return string(json_); // return the raw JSON } } /// @title Mempools generator /// @author troels_a /// @notice Generates images for mempools contract LWMempools_Gen { struct Pool { uint id; bytes items; string base; string seed; string seed1; string seed2; string filter; uint epoch; string shape1_width; string shape1_height; string shape2_width; string shape2_height; string shape3_width; string shape3_height; } LWMempools public immutable _pools; // The mempools contract constructor(){ _pools = LWMempools(msg.sender); // Set the mempools contract } /// @dev generate an image for a given pool /// @return string the image /// @param pool_id_ the id of the pool /// @param epoch_ the epoch to generate the image for /// @param encode_ bool indicating if the image should be encoded as base64 or not function generateImage(uint pool_id_, uint epoch_, bool encode_) public view returns(string memory){ if(!_pools.poolExists(pool_id_)) // If the pool doesn't exist... return ''; // ...return empty string Pool memory pool_; // Create a pool struct pool_.epoch = _pools.getCurrentEpoch(pool_id_); // Get the current epoch for pool if(epoch_ > pool_.epoch) // If the epoch input is higher than the current epoch... return ''; // ...return empty string pool_.id = pool_id_; // Set the pool id pool_.seed = _pools.getPoolSeed(pool_id_, ''); // Get the main seed for this pool pool_.base = _pools.getPoolPart(pool_id_); // Get the base part for this pool pool_.filter = _pools.getPoolFilter(pool_id_); // Get the filter for this pool /** * Create the shapes for each pool epoch */ uint i; while(i < pool_.epoch){ pool_.seed1 =_pools.getPoolSeed(pool_id_, string(abi.encodePacked('1x', Strings.toString(i)))); pool_.seed2 = _pools.getPoolSeed(pool_id_, string(abi.encodePacked('1y', Strings.toString(i)))); pool_.items = abi.encodePacked( pool_.items, '<use href="#shape',Strings.toString(Rando.number(pool_.seed1, 1, 3)),'" x="',Strings.toString(Rando.number(pool_.seed1, 1, 990)),'" y="',Strings.toString(Rando.number(pool_.seed2, 1, 900)),'" fill="url(#base',Strings.toString(Rando.number(pool_.seed2, 1, 5)),')"/>' ); ++i; } i = 0; while(i < pool_.epoch){ pool_.seed1 = _pools.getPoolSeed(pool_id_, string(abi.encodePacked('2x', Strings.toString(i)))); pool_.seed2 = _pools.getPoolSeed(pool_id_, string(abi.encodePacked('2y', Strings.toString(i)))); pool_.items = abi.encodePacked( pool_.items, '<use href="#shape',Strings.toString(Rando.number(pool_.seed1, 1, 3)),'" x="',Strings.toString(Rando.number(pool_.seed1, 1, 990)),'" y="',Strings.toString(Rando.number(pool_.seed2, 1, 900)),'" fill="url(#base',Strings.toString(Rando.number(pool_.seed2, 1, 5)),')"/>' ); ++i; } i = 0; while(i < pool_.epoch){ pool_.seed1 = _pools.getPoolSeed(pool_id_, string(abi.encodePacked('3x', Strings.toString(i)))); pool_.seed2 = _pools.getPoolSeed(pool_id_, string(abi.encodePacked('3y', Strings.toString(i)))); pool_.items = abi.encodePacked( pool_.items, '<use href="#shape',Strings.toString(Rando.number(pool_.seed1, 1, 3)),'" x="',Strings.toString(Rando.number(pool_.seed1, 1, 990)),'" y="',Strings.toString(Rando.number(pool_.seed2, 1, 900)),'" fill="url(#base',Strings.toString(Rando.number(pool_.seed2, 1, 5)),')"/>' ); ++i; } /** * Create the shape dimensions */ pool_.shape1_width = Strings.toString(Rando.number(_pools.getPoolSeed(pool_.id, 'shape1width'), 1, 50)); pool_.shape1_height = Strings.toString(Rando.number(_pools.getPoolSeed(pool_.id, 'shape1height'), 20, 300)); pool_.shape2_width = Strings.toString(Rando.number(_pools.getPoolSeed(pool_.id, 'shape2width'), 20, 30)); pool_.shape2_height = Strings.toString(Rando.number(_pools.getPoolSeed(pool_.id, 'shape2height'), 20, 200)); pool_.shape3_width = Strings.toString(Rando.number(_pools.getPoolSeed(pool_.id, 'shape2height'), 10, 30)); pool_.shape3_height = Strings.toString(Rando.number(_pools.getPoolSeed(pool_.id, 'shape3width'), 20, 100)); /** * Create the svg */ bytes memory svg_ = abi.encodePacked( '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000" preserveAspectRatio="xMinYMin meet">', '<defs>', '<circle cx="500" cy="500" r="500" id="bg"/>', '<filter id="none"><feColorMatrix in="SourceGraphic" type="saturate" values="0"/></filter>', '<filter id="bw"><feColorMatrix type="matrix" values="0.491 1.650 0.166 0.000 -0.464 0.491 1.650 0.166 0.000 -0.464 0.491 1.650 0.166 0.000 -0.464 0.000 0.000 0.000 1.000 0.000"></feColorMatrix></filter>', '<filter id="s1"><feColorMatrix in="SourceGraphic" type="saturate" values="2"/></filter>', '<filter id="s2"><feColorMatrix in="SourceGraphic" type="saturate" values="4"/></filter>', '<filter id="s3"><feColorMatrix in="SourceGraphic" type="saturate" values="6"/></filter>', '<filter id="s4"><feColorMatrix in="SourceGraphic" type="saturate" values="8"/></filter>', '<filter id="s5"><feColorMatrix in="SourceGraphic" type="saturate" values="10"/></filter>', '<filter id="s6"><feColorMatrix in="SourceGraphic" type="saturate" values="12"/></filter>', '<filter id="s7"><feColorMatrix in="SourceGraphic" type="saturate" values="14"/></filter>', '<filter id="s8"><feColorMatrix in="SourceGraphic" type="saturate" values="16"/></filter>', '<filter id="s9"><feColorMatrix in="SourceGraphic" type="saturate" values="18"/></filter>', '<filter id="s10"><feColorMatrix in="SourceGraphic" type="saturate" values="20"/></filter>', '<filter id="r1"><feColorMatrix in="SourceGraphic" type="hueRotate" values="20"></feColorMatrix><feColorMatrix in="SourceGraphic" type="saturate" values="3"/></filter>', '<filter id="r2"><feColorMatrix in="SourceGraphic" type="hueRotate" values="40"></feColorMatrix><feColorMatrix in="SourceGraphic" type="saturate" values="3"/></filter>', '<filter id="r3"><feColorMatrix in="SourceGraphic" type="hueRotate" values="60"></feColorMatrix><feColorMatrix in="SourceGraphic" type="saturate" values="3"/></filter>', '<filter id="r4"><feColorMatrix in="SourceGraphic" type="hueRotate" values="80"></feColorMatrix><feColorMatrix in="SourceGraphic" type="saturate" values="3"/></filter>', '<filter id="r5"><feColorMatrix in="SourceGraphic" type="hueRotate" values="100"></feColorMatrix><feColorMatrix in="SourceGraphic" type="saturate" values="3"/></filter>', '<filter id="r6"><feColorMatrix in="SourceGraphic" type="hueRotate" values="120"></feColorMatrix><feColorMatrix in="SourceGraphic" type="saturate" values="3"/></filter>', '<filter id="r7"><feColorMatrix in="SourceGraphic" type="hueRotate" values="140"></feColorMatrix><feColorMatrix in="SourceGraphic" type="saturate" values="3"/></filter>', '<filter id="r8"><feColorMatrix in="SourceGraphic" type="hueRotate" values="160"></feColorMatrix><feColorMatrix in="SourceGraphic" type="saturate" values="3"/></filter>', '<filter id="r9"><feColorMatrix in="SourceGraphic" type="hueRotate" values="180"></feColorMatrix><feColorMatrix in="SourceGraphic" type="saturate" values="3"/></filter>', '<filter id="r10"><feColorMatrix in="SourceGraphic" type="hueRotate" values="200"></feColorMatrix><feColorMatrix in="SourceGraphic" type="saturate" values="3"/></filter>', '<filter id="internal-noise"><feTurbulence type="fractalNoise" baseFrequency="0.55" numOctaves="10" stitchTiles="stitch" /></filter>', '<filter id="internal-blur" x="0" y="0"><feGaussianBlur in="SourceGraphic" stdDeviation="4" /></filter>', '<clipPath id="clip"><use href="#bg"/></clipPath>', '<rect id="shape1" width="',pool_.shape1_width,'" height="',pool_.shape1_height,'"/>', '<rect id="shape2" width="30" height="',pool_.shape2_height,'"/>', '<rect id="shape3" width="20" height="',pool_.shape3_height,'"/>', '<image id="base" width="1000" height="1000" href="',pool_.base,'"/>', '<pattern id="base1" x="0" y="0" width="1" height="1" viewBox="0 0 200 200"><use href="#base"/></pattern>', '<pattern id="base2" x="0" y="0" width="1" height="1" viewBox="200 200 200 200" preserveAspectRatio="xMidYMid slice"><use href="#base"/></pattern>', '<pattern id="base3" x="0" y="0" width="1" height="1" viewBox="400 400 200 200" preserveAspectRatio="xMidYMid slice"><use href="#base"/></pattern>', '<pattern id="base4" x="0" y="0" width="1" height="1" viewBox="600 600 200 200" preserveAspectRatio="xMidYMid slice"><use href="#base"/></pattern>', '<pattern id="base5" x="0" y="0" width="1" height="1" viewBox="800 800 200 200" preserveAspectRatio="xMidYMid slice"><use href="#base"/></pattern>', '</defs>', '<g filter="url(#',pool_.filter,')">', '<rect width="1000" height="1000" fill="black"/>', '<rect width="1000" height="1000" fill-opacity="0.5" fill="url(#base',Strings.toString(Rando.number(_pools.getPoolSeed(pool_.id, 'bg0'), 2, 5)),')" filter="url(#bw)"/>', '<g clip-path="url(#clip)">', '<use href="#bg" fill-opacity="1" fill="url(#base',Strings.toString(Rando.number(_pools.getPoolSeed(pool_.id, 'bg1'), 2, 5)),')"/>', '<g filter="url(#internal-blur)" transform="translate(0, -100)" id="pool">', pool_.items, '</g>', '<use href="#pool" transform="scale(.5, 0.5)"/>', '<use href="#pool" transform="scale(.5, 0.5) translate(',Strings.toString(Rando.number(pool_.seed, 0, 100)),', 1000)"/>' '<use href="#pool" transform="scale(0.8, 0.8) translate(1000, 0)"/>' '<use href="#pool" transform="scale(1, 1.5) translate(',Strings.toString(Rando.number(pool_.seed, 0, 500)),', ',Strings.toString(Rando.number(pool_.seed, 0, 500)),')"/>', '</g>', '<g filter="url(#bw)">', '<rect width="1000" height="1000" fill="white" filter="url(#internal-noise)" opacity="0.15"/>', '</g>', '</g>', '</svg>' ); if(encode_) // encode the svg return string(abi.encodePacked('data:image/svg+xml;base64,', Base64.encode(svg_))); // return the raw svg return string(svg_); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "./LTNTFont.sol"; import "base64-sol/base64.sol"; ////////////////////////////////// // // // LTNT // Passport NFTs for Latent Works // // ////////////////////////////////// /// @title LTNT /// @author troels_a contract LTNT is ERC721, Ownable { struct Param { uint _uint; address _address; string _string; bool _bool; } struct IssuerInfo { string name; string image; } struct Issuer { address location; Param param; } event Issued(uint indexed id, address indexed to); event Stamped(uint indexed id, address indexed stamper); LTNT_Meta private _ltnt_meta; address[] private _issuers; ///@dev array of addresses registered as issuers mapping(uint => mapping(address => bool)) private _stamps; ///@dev (ltnt => (issuer => is stamped?)) mapping(uint => mapping(address => Param)) private _params; ///@dev (ltnt => (issuer => stamp parameters)); mapping(uint => Issuer) private _issuer_for_id; ///@dev (ltnt => issuer) - the Issuer for a given LTNT uint private _ids; ///@dev LTNT _id counter /// @dev pass address of onchain fonts to the constructor constructor(address regular_, address italic_) ERC721("Latents", "LTNT"){ LTNT_Meta ltnt_meta_ = new LTNT_Meta(address(this), regular_, italic_); _ltnt_meta = LTNT_Meta(address(ltnt_meta_)); } /// @notice Require a given address to be a registered issuer /// @param caller_ the address to check for issuer privilegies function _reqOnlyIssuer(address caller_) private view { require(isIssuer(caller_), 'ONLY_ISSUER'); } /// @notice Issue a token to the address /// @param to_ the address to issue the LTNT to /// @param param_ a Param struct of parameters associated with the token /// @param stamp_ boolean determining wether the newly issued LTNT should be stamped by the issuer /// @return uint the id of the newly issued LTNT function issueTo(address to_, Param memory param_, bool stamp_) public returns(uint){ _reqOnlyIssuer(msg.sender); _ids++; _safeMint(to_, _ids); _issuer_for_id[_ids] = Issuer(msg.sender, param_); emit Issued(_ids, to_); if(stamp_) _stamp(_ids, msg.sender, param_); return _ids; } /// @dev Lets a registered issuer stamp a given LTNT /// @param id_ the ID of the LTNT to stamp /// @param param_ a Param struct with any associated params function stamp(uint id_, Param memory param_) public { _reqOnlyIssuer(msg.sender); _stamp(id_, msg.sender, param_); } /// @dev internal stamping mechanism /// @param id_ the id of the LTNT to stamp /// @param issuer_ the address of the issuer stamping the LTNT /// @param param_ a Param struct with stamp parameters function _stamp(uint id_, address issuer_, Param memory param_) private { _stamps[id_][issuer_] = true; _params[id_][issuer_] = param_; emit Stamped(_ids, issuer_); } /// @dev checks if a given id_ is stamped by address_ /// @param id_ the ID of the LTNT to check /// @param address_ the address of the stamper /// @return bool indicating wether LTNT is stamped function hasStamp(uint id_, address address_) public view returns(bool){ return _stamps[id_][address_]; } /// @dev get params for a given stamp on a LTNT /// @param id_ the id of the LTNT /// @param address_ the address of the stamper /// @return Param the param to return function getStampParams(uint id_, address address_) public view returns(Param memory){ return _params[id_][address_]; } /// @dev Get the addresses of the issuers that have stamped a given LTNT /// @param id_ the ID of the LTNT to fetch stamps for /// @return addresses an array of issuer addresses that have stamped the LTNT function getStamps(uint id_) public view returns(address[] memory){ // First count the stamps uint count; for(uint i = 0; i < _issuers.length; i++){ if(_stamps[id_][_issuers[i]]) ++count; } // Init a stamps_ array with the right length from count_ address[] memory stamps_ = new address[](count); // Loop over the issuers and save stampers in stamps_ count = 0; for(uint i = 0; i < _issuers.length; i++){ if(_stamps[id_][_issuers[i]]){ stamps_[count] = _issuers[i]; ++count; } } return stamps_; } /// @dev list all issuer addresses /// @return addresses list of all issuers function getIssuers() public view returns(address[] memory){ return _issuers; } /// @dev get the issuer of a LTNT function getIssuerFor(uint id_) public view returns(LTNT.Issuer memory){ return _issuer_for_id[id_]; } /// @dev set the meta contract /// @param address_ the address of the meta contract function setMetaContract(address address_) public onlyOwner { _ltnt_meta = LTNT_Meta(address_); } /// @dev get the meta contract /// @return LTNT_Meta the meta contract currently in use function getMetaContract() public view returns(LTNT_Meta) { return _ltnt_meta; } /// @notice register an issuer address /// @param address_ the address of the issuer to add function addIssuer(address address_) public onlyOwner { _issuers.push(address_); } /// @notice determine if an address is a LW project /// @param address_ the address of the issuer /// @return bool indicating wether the address is an issuer or not function isIssuer(address address_) public view returns(bool){ for(uint i = 0; i < _issuers.length; i++) { if(_issuers[i] == address_) return true; } return false; } /// @notice the ERC721 tokenURI for a given LTNT /// @param id_ the id of the LTNT /// @return json_ base64 encoded data URI containing the JSON metadata function tokenURI(uint id_) public view override returns(string memory json_){ return _ltnt_meta.getJSON(id_, true); } } /// @title A title that should describe the contract/interface /// @author troels_a /// @dev Handles meta for this contract contract LTNT_Meta { LTNT public immutable _ltnt; ///@dev latent fonts XanhMonoRegularLatin public immutable _xanh_regular; XanhMonoItalicLatin public immutable _xanh_italic; constructor(address ltnt_, address regular_, address italic_){ _ltnt = LTNT(ltnt_); _xanh_regular = XanhMonoRegularLatin(regular_); _xanh_italic = XanhMonoItalicLatin(italic_); } /// @notice return image string for id_ /// @param id_ the id of the LTNT to retrieve the image for /// @param encode_ encode output as base64 uri /// @return string the image string function getImage(uint id_, bool encode_) public view returns(string memory){ LTNT.Issuer memory issuer_for_id_ = _ltnt.getIssuerFor(id_); LTNT.IssuerInfo memory issuer_info_ = LTNTIssuer(issuer_for_id_.location).issuerInfo(id_, issuer_for_id_.param); LTNT.IssuerInfo memory stamper_; LTNT.Param memory stamp_param_; address[] memory issuers_ = _ltnt.getIssuers(); bytes memory stamps_svg_; string memory delay_; uint stamp_count_; bool has_stamp_; for(uint i = 0; i < issuers_.length; i++) { delay_ = Strings.toString(i*150); stamp_param_ = _ltnt.getStampParams(id_,issuers_[i]); stamper_ = LTNTIssuer(issuers_[i]).issuerInfo(id_, stamp_param_); has_stamp_ = _ltnt.hasStamp(id_, issuers_[i]); stamps_svg_ = abi.encodePacked(stamps_svg_, '<text class="txt italic" fill-opacity="0" y="',Strings.toString(25*i),'">',stamper_.name,' <animate attributeName="fill-opacity" values="0;',has_stamp_ ? '1' : '0.4','" dur="500ms" repeatCount="1" begin="',delay_,'ms" fill="freeze"/></text>'); if(has_stamp_) ++stamp_count_; } bytes memory image_; image_ = abi.encodePacked( '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 1000" preserveAspectRatio="xMinYMin meet">', '<defs><style>', _xanh_regular.fontFace(), _xanh_italic.fontFace(),' .txt {font-family: "Xanh Mono"; font-size:20px; font-weight: normal; letter-spacing: 0.01em; fill: white;} .italic {font-style: italic;} .large {font-size: 55px;} .small {font-size: 12px;}</style><rect ry="30" rx="30" id="bg" height="1000" width="600" fill="black"/></defs>', '<use href="#bg"/>', '<g transform="translate(65, 980) rotate(-90)">', '<text class="txt large italic">Latent Works</text>', '</g>', '<g transform="translate(537, 21) rotate(90)">', '<text class="txt large italic">LTNT #',Strings.toString(id_),'</text>', '</g>', '<g transform="translate(517, 22) rotate(90)">', '<text class="txt small">Issued by ',issuer_info_.name,unicode' · ', Strings.toString(stamp_count_) , stamp_count_ > 1 ? ' stamps' : ' stamp', '</text>', '</g>' '<g transform="translate(25, 25)">', '<image width="300" href="', issuer_info_.image, '"/>', '</g>', '<g transform="translate(343, 41)">', stamps_svg_, '</g>', '<g transform="translate(509, 980)">', '<text class="txt small">latent.works</text>', '</g>', '</svg>' ); if(encode_) image_ = abi.encodePacked('data:image/svg+xml;base64,', Base64.encode(image_)); return string(image_); } /// @notice return base64 encoded JSON metadata for id_ /// @param id_ the id of the LTNT to retrieve the image for /// @param encode_ encode output as base64 uri /// @return string the image string function getJSON(uint id_, bool encode_) public view returns(string memory) { LTNT.Issuer memory issuer_for_id_ = _ltnt.getIssuerFor(id_); LTNT.IssuerInfo memory issuer_info_ = LTNTIssuer(issuer_for_id_.location).issuerInfo(id_, issuer_for_id_.param); bytes memory json_ = abi.encodePacked( '{', '"name":"LTNT #',Strings.toString(id_),'", ', '"image": "', getImage(id_, true),'", ', '"description": "latent.works",', '"attributes": [', '{"trait_type": "Stamps", "value": ',Strings.toString(_ltnt.getStamps(id_).length),'},', '{"trait_type": "Issuer", "value": "', issuer_info_.name, '"}', ']', '}' ); if(encode_) json_ = abi.encodePacked('data:application/json;base64,', Base64.encode(json_)); return string(json_); } } /// @title LTNTIssuer /// @author troels_a /// @dev LTNTIssuers implement this contract and use issuerInfo to pass info to LTNT main contract abstract contract LTNTIssuer { function issuerInfo(uint id_, LTNT.Param memory param_) external virtual view returns(LTNT.IssuerInfo memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.2; library Rando { function number(string memory seed, uint min, uint max) internal pure returns (uint) { if (max <= min) return min; return (uint256(keccak256(abi.encodePacked(seed))) % (max - min)) + min; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.2; contract XanhMonoRegularLatin { function fontFace() public pure returns(string memory){ return "@font-face { font-family: 'Xanh Mono'; font-style: normal; font-weight: 400; font-display: swap; src: url(data:font/woff2;base64,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) format('woff2'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }"; } } contract XanhMonoItalicLatin { function fontFace() public pure returns(string memory){ return "@font-face { font-family: 'Xanh Mono'; font-style: italic; font-weight: 400; font-display: swap; src: url(data:font/woff2;base64,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) format('woff2'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }"; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/ERC721.sol) pragma solidity ^0.8.0; import "./IERC721.sol"; import "./IERC721Receiver.sol"; import "./extensions/IERC721Metadata.sol"; import "../../utils/Address.sol"; import "../../utils/Context.sol"; import "../../utils/Strings.sol"; import "../../utils/introspection/ERC165.sol"; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: balance query for the zero address"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _owners[tokenId]; require(owner != address(0), "ERC721: owner query for nonexistent token"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not owner nor approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { require(_exists(tokenId), "ERC721: approved query for nonexistent token"); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _safeTransfer(from, to, tokenId, _data); } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * `_data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer( address from, address to, uint256 tokenId, bytes memory _data ) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _owners[tokenId] != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { require(_exists(tokenId), "ERC721: operator query for nonexistent token"); address owner = ERC721.ownerOf(tokenId); return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory _data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId); _balances[to] += 1; _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); _balances[owner] -= 1; delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); // Clear approvals from the previous owner _approve(address(0), tokenId); _balances[from] -= 1; _balances[to] += 1; _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId); } /** * @dev Approve `to` to operate on `tokenId` * * Emits a {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits a {ApprovalForAll} event. */ function _setApprovalForAll( address owner, address operator, bool approved ) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param _data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0; /// @title Base64 /// @author Brecht Devos - <[email protected]> /// @notice Provides functions for encoding/decoding base64 library Base64 { string internal constant TABLE_ENCODE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; bytes internal constant TABLE_DECODE = hex"0000000000000000000000000000000000000000000000000000000000000000" hex"00000000000000000000003e0000003f3435363738393a3b3c3d000000000000" hex"00000102030405060708090a0b0c0d0e0f101112131415161718190000000000" hex"001a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132330000000000"; function encode(bytes memory data) internal pure returns (string memory) { if (data.length == 0) return ''; // load the table into memory string memory table = TABLE_ENCODE; // multiply by 4/3 rounded up uint256 encodedLen = 4 * ((data.length + 2) / 3); // add some extra buffer at the end required for the writing string memory result = new string(encodedLen + 32); assembly { // set the actual output length mstore(result, encodedLen) // prepare the lookup table let tablePtr := add(table, 1) // input ptr let dataPtr := data let endPtr := add(dataPtr, mload(data)) // result ptr, jump over length let resultPtr := add(result, 32) // run over the input, 3 bytes at a time for {} lt(dataPtr, endPtr) {} { // read 3 bytes dataPtr := add(dataPtr, 3) let input := mload(dataPtr) // write 4 characters mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F)))) resultPtr := add(resultPtr, 1) mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F)))) resultPtr := add(resultPtr, 1) mstore8(resultPtr, mload(add(tablePtr, and(shr( 6, input), 0x3F)))) resultPtr := add(resultPtr, 1) mstore8(resultPtr, mload(add(tablePtr, and( input, 0x3F)))) resultPtr := add(resultPtr, 1) } // padding with '=' switch mod(mload(data), 3) case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) } case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) } } return result; } function decode(string memory _data) internal pure returns (bytes memory) { bytes memory data = bytes(_data); if (data.length == 0) return new bytes(0); require(data.length % 4 == 0, "invalid base64 decoder input"); // load the table into memory bytes memory table = TABLE_DECODE; // every 4 characters represent 3 bytes uint256 decodedLen = (data.length / 4) * 3; // add some extra buffer at the end required for the writing bytes memory result = new bytes(decodedLen + 32); assembly { // padding with '=' let lastBytes := mload(add(data, mload(data))) if eq(and(lastBytes, 0xFF), 0x3d) { decodedLen := sub(decodedLen, 1) if eq(and(lastBytes, 0xFFFF), 0x3d3d) { decodedLen := sub(decodedLen, 1) } } // set the actual output length mstore(result, decodedLen) // prepare the lookup table let tablePtr := add(table, 1) // input ptr let dataPtr := data let endPtr := add(dataPtr, mload(data)) // result ptr, jump over length let resultPtr := add(result, 32) // run over the input, 4 characters at a time for {} lt(dataPtr, endPtr) {} { // read 4 characters dataPtr := add(dataPtr, 4) let input := mload(dataPtr) // write 3 bytes let output := add( add( shl(18, and(mload(add(tablePtr, and(shr(24, input), 0xFF))), 0xFF)), shl(12, and(mload(add(tablePtr, and(shr(16, input), 0xFF))), 0xFF))), add( shl( 6, and(mload(add(tablePtr, and(shr( 8, input), 0xFF))), 0xFF)), and(mload(add(tablePtr, and( input , 0xFF))), 0xFF) ) ) mstore(resultPtr, shl(232, output)) resultPtr := add(resultPtr, 3) } } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; import "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
{ "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"ltnt_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_generator","outputs":[{"internalType":"contract LWMempools_Gen","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_ltnt","outputs":[{"internalType":"contract LTNT","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string[4]","name":"parts_","type":"string[4]"},{"internalType":"string","name":"filter_","type":"string"}],"name":"addBank","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pool_id_","type":"uint256"},{"internalType":"uint256","name":"epoch_","type":"uint256"}],"name":"fixEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index_","type":"uint256"}],"name":"getBank","outputs":[{"components":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string[4]","name":"_parts","type":"string[4]"},{"internalType":"string","name":"_filter","type":"string"},{"internalType":"uint256[15]","name":"_pools","type":"uint256[15]"}],"internalType":"struct LWMempools.Bank","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBankCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBanks","outputs":[{"components":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string[4]","name":"_parts","type":"string[4]"},{"internalType":"string","name":"_filter","type":"string"},{"internalType":"uint256[15]","name":"_pools","type":"uint256[15]"}],"internalType":"struct LWMempools.Bank[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pool_id_","type":"uint256"}],"name":"getCurrentEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pool_id_","type":"uint256"}],"name":"getEpochLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pool_id_","type":"uint256"}],"name":"getFixedEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMeta","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pool_id_","type":"uint256"}],"name":"getPoolBank","outputs":[{"components":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string[4]","name":"_parts","type":"string[4]"},{"internalType":"string","name":"_filter","type":"string"},{"internalType":"uint256[15]","name":"_pools","type":"uint256[15]"}],"internalType":"struct LWMempools.Bank","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pool_id_","type":"uint256"}],"name":"getPoolBankIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pool_id_","type":"uint256"}],"name":"getPoolFilter","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pool_id_","type":"uint256"},{"internalType":"bool","name":"encode_","type":"bool"}],"name":"getPoolImage","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pool_id_","type":"uint256"}],"name":"getPoolPart","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pool_id_","type":"uint256"}],"name":"getPoolPartIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pool_id_","type":"uint256"},{"internalType":"string","name":"append_","type":"string"}],"name":"getPoolSeed","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"components":[{"internalType":"uint256","name":"_uint","type":"uint256"},{"internalType":"address","name":"_address","type":"address"},{"internalType":"string","name":"_string","type":"string"},{"internalType":"bool","name":"_bool","type":"bool"}],"internalType":"struct LTNT.Param","name":"param_","type":"tuple"}],"name":"issuerInfo","outputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"image","type":"string"}],"internalType":"struct LTNT.IssuerInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"bank_index_","type":"uint256"},{"internalType":"uint256","name":"pool_index_","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"ltnt_id_","type":"uint256"},{"internalType":"uint256","name":"bank_index_","type":"uint256"},{"internalType":"uint256","name":"pool_index_","type":"uint256"}],"name":"mintWithLTNT","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pool_id_","type":"uint256"}],"name":"poolExists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"meta_","type":"address"}],"name":"setMeta","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pool_id_","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to_","type":"address"}],"name":"withdrawAllTo","outputs":[],"stateMutability":"payable","type":"function"}]
Contract Creation Code
60c06040523480156200001157600080fd5b506040516200c79a3803806200c79a8339818101604052810190620000379190620003bd565b6040518060400160405280600881526020017f4d656d706f6f6c730000000000000000000000000000000000000000000000008152506040518060400160405280600581526020017f4d4d504c530000000000000000000000000000000000000000000000000000008152508160009080519060200190620000bb929190620002da565b508060019080519060200190620000d4929190620002da565b505050620000f7620000eb6200020c60201b60201c565b6200021460201b60201c565b60016007819055508073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b8152505060405162000144906200036b565b604051809103906000f08015801562000161573d6000803e3d6000fd5b5073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b81525050604051620001a69062000379565b604051809103906000f080158015620001c3573d6000803e3d6000fd5b5061014760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506200049c565b600033905090565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b828054620002e8906200041d565b90600052602060002090601f0160209004810192826200030c576000855562000358565b82601f106200032757805160ff191683800117855562000358565b8280016001018555821562000358579182015b82811115620003575782518255916020019190600101906200033a565b5b50905062000367919062000387565b5090565b614eb38062005ebf83390190565b611a28806200ad7283390190565b5b80821115620003a257600081600090555060010162000388565b5090565b600081519050620003b78162000482565b92915050565b600060208284031215620003d057600080fd5b6000620003e084828501620003a6565b91505092915050565b6000620003f682620003fd565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600060028204905060018216806200043657607f821691505b602082108114156200044d576200044c62000453565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6200048d81620003e9565b81146200049957600080fd5b50565b60805160601c60a05160601c6159db620004e46000396000818161176001526119f3015260008181610d7a01528181611bc801528181611cc70152611ecc01526159db6000f3fe6080604052600436106102515760003560e01c80637869b9f311610139578063a22cb465116100b6578063c87b56dd1161007a578063c87b56dd1461092e578063c95b41621461096b578063ca9add8f146109a8578063d381fa6a146109c4578063e985e9c514610a01578063f2fde38b14610a3e57610251565b8063a22cb4651461084b578063a79af2ce14610874578063b88d4fde1461089f578063be95592e146108c8578063c3b95b1b146108f157610251565b80638da5cb5b116100fd5780638da5cb5b1461073e57806395d89b4114610769578063967f2222146107945780639b0f2b5a146107d15780639bfaab661461080e57610251565b80637869b9f3146106665780638060156b146106a357806382219416146106ce5780638b83ade8146106f75780638d859f3e1461071357610251565b80633c6e8e81116101d25780636352211e116101965780636352211e1461051e57806366044cf51461055b5780636c7f590f1461059857806370a08231146105d5578063715018a61461061257806373663d081461062957610251565b80633c6e8e811461041357806342842e0e1461045057806343347e0e146104795780635d7035c6146104a45780635e1871d2146104e157610251565b806318160ddd1161021957806318160ddd1461034f5780631adfee421461037a5780631b2ef1ca146103a357806323b872dd146103bf5780632e44715d146103e857610251565b806301ffc9a71461025657806306fdde0314610293578063081812fc146102be578063095ea7b3146102fb57806309e61a7314610324575b600080fd5b34801561026257600080fd5b5061027d60048036038101906102789190613eb8565b610a67565b60405161028a91906149f3565b60405180910390f35b34801561029f57600080fd5b506102a8610b49565b6040516102b59190614a44565b60405180910390f35b3480156102ca57600080fd5b506102e560048036038101906102e09190613fe2565b610bdb565b6040516102f2919061496a565b60405180910390f35b34801561030757600080fd5b50610322600480360381019061031d9190613e53565b610c60565b005b34801561033057600080fd5b50610339610d78565b6040516103469190614a0e565b60405180910390f35b34801561035b57600080fd5b50610364610d9c565b6040516103719190614daa565b60405180910390f35b34801561038657600080fd5b506103a1600480360381019061039c9190613f4b565b610da6565b005b6103bd60048036038101906103b891906140ef565b610f74565b005b3480156103cb57600080fd5b506103e660048036038101906103e19190613d4d565b61113c565b005b3480156103f457600080fd5b506103fd61119c565b60405161040a9190614daa565b60405180910390f35b34801561041f57600080fd5b5061043a60048036038101906104359190613fe2565b61122b565b6040516104479190614d66565b60405180910390f35b34801561045c57600080fd5b5061047760048036038101906104729190613d4d565b61124b565b005b34801561048557600080fd5b5061048e61126b565b60405161049b91906149d1565b60405180910390f35b3480156104b057600080fd5b506104cb60048036038101906104c69190613fe2565b6115db565b6040516104d89190614daa565b60405180910390f35b3480156104ed57600080fd5b5061050860048036038101906105039190613fe2565b611628565b60405161051591906149f3565b60405180910390f35b34801561052a57600080fd5b5061054560048036038101906105409190613fe2565b61163a565b604051610552919061496a565b60405180910390f35b34801561056757600080fd5b50610582600480360381019061057d9190613fe2565b6116ec565b60405161058f9190614daa565b60405180910390f35b3480156105a457600080fd5b506105bf60048036038101906105ba919061400b565b61170a565b6040516105cc9190614a44565b60405180910390f35b3480156105e157600080fd5b506105fc60048036038101906105f79190613cbf565b61181a565b6040516106099190614daa565b60405180910390f35b34801561061e57600080fd5b506106276118d2565b005b34801561063557600080fd5b50610650600480360381019061064b9190613fe2565b61195a565b60405161065d9190614daa565b60405180910390f35b34801561067257600080fd5b5061068d60048036038101906106889190613fe2565b611978565b60405161069a9190614daa565b60405180910390f35b3480156106af57600080fd5b506106b86119f1565b6040516106c59190614a29565b60405180910390f35b3480156106da57600080fd5b506106f560048036038101906106f091906140ef565b611a15565b005b610711600480360381019061070c919061412b565b611af3565b005b34801561071f57600080fd5b50610728611faf565b6040516107359190614daa565b60405180910390f35b34801561074a57600080fd5b50610753611fbb565b604051610760919061496a565b60405180910390f35b34801561077557600080fd5b5061077e611fe5565b60405161078b9190614a44565b60405180910390f35b3480156107a057600080fd5b506107bb60048036038101906107b6919061409b565b612077565b6040516107c89190614d88565b60405180910390f35b3480156107dd57600080fd5b506107f860048036038101906107f39190613fe2565b6120df565b6040516108059190614a44565b60405180910390f35b34801561081a57600080fd5b5061083560048036038101906108309190614047565b612140565b6040516108429190614a44565b60405180910390f35b34801561085757600080fd5b50610872600480360381019061086d9190613e17565b612192565b005b34801561088057600080fd5b506108896121a8565b604051610896919061496a565b60405180910390f35b3480156108ab57600080fd5b506108c660048036038101906108c19190613d9c565b6121d3565b005b3480156108d457600080fd5b506108ef60048036038101906108ea9190613cbf565b612235565b005b3480156108fd57600080fd5b5061091860048036038101906109139190613fe2565b6122f6565b6040516109259190614d66565b60405180910390f35b34801561093a57600080fd5b5061095560048036038101906109509190613fe2565b61257e565b6040516109629190614a44565b60405180910390f35b34801561097757600080fd5b50610992600480360381019061098d9190613fe2565b61263b565b60405161099f9190614a44565b60405180910390f35b6109c260048036038101906109bd9190613cbf565b612722565b005b3480156109d057600080fd5b506109eb60048036038101906109e69190613fe2565b6127df565b6040516109f89190614daa565b60405180910390f35b348015610a0d57600080fd5b50610a286004803603810190610a239190613d11565b612841565b604051610a3591906149f3565b60405180910390f35b348015610a4a57600080fd5b50610a656004803603810190610a609190613cbf565b6128d5565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610b3257507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610b425750610b41826129cd565b5b9050919050565b606060008054610b5890615225565b80601f0160208091040260200160405190810160405280929190818152602001828054610b8490615225565b8015610bd15780601f10610ba657610100808354040283529160200191610bd1565b820191906000526020600020905b815481529060010190602001808311610bb457829003601f168201915b5050505050905090565b6000610be682612a37565b610c25576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c1c90614c66565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610c6b8261163a565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610cdc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cd390614cc6565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610cfb612aa3565b73ffffffffffffffffffffffffffffffffffffffff161480610d2a5750610d2981610d24612aa3565b612841565b5b610d69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6090614be6565b60405180910390fd5b610d738383612aab565b505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000600854905090565b610dae612aa3565b73ffffffffffffffffffffffffffffffffffffffff16610dcc611fbb565b73ffffffffffffffffffffffffffffffffffffffff1614610e22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e1990614c86565b60405180910390fd5b6000610e2c61119c565b9050600f8110610e71576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6890614a66565b60405180910390fd5b83600982600f8110610eac577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b601502016000019080519060200190610ec69291906137d2565b5082600982600f8110610f02577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60150201600101906004610f17929190613858565b5081600982600f8110610f53577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b601502016005019080519060200190610f6d9291906137d2565b5050505050565b60026007541415610fba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fb190614d46565b60405180910390fd5b60026007819055506000610fcc61119c565b9050670214e8348c4f00003414611018576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161100f90614b26565b60405180910390fd5b60008111801561102757508083105b611066576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105d90614ce6565b60405180910390fd5b6000600984600f81106110a2577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6015020160060183600f81106110e1577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b015414611123576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161111a90614b06565b60405180910390fd5b61112e338484612b64565b505060016007819055505050565b61114d611147612aa3565b82612c4d565b61118c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118390614d06565b60405180910390fd5b611197838383612d2b565b505050565b60008060005b600f811015611223576000600982600f81106111e7577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6015020160000180546111f990615225565b9050111561121057818061120c90615288565b9250505b808061121b90615288565b9150506111a2565b508091505090565b6112336138ab565b61124461123f836116ec565b6122f6565b9050919050565b611266838383604051806020016040528060008152506121d3565b505050565b6060600061127761119c565b905060008167ffffffffffffffff8111156112bb577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156112f457816020015b6112e16138ab565b8152602001906001900390816112d95790505b50905060005b828110156115d257600981600f811061133c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6015020160405180608001604052908160008201805461135b90615225565b80601f016020809104026020016040519081016040528092919081815260200182805461138790615225565b80156113d45780601f106113a9576101008083540402835291602001916113d4565b820191906000526020600020905b8154815290600101906020018083116113b757829003601f168201915b5050505050815260200160018201600480602002604051908101604052809291906000905b8282101561149c57838201805461140f90615225565b80601f016020809104026020016040519081016040528092919081815260200182805461143b90615225565b80156114885780601f1061145d57610100808354040283529160200191611488565b820191906000526020600020905b81548152906001019060200180831161146b57829003601f168201915b5050505050815260200190600101906113f9565b5050505081526020016005820180546114b490615225565b80601f01602080910402602001604051908101604052809291908181526020018280546114e090615225565b801561152d5780601f106115025761010080835404028352916020019161152d565b820191906000526020600020905b81548152906001019060200180831161151057829003601f168201915b5050505050815260200160068201600f806020026040519081016040528092919082600f8015611572576020028201915b81548152602001906001019080831161155e575b5050505050815250508282815181106115b4577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018190525080806115ca90615288565b9150506112fa565b50809250505090565b60008060016115e9846127df565b6101446000868152602001908152602001600020544261160991906150f3565b6116139190615068565b61161d9190615012565b905080915050919050565b600061163382612a37565b9050919050565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156116e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116da90614c26565b60405180910390fd5b80915050919050565b60006101456000838152602001908152602001600020549050919050565b606061171583611628565b61173057604051806020016040528060008152509050611814565b60006101466000858152602001908152602001600020549050600181101561175e5761175b846115db565b90505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663662ca4b28583866040518463ffffffff1660e01b81526004016117bb93929190614e47565b60006040518083038186803b1580156117d357600080fd5b505afa1580156117e7573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906118109190613f0a565b9150505b92915050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561188b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161188290614c06565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6118da612aa3565b73ffffffffffffffffffffffffffffffffffffffff166118f8611fbb565b73ffffffffffffffffffffffffffffffffffffffff161461194e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161194590614c86565b60405180910390fd5b6119586000612f92565b565b60006101466000838152602001908152602001600020549050919050565b6000806119848361122b565b905060006119c7846040518060400160405280600481526020017f7061727400000000000000000000000000000000000000000000000000000000815250612140565b90506119e8816000600185602001515060046119e391906150f3565b613058565b92505050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff16611a358361163a565b73ffffffffffffffffffffffffffffffffffffffff1614611a8b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a8290614d26565b60405180910390fd5b80611a95836115db565b1115611ad6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611acd90614bc6565b60405180910390fd5b806101466000848152602001908152602001600020819055505050565b60026007541415611b39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b3090614d46565b60405180910390fd5b60026007819055506000611b4b61119c565b905060026003670214e8348c4f0000611b649190615068565b611b6e9190615099565b3414611baf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba690614b26565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636352211e866040518263ffffffff1660e01b8152600401611c1f9190614daa565b60206040518083038186803b158015611c3757600080fd5b505afa158015611c4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c6f9190613ce8565b73ffffffffffffffffffffffffffffffffffffffff1614611cc5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cbc90614b86565b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f834e6c585306040518363ffffffff1660e01b8152600401611d20929190614dc5565b60206040518083038186803b158015611d3857600080fd5b505afa158015611d4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d709190613e8f565b15611db0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611da790614ca6565b60405180910390fd5b600081118015611dbf57508083105b611dfe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611df590614ce6565b60405180910390fd5b6000600984600f8110611e3a577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6015020160060183600f8110611e79577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b015414611ebb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eb290614b06565b60405180910390fd5b6000611ec8338585612b64565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632a843ee0866040518060800160405280858152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001604051806020016040528060008152508152602001600015158152506040518363ffffffff1660e01b8152600401611f6e929190614e17565b600060405180830381600087803b158015611f8857600080fd5b505af1158015611f9c573d6000803e3d6000fd5b5050505050506001600781905550505050565b670214e8348c4f000081565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060018054611ff490615225565b80601f016020809104026020016040519081016040528092919081815260200182805461202090615225565b801561206d5780601f106120425761010080835404028352916020019161206d565b820191906000526020600020905b81548152906001019060200180831161205057829003601f168201915b5050505050905090565b61207f6138df565b60405180604001604052806040518060400160405280600881526020017f6d656d706f6f6c7300000000000000000000000000000000000000000000000081525081526020016120d48460000151600161170a565b815250905092915050565b606060006120ec8361122b565b905080602001516120fc84611978565b60048110612133577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020020151915050919050565b606061215f6101446000858152602001908152602001600020546130be565b612168846130be565b8360405160200161217b93929190614939565b604051602081830303815290604052905092915050565b6121a461219d612aa3565b838361326b565b5050565b600061014760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6121e46121de612aa3565b83612c4d565b612223576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161221a90614d06565b60405180910390fd5b61222f848484846133d8565b50505050565b61223d612aa3565b73ffffffffffffffffffffffffffffffffffffffff1661225b611fbb565b73ffffffffffffffffffffffffffffffffffffffff16146122b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122a890614c86565b60405180910390fd5b8061014760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6122fe6138ab565b600982600f8110612338577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6015020160405180608001604052908160008201805461235790615225565b80601f016020809104026020016040519081016040528092919081815260200182805461238390615225565b80156123d05780601f106123a5576101008083540402835291602001916123d0565b820191906000526020600020905b8154815290600101906020018083116123b357829003601f168201915b5050505050815260200160018201600480602002604051908101604052809291906000905b8282101561249857838201805461240b90615225565b80601f016020809104026020016040519081016040528092919081815260200182805461243790615225565b80156124845780601f1061245957610100808354040283529160200191612484565b820191906000526020600020905b81548152906001019060200180831161246757829003601f168201915b5050505050815260200190600101906123f5565b5050505081526020016005820180546124b090615225565b80601f01602080910402602001604051908101604052809291908181526020018280546124dc90615225565b80156125295780601f106124fe57610100808354040283529160200191612529565b820191906000526020600020905b81548152906001019060200180831161250c57829003601f168201915b5050505050815260200160068201600f806020026040519081016040528092919082600f801561256e576020028201915b81548152602001906001019080831161255a575b5050505050815250509050919050565b606061014760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663477043bb8360016040518363ffffffff1660e01b81526004016125df929190614dee565b60006040518083038186803b1580156125f757600080fd5b505afa15801561260b573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906126349190613f0a565b9050919050565b60606009610145600084815260200190815260200160002054600f811061268b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60150201600501805461269d90615225565b80601f01602080910402602001604051908101604052809291908181526020018280546126c990615225565b80156127165780601f106126eb57610100808354040283529160200191612716565b820191906000526020600020905b8154815290600101906020018083116126f957829003601f168201915b50505050509050919050565b61272a612aa3565b73ffffffffffffffffffffffffffffffffffffffff16612748611fbb565b73ffffffffffffffffffffffffffffffffffffffff161461279e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161279590614c86565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f193505050506127dc57600080fd5b50565b60006276a700612830612827846040518060400160405280600581526020017f65706f6368000000000000000000000000000000000000000000000000000000815250612140565b60016006613058565b61283a9190615099565b9050919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6128dd612aa3565b73ffffffffffffffffffffffffffffffffffffffff166128fb611fbb565b73ffffffffffffffffffffffffffffffffffffffff1614612951576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161294890614c86565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156129c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129b890614aa6565b60405180910390fd5b6129ca81612f92565b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16612b1e8361163a565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600060086000815480929190612b7990615288565b9190505550612b8a84600854613434565b426101446000600854815260200190815260200160002081905550826101456000600854815260200190815260200160002081905550600854600984600f8110612bfd577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6015020160060183600f8110612c3c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b018190555060085490509392505050565b6000612c5882612a37565b612c97576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c8e90614ba6565b60405180910390fd5b6000612ca28361163a565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612ce45750612ce38185612841565b5b80612d2257508373ffffffffffffffffffffffffffffffffffffffff16612d0a84610bdb565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16612d4b8261163a565b73ffffffffffffffffffffffffffffffffffffffff1614612da1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d9890614ac6565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612e11576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e0890614b46565b60405180910390fd5b612e1c83838361360e565b612e27600082612aab565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612e7791906150f3565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612ece9190615012565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612f8d838383613613565b505050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000828211613069578290506130b7565b82838361307691906150f3565b856040516020016130879190614922565b6040516020818303038152906040528051906020012060001c6130aa91906152d1565b6130b49190615012565b90505b9392505050565b60606000821415613106576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050613266565b600082905060005b6000821461313857808061312190615288565b915050600a826131319190615068565b915061310e565b60008167ffffffffffffffff81111561317a577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156131ac5781602001600182028036833780820191505090505b5090505b6000851461325f576001826131c591906150f3565b9150600a856131d491906152d1565b60306131e09190615012565b60f81b81838151811061321c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856132589190615068565b94506131b0565b8093505050505b919050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156132da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132d190614b66565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516133cb91906149f3565b60405180910390a3505050565b6133e3848484612d2b565b6133ef84848484613618565b61342e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161342590614a86565b60405180910390fd5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156134a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161349b90614c46565b60405180910390fd5b6134ad81612a37565b156134ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016134e490614ae6565b60405180910390fd5b6134f96000838361360e565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546135499190615012565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461360a60008383613613565b5050565b505050565b505050565b60006136398473ffffffffffffffffffffffffffffffffffffffff166137af565b156137a2578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613662612aa3565b8786866040518563ffffffff1660e01b81526004016136849493929190614985565b602060405180830381600087803b15801561369e57600080fd5b505af19250505080156136cf57506040513d601f19601f820116820180604052508101906136cc9190613ee1565b60015b613752573d80600081146136ff576040519150601f19603f3d011682016040523d82523d6000602084013e613704565b606091505b5060008151141561374a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161374190614a86565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149150506137a7565b600190505b949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b8280546137de90615225565b90600052602060002090601f0160209004810192826138005760008555613847565b82601f1061381957805160ff1916838001178555613847565b82800160010185558215613847579182015b8281111561384657825182559160200191906001019061382b565b5b50905061385491906138f9565b5090565b826004810192821561389a579160200282015b828111156138995782518290805190602001906138899291906137d2565b509160200191906001019061386b565b5b5090506138a79190613916565b5090565b6040518060800160405280606081526020016138c561393a565b8152602001606081526020016138d9613961565b81525090565b604051806040016040528060608152602001606081525090565b5b808211156139125760008160009055506001016138fa565b5090565b5b80821115613936576000818161392d9190613984565b50600101613917565b5090565b60405180608001604052806004905b60608152602001906001900390816139495790505090565b604051806101e00160405280600f90602082028036833780820191505090505090565b50805461399090615225565b6000825580601f106139a257506139c1565b601f0160209004906000526020600020908101906139c091906138f9565b5b50565b60006139d76139d284614ea3565b614e7e565b905080828560208602820111156139ed57600080fd5b60005b85811015613a3757813567ffffffffffffffff811115613a0f57600080fd5b808601613a1c8982613bca565b855260208501945060208401935050506001810190506139f0565b5050509392505050565b6000613a54613a4f84614ec9565b614e7e565b905082815260208101848484011115613a6c57600080fd5b613a778482856151e3565b509392505050565b6000613a92613a8d84614efa565b614e7e565b905082815260208101848484011115613aaa57600080fd5b613ab58482856151e3565b509392505050565b6000613ad0613acb84614efa565b614e7e565b905082815260208101848484011115613ae857600080fd5b613af38482856151f2565b509392505050565b600081359050613b0a81615949565b92915050565b600081519050613b1f81615949565b92915050565b600082601f830112613b3657600080fd5b6004613b438482856139c4565b91505092915050565b600081359050613b5b81615960565b92915050565b600081519050613b7081615960565b92915050565b600081359050613b8581615977565b92915050565b600081519050613b9a81615977565b92915050565b600082601f830112613bb157600080fd5b8135613bc1848260208601613a41565b91505092915050565b600082601f830112613bdb57600080fd5b8135613beb848260208601613a7f565b91505092915050565b600082601f830112613c0557600080fd5b8151613c15848260208601613abd565b91505092915050565b600060808284031215613c3057600080fd5b613c3a6080614e7e565b90506000613c4a84828501613caa565b6000830152506020613c5e84828501613afb565b602083015250604082013567ffffffffffffffff811115613c7e57600080fd5b613c8a84828501613bca565b6040830152506060613c9e84828501613b4c565b60608301525092915050565b600081359050613cb98161598e565b92915050565b600060208284031215613cd157600080fd5b6000613cdf84828501613afb565b91505092915050565b600060208284031215613cfa57600080fd5b6000613d0884828501613b10565b91505092915050565b60008060408385031215613d2457600080fd5b6000613d3285828601613afb565b9250506020613d4385828601613afb565b9150509250929050565b600080600060608486031215613d6257600080fd5b6000613d7086828701613afb565b9350506020613d8186828701613afb565b9250506040613d9286828701613caa565b9150509250925092565b60008060008060808587031215613db257600080fd5b6000613dc087828801613afb565b9450506020613dd187828801613afb565b9350506040613de287828801613caa565b925050606085013567ffffffffffffffff811115613dff57600080fd5b613e0b87828801613ba0565b91505092959194509250565b60008060408385031215613e2a57600080fd5b6000613e3885828601613afb565b9250506020613e4985828601613b4c565b9150509250929050565b60008060408385031215613e6657600080fd5b6000613e7485828601613afb565b9250506020613e8585828601613caa565b9150509250929050565b600060208284031215613ea157600080fd5b6000613eaf84828501613b61565b91505092915050565b600060208284031215613eca57600080fd5b6000613ed884828501613b76565b91505092915050565b600060208284031215613ef357600080fd5b6000613f0184828501613b8b565b91505092915050565b600060208284031215613f1c57600080fd5b600082015167ffffffffffffffff811115613f3657600080fd5b613f4284828501613bf4565b91505092915050565b600080600060608486031215613f6057600080fd5b600084013567ffffffffffffffff811115613f7a57600080fd5b613f8686828701613bca565b935050602084013567ffffffffffffffff811115613fa357600080fd5b613faf86828701613b25565b925050604084013567ffffffffffffffff811115613fcc57600080fd5b613fd886828701613bca565b9150509250925092565b600060208284031215613ff457600080fd5b600061400284828501613caa565b91505092915050565b6000806040838503121561401e57600080fd5b600061402c85828601613caa565b925050602061403d85828601613b4c565b9150509250929050565b6000806040838503121561405a57600080fd5b600061406885828601613caa565b925050602083013567ffffffffffffffff81111561408557600080fd5b61409185828601613bca565b9150509250929050565b600080604083850312156140ae57600080fd5b60006140bc85828601613caa565b925050602083013567ffffffffffffffff8111156140d957600080fd5b6140e585828601613c1e565b9150509250929050565b6000806040838503121561410257600080fd5b600061411085828601613caa565b925050602061412185828601613caa565b9150509250929050565b60008060006060848603121561414057600080fd5b600061414e86828701613caa565b935050602061415f86828701613caa565b925050604061417086828701613caa565b9150509250925092565b6000614186838361438e565b905092915050565b600061419a8383614779565b905092915050565b60006141ae8383614904565b60208301905092915050565b6141c381615127565b82525050565b6141d281615127565b82525050565b60006141e382614f4f565b6141ed8185614fad565b9350836020820285016141ff85614f2b565b8060005b8581101561423b578484038952815161421c858261417a565b945061422783614f86565b925060208a01995050600181019050614203565b50829750879550505050505092915050565b600061425882614f5a565b6142628185614fb8565b93508360208202850161427485614f35565b8060005b858110156142b05784840389528151614291858261418e565b945061429c83614f93565b925060208a01995050600181019050614278565b50829750879550505050505092915050565b6142cb81614f65565b6142d58184614fc9565b92506142e082614f45565b8060005b838110156143115781516142f887826141a2565b965061430383614fa0565b9250506001810190506142e4565b505050505050565b61432281615139565b82525050565b61433181615139565b82525050565b600061434282614f70565b61434c8185614fd4565b935061435c8185602086016151f2565b614365816153be565b840191505092915050565b6143798161519b565b82525050565b614388816151bf565b82525050565b600061439982614f7b565b6143a38185614fe5565b93506143b38185602086016151f2565b6143bc816153be565b840191505092915050565b60006143d282614f7b565b6143dc8185614ff6565b93506143ec8185602086016151f2565b6143f5816153be565b840191505092915050565b600061440b82614f7b565b6144158185615007565b93506144258185602086016151f2565b80840191505092915050565b600061443e600983614ff6565b9150614449826153cf565b602082019050919050565b6000614461603283614ff6565b915061446c826153f8565b604082019050919050565b6000614484602683614ff6565b915061448f82615447565b604082019050919050565b60006144a7602583614ff6565b91506144b282615496565b604082019050919050565b60006144ca601c83614ff6565b91506144d5826154e5565b602082019050919050565b60006144ed600f83614ff6565b91506144f88261550e565b602082019050919050565b6000614510600d83614ff6565b915061451b82615537565b602082019050919050565b6000614533602483614ff6565b915061453e82615560565b604082019050919050565b6000614556601983614ff6565b9150614561826155af565b602082019050919050565b6000614579600f83614ff6565b9150614584826155d8565b602082019050919050565b600061459c602c83614ff6565b91506145a782615601565b604082019050919050565b60006145bf601183614ff6565b91506145ca82615650565b602082019050919050565b60006145e2603883614ff6565b91506145ed82615679565b604082019050919050565b6000614605602a83614ff6565b9150614610826156c8565b604082019050919050565b6000614628602983614ff6565b915061463382615717565b604082019050919050565b600061464b602083614ff6565b915061465682615766565b602082019050919050565b600061466e602c83614ff6565b91506146798261578f565b604082019050919050565b6000614691602083614ff6565b915061469c826157de565b602082019050919050565b60006146b4600f83614ff6565b91506146bf82615807565b602082019050919050565b60006146d7602183614ff6565b91506146e282615830565b604082019050919050565b60006146fa600c83614ff6565b91506147058261587f565b602082019050919050565b600061471d603183614ff6565b9150614728826158a8565b604082019050919050565b6000614740600983614ff6565b915061474b826158f7565b602082019050919050565b6000614763601f83614ff6565b915061476e82615920565b602082019050919050565b6000610240830160008301518482036000860152614797828261438e565b915050602083015184820360208601526147b182826141d8565b915050604083015184820360408601526147cb828261438e565b91505060608301516147e060608601826142c2565b508091505092915050565b6000610240830160008301518482036000860152614809828261438e565b9150506020830151848203602086015261482382826141d8565b9150506040830151848203604086015261483d828261438e565b915050606083015161485260608601826142c2565b508091505092915050565b6000604083016000830151848203600086015261487a828261438e565b91505060208301518482036020860152614894828261438e565b9150508091505092915050565b60006080830160008301516148b96000860182614904565b5060208301516148cc60208601826141ba565b50604083015184820360408601526148e4828261438e565b91505060608301516148f96060860182614319565b508091505092915050565b61490d81615191565b82525050565b61491c81615191565b82525050565b600061492e8284614400565b915081905092915050565b60006149458286614400565b91506149518285614400565b915061495d8284614400565b9150819050949350505050565b600060208201905061497f60008301846141c9565b92915050565b600060808201905061499a60008301876141c9565b6149a760208301866141c9565b6149b46040830185614913565b81810360608301526149c68184614337565b905095945050505050565b600060208201905081810360008301526149eb818461424d565b905092915050565b6000602082019050614a086000830184614328565b92915050565b6000602082019050614a236000830184614370565b92915050565b6000602082019050614a3e600083018461437f565b92915050565b60006020820190508181036000830152614a5e81846143c7565b905092915050565b60006020820190508181036000830152614a7f81614431565b9050919050565b60006020820190508181036000830152614a9f81614454565b9050919050565b60006020820190508181036000830152614abf81614477565b9050919050565b60006020820190508181036000830152614adf8161449a565b9050919050565b60006020820190508181036000830152614aff816144bd565b9050919050565b60006020820190508181036000830152614b1f816144e0565b9050919050565b60006020820190508181036000830152614b3f81614503565b9050919050565b60006020820190508181036000830152614b5f81614526565b9050919050565b60006020820190508181036000830152614b7f81614549565b9050919050565b60006020820190508181036000830152614b9f8161456c565b9050919050565b60006020820190508181036000830152614bbf8161458f565b9050919050565b60006020820190508181036000830152614bdf816145b2565b9050919050565b60006020820190508181036000830152614bff816145d5565b9050919050565b60006020820190508181036000830152614c1f816145f8565b9050919050565b60006020820190508181036000830152614c3f8161461b565b9050919050565b60006020820190508181036000830152614c5f8161463e565b9050919050565b60006020820190508181036000830152614c7f81614661565b9050919050565b60006020820190508181036000830152614c9f81614684565b9050919050565b60006020820190508181036000830152614cbf816146a7565b9050919050565b60006020820190508181036000830152614cdf816146ca565b9050919050565b60006020820190508181036000830152614cff816146ed565b9050919050565b60006020820190508181036000830152614d1f81614710565b9050919050565b60006020820190508181036000830152614d3f81614733565b9050919050565b60006020820190508181036000830152614d5f81614756565b9050919050565b60006020820190508181036000830152614d8081846147eb565b905092915050565b60006020820190508181036000830152614da2818461485d565b905092915050565b6000602082019050614dbf6000830184614913565b92915050565b6000604082019050614dda6000830185614913565b614de760208301846141c9565b9392505050565b6000604082019050614e036000830185614913565b614e106020830184614328565b9392505050565b6000604082019050614e2c6000830185614913565b8181036020830152614e3e81846148a1565b90509392505050565b6000606082019050614e5c6000830186614913565b614e696020830185614913565b614e766040830184614328565b949350505050565b6000614e88614e99565b9050614e948282615257565b919050565b6000604051905090565b600067ffffffffffffffff821115614ebe57614ebd61538f565b5b602082029050919050565b600067ffffffffffffffff821115614ee457614ee361538f565b5b614eed826153be565b9050602081019050919050565b600067ffffffffffffffff821115614f1557614f1461538f565b5b614f1e826153be565b9050602081019050919050565b6000819050919050565b6000819050602082019050919050565b6000819050919050565b600060049050919050565b600081519050919050565b6000600f9050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600061501d82615191565b915061502883615191565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561505d5761505c615302565b5b828201905092915050565b600061507382615191565b915061507e83615191565b92508261508e5761508d615331565b5b828204905092915050565b60006150a482615191565b91506150af83615191565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156150e8576150e7615302565b5b828202905092915050565b60006150fe82615191565b915061510983615191565b92508282101561511c5761511b615302565b5b828203905092915050565b600061513282615171565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006151a6826151ad565b9050919050565b60006151b882615171565b9050919050565b60006151ca826151d1565b9050919050565b60006151dc82615171565b9050919050565b82818337600083830152505050565b60005b838110156152105780820151818401526020810190506151f5565b8381111561521f576000848401525b50505050565b6000600282049050600182168061523d57607f821691505b6020821081141561525157615250615360565b5b50919050565b615260826153be565b810181811067ffffffffffffffff8211171561527f5761527e61538f565b5b80604052505050565b600061529382615191565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156152c6576152c5615302565b5b600182019050919050565b60006152dc82615191565b91506152e783615191565b9250826152f7576152f6615331565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f4d41585f42414e4b530000000000000000000000000000000000000000000000600082015250565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b7f504f4f4c5f494e4445585f555345440000000000000000000000000000000000600082015250565b7f494e56414c49445f505249434500000000000000000000000000000000000000600082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f4e4f545f4c544e545f484f4c4445520000000000000000000000000000000000600082015250565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f45504f43485f4e4f545f52454143484544000000000000000000000000000000600082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000602082015250565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b7f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460008201527f656e7420746f6b656e0000000000000000000000000000000000000000000000602082015250565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f414c52454144595f5354414d5045440000000000000000000000000000000000600082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f494e56414c49445f42414e4b0000000000000000000000000000000000000000600082015250565b7f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f766564000000000000000000000000000000602082015250565b7f4e4f545f4f574e45520000000000000000000000000000000000000000000000600082015250565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b61595281615127565b811461595d57600080fd5b50565b61596981615139565b811461597457600080fd5b50565b61598081615145565b811461598b57600080fd5b50565b61599781615191565b81146159a257600080fd5b5056fea26469706673582212203cc3c29ed7b9549baa00f9a82e5ab8489c551231d1fb9788d40b5d2e66c1112764736f6c6343000804003360a060405234801561001057600080fd5b503373ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b8152505060805160601c614dc96100ea60003960008181608d0152818161015901528181610239015281816102ef015281816103a50152818161046a01528181610549015281816106e0015281816107bf0152818161095601528181610a3501528181610bc101528181610c9001528181610d6001528181610e2f01528181610efe01528181610fcd015281816110c001528181611186015261130a0152614dc96000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063662ca4b21461003b578063ed41564b1461006b575b600080fd5b6100556004803603810190610050919061189c565b610089565b6040516100629190612910565b60405180910390f35b610073611308565b60405161008091906128f5565b60405180910390f35b60607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635e1871d2856040518263ffffffff1660e01b81526004016100e49190612932565b60206040518083038186803b1580156100fc57600080fd5b505afa158015610110573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101349190611809565b61014f57604051806020016040528060008152509050611301565b6101576116de565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635d7035c6866040518263ffffffff1660e01b81526004016101b09190612932565b60206040518083038186803b1580156101c857600080fd5b505afa1580156101dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102009190611873565b8160e00181815250508060e0015184111561022d5760405180602001604052806000815250915050611301565b848160000181815250507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639bfaab66866040518263ffffffff1660e01b81526004016102909190612abf565b60006040518083038186803b1580156102a857600080fd5b505afa1580156102bc573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906102e59190611832565b81606001819052507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639b0f2b5a866040518263ffffffff1660e01b81526004016103469190612932565b60006040518083038186803b15801561035e57600080fd5b505afa158015610372573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061039b9190611832565b81604001819052507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663c95b4162866040518263ffffffff1660e01b81526004016103fc9190612932565b60006040518083038186803b15801561041457600080fd5b505afa158015610428573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906104519190611832565b8160c0018190525060005b8160e001518110156106cd577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639bfaab66876104ae8461132c565b6040516020016104be91906124c3565b6040516020818303038152906040526040518363ffffffff1660e01b81526004016104ea92919061294d565b60006040518083038186803b15801561050257600080fd5b505afa158015610516573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061053f9190611832565b82608001819052507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639bfaab668761058d8461132c565b60405160200161059d91906124a1565b6040516020818303038152906040526040518363ffffffff1660e01b81526004016105c992919061294d565b60006040518083038186803b1580156105e157600080fd5b505afa1580156105f5573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061061e9190611832565b8260a00181905250816020015161064461063f8460800151600160036114d9565b61132c565b61065e610659856080015160016103de6114d9565b61132c565b6106786106738660a0015160016103846114d9565b61132c565b61069161068c8760a00151600160056114d9565b61132c565b6040516020016106a5959493929190612408565b6040516020818303038152906040528260200181905250806106c690612d53565b905061045c565b600090505b8160e00151811015610943577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639bfaab66876107248461132c565b6040516020016107349190612507565b6040516020818303038152906040526040518363ffffffff1660e01b815260040161076092919061294d565b60006040518083038186803b15801561077857600080fd5b505afa15801561078c573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906107b59190611832565b82608001819052507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639bfaab66876108038461132c565b60405160200161081391906128b1565b6040516020818303038152906040526040518363ffffffff1660e01b815260040161083f92919061294d565b60006040518083038186803b15801561085757600080fd5b505afa15801561086b573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906108949190611832565b8260a0018190525081602001516108ba6108b58460800151600160036114d9565b61132c565b6108d46108cf856080015160016103de6114d9565b61132c565b6108ee6108e98660a0015160016103846114d9565b61132c565b6109076109028760a00151600160056114d9565b61132c565b60405160200161091b959493929190612408565b60405160208183030381529060405282602001819052508061093c90612d53565b90506106d2565b600090505b8160e00151811015610bb9577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639bfaab668761099a8461132c565b6040516020016109aa9190612529565b6040516020818303038152906040526040518363ffffffff1660e01b81526004016109d692919061294d565b60006040518083038186803b1580156109ee57600080fd5b505afa158015610a02573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610a2b9190611832565b82608001819052507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639bfaab6687610a798461132c565b604051602001610a8991906124e5565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401610ab592919061294d565b60006040518083038186803b158015610acd57600080fd5b505afa158015610ae1573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610b0a9190611832565b8260a001819052508160200151610b30610b2b8460800151600160036114d9565b61132c565b610b4a610b45856080015160016103de6114d9565b61132c565b610b64610b5f8660a0015160016103846114d9565b61132c565b610b7d610b788760a00151600160056114d9565b61132c565b604051602001610b91959493929190612408565b604051602081830303815290604052826020018190525080610bb290612d53565b9050610948565b610c7f610c7a7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639bfaab6685600001516040518263ffffffff1660e01b8152600401610c1c91906129d9565b60006040518083038186803b158015610c3457600080fd5b505afa158015610c48573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610c719190611832565b600160326114d9565b61132c565b826101000181905250610d4f610d4a7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639bfaab6685600001516040518263ffffffff1660e01b8152600401610ceb91906129ab565b60006040518083038186803b158015610d0357600080fd5b505afa158015610d17573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610d409190611832565b601461012c6114d9565b61132c565b826101200181905250610e1e610e197f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639bfaab6685600001516040518263ffffffff1660e01b8152600401610dbb919061297d565b60006040518083038186803b158015610dd357600080fd5b505afa158015610de7573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610e109190611832565b6014601e6114d9565b61132c565b826101400181905250610eed610ee87f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639bfaab6685600001516040518263ffffffff1660e01b8152600401610e8a9190612a07565b60006040518083038186803b158015610ea257600080fd5b505afa158015610eb6573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610edf9190611832565b601460c86114d9565b61132c565b826101600181905250610fbc610fb77f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639bfaab6685600001516040518263ffffffff1660e01b8152600401610f599190612a07565b60006040518083038186803b158015610f7157600080fd5b505afa158015610f85573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610fae9190611832565b600a601e6114d9565b61132c565b82610180018190525061108b6110867f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639bfaab6685600001516040518263ffffffff1660e01b81526004016110289190612a35565b60006040518083038186803b15801561104057600080fd5b505afa158015611054573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061107d9190611832565b601460646114d9565b61132c565b826101a001819052506000826101000151836101200151846101600151856101a0015186604001518760c0015161117e6111797f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639bfaab668c600001516040518263ffffffff1660e01b815260040161111b9190612a63565b60006040518083038186803b15801561113357600080fd5b505afa158015611147573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906111709190611832565b600260056114d9565b61132c565b61124461123f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639bfaab668d600001516040518263ffffffff1660e01b81526004016111e19190612a91565b60006040518083038186803b1580156111f957600080fd5b505afa15801561120d573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906112369190611832565b600260056114d9565b61132c565b8a6020015161126261125d8d60600151600060646114d9565b61132c565b61127c6112778e6060015160006101f46114d9565b61132c565b6112966112918f6060015160006101f46114d9565b61132c565b6040516020016112b19c9b9a9998979695949392919061254b565b604051602081830303815290604052905084156112fa576112d18161153f565b6040516020016112e191906128d3565b6040516020818303038152906040529350505050611301565b8093505050505b9392505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60606000821415611374576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506114d4565b600082905060005b600082146113a657808061138f90612d53565b915050600a8261139f9190612bd6565b915061137c565b60008167ffffffffffffffff8111156113e8577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f19166020018201604052801561141a5781602001600182028036833780820191505090505b5090505b600085146114cd576001826114339190612c61565b9150600a856114429190612d9c565b603061144e9190612b80565b60f81b81838151811061148a577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856114c69190612bd6565b945061141e565b8093505050505b919050565b60008282116114ea57829050611538565b8283836114f79190612c61565b85604051602001611508919061248a565b6040516020818303038152906040528051906020012060001c61152b9190612d9c565b6115359190612b80565b90505b9392505050565b6060600082511415611562576040518060200160405280600081525090506116d9565b6000604051806060016040528060408152602001614d5460409139905060006003600285516115919190612b80565b61159b9190612bd6565b60046115a79190612c07565b905060006020826115b89190612b80565b67ffffffffffffffff8111156115f7577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156116295781602001600182028036833780820191505090505b509050818152600183018586518101602084015b81831015611698576003830192508251603f8160121c168501518253600182019150603f81600c1c168501518253600182019150603f8160061c168501518253600182019150603f811685015182536001820191505061163d565b6003895106600181146116b257600281146116c2576116cd565b613d3d60f01b60028303526116cd565b603d60f81b60018303525b50505050508093505050505b919050565b604051806101c0016040528060008152602001606081526020016060815260200160608152602001606081526020016060815260200160608152602001600081526020016060815260200160608152602001606081526020016060815260200160608152602001606081525090565b600061176061175b84612b12565b612aed565b90508281526020810184848401111561177857600080fd5b611783848285612cef565b509392505050565b60008135905061179a81614d25565b92915050565b6000815190506117af81614d25565b92915050565b600082601f8301126117c657600080fd5b81516117d684826020860161174d565b91505092915050565b6000813590506117ee81614d3c565b92915050565b60008151905061180381614d3c565b92915050565b60006020828403121561181b57600080fd5b6000611829848285016117a0565b91505092915050565b60006020828403121561184457600080fd5b600082015167ffffffffffffffff81111561185e57600080fd5b61186a848285016117b5565b91505092915050565b60006020828403121561188557600080fd5b6000611893848285016117f4565b91505092915050565b6000806000606084860312156118b157600080fd5b60006118bf868287016117df565b93505060206118d0868287016117df565b92505060406118e18682870161178b565b9150509250925092565b60006118f682612b43565b6119008185612b59565b9350611910818560208601612cef565b80840191505092915050565b61192581612ccb565b82525050565b600061193682612b4e565b6119408185612b64565b9350611950818560208601612cef565b61195981612e5a565b840191505092915050565b600061196f82612b4e565b6119798185612b75565b9350611989818560208601612cef565b80840191505092915050565b60006119a2600283612b75565b91506119ad82612e6b565b600282019050919050565b60006119c5601983612b75565b91506119d082612e94565b601982019050919050565b60006119e8605783612b75565b91506119f382612ebd565b605782019050919050565b6000611a0b603083612b75565b9150611a1682612f32565b603082019050919050565b6000611a2e609183612b75565b9150611a3982612f81565b609182019050919050565b6000611a51609183612b75565b9150611a5c82613042565b609182019050919050565b6000611a7460a783612b75565b9150611a7f82613103565b60a782019050919050565b6000611a97605983612b75565b9150611aa2826131ea565b605982019050919050565b6000611aba600b83612b64565b9150611ac58261325f565b602082019050919050565b6000611add602f83612b75565b9150611ae882613288565b602f82019050919050565b6000611b00603083612b75565b9150611b0b826132d7565b603082019050919050565b6000611b2360a783612b75565b9150611b2e82613326565b60a782019050919050565b6000611b46605783612b75565b9150611b518261340d565b605782019050919050565b6000611b69605783612b75565b9150611b7482613482565b605782019050919050565b6000611b8c600283612b75565b9150611b97826134f7565b600282019050919050565b6000611baf605c83612b75565b9150611bba82613520565b605c82019050919050565b6000611bd2601583612b75565b9150611bdd82613595565b601582019050919050565b6000611bf5605883612b75565b9150611c00826135be565b605882019050919050565b6000611c18600c83612b64565b9150611c2382613633565b602082019050919050565b6000611c3b600a83612b75565b9150611c468261365c565b600a82019050919050565b6000611c5e600283612b75565b9150611c6982613685565b600282019050919050565b6000611c81603283612b75565b9150611c8c826136ae565b603282019050919050565b6000611ca4600b83612b64565b9150611caf826136fd565b602082019050919050565b6000611cc7605883612b75565b9150611cd282613726565b605882019050919050565b6000611cea600c83612b64565b9150611cf58261379b565b602082019050919050565b6000611d0d600283612b75565b9150611d18826137c4565b600282019050919050565b6000611d30600b83612b64565b9150611d3b826137ed565b602082019050919050565b6000611d53600383612b64565b9150611d5e82613816565b602082019050919050565b6000611d76601683612b75565b9150611d818261383f565b601682019050919050565b6000611d99600283612b75565b9150611da482613868565b600282019050919050565b6000611dbc600383612b64565b9150611dc782613891565b602082019050919050565b6000611ddf601083612b75565b9150611dea826138ba565b601082019050919050565b6000611e0260a883612b75565b9150611e0d826138e3565b60a882019050919050565b6000611e2560a783612b75565b9150611e30826139ca565b60a782019050919050565b6000611e48605983612b75565b9150611e5382613ab1565b605982019050919050565b6000611e6b600483612b75565b9150611e7682613b26565b600482019050919050565b6000611e8e603683612b75565b9150611e9982613b4f565b603682019050919050565b6000611eb1606483612b75565b9150611ebc82613b9e565b606482019050919050565b6000611ed4608383612b75565b9150611edf82613c39565b608382019050919050565b6000611ef760a783612b75565b9150611f0282613cfa565b60a782019050919050565b6000611f1a601a83612b75565b9150611f2582613de1565b601a82019050919050565b6000611f3d602e83612b75565b9150611f4882613e0a565b602e82019050919050565b6000611f60605883612b75565b9150611f6b82613e59565b605882019050919050565b6000611f83602583612b75565b9150611f8e82613ece565b602582019050919050565b6000611fa660a783612b75565b9150611fb182613f1d565b60a782019050919050565b6000611fc9600483612b75565b9150611fd482614004565b600482019050919050565b6000611fec60a683612b75565b9150611ff78261402d565b60a682019050919050565b600061200f606683612b75565b915061201a82614114565b606682019050919050565b6000612032601183612b75565b915061203d826141af565b601182019050919050565b6000612055602b83612b75565b9150612060826141d8565b602b82019050919050565b6000612078602583612b75565b915061208382614227565b602582019050919050565b600061209b600383612b75565b91506120a682614276565b600382019050919050565b60006120be600283612b75565b91506120c98261429f565b600282019050919050565b60006120e160a683612b75565b91506120ec826142c8565b60a682019050919050565b6000612104600283612b75565b915061210f826143af565b600282019050919050565b6000612127600783612b75565b9150612132826143d8565b600782019050919050565b600061214a600583612b75565b915061215582614401565b600582019050919050565b600061216d600083612b64565b91506121788261442a565b600082019050919050565b6000612190606883612b75565b915061219b8261442d565b606882019050919050565b60006121b3600683612b75565b91506121be826144c8565b600682019050919050565b60006121d6604983612b75565b91506121e1826144f1565b604982019050919050565b60006121f9605783612b75565b915061220482614566565b605782019050919050565b600061221c605883612b75565b9150612227826145db565b605882019050919050565b600061223f601183612b75565b915061224a82614650565b601182019050919050565b600061226260a683612b75565b915061226d82614679565b60a682019050919050565b6000612285604383612b75565b915061229082614760565b604382019050919050565b60006122a8608283612b75565b91506122b3826147d5565b608282019050919050565b60006122cb60ca83612b75565b91506122d682614896565b60ca82019050919050565b60006122ee609183612b75565b91506122f9826149a3565b609182019050919050565b6000612311609183612b75565b915061231c82614a64565b609182019050919050565b600061233460a683612b75565b915061233f82614b25565b60a682019050919050565b6000612357600683612b75565b915061236282614c0c565b600682019050919050565b600061237a600383612b75565b915061238582614c35565b600382019050919050565b600061239d601a83612b75565b91506123a882614c5e565b601a82019050919050565b60006123c0605883612b75565b91506123cb82614c87565b605882019050919050565b60006123e3600583612b75565b91506123ee82614cfc565b600582019050919050565b61240281612cc1565b82525050565b600061241482886118eb565b915061241f82612025565b915061242b8287611964565b9150612436826123d6565b91506124428286611964565b915061244d8261213d565b91506124598285611964565b915061246482612232565b91506124708284611964565b915061247b82611e5e565b91508190509695505050505050565b60006124968284611964565b915081905092915050565b60006124ac82611995565b91506124b88284611964565b915081905092915050565b60006124ce82611b7f565b91506124da8284611964565b915081905092915050565b60006124f082611c51565b91506124fc8284611964565b915081905092915050565b600061251282611d00565b915061251e8284611964565b915081905092915050565b600061253482611d8c565b91506125408284611964565b915081905092915050565b600061255682611ea4565b9150612561826121a6565b915061256c82612048565b915061257782611a8a565b9150612582826122be565b915061258d82611b39565b915061259882611b5c565b91506125a3826121ec565b91506125ae826119db565b91506125b9826123b3565b91506125c482611f53565b91506125cf8261220f565b91506125da82611be8565b91506125e582611cba565b91506125f082611e3b565b91506125fb82611fdf565b915061260682612327565b9150612611826120d4565b915061261c82612255565b915061262782611f99565b915061263282611eea565b915061263d82611e18565b915061264882611b16565b915061265382611a67565b915061265e82611df5565b915061266982611ec7565b915061267482612002565b915061267f826119fe565b915061268a826119b8565b9150612696828f611964565b91506126a182611c2e565b91506126ad828e611964565b91506126b88261208e565b91506126c38261206b565b91506126cf828d611964565b91506126da8261208e565b91506126e582611f76565b91506126f1828c611964565b91506126fc8261208e565b915061270782611c74565b9150612713828b611964565b915061271e8261208e565b915061272982612183565b915061273482611a44565b915061273f826122e1565b915061274a82611a21565b915061275582612304565b91506127608261211a565b915061276b82611dd2565b9150612777828a611964565b91506127828261236d565b915061278d82611ad0565b915061279882612278565b91506127a48289611964565b91506127af82611d69565b91506127ba82611f0d565b91506127c582611af3565b91506127d18288611964565b91506127dc82611e5e565b91506127e7826121c9565b91506127f382876118eb565b91506127fe82611fbc565b915061280982611f30565b915061281482611e81565b91506128208286611964565b915061282b8261229b565b91506128378285611964565b9150612842826120f7565b915061284e8284611964565b915061285982611e5e565b915061286482611fbc565b915061286f82611bc5565b915061287a82611ba2565b915061288582611fbc565b915061289082611fbc565b915061289b8261234a565b91508190509d9c50505050505050505050505050565b60006128bc826120b1565b91506128c88284611964565b915081905092915050565b60006128de82612390565b91506128ea8284611964565b915081905092915050565b600060208201905061290a600083018461191c565b92915050565b6000602082019050818103600083015261292a818461192b565b905092915050565b600060208201905061294760008301846123f9565b92915050565b600060408201905061296260008301856123f9565b8181036020830152612974818461192b565b90509392505050565b600060408201905061299260008301846123f9565b81810360208301526129a381611aad565b905092915050565b60006040820190506129c060008301846123f9565b81810360208301526129d181611c0b565b905092915050565b60006040820190506129ee60008301846123f9565b81810360208301526129ff81611c97565b905092915050565b6000604082019050612a1c60008301846123f9565b8181036020830152612a2d81611cdd565b905092915050565b6000604082019050612a4a60008301846123f9565b8181036020830152612a5b81611d23565b905092915050565b6000604082019050612a7860008301846123f9565b8181036020830152612a8981611d46565b905092915050565b6000604082019050612aa660008301846123f9565b8181036020830152612ab781611daf565b905092915050565b6000604082019050612ad460008301846123f9565b8181036020830152612ae581612160565b905092915050565b6000612af7612b08565b9050612b038282612d22565b919050565b6000604051905090565b600067ffffffffffffffff821115612b2d57612b2c612e2b565b5b612b3682612e5a565b9050602081019050919050565b600081519050919050565b600081519050919050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000612b8b82612cc1565b9150612b9683612cc1565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115612bcb57612bca612dcd565b5b828201905092915050565b6000612be182612cc1565b9150612bec83612cc1565b925082612bfc57612bfb612dfc565b5b828204905092915050565b6000612c1282612cc1565b9150612c1d83612cc1565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612c5657612c55612dcd565b5b828202905092915050565b6000612c6c82612cc1565b9150612c7783612cc1565b925082821015612c8a57612c89612dcd565b5b828203905092915050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6000612cd682612cdd565b9050919050565b6000612ce882612ca1565b9050919050565b60005b83811015612d0d578082015181840152602081019050612cf2565b83811115612d1c576000848401525b50505050565b612d2b82612e5a565b810181811067ffffffffffffffff82111715612d4a57612d49612e2b565b5b80604052505050565b6000612d5e82612cc1565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612d9157612d90612dcd565b5b600182019050919050565b6000612da782612cc1565b9150612db283612cc1565b925082612dc257612dc1612dfc565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f3179000000000000000000000000000000000000000000000000000000000000600082015250565b7f3c726563742069643d22736861706531222077696474683d2200000000000000600082015250565b7f3c66696c7465722069643d227334223e3c6665436f6c6f724d6174726978206960008201527f6e3d22536f75726365477261706869632220747970653d22736174757261746560208201527f222076616c7565733d2238222f3e3c2f66696c7465723e000000000000000000604082015250565b7f3c636c6970506174682069643d22636c6970223e3c75736520687265663d222360008201527f6267222f3e3c2f636c6970506174683e00000000000000000000000000000000602082015250565b7f3c7061747465726e2069643d2262617365342220783d22302220793d2230222060008201527f77696474683d223122206865696768743d2231222076696577426f783d22363060208201527f302036303020323030203230302220707265736572766541737065637452617460408201527f696f3d22784d6964594d696420736c696365223e3c75736520687265663d222360608201527f62617365222f3e3c2f7061747465726e3e000000000000000000000000000000608082015250565b7f3c7061747465726e2069643d2262617365322220783d22302220793d2230222060008201527f77696474683d223122206865696768743d2231222076696577426f783d22323060208201527f302032303020323030203230302220707265736572766541737065637452617460408201527f696f3d22784d6964594d696420736c696365223e3c75736520687265663d222360608201527f62617365222f3e3c2f7061747465726e3e000000000000000000000000000000608082015250565b7f3c66696c7465722069643d227239223e3c6665436f6c6f724d6174726978206960008201527f6e3d22536f75726365477261706869632220747970653d22687565526f74617460208201527f65222076616c7565733d22313830223e3c2f6665436f6c6f724d61747269783e60408201527f3c6665436f6c6f724d617472697820696e3d22536f757263654772617068696360608201527f2220747970653d227361747572617465222076616c7565733d2233222f3e3c2f60808201527f66696c7465723e0000000000000000000000000000000000000000000000000060a082015250565b7f3c66696c7465722069643d226e6f6e65223e3c6665436f6c6f724d617472697860008201527f20696e3d22536f75726365477261706869632220747970653d2273617475726160208201527f7465222076616c7565733d2230222f3e3c2f66696c7465723e00000000000000604082015250565b7f7368617065327769647468000000000000000000000000000000000000000000600082015250565b7f3c726563742077696474683d223130303022206865696768743d22313030302260008201527f2066696c6c3d22626c61636b222f3e0000000000000000000000000000000000602082015250565b7f3c75736520687265663d22236267222066696c6c2d6f7061636974793d22312260008201527f2066696c6c3d2275726c28236261736500000000000000000000000000000000602082015250565b7f3c66696c7465722069643d227238223e3c6665436f6c6f724d6174726978206960008201527f6e3d22536f75726365477261706869632220747970653d22687565526f74617460208201527f65222076616c7565733d22313630223e3c2f6665436f6c6f724d61747269783e60408201527f3c6665436f6c6f724d617472697820696e3d22536f757263654772617068696360608201527f2220747970653d227361747572617465222076616c7565733d2233222f3e3c2f60808201527f66696c7465723e0000000000000000000000000000000000000000000000000060a082015250565b7f3c66696c7465722069643d227331223e3c6665436f6c6f724d6174726978206960008201527f6e3d22536f75726365477261706869632220747970653d22736174757261746560208201527f222076616c7565733d2232222f3e3c2f66696c7465723e000000000000000000604082015250565b7f3c66696c7465722069643d227332223e3c6665436f6c6f724d6174726978206960008201527f6e3d22536f75726365477261706869632220747970653d22736174757261746560208201527f222076616c7565733d2234222f3e3c2f66696c7465723e000000000000000000604082015250565b7f3178000000000000000000000000000000000000000000000000000000000000600082015250565b7f3c726563742077696474683d223130303022206865696768743d22313030302260008201527f2066696c6c3d227768697465222066696c7465723d2275726c2823696e74657260208201527f6e616c2d6e6f6973652922206f7061636974793d22302e3135222f3e00000000604082015250565b7f3c672066696c7465723d2275726c2823627729223e0000000000000000000000600082015250565b7f3c66696c7465722069643d227338223e3c6665436f6c6f724d6174726978206960008201527f6e3d22536f75726365477261706869632220747970653d22736174757261746560208201527f222076616c7565733d223136222f3e3c2f66696c7465723e0000000000000000604082015250565b7f7368617065316865696768740000000000000000000000000000000000000000600082015250565b7f22206865696768743d2200000000000000000000000000000000000000000000600082015250565b7f3379000000000000000000000000000000000000000000000000000000000000600082015250565b7f3c696d6167652069643d2262617365222077696474683d22313030302220686560008201527f696768743d22313030302220687265663d220000000000000000000000000000602082015250565b7f7368617065317769647468000000000000000000000000000000000000000000600082015250565b7f3c66696c7465722069643d227339223e3c6665436f6c6f724d6174726978206960008201527f6e3d22536f75726365477261706869632220747970653d22736174757261746560208201527f222076616c7565733d223138222f3e3c2f66696c7465723e0000000000000000604082015250565b7f7368617065326865696768740000000000000000000000000000000000000000600082015250565b7f3278000000000000000000000000000000000000000000000000000000000000600082015250565b7f7368617065337769647468000000000000000000000000000000000000000000600082015250565b7f6267300000000000000000000000000000000000000000000000000000000000600082015250565b7f29222066696c7465723d2275726c2823627729222f3e00000000000000000000600082015250565b7f3378000000000000000000000000000000000000000000000000000000000000600082015250565b7f6267310000000000000000000000000000000000000000000000000000000000600082015250565b7f3c672066696c7465723d2275726c282300000000000000000000000000000000600082015250565b7f3c66696c7465722069643d22723130223e3c6665436f6c6f724d61747269782060008201527f696e3d22536f75726365477261706869632220747970653d22687565526f746160208201527f7465222076616c7565733d22323030223e3c2f6665436f6c6f724d617472697860408201527f3e3c6665436f6c6f724d617472697820696e3d22536f7572636547726170686960608201527f632220747970653d227361747572617465222076616c7565733d2233222f3e3c60808201527f2f66696c7465723e00000000000000000000000000000000000000000000000060a082015250565b7f3c66696c7465722069643d227237223e3c6665436f6c6f724d6174726978206960008201527f6e3d22536f75726365477261706869632220747970653d22687565526f74617460208201527f65222076616c7565733d22313430223e3c2f6665436f6c6f724d61747269783e60408201527f3c6665436f6c6f724d617472697820696e3d22536f757263654772617068696360608201527f2220747970653d227361747572617465222076616c7565733d2233222f3e3c2f60808201527f66696c7465723e0000000000000000000000000000000000000000000000000060a082015250565b7f3c66696c7465722069643d22733130223e3c6665436f6c6f724d61747269782060008201527f696e3d22536f75726365477261706869632220747970653d227361747572617460208201527f65222076616c7565733d223230222f3e3c2f66696c7465723e00000000000000604082015250565b7f29222f3e00000000000000000000000000000000000000000000000000000000600082015250565b7f3c75736520687265663d2223706f6f6c22207472616e73666f726d3d2273636160008201527f6c65282e352c20302e3529207472616e736c6174652800000000000000000000602082015250565b7f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323060008201527f30302f737667222076696577426f783d2230203020313030302031303030222060208201527f7072657365727665417370656374526174696f3d22784d696e594d696e206d6560408201527f6574223e00000000000000000000000000000000000000000000000000000000606082015250565b7f3c66696c7465722069643d22696e7465726e616c2d6e6f697365223e3c66655460008201527f757262756c656e636520747970653d226672616374616c4e6f6973652220626160208201527f73654672657175656e63793d22302e353522206e756d4f6374617665733d223160408201527f30222073746974636854696c65733d2273746974636822202f3e3c2f66696c7460608201527f65723e0000000000000000000000000000000000000000000000000000000000608082015250565b7f3c66696c7465722069643d227236223e3c6665436f6c6f724d6174726978206960008201527f6e3d22536f75726365477261706869632220747970653d22687565526f74617460208201527f65222076616c7565733d22313230223e3c2f6665436f6c6f724d61747269783e60408201527f3c6665436f6c6f724d617472697820696e3d22536f757263654772617068696360608201527f2220747970653d227361747572617465222076616c7565733d2233222f3e3c2f60808201527f66696c7465723e0000000000000000000000000000000000000000000000000060a082015250565b7f3c6720636c69702d706174683d2275726c2823636c697029223e000000000000600082015250565b7f3c75736520687265663d2223706f6f6c22207472616e73666f726d3d2273636160008201527f6c65282e352c20302e3529222f3e000000000000000000000000000000000000602082015250565b7f3c66696c7465722069643d227336223e3c6665436f6c6f724d6174726978206960008201527f6e3d22536f75726365477261706869632220747970653d22736174757261746560208201527f222076616c7565733d223132222f3e3c2f66696c7465723e0000000000000000604082015250565b7f3c726563742069643d22736861706533222077696474683d223230222068656960008201527f6768743d22000000000000000000000000000000000000000000000000000000602082015250565b7f3c66696c7465722069643d227235223e3c6665436f6c6f724d6174726978206960008201527f6e3d22536f75726365477261706869632220747970653d22687565526f74617460208201527f65222076616c7565733d22313030223e3c2f6665436f6c6f724d61747269783e60408201527f3c6665436f6c6f724d617472697820696e3d22536f757263654772617068696360608201527f2220747970653d227361747572617465222076616c7565733d2233222f3e3c2f60808201527f66696c7465723e0000000000000000000000000000000000000000000000000060a082015250565b7f3c2f673e00000000000000000000000000000000000000000000000000000000600082015250565b7f3c66696c7465722069643d227231223e3c6665436f6c6f724d6174726978206960008201527f6e3d22536f75726365477261706869632220747970653d22687565526f74617460208201527f65222076616c7565733d223230223e3c2f6665436f6c6f724d61747269783e3c60408201527f6665436f6c6f724d617472697820696e3d22536f75726365477261706869632260608201527f20747970653d227361747572617465222076616c7565733d2233222f3e3c2f6660808201527f696c7465723e000000000000000000000000000000000000000000000000000060a082015250565b7f3c66696c7465722069643d22696e7465726e616c2d626c75722220783d22302260008201527f20793d2230223e3c6665476175737369616e426c757220696e3d22536f75726360208201527f65477261706869632220737464446576696174696f6e3d223422202f3e3c2f6660408201527f696c7465723e0000000000000000000000000000000000000000000000000000606082015250565b7f3c75736520687265663d22237368617065000000000000000000000000000000600082015250565b7f3c636972636c652063783d22353030222063793d223530302220723d2235303060008201527f222069643d226267222f3e000000000000000000000000000000000000000000602082015250565b7f3c726563742069643d22736861706532222077696474683d223330222068656960008201527f6768743d22000000000000000000000000000000000000000000000000000000602082015250565b7f222f3e0000000000000000000000000000000000000000000000000000000000600082015250565b7f3279000000000000000000000000000000000000000000000000000000000000600082015250565b7f3c66696c7465722069643d227233223e3c6665436f6c6f724d6174726978206960008201527f6e3d22536f75726365477261706869632220747970653d22687565526f74617460208201527f65222076616c7565733d223630223e3c2f6665436f6c6f724d61747269783e3c60408201527f6665436f6c6f724d617472697820696e3d22536f75726365477261706869632260608201527f20747970653d227361747572617465222076616c7565733d2233222f3e3c2f6660808201527f696c7465723e000000000000000000000000000000000000000000000000000060a082015250565b7f2c20000000000000000000000000000000000000000000000000000000000000600082015250565b7f3c2f646566733e00000000000000000000000000000000000000000000000000600082015250565b7f2220793d22000000000000000000000000000000000000000000000000000000600082015250565b50565b7f3c7061747465726e2069643d2262617365312220783d22302220793d2230222060008201527f77696474683d223122206865696768743d2231222076696577426f783d22302060208201527f302032303020323030223e3c75736520687265663d222362617365222f3e3c2f60408201527f7061747465726e3e000000000000000000000000000000000000000000000000606082015250565b7f3c646566733e0000000000000000000000000000000000000000000000000000600082015250565b7f3c672066696c7465723d2275726c2823696e7465726e616c2d626c757229222060008201527f7472616e73666f726d3d227472616e736c61746528302c202d3130302922206960208201527f643d22706f6f6c223e0000000000000000000000000000000000000000000000604082015250565b7f3c66696c7465722069643d227333223e3c6665436f6c6f724d6174726978206960008201527f6e3d22536f75726365477261706869632220747970653d22736174757261746560208201527f222076616c7565733d2236222f3e3c2f66696c7465723e000000000000000000604082015250565b7f3c66696c7465722069643d227337223e3c6665436f6c6f724d6174726978206960008201527f6e3d22536f75726365477261706869632220747970653d22736174757261746560208201527f222076616c7565733d223134222f3e3c2f66696c7465723e0000000000000000604082015250565b7f222066696c6c3d2275726c282362617365000000000000000000000000000000600082015250565b7f3c66696c7465722069643d227234223e3c6665436f6c6f724d6174726978206960008201527f6e3d22536f75726365477261706869632220747970653d22687565526f74617460208201527f65222076616c7565733d223830223e3c2f6665436f6c6f724d61747269783e3c60408201527f6665436f6c6f724d617472697820696e3d22536f75726365477261706869632260608201527f20747970653d227361747572617465222076616c7565733d2233222f3e3c2f6660808201527f696c7465723e000000000000000000000000000000000000000000000000000060a082015250565b7f3c726563742077696474683d223130303022206865696768743d22313030302260008201527f2066696c6c2d6f7061636974793d22302e35222066696c6c3d2275726c28236260208201527f6173650000000000000000000000000000000000000000000000000000000000604082015250565b7f2c203130303029222f3e3c75736520687265663d2223706f6f6c22207472616e60008201527f73666f726d3d227363616c6528302e382c20302e3829207472616e736c61746560208201527f28313030302c203029222f3e3c75736520687265663d2223706f6f6c2220207460408201527f72616e73666f726d3d227363616c6528312c20312e3529207472616e736c617460608201527f6528000000000000000000000000000000000000000000000000000000000000608082015250565b7f3c66696c7465722069643d226277223e3c6665436f6c6f724d6174726978207460008201527f7970653d226d6174726978222076616c7565733d22302e34393120312e36353060208201527f20302e31363620302e303030202d302e34363420302e34393120312e3635302060408201527f302e31363620302e303030202d302e34363420302e34393120312e363530203060608201527f2e31363620302e303030202d302e34363420302e30303020302e30303020302e60808201527f30303020312e30303020302e303030223e3c2f6665436f6c6f724d617472697860a08201527f3e3c2f66696c7465723e0000000000000000000000000000000000000000000060c082015250565b7f3c7061747465726e2069643d2262617365332220783d22302220793d2230222060008201527f77696474683d223122206865696768743d2231222076696577426f783d22343060208201527f302034303020323030203230302220707265736572766541737065637452617460408201527f696f3d22784d6964594d696420736c696365223e3c75736520687265663d222360608201527f62617365222f3e3c2f7061747465726e3e000000000000000000000000000000608082015250565b7f3c7061747465726e2069643d2262617365352220783d22302220793d2230222060008201527f77696474683d223122206865696768743d2231222076696577426f783d22383060208201527f302038303020323030203230302220707265736572766541737065637452617460408201527f696f3d22784d6964594d696420736c696365223e3c75736520687265663d222360608201527f62617365222f3e3c2f7061747465726e3e000000000000000000000000000000608082015250565b7f3c66696c7465722069643d227232223e3c6665436f6c6f724d6174726978206960008201527f6e3d22536f75726365477261706869632220747970653d22687565526f74617460208201527f65222076616c7565733d223430223e3c2f6665436f6c6f724d61747269783e3c60408201527f6665436f6c6f724d617472697820696e3d22536f75726365477261706869632260608201527f20747970653d227361747572617465222076616c7565733d2233222f3e3c2f6660808201527f696c7465723e000000000000000000000000000000000000000000000000000060a082015250565b7f3c2f7376673e0000000000000000000000000000000000000000000000000000600082015250565b7f29223e0000000000000000000000000000000000000000000000000000000000600082015250565b7f646174613a696d6167652f7376672b786d6c3b6261736536342c000000000000600082015250565b7f3c66696c7465722069643d227335223e3c6665436f6c6f724d6174726978206960008201527f6e3d22536f75726365477261706869632220747970653d22736174757261746560208201527f222076616c7565733d223130222f3e3c2f66696c7465723e0000000000000000604082015250565b7f2220783d22000000000000000000000000000000000000000000000000000000600082015250565b614d2e81612c95565b8114614d3957600080fd5b50565b614d4581612cc1565b8114614d5057600080fd5b5056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa26469706673582212204e6d66013a9f828b3c14672bf626301add129e5cf59519a789365249de8303a164736f6c63430008040033608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506119c8806100606000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063477043bb1461003b578063ed41564b1461006b575b600080fd5b61005560048036038101906100509190610ce2565b610089565b6040516100629190611193565b60405180910390f35b6100736105f7565b6040516100809190611178565b60405180910390f35b606060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635e1871d2846040518263ffffffff1660e01b81526004016100e491906111b5565b60206040518083038186803b1580156100fc57600080fd5b505afa158015610110573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101349190610c0e565b61014f576040518060200160405280600081525090506105f1565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633c6e8e81856040518263ffffffff1660e01b81526004016101ab91906111b5565b60006040518083038186803b1580156101c357600080fd5b505afa1580156101d7573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906102009190610c78565b9050600061020d8561061b565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636c7f590f8760016040518363ffffffff1660e01b81526004016102699291906111d0565b60006040518083038186803b15801561028157600080fd5b505afa158015610295573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906102be9190610c37565b8360000151846000015161037960008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637869b9f38b6040518263ffffffff1660e01b815260040161032491906111b5565b60206040518083038186803b15801561033c57600080fd5b505afa158015610350573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103749190610cb9565b61061b565b61042a60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635d7035c68c6040518263ffffffff1660e01b81526004016103d591906111b5565b60206040518083038186803b1580156103ed57600080fd5b505afa158015610401573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104259190610cb9565b61061b565b6104db60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166373663d088d6040518263ffffffff1660e01b815260040161048691906111b5565b60206040518083038186803b15801561049e57600080fd5b505afa1580156104b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104d69190610cb9565b61061b565b61058c60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d381fa6a8e6040518263ffffffff1660e01b815260040161053791906111b5565b60206040518083038186803b15801561054f57600080fd5b505afa158015610563573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105879190610cb9565b61061b565b6040516020016105a3989796959493929190611008565b604051602081830303815290604052905083156105eb576105c3816107c8565b6040516020016105d39190611156565b604051602081830303815290604052925050506105f1565b80925050505b92915050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60606000821415610663576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506107c3565b600082905060005b6000821461069557808061067e90611495565b915050600a8261068e9190611318565b915061066b565b60008167ffffffffffffffff8111156106d7577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156107095781602001600182028036833780820191505090505b5090505b600085146107bc5760018261072291906113a3565b9150600a8561073191906114de565b603061073d91906112c2565b60f81b818381518110610779577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856107b59190611318565b945061070d565b8093505050505b919050565b60606000825114156107eb57604051806020016040528060008152509050610962565b6000604051806060016040528060408152602001611953604091399050600060036002855161081a91906112c2565b6108249190611318565b60046108309190611349565b9050600060208261084191906112c2565b67ffffffffffffffff811115610880577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156108b25781602001600182028036833780820191505090505b509050818152600183018586518101602084015b81831015610921576003830192508251603f8160121c168501518253600182019150603f81600c1c168501518253600182019150603f8160061c168501518253600182019150603f81168501518253600182019150506108c6565b60038951066001811461093b576002811461094b57610956565b613d3d60f01b6002830352610956565b603d60f81b60018303525b50505050508093505050505b919050565b600061097a6109758461121e565b6111f9565b9050808285602086028201111561099057600080fd5b60005b858110156109da57815167ffffffffffffffff8111156109b257600080fd5b8086016109bf8982610afd565b85526020850194506020840193505050600181019050610993565b5050509392505050565b60006109f76109f284611244565b6111f9565b90508082856020860282011115610a0d57600080fd5b60005b85811015610a3d5781610a238882610bf9565b845260208401935060208301925050600181019050610a10565b5050509392505050565b6000610a5a610a558461126a565b6111f9565b905082815260208101848484011115610a7257600080fd5b610a7d848285611431565b509392505050565b600082601f830112610a9657600080fd5b6004610aa3848285610967565b91505092915050565b600082601f830112610abd57600080fd5b600f610aca8482856109e4565b91505092915050565b600081359050610ae281611924565b92915050565b600081519050610af781611924565b92915050565b600082601f830112610b0e57600080fd5b8151610b1e848260208601610a47565b91505092915050565b60006102408284031215610b3a57600080fd5b610b4460806111f9565b9050600082015167ffffffffffffffff811115610b6057600080fd5b610b6c84828501610afd565b600083015250602082015167ffffffffffffffff811115610b8c57600080fd5b610b9884828501610a85565b602083015250604082015167ffffffffffffffff811115610bb857600080fd5b610bc484828501610afd565b6040830152506060610bd884828501610aac565b60608301525092915050565b600081359050610bf38161193b565b92915050565b600081519050610c088161193b565b92915050565b600060208284031215610c2057600080fd5b6000610c2e84828501610ae8565b91505092915050565b600060208284031215610c4957600080fd5b600082015167ffffffffffffffff811115610c6357600080fd5b610c6f84828501610afd565b91505092915050565b600060208284031215610c8a57600080fd5b600082015167ffffffffffffffff811115610ca457600080fd5b610cb084828501610b27565b91505092915050565b600060208284031215610ccb57600080fd5b6000610cd984828501610bf9565b91505092915050565b60008060408385031215610cf557600080fd5b6000610d0385828601610be4565b9250506020610d1485828601610ad3565b9150509250929050565b610d27816113d7565b82525050565b610d368161140d565b82525050565b6000610d478261129b565b610d5181856112a6565b9350610d61818560208601611431565b610d6a8161159c565b840191505092915050565b6000610d808261129b565b610d8a81856112b7565b9350610d9a818560208601611431565b80840191505092915050565b6000610db36002836112b7565b9150610dbe826115ad565b600282019050919050565b6000610dd66027836112b7565b9150610de1826115d6565b602782019050919050565b6000610df96011836112b7565b9150610e0482611625565b601182019050919050565b6000610e1c6002836112b7565b9150610e278261164e565b600282019050919050565b6000610e3f6003836112b7565b9150610e4a82611677565b600382019050919050565b6000610e626021836112b7565b9150610e6d826116a0565b602182019050919050565b6000610e856028836112b7565b9150610e90826116ef565b602882019050919050565b6000610ea86001836112b7565b9150610eb38261173e565b600182019050919050565b6000610ecb6001836112b7565b9150610ed682611767565b600182019050919050565b6000610eee600f836112b7565b9150610ef982611790565b600f82019050919050565b6000610f116001836112b7565b9150610f1c826117b9565b600182019050919050565b6000610f34601d836112b7565b9150610f3f826117e2565b601d82019050919050565b6000610f576001836112b7565b9150610f628261180b565b600182019050919050565b6000610f7a6027836112b7565b9150610f8582611834565b602782019050919050565b6000610f9d601e836112b7565b9150610fa882611883565b601e82019050919050565b6000610fc0600a836112b7565b9150610fcb826118ac565b600a82019050919050565b6000610fe36021836112b7565b9150610fee826118d5565b602182019050919050565b61100281611403565b82525050565b600061101382610ebe565b915061101e82610dec565b915061102a828b610d75565b915061103582610e0f565b915061104082610fb3565b915061104c828a610d75565b915061105782610e0f565b915061106282610f90565b915061106d82610ee1565b915061107882610fd6565b91506110848289610d75565b915061108f82610e32565b915061109a82610f6d565b91506110a68288610d75565b91506110b182610f4a565b91506110bd8287610d75565b91506110c882610e32565b91506110d382610e55565b91506110df8286610d75565b91506110ea82610da6565b91506110f582610dc9565b91506111018285610d75565b915061110c82610da6565b915061111782610e78565b91506111238284610d75565b915061112e82610e9b565b915061113982610f04565b915061114482610e9b565b91508190509998505050505050505050565b600061116182610f27565b915061116d8284610d75565b915081905092915050565b600060208201905061118d6000830184610d2d565b92915050565b600060208201905081810360008301526111ad8184610d3c565b905092915050565b60006020820190506111ca6000830184610ff9565b92915050565b60006040820190506111e56000830185610ff9565b6111f26020830184610d1e565b9392505050565b6000611203611214565b905061120f8282611464565b919050565b6000604051905090565b600067ffffffffffffffff8211156112395761123861156d565b5b602082029050919050565b600067ffffffffffffffff82111561125f5761125e61156d565b5b602082029050919050565b600067ffffffffffffffff8211156112855761128461156d565b5b61128e8261159c565b9050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b60006112cd82611403565b91506112d883611403565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561130d5761130c61150f565b5b828201905092915050565b600061132382611403565b915061132e83611403565b92508261133e5761133d61153e565b5b828204905092915050565b600061135482611403565b915061135f83611403565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156113985761139761150f565b5b828202905092915050565b60006113ae82611403565b91506113b983611403565b9250828210156113cc576113cb61150f565b5b828203905092915050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006114188261141f565b9050919050565b600061142a826113e3565b9050919050565b60005b8381101561144f578082015181840152602081019050611434565b8381111561145e576000848401525b50505050565b61146d8261159c565b810181811067ffffffffffffffff8211171561148c5761148b61156d565b5b80604052505050565b60006114a082611403565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156114d3576114d261150f565b5b600182019050919050565b60006114e982611403565b91506114f483611403565b9250826115045761150361153e565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f7d2c000000000000000000000000000000000000000000000000000000000000600082015250565b7f7b2274726169745f74797065223a202266697865645f65706f6368222c20227660008201527f616c7565223a2000000000000000000000000000000000000000000000000000602082015250565b7f226e616d65223a226d656d706f6f6c2023000000000000000000000000000000600082015250565b7f222c000000000000000000000000000000000000000000000000000000000000600082015250565b7f227d2c0000000000000000000000000000000000000000000000000000000000600082015250565b7f7b2274726169745f74797065223a202265706f6368222c202276616c7565223a60008201527f2000000000000000000000000000000000000000000000000000000000000000602082015250565b7f7b2274726169745f74797065223a202265706f63685f6c656e677468222c202260008201527f76616c7565223a20000000000000000000000000000000000000000000000000602082015250565b7f7d00000000000000000000000000000000000000000000000000000000000000600082015250565b7f7b00000000000000000000000000000000000000000000000000000000000000600082015250565b7f2261747472696275746573223a205b0000000000000000000000000000000000600082015250565b7f5d00000000000000000000000000000000000000000000000000000000000000600082015250565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b7f2d00000000000000000000000000000000000000000000000000000000000000600082015250565b7f7b2274726169745f74797065223a202262616e6b5f696e646578222c2022766160008201527f6c7565223a202200000000000000000000000000000000000000000000000000602082015250565b7f226465736372697074696f6e223a20226c6174656e742e776f726b73222c0000600082015250565b7f22696d616765223a202200000000000000000000000000000000000000000000600082015250565b7f7b2274726169745f74797065223a202262616e6b222c202276616c7565223a2060008201527f2200000000000000000000000000000000000000000000000000000000000000602082015250565b61192d816113d7565b811461193857600080fd5b50565b61194481611403565b811461194f57600080fd5b5056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220a8f7a16f00fbdddccf34eedc4896d769fedd8c9ca2151fa3f32ee8cb8bcbdaa764736f6c634300080400330000000000000000000000006f2ff40f793776aa559644f52e58d83e21871ec3
Deployed Bytecode
0x6080604052600436106102515760003560e01c80637869b9f311610139578063a22cb465116100b6578063c87b56dd1161007a578063c87b56dd1461092e578063c95b41621461096b578063ca9add8f146109a8578063d381fa6a146109c4578063e985e9c514610a01578063f2fde38b14610a3e57610251565b8063a22cb4651461084b578063a79af2ce14610874578063b88d4fde1461089f578063be95592e146108c8578063c3b95b1b146108f157610251565b80638da5cb5b116100fd5780638da5cb5b1461073e57806395d89b4114610769578063967f2222146107945780639b0f2b5a146107d15780639bfaab661461080e57610251565b80637869b9f3146106665780638060156b146106a357806382219416146106ce5780638b83ade8146106f75780638d859f3e1461071357610251565b80633c6e8e81116101d25780636352211e116101965780636352211e1461051e57806366044cf51461055b5780636c7f590f1461059857806370a08231146105d5578063715018a61461061257806373663d081461062957610251565b80633c6e8e811461041357806342842e0e1461045057806343347e0e146104795780635d7035c6146104a45780635e1871d2146104e157610251565b806318160ddd1161021957806318160ddd1461034f5780631adfee421461037a5780631b2ef1ca146103a357806323b872dd146103bf5780632e44715d146103e857610251565b806301ffc9a71461025657806306fdde0314610293578063081812fc146102be578063095ea7b3146102fb57806309e61a7314610324575b600080fd5b34801561026257600080fd5b5061027d60048036038101906102789190613eb8565b610a67565b60405161028a91906149f3565b60405180910390f35b34801561029f57600080fd5b506102a8610b49565b6040516102b59190614a44565b60405180910390f35b3480156102ca57600080fd5b506102e560048036038101906102e09190613fe2565b610bdb565b6040516102f2919061496a565b60405180910390f35b34801561030757600080fd5b50610322600480360381019061031d9190613e53565b610c60565b005b34801561033057600080fd5b50610339610d78565b6040516103469190614a0e565b60405180910390f35b34801561035b57600080fd5b50610364610d9c565b6040516103719190614daa565b60405180910390f35b34801561038657600080fd5b506103a1600480360381019061039c9190613f4b565b610da6565b005b6103bd60048036038101906103b891906140ef565b610f74565b005b3480156103cb57600080fd5b506103e660048036038101906103e19190613d4d565b61113c565b005b3480156103f457600080fd5b506103fd61119c565b60405161040a9190614daa565b60405180910390f35b34801561041f57600080fd5b5061043a60048036038101906104359190613fe2565b61122b565b6040516104479190614d66565b60405180910390f35b34801561045c57600080fd5b5061047760048036038101906104729190613d4d565b61124b565b005b34801561048557600080fd5b5061048e61126b565b60405161049b91906149d1565b60405180910390f35b3480156104b057600080fd5b506104cb60048036038101906104c69190613fe2565b6115db565b6040516104d89190614daa565b60405180910390f35b3480156104ed57600080fd5b5061050860048036038101906105039190613fe2565b611628565b60405161051591906149f3565b60405180910390f35b34801561052a57600080fd5b5061054560048036038101906105409190613fe2565b61163a565b604051610552919061496a565b60405180910390f35b34801561056757600080fd5b50610582600480360381019061057d9190613fe2565b6116ec565b60405161058f9190614daa565b60405180910390f35b3480156105a457600080fd5b506105bf60048036038101906105ba919061400b565b61170a565b6040516105cc9190614a44565b60405180910390f35b3480156105e157600080fd5b506105fc60048036038101906105f79190613cbf565b61181a565b6040516106099190614daa565b60405180910390f35b34801561061e57600080fd5b506106276118d2565b005b34801561063557600080fd5b50610650600480360381019061064b9190613fe2565b61195a565b60405161065d9190614daa565b60405180910390f35b34801561067257600080fd5b5061068d60048036038101906106889190613fe2565b611978565b60405161069a9190614daa565b60405180910390f35b3480156106af57600080fd5b506106b86119f1565b6040516106c59190614a29565b60405180910390f35b3480156106da57600080fd5b506106f560048036038101906106f091906140ef565b611a15565b005b610711600480360381019061070c919061412b565b611af3565b005b34801561071f57600080fd5b50610728611faf565b6040516107359190614daa565b60405180910390f35b34801561074a57600080fd5b50610753611fbb565b604051610760919061496a565b60405180910390f35b34801561077557600080fd5b5061077e611fe5565b60405161078b9190614a44565b60405180910390f35b3480156107a057600080fd5b506107bb60048036038101906107b6919061409b565b612077565b6040516107c89190614d88565b60405180910390f35b3480156107dd57600080fd5b506107f860048036038101906107f39190613fe2565b6120df565b6040516108059190614a44565b60405180910390f35b34801561081a57600080fd5b5061083560048036038101906108309190614047565b612140565b6040516108429190614a44565b60405180910390f35b34801561085757600080fd5b50610872600480360381019061086d9190613e17565b612192565b005b34801561088057600080fd5b506108896121a8565b604051610896919061496a565b60405180910390f35b3480156108ab57600080fd5b506108c660048036038101906108c19190613d9c565b6121d3565b005b3480156108d457600080fd5b506108ef60048036038101906108ea9190613cbf565b612235565b005b3480156108fd57600080fd5b5061091860048036038101906109139190613fe2565b6122f6565b6040516109259190614d66565b60405180910390f35b34801561093a57600080fd5b5061095560048036038101906109509190613fe2565b61257e565b6040516109629190614a44565b60405180910390f35b34801561097757600080fd5b50610992600480360381019061098d9190613fe2565b61263b565b60405161099f9190614a44565b60405180910390f35b6109c260048036038101906109bd9190613cbf565b612722565b005b3480156109d057600080fd5b506109eb60048036038101906109e69190613fe2565b6127df565b6040516109f89190614daa565b60405180910390f35b348015610a0d57600080fd5b50610a286004803603810190610a239190613d11565b612841565b604051610a3591906149f3565b60405180910390f35b348015610a4a57600080fd5b50610a656004803603810190610a609190613cbf565b6128d5565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610b3257507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610b425750610b41826129cd565b5b9050919050565b606060008054610b5890615225565b80601f0160208091040260200160405190810160405280929190818152602001828054610b8490615225565b8015610bd15780601f10610ba657610100808354040283529160200191610bd1565b820191906000526020600020905b815481529060010190602001808311610bb457829003601f168201915b5050505050905090565b6000610be682612a37565b610c25576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c1c90614c66565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610c6b8261163a565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610cdc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cd390614cc6565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610cfb612aa3565b73ffffffffffffffffffffffffffffffffffffffff161480610d2a5750610d2981610d24612aa3565b612841565b5b610d69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6090614be6565b60405180910390fd5b610d738383612aab565b505050565b7f0000000000000000000000006f2ff40f793776aa559644f52e58d83e21871ec381565b6000600854905090565b610dae612aa3565b73ffffffffffffffffffffffffffffffffffffffff16610dcc611fbb565b73ffffffffffffffffffffffffffffffffffffffff1614610e22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e1990614c86565b60405180910390fd5b6000610e2c61119c565b9050600f8110610e71576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6890614a66565b60405180910390fd5b83600982600f8110610eac577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b601502016000019080519060200190610ec69291906137d2565b5082600982600f8110610f02577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60150201600101906004610f17929190613858565b5081600982600f8110610f53577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b601502016005019080519060200190610f6d9291906137d2565b5050505050565b60026007541415610fba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fb190614d46565b60405180910390fd5b60026007819055506000610fcc61119c565b9050670214e8348c4f00003414611018576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161100f90614b26565b60405180910390fd5b60008111801561102757508083105b611066576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105d90614ce6565b60405180910390fd5b6000600984600f81106110a2577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6015020160060183600f81106110e1577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b015414611123576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161111a90614b06565b60405180910390fd5b61112e338484612b64565b505060016007819055505050565b61114d611147612aa3565b82612c4d565b61118c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118390614d06565b60405180910390fd5b611197838383612d2b565b505050565b60008060005b600f811015611223576000600982600f81106111e7577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6015020160000180546111f990615225565b9050111561121057818061120c90615288565b9250505b808061121b90615288565b9150506111a2565b508091505090565b6112336138ab565b61124461123f836116ec565b6122f6565b9050919050565b611266838383604051806020016040528060008152506121d3565b505050565b6060600061127761119c565b905060008167ffffffffffffffff8111156112bb577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156112f457816020015b6112e16138ab565b8152602001906001900390816112d95790505b50905060005b828110156115d257600981600f811061133c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6015020160405180608001604052908160008201805461135b90615225565b80601f016020809104026020016040519081016040528092919081815260200182805461138790615225565b80156113d45780601f106113a9576101008083540402835291602001916113d4565b820191906000526020600020905b8154815290600101906020018083116113b757829003601f168201915b5050505050815260200160018201600480602002604051908101604052809291906000905b8282101561149c57838201805461140f90615225565b80601f016020809104026020016040519081016040528092919081815260200182805461143b90615225565b80156114885780601f1061145d57610100808354040283529160200191611488565b820191906000526020600020905b81548152906001019060200180831161146b57829003601f168201915b5050505050815260200190600101906113f9565b5050505081526020016005820180546114b490615225565b80601f01602080910402602001604051908101604052809291908181526020018280546114e090615225565b801561152d5780601f106115025761010080835404028352916020019161152d565b820191906000526020600020905b81548152906001019060200180831161151057829003601f168201915b5050505050815260200160068201600f806020026040519081016040528092919082600f8015611572576020028201915b81548152602001906001019080831161155e575b5050505050815250508282815181106115b4577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018190525080806115ca90615288565b9150506112fa565b50809250505090565b60008060016115e9846127df565b6101446000868152602001908152602001600020544261160991906150f3565b6116139190615068565b61161d9190615012565b905080915050919050565b600061163382612a37565b9050919050565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156116e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116da90614c26565b60405180910390fd5b80915050919050565b60006101456000838152602001908152602001600020549050919050565b606061171583611628565b61173057604051806020016040528060008152509050611814565b60006101466000858152602001908152602001600020549050600181101561175e5761175b846115db565b90505b7f000000000000000000000000a8584721181b3ff99d6072be2bf2aeb2f1a092ff73ffffffffffffffffffffffffffffffffffffffff1663662ca4b28583866040518463ffffffff1660e01b81526004016117bb93929190614e47565b60006040518083038186803b1580156117d357600080fd5b505afa1580156117e7573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906118109190613f0a565b9150505b92915050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561188b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161188290614c06565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6118da612aa3565b73ffffffffffffffffffffffffffffffffffffffff166118f8611fbb565b73ffffffffffffffffffffffffffffffffffffffff161461194e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161194590614c86565b60405180910390fd5b6119586000612f92565b565b60006101466000838152602001908152602001600020549050919050565b6000806119848361122b565b905060006119c7846040518060400160405280600481526020017f7061727400000000000000000000000000000000000000000000000000000000815250612140565b90506119e8816000600185602001515060046119e391906150f3565b613058565b92505050919050565b7f000000000000000000000000a8584721181b3ff99d6072be2bf2aeb2f1a092ff81565b3373ffffffffffffffffffffffffffffffffffffffff16611a358361163a565b73ffffffffffffffffffffffffffffffffffffffff1614611a8b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a8290614d26565b60405180910390fd5b80611a95836115db565b1115611ad6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611acd90614bc6565b60405180910390fd5b806101466000848152602001908152602001600020819055505050565b60026007541415611b39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b3090614d46565b60405180910390fd5b60026007819055506000611b4b61119c565b905060026003670214e8348c4f0000611b649190615068565b611b6e9190615099565b3414611baf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba690614b26565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167f0000000000000000000000006f2ff40f793776aa559644f52e58d83e21871ec373ffffffffffffffffffffffffffffffffffffffff16636352211e866040518263ffffffff1660e01b8152600401611c1f9190614daa565b60206040518083038186803b158015611c3757600080fd5b505afa158015611c4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c6f9190613ce8565b73ffffffffffffffffffffffffffffffffffffffff1614611cc5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cbc90614b86565b60405180910390fd5b7f0000000000000000000000006f2ff40f793776aa559644f52e58d83e21871ec373ffffffffffffffffffffffffffffffffffffffff1663f834e6c585306040518363ffffffff1660e01b8152600401611d20929190614dc5565b60206040518083038186803b158015611d3857600080fd5b505afa158015611d4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d709190613e8f565b15611db0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611da790614ca6565b60405180910390fd5b600081118015611dbf57508083105b611dfe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611df590614ce6565b60405180910390fd5b6000600984600f8110611e3a577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6015020160060183600f8110611e79577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b015414611ebb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eb290614b06565b60405180910390fd5b6000611ec8338585612b64565b90507f0000000000000000000000006f2ff40f793776aa559644f52e58d83e21871ec373ffffffffffffffffffffffffffffffffffffffff16632a843ee0866040518060800160405280858152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001604051806020016040528060008152508152602001600015158152506040518363ffffffff1660e01b8152600401611f6e929190614e17565b600060405180830381600087803b158015611f8857600080fd5b505af1158015611f9c573d6000803e3d6000fd5b5050505050506001600781905550505050565b670214e8348c4f000081565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060018054611ff490615225565b80601f016020809104026020016040519081016040528092919081815260200182805461202090615225565b801561206d5780601f106120425761010080835404028352916020019161206d565b820191906000526020600020905b81548152906001019060200180831161205057829003601f168201915b5050505050905090565b61207f6138df565b60405180604001604052806040518060400160405280600881526020017f6d656d706f6f6c7300000000000000000000000000000000000000000000000081525081526020016120d48460000151600161170a565b815250905092915050565b606060006120ec8361122b565b905080602001516120fc84611978565b60048110612133577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020020151915050919050565b606061215f6101446000858152602001908152602001600020546130be565b612168846130be565b8360405160200161217b93929190614939565b604051602081830303815290604052905092915050565b6121a461219d612aa3565b838361326b565b5050565b600061014760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6121e46121de612aa3565b83612c4d565b612223576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161221a90614d06565b60405180910390fd5b61222f848484846133d8565b50505050565b61223d612aa3565b73ffffffffffffffffffffffffffffffffffffffff1661225b611fbb565b73ffffffffffffffffffffffffffffffffffffffff16146122b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122a890614c86565b60405180910390fd5b8061014760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6122fe6138ab565b600982600f8110612338577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6015020160405180608001604052908160008201805461235790615225565b80601f016020809104026020016040519081016040528092919081815260200182805461238390615225565b80156123d05780601f106123a5576101008083540402835291602001916123d0565b820191906000526020600020905b8154815290600101906020018083116123b357829003601f168201915b5050505050815260200160018201600480602002604051908101604052809291906000905b8282101561249857838201805461240b90615225565b80601f016020809104026020016040519081016040528092919081815260200182805461243790615225565b80156124845780601f1061245957610100808354040283529160200191612484565b820191906000526020600020905b81548152906001019060200180831161246757829003601f168201915b5050505050815260200190600101906123f5565b5050505081526020016005820180546124b090615225565b80601f01602080910402602001604051908101604052809291908181526020018280546124dc90615225565b80156125295780601f106124fe57610100808354040283529160200191612529565b820191906000526020600020905b81548152906001019060200180831161250c57829003601f168201915b5050505050815260200160068201600f806020026040519081016040528092919082600f801561256e576020028201915b81548152602001906001019080831161255a575b5050505050815250509050919050565b606061014760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663477043bb8360016040518363ffffffff1660e01b81526004016125df929190614dee565b60006040518083038186803b1580156125f757600080fd5b505afa15801561260b573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906126349190613f0a565b9050919050565b60606009610145600084815260200190815260200160002054600f811061268b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60150201600501805461269d90615225565b80601f01602080910402602001604051908101604052809291908181526020018280546126c990615225565b80156127165780601f106126eb57610100808354040283529160200191612716565b820191906000526020600020905b8154815290600101906020018083116126f957829003601f168201915b50505050509050919050565b61272a612aa3565b73ffffffffffffffffffffffffffffffffffffffff16612748611fbb565b73ffffffffffffffffffffffffffffffffffffffff161461279e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161279590614c86565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f193505050506127dc57600080fd5b50565b60006276a700612830612827846040518060400160405280600581526020017f65706f6368000000000000000000000000000000000000000000000000000000815250612140565b60016006613058565b61283a9190615099565b9050919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6128dd612aa3565b73ffffffffffffffffffffffffffffffffffffffff166128fb611fbb565b73ffffffffffffffffffffffffffffffffffffffff1614612951576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161294890614c86565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156129c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129b890614aa6565b60405180910390fd5b6129ca81612f92565b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16612b1e8361163a565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600060086000815480929190612b7990615288565b9190505550612b8a84600854613434565b426101446000600854815260200190815260200160002081905550826101456000600854815260200190815260200160002081905550600854600984600f8110612bfd577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6015020160060183600f8110612c3c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b018190555060085490509392505050565b6000612c5882612a37565b612c97576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c8e90614ba6565b60405180910390fd5b6000612ca28361163a565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612ce45750612ce38185612841565b5b80612d2257508373ffffffffffffffffffffffffffffffffffffffff16612d0a84610bdb565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16612d4b8261163a565b73ffffffffffffffffffffffffffffffffffffffff1614612da1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d9890614ac6565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612e11576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e0890614b46565b60405180910390fd5b612e1c83838361360e565b612e27600082612aab565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612e7791906150f3565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612ece9190615012565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612f8d838383613613565b505050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000828211613069578290506130b7565b82838361307691906150f3565b856040516020016130879190614922565b6040516020818303038152906040528051906020012060001c6130aa91906152d1565b6130b49190615012565b90505b9392505050565b60606000821415613106576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050613266565b600082905060005b6000821461313857808061312190615288565b915050600a826131319190615068565b915061310e565b60008167ffffffffffffffff81111561317a577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156131ac5781602001600182028036833780820191505090505b5090505b6000851461325f576001826131c591906150f3565b9150600a856131d491906152d1565b60306131e09190615012565b60f81b81838151811061321c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856132589190615068565b94506131b0565b8093505050505b919050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156132da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132d190614b66565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516133cb91906149f3565b60405180910390a3505050565b6133e3848484612d2b565b6133ef84848484613618565b61342e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161342590614a86565b60405180910390fd5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156134a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161349b90614c46565b60405180910390fd5b6134ad81612a37565b156134ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016134e490614ae6565b60405180910390fd5b6134f96000838361360e565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546135499190615012565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461360a60008383613613565b5050565b505050565b505050565b60006136398473ffffffffffffffffffffffffffffffffffffffff166137af565b156137a2578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613662612aa3565b8786866040518563ffffffff1660e01b81526004016136849493929190614985565b602060405180830381600087803b15801561369e57600080fd5b505af19250505080156136cf57506040513d601f19601f820116820180604052508101906136cc9190613ee1565b60015b613752573d80600081146136ff576040519150601f19603f3d011682016040523d82523d6000602084013e613704565b606091505b5060008151141561374a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161374190614a86565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149150506137a7565b600190505b949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b8280546137de90615225565b90600052602060002090601f0160209004810192826138005760008555613847565b82601f1061381957805160ff1916838001178555613847565b82800160010185558215613847579182015b8281111561384657825182559160200191906001019061382b565b5b50905061385491906138f9565b5090565b826004810192821561389a579160200282015b828111156138995782518290805190602001906138899291906137d2565b509160200191906001019061386b565b5b5090506138a79190613916565b5090565b6040518060800160405280606081526020016138c561393a565b8152602001606081526020016138d9613961565b81525090565b604051806040016040528060608152602001606081525090565b5b808211156139125760008160009055506001016138fa565b5090565b5b80821115613936576000818161392d9190613984565b50600101613917565b5090565b60405180608001604052806004905b60608152602001906001900390816139495790505090565b604051806101e00160405280600f90602082028036833780820191505090505090565b50805461399090615225565b6000825580601f106139a257506139c1565b601f0160209004906000526020600020908101906139c091906138f9565b5b50565b60006139d76139d284614ea3565b614e7e565b905080828560208602820111156139ed57600080fd5b60005b85811015613a3757813567ffffffffffffffff811115613a0f57600080fd5b808601613a1c8982613bca565b855260208501945060208401935050506001810190506139f0565b5050509392505050565b6000613a54613a4f84614ec9565b614e7e565b905082815260208101848484011115613a6c57600080fd5b613a778482856151e3565b509392505050565b6000613a92613a8d84614efa565b614e7e565b905082815260208101848484011115613aaa57600080fd5b613ab58482856151e3565b509392505050565b6000613ad0613acb84614efa565b614e7e565b905082815260208101848484011115613ae857600080fd5b613af38482856151f2565b509392505050565b600081359050613b0a81615949565b92915050565b600081519050613b1f81615949565b92915050565b600082601f830112613b3657600080fd5b6004613b438482856139c4565b91505092915050565b600081359050613b5b81615960565b92915050565b600081519050613b7081615960565b92915050565b600081359050613b8581615977565b92915050565b600081519050613b9a81615977565b92915050565b600082601f830112613bb157600080fd5b8135613bc1848260208601613a41565b91505092915050565b600082601f830112613bdb57600080fd5b8135613beb848260208601613a7f565b91505092915050565b600082601f830112613c0557600080fd5b8151613c15848260208601613abd565b91505092915050565b600060808284031215613c3057600080fd5b613c3a6080614e7e565b90506000613c4a84828501613caa565b6000830152506020613c5e84828501613afb565b602083015250604082013567ffffffffffffffff811115613c7e57600080fd5b613c8a84828501613bca565b6040830152506060613c9e84828501613b4c565b60608301525092915050565b600081359050613cb98161598e565b92915050565b600060208284031215613cd157600080fd5b6000613cdf84828501613afb565b91505092915050565b600060208284031215613cfa57600080fd5b6000613d0884828501613b10565b91505092915050565b60008060408385031215613d2457600080fd5b6000613d3285828601613afb565b9250506020613d4385828601613afb565b9150509250929050565b600080600060608486031215613d6257600080fd5b6000613d7086828701613afb565b9350506020613d8186828701613afb565b9250506040613d9286828701613caa565b9150509250925092565b60008060008060808587031215613db257600080fd5b6000613dc087828801613afb565b9450506020613dd187828801613afb565b9350506040613de287828801613caa565b925050606085013567ffffffffffffffff811115613dff57600080fd5b613e0b87828801613ba0565b91505092959194509250565b60008060408385031215613e2a57600080fd5b6000613e3885828601613afb565b9250506020613e4985828601613b4c565b9150509250929050565b60008060408385031215613e6657600080fd5b6000613e7485828601613afb565b9250506020613e8585828601613caa565b9150509250929050565b600060208284031215613ea157600080fd5b6000613eaf84828501613b61565b91505092915050565b600060208284031215613eca57600080fd5b6000613ed884828501613b76565b91505092915050565b600060208284031215613ef357600080fd5b6000613f0184828501613b8b565b91505092915050565b600060208284031215613f1c57600080fd5b600082015167ffffffffffffffff811115613f3657600080fd5b613f4284828501613bf4565b91505092915050565b600080600060608486031215613f6057600080fd5b600084013567ffffffffffffffff811115613f7a57600080fd5b613f8686828701613bca565b935050602084013567ffffffffffffffff811115613fa357600080fd5b613faf86828701613b25565b925050604084013567ffffffffffffffff811115613fcc57600080fd5b613fd886828701613bca565b9150509250925092565b600060208284031215613ff457600080fd5b600061400284828501613caa565b91505092915050565b6000806040838503121561401e57600080fd5b600061402c85828601613caa565b925050602061403d85828601613b4c565b9150509250929050565b6000806040838503121561405a57600080fd5b600061406885828601613caa565b925050602083013567ffffffffffffffff81111561408557600080fd5b61409185828601613bca565b9150509250929050565b600080604083850312156140ae57600080fd5b60006140bc85828601613caa565b925050602083013567ffffffffffffffff8111156140d957600080fd5b6140e585828601613c1e565b9150509250929050565b6000806040838503121561410257600080fd5b600061411085828601613caa565b925050602061412185828601613caa565b9150509250929050565b60008060006060848603121561414057600080fd5b600061414e86828701613caa565b935050602061415f86828701613caa565b925050604061417086828701613caa565b9150509250925092565b6000614186838361438e565b905092915050565b600061419a8383614779565b905092915050565b60006141ae8383614904565b60208301905092915050565b6141c381615127565b82525050565b6141d281615127565b82525050565b60006141e382614f4f565b6141ed8185614fad565b9350836020820285016141ff85614f2b565b8060005b8581101561423b578484038952815161421c858261417a565b945061422783614f86565b925060208a01995050600181019050614203565b50829750879550505050505092915050565b600061425882614f5a565b6142628185614fb8565b93508360208202850161427485614f35565b8060005b858110156142b05784840389528151614291858261418e565b945061429c83614f93565b925060208a01995050600181019050614278565b50829750879550505050505092915050565b6142cb81614f65565b6142d58184614fc9565b92506142e082614f45565b8060005b838110156143115781516142f887826141a2565b965061430383614fa0565b9250506001810190506142e4565b505050505050565b61432281615139565b82525050565b61433181615139565b82525050565b600061434282614f70565b61434c8185614fd4565b935061435c8185602086016151f2565b614365816153be565b840191505092915050565b6143798161519b565b82525050565b614388816151bf565b82525050565b600061439982614f7b565b6143a38185614fe5565b93506143b38185602086016151f2565b6143bc816153be565b840191505092915050565b60006143d282614f7b565b6143dc8185614ff6565b93506143ec8185602086016151f2565b6143f5816153be565b840191505092915050565b600061440b82614f7b565b6144158185615007565b93506144258185602086016151f2565b80840191505092915050565b600061443e600983614ff6565b9150614449826153cf565b602082019050919050565b6000614461603283614ff6565b915061446c826153f8565b604082019050919050565b6000614484602683614ff6565b915061448f82615447565b604082019050919050565b60006144a7602583614ff6565b91506144b282615496565b604082019050919050565b60006144ca601c83614ff6565b91506144d5826154e5565b602082019050919050565b60006144ed600f83614ff6565b91506144f88261550e565b602082019050919050565b6000614510600d83614ff6565b915061451b82615537565b602082019050919050565b6000614533602483614ff6565b915061453e82615560565b604082019050919050565b6000614556601983614ff6565b9150614561826155af565b602082019050919050565b6000614579600f83614ff6565b9150614584826155d8565b602082019050919050565b600061459c602c83614ff6565b91506145a782615601565b604082019050919050565b60006145bf601183614ff6565b91506145ca82615650565b602082019050919050565b60006145e2603883614ff6565b91506145ed82615679565b604082019050919050565b6000614605602a83614ff6565b9150614610826156c8565b604082019050919050565b6000614628602983614ff6565b915061463382615717565b604082019050919050565b600061464b602083614ff6565b915061465682615766565b602082019050919050565b600061466e602c83614ff6565b91506146798261578f565b604082019050919050565b6000614691602083614ff6565b915061469c826157de565b602082019050919050565b60006146b4600f83614ff6565b91506146bf82615807565b602082019050919050565b60006146d7602183614ff6565b91506146e282615830565b604082019050919050565b60006146fa600c83614ff6565b91506147058261587f565b602082019050919050565b600061471d603183614ff6565b9150614728826158a8565b604082019050919050565b6000614740600983614ff6565b915061474b826158f7565b602082019050919050565b6000614763601f83614ff6565b915061476e82615920565b602082019050919050565b6000610240830160008301518482036000860152614797828261438e565b915050602083015184820360208601526147b182826141d8565b915050604083015184820360408601526147cb828261438e565b91505060608301516147e060608601826142c2565b508091505092915050565b6000610240830160008301518482036000860152614809828261438e565b9150506020830151848203602086015261482382826141d8565b9150506040830151848203604086015261483d828261438e565b915050606083015161485260608601826142c2565b508091505092915050565b6000604083016000830151848203600086015261487a828261438e565b91505060208301518482036020860152614894828261438e565b9150508091505092915050565b60006080830160008301516148b96000860182614904565b5060208301516148cc60208601826141ba565b50604083015184820360408601526148e4828261438e565b91505060608301516148f96060860182614319565b508091505092915050565b61490d81615191565b82525050565b61491c81615191565b82525050565b600061492e8284614400565b915081905092915050565b60006149458286614400565b91506149518285614400565b915061495d8284614400565b9150819050949350505050565b600060208201905061497f60008301846141c9565b92915050565b600060808201905061499a60008301876141c9565b6149a760208301866141c9565b6149b46040830185614913565b81810360608301526149c68184614337565b905095945050505050565b600060208201905081810360008301526149eb818461424d565b905092915050565b6000602082019050614a086000830184614328565b92915050565b6000602082019050614a236000830184614370565b92915050565b6000602082019050614a3e600083018461437f565b92915050565b60006020820190508181036000830152614a5e81846143c7565b905092915050565b60006020820190508181036000830152614a7f81614431565b9050919050565b60006020820190508181036000830152614a9f81614454565b9050919050565b60006020820190508181036000830152614abf81614477565b9050919050565b60006020820190508181036000830152614adf8161449a565b9050919050565b60006020820190508181036000830152614aff816144bd565b9050919050565b60006020820190508181036000830152614b1f816144e0565b9050919050565b60006020820190508181036000830152614b3f81614503565b9050919050565b60006020820190508181036000830152614b5f81614526565b9050919050565b60006020820190508181036000830152614b7f81614549565b9050919050565b60006020820190508181036000830152614b9f8161456c565b9050919050565b60006020820190508181036000830152614bbf8161458f565b9050919050565b60006020820190508181036000830152614bdf816145b2565b9050919050565b60006020820190508181036000830152614bff816145d5565b9050919050565b60006020820190508181036000830152614c1f816145f8565b9050919050565b60006020820190508181036000830152614c3f8161461b565b9050919050565b60006020820190508181036000830152614c5f8161463e565b9050919050565b60006020820190508181036000830152614c7f81614661565b9050919050565b60006020820190508181036000830152614c9f81614684565b9050919050565b60006020820190508181036000830152614cbf816146a7565b9050919050565b60006020820190508181036000830152614cdf816146ca565b9050919050565b60006020820190508181036000830152614cff816146ed565b9050919050565b60006020820190508181036000830152614d1f81614710565b9050919050565b60006020820190508181036000830152614d3f81614733565b9050919050565b60006020820190508181036000830152614d5f81614756565b9050919050565b60006020820190508181036000830152614d8081846147eb565b905092915050565b60006020820190508181036000830152614da2818461485d565b905092915050565b6000602082019050614dbf6000830184614913565b92915050565b6000604082019050614dda6000830185614913565b614de760208301846141c9565b9392505050565b6000604082019050614e036000830185614913565b614e106020830184614328565b9392505050565b6000604082019050614e2c6000830185614913565b8181036020830152614e3e81846148a1565b90509392505050565b6000606082019050614e5c6000830186614913565b614e696020830185614913565b614e766040830184614328565b949350505050565b6000614e88614e99565b9050614e948282615257565b919050565b6000604051905090565b600067ffffffffffffffff821115614ebe57614ebd61538f565b5b602082029050919050565b600067ffffffffffffffff821115614ee457614ee361538f565b5b614eed826153be565b9050602081019050919050565b600067ffffffffffffffff821115614f1557614f1461538f565b5b614f1e826153be565b9050602081019050919050565b6000819050919050565b6000819050602082019050919050565b6000819050919050565b600060049050919050565b600081519050919050565b6000600f9050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600061501d82615191565b915061502883615191565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561505d5761505c615302565b5b828201905092915050565b600061507382615191565b915061507e83615191565b92508261508e5761508d615331565b5b828204905092915050565b60006150a482615191565b91506150af83615191565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156150e8576150e7615302565b5b828202905092915050565b60006150fe82615191565b915061510983615191565b92508282101561511c5761511b615302565b5b828203905092915050565b600061513282615171565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006151a6826151ad565b9050919050565b60006151b882615171565b9050919050565b60006151ca826151d1565b9050919050565b60006151dc82615171565b9050919050565b82818337600083830152505050565b60005b838110156152105780820151818401526020810190506151f5565b8381111561521f576000848401525b50505050565b6000600282049050600182168061523d57607f821691505b6020821081141561525157615250615360565b5b50919050565b615260826153be565b810181811067ffffffffffffffff8211171561527f5761527e61538f565b5b80604052505050565b600061529382615191565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156152c6576152c5615302565b5b600182019050919050565b60006152dc82615191565b91506152e783615191565b9250826152f7576152f6615331565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f4d41585f42414e4b530000000000000000000000000000000000000000000000600082015250565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b7f504f4f4c5f494e4445585f555345440000000000000000000000000000000000600082015250565b7f494e56414c49445f505249434500000000000000000000000000000000000000600082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f4e4f545f4c544e545f484f4c4445520000000000000000000000000000000000600082015250565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f45504f43485f4e4f545f52454143484544000000000000000000000000000000600082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000602082015250565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b7f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460008201527f656e7420746f6b656e0000000000000000000000000000000000000000000000602082015250565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f414c52454144595f5354414d5045440000000000000000000000000000000000600082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f494e56414c49445f42414e4b0000000000000000000000000000000000000000600082015250565b7f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f766564000000000000000000000000000000602082015250565b7f4e4f545f4f574e45520000000000000000000000000000000000000000000000600082015250565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b61595281615127565b811461595d57600080fd5b50565b61596981615139565b811461597457600080fd5b50565b61598081615145565b811461598b57600080fd5b50565b61599781615191565b81146159a257600080fd5b5056fea26469706673582212203cc3c29ed7b9549baa00f9a82e5ab8489c551231d1fb9788d40b5d2e66c1112764736f6c63430008040033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000006f2ff40f793776aa559644f52e58d83e21871ec3
-----Decoded View---------------
Arg [0] : ltnt_ (address): 0x6f2Ff40F793776Aa559644F52e58D83E21871EC3
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000006f2ff40f793776aa559644f52e58d83e21871ec3
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.