Feature Tip: Add private address tag to any address under My Name Tag !
ERC-721
Overview
Max Total Supply
270 OCAv2
Holders
132
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
1 OCAv2Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
OnChainAlphaV2
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity Standard Json-Input format)
/* SPDX-License-Identifier: MIT ██████ ░░░░░░ ▒▒▒▒▒▒ ██████████ ░░░░░░░░░░ ▒▒▒▒▒▒▒▒▒▒ ███ ███ ░░░░ ▒▒▒▒ ▒▒▒▒ ██████████ ░░░░░░░░░░ ▒▒▒▒ ▒▒▒▒ ██████ ░░░░░░ ▒▒▒ ▒▒▒ ******************************** * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * * ░░░██████████████████████░░░ * * ░░░██░░░░░░██░░░░░░████░░░░░ * * ░░░██░░░░░░██░░░░░░██░░░░░░░ * * ░░░██████████████████░░░░░░░ * * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * ************************♥tt****/ // onChainAlphaV2.sol is a fork of // IndelibleERC721A.sol by 0xHirch.eth // With modifications by ogkenobi.eth pragma solidity 0.8.17; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/Multicall.sol"; import "@openzeppelin/contracts/utils/Base64.sol"; import "@openzeppelin/contracts/utils/Address.sol"; import "./helpers/SSTORE2.sol"; import "./helpers/DynamicBuffer.sol"; import "./helpers/HelperLib.sol"; import "./helpers/ERC721A.sol"; contract OnChainAlphaV2 is ERC721A, IERC721Receiver, Multicall, ReentrancyGuard, Ownable { using HelperLib for uint256; using DynamicBuffer for bytes; event AttributesUpdated( uint256 tokenId, string userName, string social, string website, string profileName ); event LabelsValuesUpdated( uint256 tokenId, uint256 labelId, string customLabels, string customValues ); event LayersUpdated(uint256 tokenId, bool[] layerIsHidden); event LayersRevealed(uint256 tokenId, uint layerRevealed); event ImagePhlipped(uint256 tokenId, bool isPhlipped); event bgChanged(uint256 tokenId, string color); struct TraitDTO { string name; string mimetype; bytes data; } struct Trait { string name; string mimetype; } struct AlphaToken { Profile AlphaProfile; mapping(uint => string) labels; mapping(uint => string) values; uint256 labelcount; } struct Profile { string userName; string social; string website; string profileName; } struct ContractData { string name; string description; string image; string banner; string website; uint256 royalties; string royaltiesRecipient; } mapping(uint256 => address[]) internal _traitDataPointers; mapping(uint256 => mapping(uint256 => Trait)) internal _traitDetails; mapping(uint256 => bool) internal _renderTokenOffChain; mapping(uint256 => mapping(uint256 => bool)) internal _hideLayer; mapping(uint256 => mapping(uint256 => bool)) internal _revealLayer; mapping(uint256 => bool) internal _phlipImage; mapping(uint256 => AlphaToken) idValues; mapping(uint256 => string) bgColor; mapping(address => uint256) rebates; mapping(uint256 => bool) ogMints; mapping(uint256 => bool) ocaClaims; mapping(address => uint256) mints; uint256 private constant NUM_LAYERS = 15; uint256 private constant MAX_BATCH_MINT = 20; uint256[][NUM_LAYERS] private TIERS; string[] private LAYER_NAMES = [ unicode"Special", unicode"1", unicode"Mouth Special", unicode"3", unicode"Headwear", unicode"5", unicode"Eyewear", unicode"7", unicode"Eyes", unicode"9", unicode"Mouth", unicode"11", unicode"Ears", unicode"13", unicode"Body" ]; address public faContract = 0x89d92A754FD1A672c21b5fc2a347198D1A9456b3; address public ocaContract = 0x6A04d2443Be907DD7E83236398c985688acB796E; uint256 public constant maxSupply = 7262; uint256 public mintPrice = 0.05 ether; uint256 public rebateAmt = 0.02 ether; string public baseURI = "https://static.flooredApe.io/oca/"; bool public isPublicMintActive = false; ContractData public contractData = ContractData( unicode"On-Chain Alpha V2", unicode"On-Chain Alpha is a collection of 7777 customizable digital identity tokens stored entirely on the Ethereum blockchain. Token holders can visit https://oca.gg to enable/disable existing traits, change background color, flip the image, enable Twitter hex, and more as well as reveal new trait drops to be released in the future.", "https://ipfs.io/ipfs/Qmdbq7N5izrazoYcbwSuxcms2dBemxuxbrLaFtw2dufdV6/collection.gif", "https://ipfs.io/ipfs/Qmdbq7N5izrazoYcbwSuxcms2dBemxuxbrLaFtw2dufdV6/banner.png", "https://oca.gg", 500, "0x957356F9412830c992D465FF8CDb9b0AA023020b" ); constructor() ERC721A("On-Chain Alpha V2", "OCAv2") { TIERS[0] = [10,15,25,50,75,100,7225]; TIERS[1] = [35,65,100,130,160,190,220,250,280,310,340,370,400,430,460,490,520,550,600,1600]; TIERS[2] = [50,100,150,200,250,300,350,400,450,500,550,600,650,700,750,1500]; TIERS[3] = [35,65,100,130,160,190,220,250,280,310,340,370,400,430,460,490,520,550,600,1600]; TIERS[4] = [10,20,30,40,50,70,100,120,140,160,180,200,220,240,260,280,300,320,340,360,380,400,420,440,460,480,500,980]; TIERS[5] = [35,65,100,130,160,190,220,250,280,310,340,370,400,430,460,490,520,550,600,1600]; TIERS[6] = [35,65,100,130,160,190,220,250,280,310,340,370,400,430,460,490,520,550,600,1600]; TIERS[7] = [35,65,100,130,160,190,220,250,280,310,340,370,400,430,460,490,520,550,600,1600]; TIERS[8] = [20,40,60,80,100,120,140,160,180,200,240,280,320,360,400,440,480,520,560,600,640,1560]; TIERS[9] = [35,65,100,130,160,190,220,250,280,310,340,370,400,430,460,490,520,550,600,1600]; TIERS[10] = [25,50,75,100,125,150,175,200,225,300,450,600,750,900,1050,2850]; TIERS[11] = [35,65,100,130,160,190,220,250,280,310,340,370,400,430,460,490,520,550,600,1600]; TIERS[12] = [50,100,150,200,300,400,500,600,700,900,1000,1200,2600]; TIERS[13] = [35,65,100,130,160,190,220,250,280,310,340,370,400,430,460,490,520,550,600,1600]; TIERS[14] = [75,100,150,200,250,300,350,400,450,500,550,600,700,800,900,1175,0]; } function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) public override returns (bytes4) { require( msg.sender == faContract || ERC721(faContract).ownerOf( tokenId ) == from ); rebates[from]++; return this.onERC721Received.selector; } function publicMint(uint256 _count) external payable nonReentrant whenMintActive returns (uint256) { uint256 totalMinted = _totalMinted(); require(mints[msg.sender] + _count <= 100); require(_count <= MAX_BATCH_MINT && _count > 0); require(totalMinted + _count <= maxSupply); require(msg.sender == tx.origin); uint256 discount; uint256 numDisc = rebates[msg.sender]; if (numDisc > 0) { if (numDisc <= _count) { discount = rebateAmt * numDisc; require(msg.value >= (_count * mintPrice) - discount); rebates[msg.sender] = 0; } else { discount = rebateAmt * _count; require(msg.value >= (_count * mintPrice) - discount); rebates[msg.sender] -= _count; } } else { require(msg.value >= _count * mintPrice); } mints[msg.sender] += _count; _mint(msg.sender, _count); return totalMinted; } function freeClaim(uint256 _tokenId, bool _isOcaClaim) external nonReentrant whenMintActive returns (uint256) { uint256 totalMinted = _totalMinted(); if(_isOcaClaim){ require(ocaClaims[_tokenId] == false); require(msg.sender == ERC721(ocaContract).ownerOf(_tokenId)); require(totalMinted + 1 <= maxSupply); ocaClaims[_tokenId] = true; _mint(msg.sender, 1); } if(!_isOcaClaim){ require(_tokenId <= 1000); require(ogMints[_tokenId] == false); require(msg.sender == ERC721(faContract).ownerOf(_tokenId)); require(totalMinted + 1 <= maxSupply); ogMints[_tokenId] = true; _mint(msg.sender, 1); } return totalMinted; } function getClaimed(uint256 _tokenId, bool _isOcaClaim) public view returns (bool){ if(_isOcaClaim){ return ocaClaims[_tokenId]; } else { return ogMints[_tokenId]; } } function getRebates(address _address) public view returns (uint256) { return rebates[_address]; } function rarityGen(uint256 _randinput, uint256 _rarityTier) internal view returns (uint256) { uint256 currentLowerBound = 0; for (uint256 i = 0; i < TIERS[_rarityTier].length; i++) { uint256 thisPercentage = TIERS[_rarityTier][i]; if ( _randinput >= currentLowerBound && _randinput < currentLowerBound + thisPercentage ) return i; currentLowerBound = currentLowerBound + thisPercentage; } return TIERS[_rarityTier].length - 1; } function entropyForExtraData() internal view returns (uint24) { uint256 randomNumber = uint256( keccak256( abi.encodePacked( tx.gasprice, block.number, block.timestamp, block.difficulty, blockhash(block.number - 1), msg.sender ) ) ); return uint24(randomNumber); } function reRollDuplicate(uint256 tokenIdA, uint256 tokenIdB) public onlyOwner { uint256 largerTokenId = tokenIdA > tokenIdB ? tokenIdA : tokenIdB; _initializeOwnershipAt(largerTokenId); if (_exists(largerTokenId + 1)) { _initializeOwnershipAt(largerTokenId + 1); } _setExtraDataAt(largerTokenId, entropyForExtraData()); } function _extraData( address from, address to, uint24 previousExtraData ) internal view virtual override returns (uint24) { return from == address(0) ? entropyForExtraData() : previousExtraData; } function tokenIdToHash(uint256 _tokenId) public view returns (string memory) { require(_exists(_tokenId)); // This will generate a NUM_LAYERS * 3 character string. bytes memory hashBytes = DynamicBuffer.allocate(NUM_LAYERS * 4); uint256[] memory hash = new uint256[](NUM_LAYERS); for (uint256 i = 0; i < NUM_LAYERS; i++) { uint256 traitIndex = hash[i]; if(i % 2 > 0 && _revealLayer[_tokenId][i] == false){ hash[i] = TIERS[i].length - 1; } else { uint256 tokenExtraData = uint24(_ownershipOf(_tokenId).extraData); uint256 _randinput = uint256( keccak256( abi.encodePacked( tokenExtraData, _tokenId, _tokenId + i ) ) ) % maxSupply; traitIndex = rarityGen(_randinput, i); hash[i] = traitIndex; uint blank = TIERS[i].length - 1; if (_hideLayer[_tokenId][i] == true){ if (i == 10 && hash[i] == 10){ hash[i] = blank; if(_hideLayer[_tokenId][2] == false){hash[2] = 15;} } else if (i == 14 && hash[i] == 0) { hash[i] = blank; if(_hideLayer[_tokenId][8] == false){hash[8] = 5;} } else if (i == 14 && hash[i] == 2) { hash[i] = blank; if(_hideLayer[_tokenId][10] == false){hash[10] = 1;} if(_hideLayer[_tokenId][8] == false){hash[8] = 0;} if(_hideLayer[_tokenId][4] == false){hash[4] = 1;} } else if (i == 14 && hash[i] == 4) { hash[i] = blank; if(_hideLayer[_tokenId][10] == false){hash[10] = 8;} if(_hideLayer[_tokenId][8] == false){hash[8] = 9;} } else if (i == 14 && hash[i] == 5) { hash[i] = blank; if(_hideLayer[_tokenId][10] == false){hash[10] = 6;} if(_hideLayer[_tokenId][8] == false){hash[8] = 7;} } else if (i == 14 && hash[i] == 6) { hash[i] = blank; if(_hideLayer[_tokenId][10] == false){hash[10] = 7;} if(_hideLayer[_tokenId][8] == false){hash[8] = 8;} } else if (i == 14 && hash[i] == 7) { hash[i] = blank; if(_hideLayer[_tokenId][10] == false){hash[10] = 2;} if(_hideLayer[_tokenId][8] == false){hash[8] = 4;} } else if (i == 14 && hash[i] == 9) { hash[i] = blank; if(_hideLayer[_tokenId][10] == false){hash[10] = 5;} if(_hideLayer[_tokenId][8] == false){hash[8] = 1;} } else if (i == 14 && hash[i] == 10) { hash[i] = blank; if(_hideLayer[_tokenId][10] == false){hash[10] = 4;} if(_hideLayer[_tokenId][8] == false){hash[8] = 2;} } else if (i == 14 && hash[i] == 11) { hash[i] = blank; if(_hideLayer[_tokenId][10] == false){hash[10] = 3;} if(_hideLayer[_tokenId][8] == false){hash[8] = 3;} } else { hash[i] = blank; } } else { if (i == 10 && hash[10] == 10){ if(_hideLayer[_tokenId][2] == false){hash[2] = 15;} } if (i == 14){ if (hash[14] == 0) { if(_hideLayer[_tokenId][8] == false){hash[8] = 5;} } else if (hash[14] == 2) { if(_hideLayer[_tokenId][10] == false){hash[10] = 1;} if(_hideLayer[_tokenId][8] == false){hash[8] = 0;} if(_hideLayer[_tokenId][4] == false){hash[4] = 1;} } else if (hash[14] == 4) { if(_hideLayer[_tokenId][10] == false){hash[10] = 8;} if(_hideLayer[_tokenId][8] == false){hash[8] = 9;} } else if (hash[14] == 5) { if(_hideLayer[_tokenId][10] == false){hash[10] = 6;} if(_hideLayer[_tokenId][8] == false){hash[8] = 7;} } else if (hash[14] == 6) { if(_hideLayer[_tokenId][10] == false){hash[10] = 7;} if(_hideLayer[_tokenId][8] == false){hash[8] = 8;} } else if (hash[14] == 7) { if(_hideLayer[_tokenId][10] == false){hash[10] = 2;} if(_hideLayer[_tokenId][8] == false){hash[8] = 4;} } else if (hash[14] == 9) { if(_hideLayer[_tokenId][10] == false){hash[10] = 5;} if(_hideLayer[_tokenId][8] == false){hash[8] = 1;} } else if (hash[14] == 10) { if(_hideLayer[_tokenId][10] == false){hash[10] = 4;} if(_hideLayer[_tokenId][8] == false){hash[8] = 2;} } else if (hash[14] == 11) { if(_hideLayer[_tokenId][10] == false){hash[10] = 3;} if(_hideLayer[_tokenId][8] == false){hash[8] = 3;} } } } } } for (uint256 i = 0; i < hash.length; i++) { if (hash[i] < 10) { hashBytes.appendSafe("00"); } else if (hash[i] < 100) { hashBytes.appendSafe("0"); } if (hash[i] > 999) { hashBytes.appendSafe("999"); } else { hashBytes.appendSafe(bytes(_toString(hash[i]))); } } return string(hashBytes); } function hashToSVG(string memory _hash, uint256 _tokenId) public view returns (string memory) { uint256 thisTraitIndex; string memory _bgColor = "1C1531"; if (bytes(bgColor[_tokenId]).length > 0) { _bgColor = bgColor[_tokenId]; } bytes memory svgBytes = DynamicBuffer.allocate(1024 * 128); svgBytes.appendSafe( '<svg width="1600" height="1600" viewBox="0 0 1600 1600" version="1.2" xmlns="http://www.w3.org/2000/svg" style="background-color: #' ); svgBytes.appendSafe( abi.encodePacked(_bgColor, ";background-image:url(") ); for (uint256 i = 0; i < NUM_LAYERS - 1; i++) { if(!(i % 2 > 0 && _revealLayer[_tokenId][i] == false)){ thisTraitIndex = HelperLib.parseInt( HelperLib._substring(_hash, (i * 3), (i * 3) + 3) ); svgBytes.appendSafe( abi.encodePacked( "data:", _traitDetails[i][thisTraitIndex].mimetype, ";base64,", Base64.encode( SSTORE2.read(_traitDataPointers[i][thisTraitIndex]) ), "),url(" ) ); } } thisTraitIndex = HelperLib.parseInt( HelperLib._substring(_hash, (NUM_LAYERS * 3) - 3, NUM_LAYERS * 3) ); svgBytes.appendSafe( abi.encodePacked( "data:", _traitDetails[NUM_LAYERS - 1][thisTraitIndex].mimetype, ";base64,", Base64.encode( SSTORE2.read( _traitDataPointers[NUM_LAYERS - 1][thisTraitIndex] ) ), ');background-repeat:no-repeat;background-size:contain;background-position:center;image-rendering:-webkit-optimize-contrast;-ms-interpolation-mode:nearest-neighbor;image-rendering:-moz-crisp-edges;image-rendering:pixelated;"></svg>' ) ); return string( abi.encodePacked( "data:image/svg+xml;base64,", Base64.encode(svgBytes) ) ); } function hashToMetadata(string memory _hash) public view returns (string memory) { bytes memory metadataBytes = DynamicBuffer.allocate(1024 * 128); metadataBytes.appendSafe("["); bool trait11 = bytes(_traitDetails[11][HelperLib.parseInt(HelperLib._substring(_hash, 33, 36))].name).length < 3; bool trait12 = bytes(_traitDetails[12][HelperLib.parseInt(HelperLib._substring(_hash, 36, 39))].name).length < 3; bool trait13 = bytes(_traitDetails[13][HelperLib.parseInt(HelperLib._substring(_hash, 39, 42))].name).length < 3; bool trait14 = bytes(_traitDetails[14][HelperLib.parseInt(HelperLib._substring(_hash, 42, 45))].name).length < 3; for (uint256 i = 0; i < NUM_LAYERS; i++) { uint256 thisTraitIndex = HelperLib.parseInt( HelperLib._substring(_hash, (i * 3), (i * 3) + 3) ); if (bytes(_traitDetails[i][thisTraitIndex].name).length > 2 ) { metadataBytes.appendSafe( abi.encodePacked( '{"trait_type":"', LAYER_NAMES[i], '","value":"', _traitDetails[i][thisTraitIndex].name, '"}' ) ); if (i == 10 && (trait11 && trait12 && trait13 && trait14)){ metadataBytes.appendSafe("]"); } else if (i == 11 && (trait12 && trait13 && trait14)){ metadataBytes.appendSafe("]"); } else if (i == 12 && (trait13 && trait14)){ metadataBytes.appendSafe("]"); } else if (i == 13 && trait14){ metadataBytes.appendSafe("]"); } else if (i == 14) { metadataBytes.appendSafe("]"); } else { metadataBytes.appendSafe(","); } } } return string(metadataBytes); } function tokenURI(uint256 _tokenId) public view override returns (string memory) { require(_exists(_tokenId)); require(_traitDataPointers[0].length > 0); string memory tokenHash = tokenIdToHash(_tokenId); bytes memory jsonBytes = DynamicBuffer.allocate(1024 * 128); if (bytes(idValues[_tokenId].AlphaProfile.userName).length > 0) { jsonBytes.appendSafe( abi.encodePacked( unicode'{"name":"', idValues[_tokenId].AlphaProfile.userName ) ); } else { jsonBytes.appendSafe(unicode'{"name":"OnChainAlpha'); } jsonBytes.appendSafe( abi.encodePacked( "#", _toString(_tokenId), '","description":"', contractData.description, '",' ) ); if (bytes(baseURI).length > 0 && _renderTokenOffChain[_tokenId]) { jsonBytes.appendSafe( abi.encodePacked('"image":"', baseURI, _toString(_tokenId)) ); } else { string memory svgCode = ""; if (_phlipImage[_tokenId]) { string memory svgString = hashToSVG(tokenHash, _tokenId); svgCode = string( abi.encodePacked( "data:image/svg+xml;base64,", Base64.encode( abi.encodePacked( '<svg width="100%" height="100%" viewBox="0 0 1200 1200" style="display: block; transform: scale(-1,1)" version="1.2" xmlns="http://www.w3.org/2000/svg"><image width="1200" height="1200" href="', svgString, '"></image></svg>' ) ) ) ); jsonBytes.appendSafe( abi.encodePacked('"svg_image_data":"', svgString, '",') ); } else { string memory svgString = hashToSVG(tokenHash, _tokenId); svgCode = string( abi.encodePacked( "data:image/svg+xml;base64,", Base64.encode( abi.encodePacked( '<svg width="100%" height="100%" viewBox="0 0 1200 1200" version="1.2" xmlns="http://www.w3.org/2000/svg"><image width="1200" height="1200" href="', svgString, '"></image></svg>' ) ) ) ); jsonBytes.appendSafe( abi.encodePacked('"svg_image_data":"', svgString, '",') ); } jsonBytes.appendSafe( abi.encodePacked('"image_data":"', svgCode, '",') ); } jsonBytes.appendSafe( abi.encodePacked('"attributes":', hashToMetadata(tokenHash), "}") ); return string( abi.encodePacked( "data:application/json;base64,", Base64.encode(jsonBytes) ) ); } function contractURI() public view returns (string memory) { return string( abi.encodePacked( "data:application/json;base64,", Base64.encode( abi.encodePacked( '{"name":"', contractData.name, '","description":"', contractData.description, '","image":"', contractData.image, '","banner":"', contractData.banner, '","external_link":"', contractData.website, '","seller_fee_basis_points":', _toString(contractData.royalties), ',"fee_recipient":"', contractData.royaltiesRecipient, '"}' ) ) ) ); } function setRenderOfTokenId(uint256 _tokenId, bool _renderOffChain) external { require(msg.sender == ownerOf(_tokenId)); _renderTokenOffChain[_tokenId] = _renderOffChain; } modifier whenMintActive() { require(isMintActive()); _; } function isMintActive() public view returns (bool) { return _totalMinted() < maxSupply && isPublicMintActive; } function togglePublicMint() external onlyOwner { isPublicMintActive = !isPublicMintActive; } //metadata URI function setBaseURI(string memory _baseURI) external onlyOwner { baseURI = _baseURI; } function setContractData(ContractData memory _contractData) external onlyOwner { contractData = _contractData; } //address info address private helper = 0x95c0a28443F4897Bf718243A539fd018B6C16F63; //withdraw to helper address function withdraw() external { uint256 balance = address(this).balance; require(balance > 0); Address.sendValue(payable(helper), balance); } //oca profile functions function setBgColor(uint256 _tokenId, string memory _bgColor) public { require(ownerOf(_tokenId) == msg.sender); bgColor[_tokenId] = _bgColor; emit bgChanged(_tokenId, _bgColor); } function setProfile( uint256 _tokenId, string memory _username, string memory _social, string memory _website ) public { require(ownerOf(_tokenId) == msg.sender); idValues[_tokenId].AlphaProfile.userName = _username; idValues[_tokenId].AlphaProfile.social = _social; idValues[_tokenId].AlphaProfile.website = _website; string memory str = string(abi.encodePacked(_username,"#",_toString(_tokenId))); idValues[_tokenId].AlphaProfile.profileName = str; emit AttributesUpdated( _tokenId, _username, _social, _website, str ); } function setLabelsValues(uint256 _tokenId, uint _labelNum, string memory _label, string memory _value) external { require(msg.sender == ownerOf(_tokenId)); uint count = idValues[_tokenId].labelcount; if(_labelNum >= count){ _labelNum = count; idValues[_tokenId].labelcount++; } idValues[_tokenId].labels[_labelNum] = _label; idValues[_tokenId].values[_labelNum] = _value; emit LabelsValuesUpdated(_tokenId, _labelNum, _label, _value); } function toggleLayers(uint256 _tokenId, bool[] memory states) public { require(msg.sender == ownerOf(_tokenId)); for (uint256 i = 0; i < NUM_LAYERS; i++) { _hideLayer[_tokenId][i] = states[i]; } emit LayersUpdated(_tokenId, states); } function togglePhlipPFP(uint256 _tokenId, bool _flipped) public { require(msg.sender == ownerOf(_tokenId)); _phlipImage[_tokenId] = _flipped; emit ImagePhlipped(_tokenId, _flipped); } //layers function addLayer(uint256 _layerIndex, TraitDTO[] memory traits) public onlyOwner { require(TIERS[_layerIndex].length == traits.length); address[] memory dataPointers = new address[](traits.length); for (uint256 i = 0; i < traits.length; i++) { dataPointers[i] = SSTORE2.write(traits[i].data); _traitDetails[_layerIndex][i] = Trait( traits[i].name, traits[i].mimetype ); } _traitDataPointers[_layerIndex] = dataPointers; return; } function setLayerNames(uint _layerNum, string memory _value) public onlyOwner { LAYER_NAMES[_layerNum] = _value; } function revealLayers(uint256 _tokenId, uint _layer) public { require(_layer < 15); require(msg.sender == ownerOf(_tokenId)); _revealLayer[_tokenId][_layer] = true; emit LayersRevealed(_tokenId, _layer); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (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 Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { 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.8.0) (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() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // 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 // OpenZeppelin Contracts (last updated v4.8.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: address zero is not a valid owner"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _ownerOf(tokenId); require(owner != address(0), "ERC721: invalid token ID"); 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) { _requireMinted(tokenId); 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 token owner or approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { _requireMinted(tokenId); 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: caller is not token owner or 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: caller is not token owner or 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 the owner of the `tokenId`. Does NOT revert if token doesn't exist */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { return _owners[tokenId]; } /** * @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 _ownerOf(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) { 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, 1); // Check that tokenId was not minted by `_beforeTokenTransfer` hook require(!_exists(tokenId), "ERC721: token already minted"); unchecked { // Will not overflow unless all 2**256 token ids are minted to the same owner. // Given that tokens are minted one by one, it is impossible in practice that // this ever happens. Might change if we allow batch minting. // The ERC fails to describe this case. _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId, 1); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId, 1); // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook owner = ERC721.ownerOf(tokenId); // Clear approvals delete _tokenApprovals[tokenId]; unchecked { // Cannot overflow, as that would require more tokens to be burned/transferred // out than the owner initially received through minting and transferring in. _balances[owner] -= 1; } delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId, 1); } /** * @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, 1); // Check that tokenId was not transferred by `_beforeTokenTransfer` hook require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); // Clear approvals from the previous owner delete _tokenApprovals[tokenId]; unchecked { // `_balances[from]` cannot overflow for the same reason as described in `_burn`: // `from`'s balance is the number of token held, which is at least one before the current // transfer. // `_balances[to]` could overflow in the conditions described in `_mint`. That would require // all 2**256 token ids to be minted, which in practice is impossible. _balances[from] -= 1; _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId, 1); } /** * @dev Approve `to` to operate on `tokenId` * * Emits an {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 an {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 Reverts if the `tokenId` has not been minted yet. */ function _requireMinted(uint256 tokenId) internal view virtual { require(_exists(tokenId), "ERC721: invalid token ID"); } /** * @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 { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`. * - When `from` is zero, the tokens will be minted for `to`. * - When `to` is zero, ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256, /* firstTokenId */ uint256 batchSize ) internal virtual { if (batchSize > 1) { if (from != address(0)) { _balances[from] -= batchSize; } if (to != address(0)) { _balances[to] += batchSize; } } } /** * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`. * - When `from` is zero, the tokens were minted for `to`. * - When `to` is zero, ``from``'s tokens were burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual {} }
// 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 (last updated v4.8.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 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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * 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 (last updated v4.8.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 functionCallWithValue(target, data, 0, "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"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or 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 { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // 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 /// @solidity memory-safe-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.7.0) (utils/Base64.sol) pragma solidity ^0.8.0; /** * @dev Provides a set of functions to operate with Base64 strings. * * _Available since v4.5._ */ library Base64 { /** * @dev Base64 Encoding/Decoding Table */ string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /** * @dev Converts a `bytes` to its Bytes64 `string` representation. */ function encode(bytes memory data) internal pure returns (string memory) { /** * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol */ if (data.length == 0) return ""; // Loads the table into memory string memory table = _TABLE; // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter // and split into 4 numbers of 6 bits. // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up // - `data.length + 2` -> Round up // - `/ 3` -> Number of 3-bytes chunks // - `4 *` -> 4 characters for each chunk string memory result = new string(4 * ((data.length + 2) / 3)); /// @solidity memory-safe-assembly assembly { // Prepare the lookup table (skip the first "length" byte) let tablePtr := add(table, 1) // Prepare result pointer, jump over length let resultPtr := add(result, 32) // Run over the input, 3 bytes at a time for { let dataPtr := data let endPtr := add(data, mload(data)) } lt(dataPtr, endPtr) { } { // Advance 3 bytes dataPtr := add(dataPtr, 3) let input := mload(dataPtr) // To write each character, shift the 3 bytes (18 bits) chunk // 4 times in blocks of 6 bits for each character (18, 12, 6, 0) // and apply logical AND with 0x3F which is the number of // the previous character in the ASCII table prior to the Base64 Table // The result is then added to the table to get the character to write, // and finally write it in the result pointer but with a left shift // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F)))) resultPtr := add(resultPtr, 1) // Advance } // When data `bytes` is not exactly 3 bytes long // it is padded with `=` characters at the end switch mod(mload(data), 3) case 1 { mstore8(sub(resultPtr, 1), 0x3d) mstore8(sub(resultPtr, 2), 0x3d) } case 2 { mstore8(sub(resultPtr, 1), 0x3d) } } return result; } }
// 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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10**64) { value /= 10**64; result += 64; } if (value >= 10**32) { value /= 10**32; result += 32; } if (value >= 10**16) { value /= 10**16; result += 16; } if (value >= 10**8) { value /= 10**8; result += 8; } if (value >= 10**4) { value /= 10**4; result += 4; } if (value >= 10**2) { value /= 10**2; result += 2; } if (value >= 10**1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (utils/Multicall.sol) pragma solidity ^0.8.0; import "./Address.sol"; /** * @dev Provides a function to batch together multiple calls in a single external call. * * _Available since v4.1._ */ abstract contract Multicall { /** * @dev Receives and executes a batch of function calls on this contract. */ function multicall(bytes[] calldata data) external virtual returns (bytes[] memory results) { results = new bytes[](data.length); for (uint256 i = 0; i < data.length; i++) { results[i] = Address.functionDelegateCall(address(this), data[i]); } return results; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @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] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library Bytecode { error InvalidCodeAtRange(uint256 _size, uint256 _start, uint256 _end); /** @notice Generate a creation code that results on a contract with `_code` as bytecode @param _code The returning value of the resulting `creationCode` @return creationCode (constructor) for new contract */ function creationCodeFor(bytes memory _code) internal pure returns (bytes memory) { /* 0x00 0x63 0x63XXXXXX PUSH4 _code.length size 0x01 0x80 0x80 DUP1 size size 0x02 0x60 0x600e PUSH1 14 14 size size 0x03 0x60 0x6000 PUSH1 00 0 14 size size 0x04 0x39 0x39 CODECOPY size 0x05 0x60 0x6000 PUSH1 00 0 size 0x06 0xf3 0xf3 RETURN <CODE> */ return abi.encodePacked( hex"63", uint32(_code.length), hex"80_60_0E_60_00_39_60_00_F3", _code ); } /** @notice Returns the size of the code on a given address @param _addr Address that may or may not contain code @return size of the code on the given `_addr` */ function codeSize(address _addr) internal view returns (uint256 size) { assembly { size := extcodesize(_addr) } } /** @notice Returns the code of a given address @dev It will fail if `_end < _start` @param _addr Address that may or may not contain code @param _start number of bytes of code to skip on read @param _end index before which to end extraction @return oCode read from `_addr` deployed bytecode Forked from: https://gist.github.com/KardanovIR/fe98661df9338c842b4a30306d507fbd */ function codeAt(address _addr, uint256 _start, uint256 _end) internal view returns (bytes memory oCode) { uint256 csize = codeSize(_addr); if (csize == 0) return bytes(""); if (_start > csize) return bytes(""); if (_end < _start) revert InvalidCodeAtRange(csize, _start, _end); unchecked { uint256 reqSize = _end - _start; uint256 maxSize = csize - _start; uint256 size = maxSize < reqSize ? maxSize : reqSize; assembly { // allocate output byte array - this could also be done without assembly // by using o_code = new bytes(size) oCode := mload(0x40) // new "memory end" including padding mstore(0x40, add(oCode, and(add(add(size, 0x20), 0x1f), not(0x1f)))) // store length in memory mstore(oCode, size) // actually retrieve the code, this needs assembly extcodecopy(_addr, add(oCode, 0x20), _start, size) } } } }
// SPDX-License-Identifier: MIT // Copyright (c) 2021 the ethier authors (github.com/divergencetech/ethier) pragma solidity >=0.8.0; /// @title DynamicBuffer /// @author David Huber (@cxkoda) and Simon Fremaux (@dievardump). See also /// https://raw.githubusercontent.com/dievardump/solidity-dynamic-buffer /// @notice This library is used to allocate a big amount of container memory // which will be subsequently filled without needing to reallocate /// memory. /// @dev First, allocate memory. /// Then use `buffer.appendUnchecked(theBytes)` or `appendSafe()` if /// bounds checking is required. library DynamicBuffer { /// @notice Allocates container space for the DynamicBuffer /// @param capacity The intended max amount of bytes in the buffer /// @return buffer The memory location of the buffer /// @dev Allocates `capacity + 0x60` bytes of space /// The buffer array starts at the first container data position, /// (i.e. `buffer = container + 0x20`) function allocate(uint256 capacity) internal pure returns (bytes memory buffer) { assembly { // Get next-free memory address let container := mload(0x40) // Allocate memory by setting a new next-free address { // Add 2 x 32 bytes in size for the two length fields // Add 32 bytes safety space for 32B chunked copy let size := add(capacity, 0x60) let newNextFree := add(container, size) mstore(0x40, newNextFree) } // Set the correct container length { let length := add(capacity, 0x40) mstore(container, length) } // The buffer starts at idx 1 in the container (0 is length) buffer := add(container, 0x20) // Init content with length 0 mstore(buffer, 0) } return buffer; } /// @notice Appends data to buffer, and update buffer length /// @param buffer the buffer to append the data to /// @param data the data to append /// @dev Does not perform out-of-bound checks (container capacity) /// for efficiency. function appendUnchecked(bytes memory buffer, bytes memory data) internal pure { assembly { let length := mload(data) for { data := add(data, 0x20) let dataEnd := add(data, length) let copyTo := add(buffer, add(mload(buffer), 0x20)) } lt(data, dataEnd) { data := add(data, 0x20) copyTo := add(copyTo, 0x20) } { // Copy 32B chunks from data to buffer. // This may read over data array boundaries and copy invalid // bytes, which doesn't matter in the end since we will // later set the correct buffer length, and have allocated an // additional word to avoid buffer overflow. mstore(copyTo, mload(data)) } // Update buffer length mstore(buffer, add(mload(buffer), length)) } } /// @notice Appends data to buffer, and update buffer length /// @param buffer the buffer to append the data to /// @param data the data to append /// @dev Performs out-of-bound checks and calls `appendUnchecked`. function appendSafe(bytes memory buffer, bytes memory data) internal pure { uint256 capacity; uint256 length; assembly { capacity := sub(mload(sub(buffer, 0x20)), 0x40) length := mload(buffer) } require( length + data.length <= capacity, "DynamicBuffer: Appending out of bounds." ); appendUnchecked(buffer, data); } }
// SPDX-License-Identifier: MIT // ERC721A Contracts v4.1.0 // Creator: Chiru Labs pragma solidity ^0.8.4; import './IERC721A.sol'; /** * @dev ERC721 token receiver interface. */ interface ERC721A__IERC721Receiver { function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, * including the Metadata extension. Built to optimize for lower gas during batch mints. * * Assumes serials are sequentially minted starting at `_startTokenId()` * (defaults to 0, e.g. 0, 1, 2, 3..). * * Assumes that an owner cannot have more than 2**64 - 1 (max value of uint64) of supply. * * Assumes that the maximum token id cannot exceed 2**256 - 1 (max value of uint256). */ contract ERC721A is IERC721A { // Mask of an entry in packed address data. uint256 private constant BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1; // The bit position of `numberMinted` in packed address data. uint256 private constant BITPOS_NUMBER_MINTED = 64; // The bit position of `numberBurned` in packed address data. uint256 private constant BITPOS_NUMBER_BURNED = 128; // The bit position of `aux` in packed address data. uint256 private constant BITPOS_AUX = 192; // Mask of all 256 bits in packed address data except the 64 bits for `aux`. uint256 private constant BITMASK_AUX_COMPLEMENT = (1 << 192) - 1; // The bit position of `startTimestamp` in packed ownership. uint256 private constant BITPOS_START_TIMESTAMP = 160; // The bit mask of the `burned` bit in packed ownership. uint256 private constant BITMASK_BURNED = 1 << 224; // The bit position of the `nextInitialized` bit in packed ownership. uint256 private constant BITPOS_NEXT_INITIALIZED = 225; // The bit mask of the `nextInitialized` bit in packed ownership. uint256 private constant BITMASK_NEXT_INITIALIZED = 1 << 225; // The bit position of `extraData` in packed ownership. uint256 private constant BITPOS_EXTRA_DATA = 232; // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`. uint256 private constant BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1; // The mask of the lower 160 bits for addresses. uint256 private constant BITMASK_ADDRESS = (1 << 160) - 1; // The maximum `quantity` that can be minted with `_mintERC2309`. // This limit is to prevent overflows on the address data entries. // For a limit of 5000, a total of 3.689e15 calls to `_mintERC2309` // is required to cause an overflow, which is unrealistic. uint256 private constant MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000; // The tokenId of the next token to be minted. uint256 private _currentIndex; // The number of tokens burned. uint256 private _burnCounter; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to ownership details // An empty struct value does not necessarily mean the token is unowned. // See `_packedOwnershipOf` implementation for details. // // Bits Layout: // - [0..159] `addr` // - [160..223] `startTimestamp` // - [224] `burned` // - [225] `nextInitialized` // - [232..255] `extraData` mapping(uint256 => uint256) private _packedOwnerships; // Mapping owner address to address data. // // Bits Layout: // - [0..63] `balance` // - [64..127] `numberMinted` // - [128..191] `numberBurned` // - [192..255] `aux` mapping(address => uint256) private _packedAddressData; // 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; constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; _currentIndex = _startTokenId(); } /** * @dev Returns the starting token ID. * To change the starting token ID, please override this function. */ function _startTokenId() internal view virtual returns (uint256) { return 262; } /** * @dev Returns the next token ID to be minted. */ function _nextTokenId() internal view returns (uint256) { return _currentIndex; } /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see `_totalMinted`. */ function totalSupply() public view override returns (uint256) { // Counter underflow is impossible as _burnCounter cannot be incremented // more than `_currentIndex - _startTokenId()` times. unchecked { return _currentIndex - _burnCounter - _startTokenId(); } } /** * @dev Returns the total amount of tokens minted in the contract. */ function _totalMinted() internal view returns (uint256) { // Counter underflow is impossible as _currentIndex does not decrement, // and it is initialized to `_startTokenId()` unchecked { return _currentIndex - _startTokenId(); } } /** * @dev Returns the total number of tokens burned. */ function _totalBurned() internal view returns (uint256) { return _burnCounter; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { // The interface IDs are constants representing the first 4 bytes of the XOR of // all function selectors in the interface. See: https://eips.ethereum.org/EIPS/eip-165 // e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)` return interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165. interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721. interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata. } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view override returns (uint256) { if (owner == address(0)) revert BalanceQueryForZeroAddress(); return _packedAddressData[owner] & BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens minted by `owner`. */ function _numberMinted(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> BITPOS_NUMBER_MINTED) & BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens burned by or on behalf of `owner`. */ function _numberBurned(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> BITPOS_NUMBER_BURNED) & BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). */ function _getAux(address owner) internal view returns (uint64) { return uint64(_packedAddressData[owner] >> BITPOS_AUX); } /** * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). * If there are multiple variables, please pack them into a uint64. */ function _setAux(address owner, uint64 aux) internal { uint256 packed = _packedAddressData[owner]; uint256 auxCasted; // Cast `aux` with assembly to avoid redundant masking. assembly { auxCasted := aux } packed = (packed & BITMASK_AUX_COMPLEMENT) | (auxCasted << BITPOS_AUX); _packedAddressData[owner] = packed; } /** * Returns the packed ownership data of `tokenId`. */ function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) { uint256 curr = tokenId; unchecked { if (_startTokenId() <= curr) if (curr < _currentIndex) { uint256 packed = _packedOwnerships[curr]; // If not burned. if (packed & BITMASK_BURNED == 0) { // Invariant: // There will always be an ownership that has an address and is not burned // before an ownership that does not have an address and is not burned. // Hence, curr will not underflow. // // We can directly compare the packed value. // If the address is zero, packed is zero. while (packed == 0) { packed = _packedOwnerships[--curr]; } return packed; } } } revert OwnerQueryForNonexistentToken(); } /** * Returns the unpacked `TokenOwnership` struct from `packed`. */ function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) { ownership.addr = address(uint160(packed)); ownership.startTimestamp = uint64(packed >> BITPOS_START_TIMESTAMP); ownership.burned = packed & BITMASK_BURNED != 0; ownership.extraData = uint24(packed >> BITPOS_EXTRA_DATA); } /** * Returns the unpacked `TokenOwnership` struct at `index`. */ function _ownershipAt(uint256 index) internal view returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnerships[index]); } /** * @dev Initializes the ownership slot minted at `index` for efficiency purposes. */ function _initializeOwnershipAt(uint256 index) internal { if (_packedOwnerships[index] == 0) { _packedOwnerships[index] = _packedOwnershipOf(index); } } /** * Gas spent here starts off proportional to the maximum mint batch size. * It gradually moves to O(1) as tokens get transferred around in the collection over time. */ function _ownershipOf(uint256 tokenId) internal view returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnershipOf(tokenId)); } /** * @dev Packs ownership data into a single uint256. */ function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, BITMASK_ADDRESS) // `owner | (block.timestamp << BITPOS_START_TIMESTAMP) | flags`. result := or(owner, or(shl(BITPOS_START_TIMESTAMP, timestamp()), flags)) } } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view override returns (address) { return address(uint160(_packedOwnershipOf(tokenId))); } /** * @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) { if (!_exists(tokenId)) revert URIQueryForNonexistentToken(); string memory baseURI = _baseURI(); return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : ''; } /** * @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, it can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ''; } /** * @dev Returns the `nextInitialized` flag set if `quantity` equals 1. */ function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) { // For branchless setting of the `nextInitialized` flag. assembly { // `(quantity == 1) << BITPOS_NEXT_INITIALIZED`. result := shl(BITPOS_NEXT_INITIALIZED, eq(quantity, 1)) } } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public override { address owner = ownerOf(tokenId); if (_msgSenderERC721A() != owner) if (!isApprovedForAll(owner, _msgSenderERC721A())) { revert ApprovalCallerNotOwnerNorApproved(); } _tokenApprovals[tokenId] = to; emit Approval(owner, to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view override returns (address) { if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken(); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { if (operator == _msgSenderERC721A()) revert ApproveToCaller(); _operatorApprovals[_msgSenderERC721A()][operator] = approved; emit ApprovalForAll(_msgSenderERC721A(), 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-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 { transferFrom(from, to, tokenId); if (to.code.length != 0) if (!_checkContractOnERC721Received(from, to, tokenId, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } /** * @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`), */ function _exists(uint256 tokenId) internal view returns (bool) { return _startTokenId() <= tokenId && tokenId < _currentIndex && // If within bounds, _packedOwnerships[tokenId] & BITMASK_BURNED == 0; // and not burned. } /** * @dev Equivalent to `_safeMint(to, quantity, '')`. */ function _safeMint(address to, uint256 quantity) internal { _safeMint(to, quantity, ''); } /** * @dev Safely mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called for each safe transfer. * - `quantity` must be greater than 0. * * See {_mint}. * * Emits a {Transfer} event for each mint. */ function _safeMint( address to, uint256 quantity, bytes memory _data ) internal { _mint(to, quantity); unchecked { if (to.code.length != 0) { uint256 end = _currentIndex; uint256 index = end - quantity; do { if (!_checkContractOnERC721Received(address(0), to, index++, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } while (index < end); // Reentrancy protection. if (_currentIndex != end) revert(); } } } /** * @dev Mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {Transfer} event for each mint. */ function _mint(address to, uint256 quantity) internal { uint256 startTokenId = _currentIndex; if (to == address(0)) revert MintToZeroAddress(); if (quantity == 0) revert MintZeroQuantity(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are incredibly unrealistic. // `balance` and `numberMinted` have a maximum limit of 2**64. // `tokenId` has a maximum limit of 2**256. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); uint256 tokenId = startTokenId; uint256 end = startTokenId + quantity; do { emit Transfer(address(0), to, tokenId++); } while (tokenId < end); _currentIndex = end; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Mints `quantity` tokens and transfers them to `to`. * * This function is intended for efficient minting only during contract creation. * * It emits only one {ConsecutiveTransfer} as defined in * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309), * instead of a sequence of {Transfer} event(s). * * Calling this function outside of contract creation WILL make your contract * non-compliant with the ERC721 standard. * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309 * {ConsecutiveTransfer} event is only permissible during contract creation. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {ConsecutiveTransfer} event. */ function _mintERC2309(address to, uint256 quantity) internal { uint256 startTokenId = _currentIndex; if (to == address(0)) revert MintToZeroAddress(); if (quantity == 0) revert MintZeroQuantity(); if (quantity > MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are unrealistic due to the above check for `quantity` to be below the limit. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to); _currentIndex = startTokenId + quantity; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Returns the storage slot and value for the approved address of `tokenId`. */ function _getApprovedAddress(uint256 tokenId) private view returns (uint256 approvedAddressSlot, address approvedAddress) { mapping(uint256 => address) storage tokenApprovalsPtr = _tokenApprovals; // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId]`. assembly { // Compute the slot. mstore(0x00, tokenId) mstore(0x20, tokenApprovalsPtr.slot) approvedAddressSlot := keccak256(0x00, 0x40) // Load the slot's value from storage. approvedAddress := sload(approvedAddressSlot) } } /** * @dev Returns whether the `approvedAddress` is equals to `from` or `msgSender`. */ function _isOwnerOrApproved( address approvedAddress, address from, address msgSender ) private pure returns (bool result) { assembly { // Mask `from` to the lower 160 bits, in case the upper bits somehow aren't clean. from := and(from, BITMASK_ADDRESS) // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean. msgSender := and(msgSender, BITMASK_ADDRESS) // `msgSender == from || msgSender == approvedAddress`. result := or(eq(msgSender, from), eq(msgSender, approvedAddress)) } } /** * @dev Transfers `tokenId` from `from` to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner(); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedAddress(tokenId); // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isOwnerOrApproved(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); if (to == address(0)) revert TransferToZeroAddress(); _beforeTokenTransfers(from, to, tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256. unchecked { // We can directly increment and decrement the balances. --_packedAddressData[from]; // Updates: `balance -= 1`. ++_packedAddressData[to]; // Updates: `balance += 1`. // Updates: // - `address` to the next owner. // - `startTimestamp` to the timestamp of transfering. // - `burned` to `false`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( to, BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, to, tokenId); _afterTokenTransfers(from, to, tokenId, 1); } /** * @dev Equivalent to `_burn(tokenId, false)`. */ function _burn(uint256 tokenId) internal virtual { _burn(tokenId, false); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId, bool approvalCheck) internal virtual { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); address from = address(uint160(prevOwnershipPacked)); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedAddress(tokenId); if (approvalCheck) { // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isOwnerOrApproved(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); } _beforeTokenTransfers(from, address(0), tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // Updates: // - `balance -= 1`. // - `numberBurned += 1`. // // We can directly decrement the balance, and increment the number burned. // This is equivalent to `packed -= 1; packed += 1 << BITPOS_NUMBER_BURNED;`. _packedAddressData[from] += (1 << BITPOS_NUMBER_BURNED) - 1; // Updates: // - `address` to the last owner. // - `startTimestamp` to the timestamp of burning. // - `burned` to `true`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( from, (BITMASK_BURNED | BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, address(0), tokenId); _afterTokenTransfers(from, address(0), tokenId, 1); // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times. unchecked { _burnCounter++; } } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target 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 _checkContractOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns ( bytes4 retval ) { return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert TransferToNonERC721ReceiverImplementer(); } else { assembly { revert(add(32, reason), mload(reason)) } } } } /** * @dev Directly sets the extra data for the ownership data `index`. */ function _setExtraDataAt(uint256 index, uint24 extraData) internal { uint256 packed = _packedOwnerships[index]; if (packed == 0) revert OwnershipNotInitializedForExtraData(); uint256 extraDataCasted; // Cast `extraData` with assembly to avoid redundant masking. assembly { extraDataCasted := extraData } packed = (packed & BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << BITPOS_EXTRA_DATA); _packedOwnerships[index] = packed; } /** * @dev Returns the next extra data for the packed ownership data. * The returned result is shifted into position. */ function _nextExtraData( address from, address to, uint256 prevOwnershipPacked ) private view returns (uint256) { uint24 extraData = uint24(prevOwnershipPacked >> BITPOS_EXTRA_DATA); return uint256(_extraData(from, to, extraData)) << BITPOS_EXTRA_DATA; } /** * @dev Called during each token transfer to set the 24bit `extraData` field. * Intended to be overridden by the cosumer contract. * * `previousExtraData` - the value of `extraData` before transfer. * * 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, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _extraData( address from, address to, uint24 previousExtraData ) internal view virtual returns (uint24) {} /** * @dev Hook that is called before a set of serially-ordered token ids are about to be transferred. * This includes minting. * And also called before burning one token. * * startTokenId - the first token id to be transferred * quantity - the amount to be transferred * * 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, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Hook that is called after a set of serially-ordered token ids have been transferred. * This includes minting. * And also called after one token has been burned. * * startTokenId - the first token id to be transferred * quantity - the amount to be transferred * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been * transferred to `to`. * - When `from` is zero, `tokenId` has been minted for `to`. * - When `to` is zero, `tokenId` has been burned by `from`. * - `from` and `to` are never both zero. */ function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Returns the message sender (defaults to `msg.sender`). * * If you are writing GSN compatible contracts, you need to override this function. */ function _msgSenderERC721A() internal view virtual returns (address) { return msg.sender; } /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function _toString(uint256 value) internal pure returns (string memory ptr) { assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), // but we allocate 128 bytes to keep the free memory pointer 32-byte word aliged. // We will need 1 32-byte word to store the length, // and 3 32-byte words to store a maximum of 78 digits. Total: 32 + 3 * 32 = 128. ptr := add(mload(0x40), 128) // Update the free memory pointer to allocate. mstore(0x40, ptr) // Cache the end of the memory to calculate the length later. let end := ptr // We write the string from the rightmost digit to the leftmost digit. // The following is essentially a do-while loop that also handles the zero case. // Costs a bit more than early returning for the zero case, // but cheaper in terms of deployment and overall runtime costs. for { // Initialize and perform the first pass without check. let temp := value // Move the pointer 1 byte leftwards to point to an empty character slot. ptr := sub(ptr, 1) // Write the character to the pointer. 48 is the ASCII index of '0'. mstore8(ptr, add(48, mod(temp, 10))) temp := div(temp, 10) } temp { // Keep dividing `temp` until zero. temp := div(temp, 10) } { // Body of the for loop. ptr := sub(ptr, 1) mstore8(ptr, add(48, mod(temp, 10))) } let length := sub(end, ptr) // Move the pointer 32 bytes leftwards to make room for the length. ptr := sub(ptr, 32) // Store the length. mstore(ptr, length) } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.14; library HelperLib { function parseInt(string memory _a) internal pure returns (uint8 _parsedInt) { bytes memory bresult = bytes(_a); uint8 mint = 0; for (uint8 i = 0; i < bresult.length; i++) { if ( (uint8(uint8(bresult[i])) >= 48) && (uint8(uint8(bresult[i])) <= 57) ) { mint *= 10; mint += uint8(bresult[i]) - 48; } } return mint; } function _substring( string memory str, uint256 startIndex, uint256 endIndex ) internal pure returns (string memory) { bytes memory strBytes = bytes(str); bytes memory result = new bytes(endIndex - startIndex); for (uint256 i = startIndex; i < endIndex; i++) { result[i - startIndex] = strBytes[i]; } return string(result); } }
// SPDX-License-Identifier: MIT // ERC721A Contracts v4.1.0 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of an ERC721A compliant contract. */ interface IERC721A { /** * The caller must own the token or be an approved operator. */ error ApprovalCallerNotOwnerNorApproved(); /** * The token does not exist. */ error ApprovalQueryForNonexistentToken(); /** * The caller cannot approve to their own address. */ error ApproveToCaller(); /** * Cannot query the balance for the zero address. */ error BalanceQueryForZeroAddress(); /** * Cannot mint to the zero address. */ error MintToZeroAddress(); /** * The quantity of tokens minted must be more than zero. */ error MintZeroQuantity(); /** * The token does not exist. */ error OwnerQueryForNonexistentToken(); /** * The caller must own the token or be an approved operator. */ error TransferCallerNotOwnerNorApproved(); /** * The token must be owned by `from`. */ error TransferFromIncorrectOwner(); /** * Cannot safely transfer to a contract that does not implement the ERC721Receiver interface. */ error TransferToNonERC721ReceiverImplementer(); /** * Cannot transfer to the zero address. */ error TransferToZeroAddress(); /** * The token does not exist. */ error URIQueryForNonexistentToken(); /** * The `quantity` minted with ERC2309 exceeds the safety limit. */ error MintERC2309QuantityExceedsLimit(); /** * The `extraData` cannot be set on an unintialized ownership slot. */ error OwnershipNotInitializedForExtraData(); struct TokenOwnership { // The address of the owner. address addr; // Keeps track of the start time of ownership with minimal overhead for tokenomics. uint64 startTimestamp; // Whether the token has been burned. bool burned; // Arbitrary data similar to `startTimestamp` that can be set through `_extraData`. uint24 extraData; } /** * @dev Returns the total amount of tokens stored by the contract. * * Burned tokens are calculated here, use `_totalMinted()` if you want to count just minted tokens. */ function totalSupply() external view returns (uint256); // ============================== // 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); // ============================== // IERC721 // ============================== /** * @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); // ============================== // IERC721Metadata // ============================== /** * @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); // ============================== // IERC2309 // ============================== /** * @dev Emitted when tokens in `fromTokenId` to `toTokenId` (inclusive) is transferred from `from` to `to`, * as defined in the ERC2309 standard. See `_mintERC2309` for more details. */ event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../helpers/Bytecode.sol"; /** @title A key-value storage with auto-generated keys for storing chunks of data with a lower write & read cost. @author Agustin Aguilar <[email protected]> Readme: https://github.com/0xsequence/sstore2#readme */ library SSTORE2 { error WriteError(); /** @notice Stores `_data` and returns `pointer` as key for later retrieval @dev The pointer is a contract address with `_data` as code @param _data to be written @return pointer Pointer to the written `_data` */ function write(bytes memory _data) internal returns (address pointer) { // Append 00 to _data so contract can't be called // Build init code bytes memory code = Bytecode.creationCodeFor( abi.encodePacked( hex'00', _data ) ); // Deploy contract using create assembly { pointer := create(0, add(code, 32), mload(code)) } // Address MUST be non-zero if (pointer == address(0)) revert WriteError(); } /** @notice Reads the contents of the `_pointer` code as data, skips the first byte @dev The function is intended for reading pointers generated by `write` @param _pointer to be read @return data read from `_pointer` contract */ function read(address _pointer) internal view returns (bytes memory) { return Bytecode.codeAt(_pointer, 1, type(uint256).max); } /** @notice Reads the contents of the `_pointer` code as data, skips the first byte @dev The function is intended for reading pointers generated by `write` @param _pointer to be read @param _start number of bytes to skip @return data read from `_pointer` contract */ function read(address _pointer, uint256 _start) internal view returns (bytes memory) { return Bytecode.codeAt(_pointer, _start + 1, type(uint256).max); } /** @notice Reads the contents of the `_pointer` code as data, skips the first byte @dev The function is intended for reading pointers generated by `write` @param _pointer to be read @param _start number of bytes to skip @param _end index before which to end extraction @return data read from `_pointer` contract */ function read(address _pointer, uint256 _start, uint256 _end) internal view returns (bytes memory) { return Bytecode.codeAt(_pointer, _start + 1, _end + 1); } }
/* SPDX-License-Identifier: MIT ██████ ░░░░░░ ▒▒▒▒▒▒ ██████████ ░░░░░░░░░░ ▒▒▒▒▒▒▒▒▒▒ ███ ███ ░░░░ ▒▒▒▒ ▒▒▒▒ ██████████ ░░░░░░░░░░ ▒▒▒▒ ▒▒▒▒ ██████ ░░░░░░ ▒▒▒ ▒▒▒ ******************************** * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * * ░░░██████████████████████░░░ * * ░░░██░░░░░░██░░░░░░████░░░░░ * * ░░░██░░░░░░██░░░░░░██░░░░░░░ * * ░░░██████████████████░░░░░░░ * * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * ************************♥tt****/ // onChainAlpha.sol is a fork of // IndelibleERC721A.sol by 0xHirch.eth // With modifications by ogkenobi.eth pragma solidity 0.8.17; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/Multicall.sol"; import "@openzeppelin/contracts/utils/Base64.sol"; import "@openzeppelin/contracts/utils/Address.sol"; import "./helpers/SSTORE2.sol"; import "./helpers/DynamicBuffer.sol"; import "./helpers/HelperLib.sol"; import "./helpers/ERC721A.sol"; contract OnChainAlphaV1 is ERC721A, IERC721Receiver, Multicall, ReentrancyGuard, Ownable { using HelperLib for uint256; using DynamicBuffer for bytes; event AttributesUpdated( uint256 tokenId, string userName, string social, string website, string profileName ); event LabelsValuesUpdated( uint256 tokenId, uint256 labelId, string customLabels, string customValues ); event LayersUpdated(uint256 tokenId, bool[] layerIsHidden); event LayersRevealed(uint256 tokenId, uint layerRevealed); event ImagePhlipped(uint256 tokenId, bool isPhlipped); event bgChanged(uint256 tokenId, string color); struct TraitDTO { string name; string mimetype; bytes data; } struct Trait { string name; string mimetype; } struct AlphaToken { Profile AlphaProfile; mapping(uint => string) labels; mapping(uint => string) values; uint256 labelcount; } struct Profile { string userName; string social; string website; string profileName; } struct ContractData { string name; string description; string image; string banner; string website; uint256 royalties; string royaltiesRecipient; } mapping(uint256 => address[]) internal _traitDataPointers; mapping(uint256 => mapping(uint256 => Trait)) internal _traitDetails; mapping(uint256 => bool) internal _renderTokenOffChain; mapping(uint256 => mapping(uint256 => bool)) internal _hideLayer; mapping(uint256 => mapping(uint256 => bool)) internal _revealLayer; mapping(uint256 => bool) internal _phlipImage; mapping(uint256 => AlphaToken) idValues; mapping(uint256 => string) bgColor; mapping(address => uint256) rebates; mapping(uint256 => bool) ogMints; mapping(address => uint256) mints; uint256 private constant NUM_LAYERS = 15; uint256 private constant MAX_BATCH_MINT = 10; uint256[][NUM_LAYERS] private TIERS; string[] private LAYER_NAMES = [ unicode"Special", unicode"-", unicode"Mouth Special", unicode"-", unicode"Headwear", unicode"-", unicode"Eyewear", unicode"-", unicode"Eyes", unicode"-", unicode"Mouth", unicode"-", unicode"Ears", unicode"-", unicode"Body" ]; function setLayerNames(uint _layerNum, string memory _value) public onlyOwner { LAYER_NAMES[_layerNum] = _value; } address public reRollDuplicateRole = 0x957356F9412830c992D465FF8CDb9b0AA023020b; address public faContract = 0xbD2075e820FD448A3AD7b2A6a593BAC56534a950; //testnet uint256 public constant maxSupply = 7777; uint256 public mintPrice = 0.0 ether; uint256 public rebateAmt = 0.0 ether; string public baseURI = "https://static.flooredApe.io/oca/"; bool public isPublicMintActive = false; ContractData public contractData = ContractData( unicode"On-Chain Alpha", unicode"On-Chain Alpha is a collection of 7777 customizable digital identity tokens stored entirely on the Ethereum blockchain. Token holders can visit https://oca.gg to enable/disable existing traits, change background color, flip the image, enable Twitter hex, and more as well as reveal new trait drops to be released in the future.", "https://ipfs.io/ipfs/Qmdbq7N5izrazoYcbwSuxcms2dBemxuxbrLaFtw2dufdV6/collection.gif", "https://ipfs.io/ipfs/Qmdbq7N5izrazoYcbwSuxcms2dBemxuxbrLaFtw2dufdV6/banner.png", "https://oca.gg", 500, "0x957356F9412830c992D465FF8CDb9b0AA023020b" ); constructor() ERC721A("On-Chain Alpha", "OCA") { TIERS[0] = [10,15,25,50,75,100,7502]; //special 0 TIERS[1] = [35,65,100,130,160,190,220,250,280,310,340,370,400,450,500,650,700,750,850,1027]; TIERS[2] = [50,100,150,200,250,300,350,400,450,500,550,600,650,700,750,1777]; //mouth special 1 TIERS[3] = [35,65,100,130,160,190,220,250,280,310,340,370,400,450,500,650,700,750,850,1027]; TIERS[4] = [10,20,40,60,80,100,120,140,160,180,200,220,240,260,280,300,320,340,360,380,400,420,440,460,480,500,520,747]; //headwear 2 TIERS[5] = [35,65,100,130,160,190,220,250,280,310,340,370,400,450,500,650,700,750,850,1027]; TIERS[6] = [35,65,100,130,160,190,220,250,280,310,340,370,400,450,500,650,700,750,850,1027]; //eyewear 3 TIERS[7] = [35,65,100,130,160,190,220,250,280,310,340,370,400,450,500,650,700,750,850,1027]; TIERS[8] = [25,40,80,110,140,170,200,230,260,290,320,350,380,410,440,470,500,530,570,610,650,1002]; //eyes 4 TIERS[9] = [35,65,100,130,160,190,220,250,280,310,340,370,400,450,500,650,700,750,850,1027]; TIERS[10] = [100,200,250,300,350,400,450,500,550,600,650,700,750,850,1000,1727]; //mouth 5 TIERS[11] = [35,65,100,130,160,190,220,250,280,310,340,370,400,450,500,650,700,750,850,1027]; TIERS[12] = [200,300,400,500,600,700,800,900,1000,1100,1200,1300,1477]; //ears 6 TIERS[13] = [35,65,100,130,160,190,220,250,280,310,340,370,400,450,500,650,700,750,850,1027]; TIERS[14] = [75,100,150,200,250,300,350,400,450,500,550,600,700,800,900,1452,0]; //body 7 } function _startTokenId() internal view virtual override returns (uint256) { return 0; } function rarityGen(uint256 _randinput, uint256 _rarityTier) internal view returns (uint256) { uint256 currentLowerBound = 0; for (uint256 i = 0; i < TIERS[_rarityTier].length; i++) { uint256 thisPercentage = TIERS[_rarityTier][i]; if ( _randinput >= currentLowerBound && _randinput < currentLowerBound + thisPercentage ) return i; currentLowerBound = currentLowerBound + thisPercentage; } return TIERS[_rarityTier].length - 1; } modifier whenMintActive() { require(isMintActive()); _; } function entropyForExtraData() internal view returns (uint24) { uint256 randomNumber = uint256( keccak256( abi.encodePacked( tx.gasprice, block.number, block.timestamp, block.difficulty, blockhash(block.number - 1), msg.sender ) ) ); return uint24(randomNumber); } function reRollDuplicate(uint256 tokenIdA, uint256 tokenIdB) public { require(msg.sender == reRollDuplicateRole); uint256 largerTokenId = tokenIdA > tokenIdB ? tokenIdA : tokenIdB; _initializeOwnershipAt(largerTokenId); if (_exists(largerTokenId + 1)) { _initializeOwnershipAt(largerTokenId + 1); } _setExtraDataAt(largerTokenId, entropyForExtraData()); } function _extraData( address from, address to, uint24 previousExtraData ) internal view virtual override returns (uint24) { return from == address(0) ? entropyForExtraData() : previousExtraData; } function tokenIdToHash(uint256 _tokenId) public view returns (string memory) { require(_exists(_tokenId)); // This will generate a NUM_LAYERS * 3 character string. bytes memory hashBytes = DynamicBuffer.allocate(NUM_LAYERS * 4); uint256[] memory hash = new uint256[](NUM_LAYERS); for (uint256 i = 0; i < NUM_LAYERS; i++) { uint256 traitIndex = hash[i]; if(i % 2 > 0 && _revealLayer[_tokenId][i] == false){ hash[i] = TIERS[i].length - 1; } else { uint256 tokenExtraData = uint24(_ownershipOf(_tokenId).extraData); uint256 _randinput = uint256( keccak256( abi.encodePacked( tokenExtraData, _tokenId, _tokenId + i ) ) ) % maxSupply; traitIndex = rarityGen(_randinput, i); hash[i] = traitIndex; uint blank = TIERS[i].length - 1; if (_hideLayer[_tokenId][i] == true){ if (i == 10 && hash[i] == 10){ //astonished -> blank hash[i] = blank; if(_hideLayer[_tokenId][2] == false){hash[2] = 15;} } else if (i == 14 && hash[i] == 0) { //ghost hash[i] = blank; if(_hideLayer[_tokenId][8] == false){hash[8] = 5;} } else if (i == 14 && hash[i] == 2) { //robot hash[i] = blank; if(_hideLayer[_tokenId][10] == false){hash[10] = 1;} if(_hideLayer[_tokenId][8] == false){hash[8] = 0;} if(_hideLayer[_tokenId][4] == false){hash[4] = 1;} } else if (i == 14 && hash[i] == 4) { //skull hash[i] = blank; if(_hideLayer[_tokenId][10] == false){hash[10] = 8;} if(_hideLayer[_tokenId][8] == false){hash[8] = 9;} } else if (i == 14 && hash[i] == 5) { //vampire hash[i] = blank; if(_hideLayer[_tokenId][10] == false){hash[10] = 6;} if(_hideLayer[_tokenId][8] == false){hash[8] = 7;} } else if (i == 14 && hash[i] == 6) { //monster hash[i] = blank; if(_hideLayer[_tokenId][10] == false){hash[10] = 7;} if(_hideLayer[_tokenId][8] == false){hash[8] = 8;} if (hash[6] == 8 && _hideLayer[_tokenId][6] == false) {hash[6] = 19;} } else if (i == 14 && hash[i] == 7) { //clown hash[i] = blank; if(_hideLayer[_tokenId][10] == false){hash[10] = 2;} if(_hideLayer[_tokenId][8] == false){hash[8] = 4;} } else if (i == 14 && hash[i] == 9) { //pepe hash[i] = blank; if(_hideLayer[_tokenId][10] == false){hash[10] = 5;} if(_hideLayer[_tokenId][8] == false){hash[8] = 1;} } else if (i == 14 && hash[i] == 10) { //doge hash[i] = blank; if(_hideLayer[_tokenId][10] == false){hash[10] = 4;} if(_hideLayer[_tokenId][8] == false){hash[8] = 2;} } else if (i == 14 && hash[i] == 11) { //cat hash[i] = blank; if(_hideLayer[_tokenId][10] == false){hash[10] = 3;} if(_hideLayer[_tokenId][8] == false){hash[8] = 3;} } else { hash[i] = blank; } } else { if (hash[10] == 10){ //astonished -> blank if(_hideLayer[_tokenId][2] == false){hash[2] = 15;} } if (hash[14] == 0) { //ghost if(_hideLayer[_tokenId][8] == false){hash[8] = 5;} } else if (hash[14] == 2) { //robot if(_hideLayer[_tokenId][10] == false){hash[10] = 1;} if(_hideLayer[_tokenId][8] == false){hash[8] = 0;} if(_hideLayer[_tokenId][4] == false){hash[4] = 1;} } else if (hash[14] == 4) { //skull if(_hideLayer[_tokenId][10] == false){hash[10] = 8;} if(_hideLayer[_tokenId][8] == false){hash[8] = 9;} } else if (hash[14] == 5) { //vampire if(_hideLayer[_tokenId][10] == false){hash[10] = 6;} if(_hideLayer[_tokenId][8] == false){hash[8] = 7;} } else if (hash[14] == 6) { //monster if(_hideLayer[_tokenId][10] == false){hash[10] = 7;} if(_hideLayer[_tokenId][8] == false){hash[8] = 8;} if (hash[6] == 8 && _hideLayer[_tokenId][6] == false) {hash[6] = 19;} } else if (hash[14] == 7) { //clown if(_hideLayer[_tokenId][10] == false){hash[10] = 2;} if(_hideLayer[_tokenId][8] == false){hash[8] = 4;} } else if (hash[14] == 9) { //pepe if(_hideLayer[_tokenId][10] == false){hash[10] = 5;} if(_hideLayer[_tokenId][8] == false){hash[8] = 1;} } else if (hash[14] == 10) { //doge if(_hideLayer[_tokenId][10] == false){hash[10] = 4;} if(_hideLayer[_tokenId][8] == false){hash[8] = 2;} } else if (hash[14] == 11) { //cat if(_hideLayer[_tokenId][10] == false){hash[10] = 3;} if(_hideLayer[_tokenId][8] == false){hash[8] = 3;} } } } } for (uint256 i = 0; i < hash.length; i++) { if (hash[i] < 10) { hashBytes.appendSafe("00"); } else if (hash[i] < 100) { hashBytes.appendSafe("0"); } if (hash[i] > 999) { hashBytes.appendSafe("999"); } else { hashBytes.appendSafe(bytes(_toString(hash[i]))); } } return string(hashBytes); } function publicMint(uint256 _count) external payable nonReentrant whenMintActive returns (uint256) { uint256 totalMinted = _totalMinted(); require(mints[msg.sender] + _count <= 100); require(_count <= MAX_BATCH_MINT && _count > 0); require(totalMinted + _count <= maxSupply); require(msg.sender == tx.origin); uint256 discount; uint256 numDisc = rebates[msg.sender]; if (numDisc > 0) { if (numDisc <= _count) { discount = rebateAmt * numDisc; require(msg.value >= (_count * mintPrice) - discount); rebates[msg.sender] = 0; } else { discount = rebateAmt * _count; require(msg.value >= (_count * mintPrice) - discount); rebates[msg.sender] -= _count; } } else { require(msg.value >= _count * mintPrice); } mints[msg.sender] += _count; _mint(msg.sender, _count); return totalMinted; } function ogMint(uint256 _ogTokenId) external nonReentrant whenMintActive returns (uint256) { uint256 totalMinted = _totalMinted(); require(_ogTokenId <= 1000); require(ogMints[_ogTokenId] == false); require(msg.sender == ERC721(faContract).ownerOf(_ogTokenId)); require(totalMinted + 1 <= maxSupply); ogMints[_ogTokenId] = true; _mint(msg.sender, 1); return totalMinted; } function ogClaimed(uint256 _ogTokenId) public view returns (bool){ return ogMints[_ogTokenId]; } function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) public override returns (bytes4) { require( msg.sender == faContract || ERC721(faContract).ownerOf( tokenId ) == from ); rebates[from]++; return this.onERC721Received.selector; } function getRebates(address _address) public view returns (uint256) { return rebates[_address]; } function hashToSVG(string memory _hash, uint256 _tokenId) public view returns (string memory) { uint256 thisTraitIndex; string memory _bgColor = "1C1531"; if (bytes(bgColor[_tokenId]).length > 0) { _bgColor = bgColor[_tokenId]; } bytes memory svgBytes = DynamicBuffer.allocate(1024 * 128); svgBytes.appendSafe( '<svg width="1600" height="1600" viewBox="0 0 1600 1600" version="1.2" xmlns="http://www.w3.org/2000/svg" style="background-color: #' ); svgBytes.appendSafe( abi.encodePacked(_bgColor, ";background-image:url(") ); for (uint256 i = 0; i < NUM_LAYERS - 1; i++) { if(!(i % 2 > 0 && _revealLayer[_tokenId][i] == false)){ // if(_traitDataPointers[i].length > 0){ thisTraitIndex = HelperLib.parseInt( HelperLib._substring(_hash, (i * 3), (i * 3) + 3) ); svgBytes.appendSafe( abi.encodePacked( "data:", _traitDetails[i][thisTraitIndex].mimetype, ";base64,", Base64.encode( SSTORE2.read(_traitDataPointers[i][thisTraitIndex]) ), "),url(" ) ); } } thisTraitIndex = HelperLib.parseInt( HelperLib._substring(_hash, (NUM_LAYERS * 3) - 3, NUM_LAYERS * 3) ); svgBytes.appendSafe( abi.encodePacked( "data:", _traitDetails[NUM_LAYERS - 1][thisTraitIndex].mimetype, ";base64,", Base64.encode( SSTORE2.read( _traitDataPointers[NUM_LAYERS - 1][thisTraitIndex] ) ), ');background-repeat:no-repeat;background-size:contain;background-position:center;image-rendering:-webkit-optimize-contrast;-ms-interpolation-mode:nearest-neighbor;image-rendering:-moz-crisp-edges;image-rendering:pixelated;"></svg>' ) ); return string( abi.encodePacked( "data:image/svg+xml;base64,", Base64.encode(svgBytes) ) ); } function hashToMetadata(string memory _hash, uint256 _tokenId) public view returns (string memory) { bytes memory metadataBytes = DynamicBuffer.allocate(1024 * 128); metadataBytes.appendSafe("["); for (uint256 i = 0; i < NUM_LAYERS; i++) { uint256 thisTraitIndex = HelperLib.parseInt( HelperLib._substring(_hash, (i * 3), (i * 3) + 3) ); if (bytes(_traitDetails[i][thisTraitIndex].name).length > 2 ) { metadataBytes.appendSafe( abi.encodePacked( '{"trait_type":"', LAYER_NAMES[i], '","value":"', _traitDetails[i][thisTraitIndex].name, '"}' ) ); if (i == 10 && ((_hideLayer[_tokenId][11] || _revealLayer[_tokenId][11] == false) && _hideLayer[_tokenId][12] && (_hideLayer[_tokenId][13] || _revealLayer[_tokenId][13] == false) && _hideLayer[_tokenId][14])){ metadataBytes.appendSafe("]"); } else if (i == 11 && (_hideLayer[_tokenId][12] && (_hideLayer[_tokenId][13] || _revealLayer[_tokenId][13] == false) && _hideLayer[_tokenId][14])){ metadataBytes.appendSafe("]"); } else if (i == 12 && ((_hideLayer[_tokenId][13] || _revealLayer[_tokenId][13] == false) && _hideLayer[_tokenId][14])){ metadataBytes.appendSafe("]"); } else if (i == 13 && _hideLayer[_tokenId][14]){ metadataBytes.appendSafe("]"); } else if (i == 14) { metadataBytes.appendSafe("]"); } else { metadataBytes.appendSafe(","); } } } return string(metadataBytes); } function tokenURI(uint256 _tokenId) public view override returns (string memory) { require(_exists(_tokenId)); require(_traitDataPointers[0].length > 0); string memory tokenHash = tokenIdToHash(_tokenId); bytes memory jsonBytes = DynamicBuffer.allocate(1024 * 128); if (bytes(idValues[_tokenId].AlphaProfile.userName).length > 0) { jsonBytes.appendSafe( abi.encodePacked( unicode'{"name":"', idValues[_tokenId].AlphaProfile.userName ) ); } else { jsonBytes.appendSafe(unicode'{"name":"OnChainAlpha'); } jsonBytes.appendSafe( abi.encodePacked( "#", _toString(_tokenId), '","description":"', contractData.description, '",' ) ); if (bytes(baseURI).length > 0 && _renderTokenOffChain[_tokenId]) { jsonBytes.appendSafe( abi.encodePacked('"image":"', baseURI, _toString(_tokenId)) ); } else { string memory svgCode = ""; if (_phlipImage[_tokenId]) { string memory svgString = hashToSVG(tokenHash, _tokenId); svgCode = string( abi.encodePacked( "data:image/svg+xml;base64,", Base64.encode( abi.encodePacked( '<svg width="100%" height="100%" viewBox="0 0 1200 1200" style="display: block; transform: scale(-1,1)" version="1.2" xmlns="http://www.w3.org/2000/svg"><image width="1200" height="1200" href="', svgString, '"></image></svg>' ) ) ) ); jsonBytes.appendSafe( abi.encodePacked('"svg_image_data":"', svgString, '",') ); } else { string memory svgString = hashToSVG(tokenHash, _tokenId); svgCode = string( abi.encodePacked( "data:image/svg+xml;base64,", Base64.encode( abi.encodePacked( '<svg width="100%" height="100%" viewBox="0 0 1200 1200" version="1.2" xmlns="http://www.w3.org/2000/svg"><image width="1200" height="1200" href="', svgString, '"></image></svg>' ) ) ) ); jsonBytes.appendSafe( abi.encodePacked('"svg_image_data":"', svgString, '",') ); } jsonBytes.appendSafe( abi.encodePacked('"image_data":"', svgCode, '",') ); } jsonBytes.appendSafe( abi.encodePacked('"attributes":', hashToMetadata(tokenHash, _tokenId), "}") ); return string( abi.encodePacked( "data:application/json;base64,", Base64.encode(jsonBytes) ) ); } function contractURI() public view returns (string memory) { return string( abi.encodePacked( "data:application/json;base64,", Base64.encode( abi.encodePacked( '{"name":"', contractData.name, '","description":"', contractData.description, '","image":"', contractData.image, '","banner":"', contractData.banner, '","external_link":"', contractData.website, '","seller_fee_basis_points":', _toString(contractData.royalties), ',"fee_recipient":"', contractData.royaltiesRecipient, '"}' ) ) ) ); } function addLayer(uint256 _layerIndex, TraitDTO[] memory traits) public onlyOwner { require(TIERS[_layerIndex].length == traits.length); address[] memory dataPointers = new address[](traits.length); for (uint256 i = 0; i < traits.length; i++) { dataPointers[i] = SSTORE2.write(traits[i].data); _traitDetails[_layerIndex][i] = Trait( traits[i].name, traits[i].mimetype ); } _traitDataPointers[_layerIndex] = dataPointers; return; } function setRenderOfTokenId(uint256 _tokenId, bool _renderOffChain) external { require(msg.sender == ownerOf(_tokenId)); _renderTokenOffChain[_tokenId] = _renderOffChain; } function isMintActive() public view returns (bool) { return _totalMinted() < maxSupply && isPublicMintActive; } function togglePublicMint() external onlyOwner { isPublicMintActive = !isPublicMintActive; } //metadata URI function setBaseURI(string memory _baseURI) external onlyOwner { baseURI = _baseURI; } function setContractData(ContractData memory _contractData) external onlyOwner { contractData = _contractData; } //address info address private helper = 0x95c0a28443F4897Bf718243A539fd018B6C16F63; //withdraw to helper address function withdraw() external { uint256 balance = address(this).balance; require(balance > 0); Address.sendValue(payable(helper), balance); } function setBgColor(uint256 _tokenId, string memory _bgColor) public { require(ownerOf(_tokenId) == msg.sender); bgColor[_tokenId] = _bgColor; emit bgChanged(_tokenId, _bgColor); } function setProfile( uint256 _tokenId, string memory _username, string memory _social, string memory _website ) public { require(ownerOf(_tokenId) == msg.sender); idValues[_tokenId].AlphaProfile.userName = _username; idValues[_tokenId].AlphaProfile.social = _social; idValues[_tokenId].AlphaProfile.website = _website; string memory str = string(abi.encodePacked(_username,"#",_toString(_tokenId))); idValues[_tokenId].AlphaProfile.profileName = str; emit AttributesUpdated( _tokenId, _username, _social, _website, str ); } function setLabelsValues(uint256 _tokenId, uint _labelNum, string memory _label, string memory _value) external { require(msg.sender == ownerOf(_tokenId)); uint count = idValues[_tokenId].labelcount; if(_labelNum >= count){ _labelNum = count; idValues[_tokenId].labelcount++; } idValues[_tokenId].labels[_labelNum] = _label; idValues[_tokenId].values[_labelNum] = _value; emit LabelsValuesUpdated(_tokenId, _labelNum, _label, _value); } function toggleLayers(uint256 _tokenId, bool[] memory states) public { require(msg.sender == ownerOf(_tokenId)); for (uint256 i = 0; i < NUM_LAYERS; i++) { _hideLayer[_tokenId][i] = states[i]; } emit LayersUpdated(_tokenId, states); } function revealLayers(uint256 _tokenId, uint _layer) public { require(_layer < 15); require(msg.sender == ownerOf(_tokenId)); _revealLayer[_tokenId][_layer] = true; emit LayersRevealed(_tokenId, _layer); } function togglePhlipPFP(uint256 _tokenId, bool _flipped) public { require(msg.sender == ownerOf(_tokenId)); _phlipImage[_tokenId] = _flipped; emit ImagePhlipped(_tokenId, _flipped); } }
{ "optimizer": { "enabled": true, "runs": 1 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[{"internalType":"uint256","name":"_size","type":"uint256"},{"internalType":"uint256","name":"_start","type":"uint256"},{"internalType":"uint256","name":"_end","type":"uint256"}],"name":"InvalidCodeAtRange","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"WriteError","type":"error"},{"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":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"string","name":"userName","type":"string"},{"indexed":false,"internalType":"string","name":"social","type":"string"},{"indexed":false,"internalType":"string","name":"website","type":"string"},{"indexed":false,"internalType":"string","name":"profileName","type":"string"}],"name":"AttributesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isPhlipped","type":"bool"}],"name":"ImagePhlipped","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"labelId","type":"uint256"},{"indexed":false,"internalType":"string","name":"customLabels","type":"string"},{"indexed":false,"internalType":"string","name":"customValues","type":"string"}],"name":"LabelsValuesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"layerRevealed","type":"uint256"}],"name":"LayersRevealed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"bool[]","name":"layerIsHidden","type":"bool[]"}],"name":"LayersUpdated","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"string","name":"color","type":"string"}],"name":"bgChanged","type":"event"},{"inputs":[{"internalType":"uint256","name":"_layerIndex","type":"uint256"},{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"mimetype","type":"string"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct OnChainAlphaV2.TraitDTO[]","name":"traits","type":"tuple[]"}],"name":"addLayer","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":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractData","outputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"description","type":"string"},{"internalType":"string","name":"image","type":"string"},{"internalType":"string","name":"banner","type":"string"},{"internalType":"string","name":"website","type":"string"},{"internalType":"uint256","name":"royalties","type":"uint256"},{"internalType":"string","name":"royaltiesRecipient","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"faContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bool","name":"_isOcaClaim","type":"bool"}],"name":"freeClaim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"_tokenId","type":"uint256"},{"internalType":"bool","name":"_isOcaClaim","type":"bool"}],"name":"getClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"getRebates","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_hash","type":"string"}],"name":"hashToMetadata","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_hash","type":"string"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"hashToSVG","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":[],"name":"isMintActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPublicMintActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ocaContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","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":"_count","type":"uint256"}],"name":"publicMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenIdA","type":"uint256"},{"internalType":"uint256","name":"tokenIdB","type":"uint256"}],"name":"reRollDuplicate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rebateAmt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_layer","type":"uint256"}],"name":"revealLayers","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":"string","name":"_baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"string","name":"_bgColor","type":"string"}],"name":"setBgColor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"description","type":"string"},{"internalType":"string","name":"image","type":"string"},{"internalType":"string","name":"banner","type":"string"},{"internalType":"string","name":"website","type":"string"},{"internalType":"uint256","name":"royalties","type":"uint256"},{"internalType":"string","name":"royaltiesRecipient","type":"string"}],"internalType":"struct OnChainAlphaV2.ContractData","name":"_contractData","type":"tuple"}],"name":"setContractData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_labelNum","type":"uint256"},{"internalType":"string","name":"_label","type":"string"},{"internalType":"string","name":"_value","type":"string"}],"name":"setLabelsValues","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_layerNum","type":"uint256"},{"internalType":"string","name":"_value","type":"string"}],"name":"setLayerNames","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"string","name":"_username","type":"string"},{"internalType":"string","name":"_social","type":"string"},{"internalType":"string","name":"_website","type":"string"}],"name":"setProfile","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bool","name":"_renderOffChain","type":"bool"}],"name":"setRenderOfTokenId","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":"_tokenId","type":"uint256"},{"internalType":"bool[]","name":"states","type":"bool[]"}],"name":"toggleLayers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bool","name":"_flipped","type":"bool"}],"name":"togglePhlipPFP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"togglePublicMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenIdToHash","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","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":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60076102608181526614dc1958da585b60ca1b61028052608090815260016102a0818152603160f81b6102c05260a052600d6102e09081526c135bdd5d1a0814dc1958da585b609a1b6103005260c052610320818152603360f81b6103405260e0526008610360908152672432b0b23bb2b0b960c11b61038052610100526103a0818152603560f81b6103c052610120526103e09283526622bcb2bbb2b0b960c91b6104005261014092909252610420828152603760f81b61044052610160526004610460818152634579657360e01b61048052610180526104a0928352603960f81b6104c0526101a09290925260056104e09081526409adeeae8d60db1b610500526101c052600261052081815261313160f01b610540526101e052610560838152634561727360e01b61058052610200526105a090815261313360f01b6105c052610220526106206040526105e091825263426f647960e01b61060052610240919091526200017590602590600f62000f15565b50602680546001600160a01b03199081167389d92a754fd1a672c21b5fc2a347198d1a9456b31790915560278054909116736a04d2443be907dd7e83236398c985688acb796e17905566b1a2bc2ec5000060285566470de4df82000060295560408051606081019091526021808252620072926020830139602a90620001fc9082620010e3565b50602b805460ff191690556040805161012081018252601160e082019081527027b716a1b430b4b71020b6383430902b1960791b6101008301528152815161018081019092526101478083529091602080840192906200714b9083013981526020016040518060800160405280605281526020016200732b6052913981526020016040518060800160405280604e8152602001620072b3604e913981526020016040518060400160405280600e81526020016d68747470733a2f2f6f63612e676760901b81525081526020016101f481526020016040518060600160405280602a815260200162007301602a913990528051602c908190620002ff9082620010e3565b5060208201516001820190620003169082620010e3565b50604082015160028201906200032d9082620010e3565b5060608201516003820190620003449082620010e3565b50608082015160048201906200035b9082620010e3565b5060a0820151600582015560c082015160068201906200037c9082620010e3565b5050603380546001600160a01b0319167395c0a28443f4897bf718243a539fd018b6c16f6317905550348015620003b257600080fd5b506040518060400160405280601181526020017027b716a1b430b4b71020b6383430902b1960791b8152506040518060400160405280600581526020016427a1a0bb1960d91b81525081600290816200040c9190620010e3565b5060036200041b8282620010e3565b5061010660005550506001600855620004343362000ec3565b6040805160e081018252600a8152600f602082015260199181019190915260326060820152604b6080820152606460a0820152611c3960c08201526200047f90601690600762000f72565b50604080516102808101825260238152604160208201526064918101919091526082606082015260a06080820181905260be9082015260dc60c082015260fa60e08201526101186101008201526101366101208201526101546101408201526101726101608201526101906101808201526101ae6101a08201526101cc6101c08201526101ea6101e08201526102086102008201526102266102208201526102586102408201526106406102608201526200053f90601790601462000f72565b506040805161020081018252603281526064602082015260969181019190915260c8606082015260fa608082015261012c60a082015261015e60c082015261019060e08201526101c26101008201526101f461012082015261022661014082015261025861016082015261028a6101808201526102bc6101a08201526102ee6101c08201526105dc6101e0820152620005dd90601890601062000f72565b50604080516102808101825260238152604160208201526064918101919091526082606082015260a06080820181905260be9082015260dc60c082015260fa60e08201526101186101008201526101366101208201526101546101408201526101726101608201526101906101808201526101ae6101a08201526101cc6101c08201526101ea6101e08201526102086102008201526102266102208201526102586102408201526106406102608201526200069d90601990601462000f72565b506040805161038081018252600a815260146020820152601e918101919091526028606082015260326080820152604660a080830191909152606460c0830152607860e0830152608c61010083015261012082015260b46101408083019190915260c861016083015260dc61018083015260f06101a08301526101046101c08301526101186101e08084019190915261012c61020084015261022083019190915261015461024083015261016861026083015261017c6102808301526101906102a08301526101a46102c08301526101b86102e08301526101cc6103008301526103208201526101f46103408201526103d4610360820152620007a590601a90601c62000f72565b50604080516102808101825260238152604160208201526064918101919091526082606082015260a06080820181905260be9082015260dc60c082015260fa60e08201526101186101008201526101366101208201526101546101408201526101726101608201526101906101808201526101ae6101a08201526101cc6101c08201526101ea6101e08201526102086102008201526102266102208201526102586102408201526106406102608201526200086590601b90601462000f72565b50604080516102808101825260238152604160208201526064918101919091526082606082015260a06080820181905260be9082015260dc60c082015260fa60e08201526101186101008201526101366101208201526101546101408201526101726101608201526101906101808201526101ae6101a08201526101cc6101c08201526101ea6101e08201526102086102008201526102266102208201526102586102408201526106406102608201526200092590601c90601462000f72565b50604080516102808101825260238152604160208201526064918101919091526082606082015260a06080820181905260be9082015260dc60c082015260fa60e08201526101186101008201526101366101208201526101546101408201526101726101608201526101906101808201526101ae6101a08201526101cc6101c08201526101ea6101e0820152610208610200820152610226610220820152610258610240820152610640610260820152620009e590601d90601462000f72565b50604080516102c0810182526014815260286020820152603c918101919091526050606082015260646080820152607860a080830191909152608c60c083015260e082015260b461010082015260c861012082015260f0610140808301919091526101186101608301526101808201526101686101a08201526101906101c08201526101b86101e080830191909152610200820152610208610220820152610230610240820152610258610260820152610280808201526106186102a082015262000ab590601e90601662000f72565b50604080516102808101825260238152604160208201526064918101919091526082606082015260a06080820181905260be9082015260dc60c082015260fa60e08201526101186101008201526101366101208201526101546101408201526101726101608201526101906101808201526101ae6101a08201526101cc6101c08201526101ea6101e082015261020861020082015261022661022082015261025861024082015261064061026082015262000b7590601f90601462000f72565b5060408051610200810182526019815260326020820152604b9181019190915260646060820152607d6080820152609660a082015260af60c082015260c860e082015260e161010082015261012c6101208201526101c26101408201526102586101608201526102ee6101808201526103846101a082015261041a6101c0820152610b226101e08201526016600a62000c1392910190601062000f72565b50604080516102808101825260238152604160208201526064918101919091526082606082015260a06080820181905260be9082015260dc60c082015260fa60e08201526101186101008201526101366101208201526101546101408201526101726101608201526101906101808201526101ae6101a08201526101cc6101c08201526101ea6101e082015261020861020082015261022661022082015261025861024082015261064061026082015262000cd390602190601462000f72565b50604080516101a081018252603281526064602082015260969181019190915260c8606082015261012c608082015261019060a08201526101f460c082015261025860e08201526102bc6101008201526103846101208201526103e86101408201526104b0610160820152610a2861018082015262000d5790602290600d62000f72565b5060408051610280810182526023808252604160208301526064928201929092526082606082015260a06080820181905260be9082015260dc60c082015260fa60e08201526101186101008201526101366101208201526101546101408201526101726101608201526101906101808201526101ae6101a08201526101cc6101c08201526101ea6101e082015261020861020082015261022661022082015261025861024082015261064061026082015262000e169190601462000f72565b506040805161022081018252604b81526064602082015260969181019190915260c8606082015260fa608082015261012c60a082015261015e60c082015261019060e08201526101c26101008201526101f46101208201526102266101408201526102586101608201526102bc6101808201526103206101a08201526103846101c08201526104976101e0820152600061020082015262000ebc90602490601162000f72565b50620011af565b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b82805482825590600052602060002090810192821562000f60579160200282015b8281111562000f60578251829062000f4f9082620010e3565b509160200191906001019062000f36565b5062000f6e92915062000fc4565b5090565b82805482825590600052602060002090810192821562000fb6579160200282015b8281111562000fb6578251829061ffff1690559160200191906001019062000f93565b5062000f6e92915062000fe5565b8082111562000f6e57600062000fdb828262000ffc565b5060010162000fc4565b5b8082111562000f6e576000815560010162000fe6565b5080546200100a9062001054565b6000825580601f106200101b575050565b601f0160209004906000526020600020908101906200103b919062000fe5565b50565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200106957607f821691505b6020821081036200108a57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620010de57600081815260208120601f850160051c81016020861015620010b95750805b601f850160051c820191505b81811015620010da57828155600101620010c5565b5050505b505050565b81516001600160401b03811115620010ff57620010ff6200103e565b620011178162001110845462001054565b8462001090565b602080601f8311600181146200114f5760008415620011365750858301515b600019600386901b1c1916600185901b178555620010da565b600085815260208120601f198616915b8281101562001180578886015182559484019460019091019084016200115f565b50858210156200119f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b615f8c80620011bf6000396000f3fe6080604052600436106102395760003560e01c806301ffc9a71461023e57806306fdde0314610273578063081812fc14610295578063095ea7b3146102cd5780630ea71cfc146102ef5780630f3debbe1461030f578063150b7a021461032f57806318160ddd1461036857806319c841fd1461039057806323b872dd146103b05780632437013d146103d05780632d6b6224146103f05780632db115441461040a5780633cca24201461041d5780633ccfd60b146104455780634047638d1461045a57806342842e0e1461046f57806355f804b31461048f57806357380daa146104af5780635b92ac0d146104cf578063621a1f74146104e45780636352211e1461050457806366e33870146105245780636817c76c146105445780636c0360eb1461055a57806370a082311461056f578063715018a61461058f578063716e43d7146105a45780637a75353a146105c45780638a8c0e0c146105e45780638da5cb5b1461060457806395d89b411461061957806397e2155d1461062e578063a22cb4651461064e578063a78c8a7a1461066e578063ac9650d814610684578063ad9adfe3146106b1578063b88d4fde146106d1578063c406ec72146106f1578063c87b56dd14610711578063d5abeb0114610731578063dbe9875f14610747578063e488627314610767578063e8a3d48514610787578063e985e9c51461079c578063ed39d98d146107e5578063f2f0dc0514610805578063f2fde38b1461083b578063fb38d2111461085b578063fd6b3cf51461087b575b600080fd5b34801561024a57600080fd5b5061025e610259366004614756565b61089b565b60405190151581526020015b60405180910390f35b34801561027f57600080fd5b506102886108ed565b60405161026a91906147c3565b3480156102a157600080fd5b506102b56102b03660046147d6565b61097f565b6040516001600160a01b03909116815260200161026a565b3480156102d957600080fd5b506102ed6102e8366004614804565b6109c3565b005b3480156102fb57600080fd5b506102ed61030a36600461492f565b610a63565b34801561031b57600080fd5b506102ed61032a3660046149c0565b610b60565b34801561033b57600080fd5b5061034f61034a366004614aea565b610bf4565b6040516001600160e01b0319909116815260200161026a565b34801561037457600080fd5b506001546000540361010519015b60405190815260200161026a565b34801561039c57600080fd5b506102ed6103ab366004614b98565b610cc9565b3480156103bc57600080fd5b506102ed6103cb366004614bc4565b610d49565b3480156103dc57600080fd5b506102ed6103eb366004614c28565b610edc565b3480156103fc57600080fd5b50602b5461025e9060ff1681565b6103826104183660046147d6565b610f97565b34801561042957600080fd5b50610432611146565b60405161026a9796959493929190614cd0565b34801561045157600080fd5b506102ed6114a4565b34801561046657600080fd5b506102ed6114c8565b34801561047b57600080fd5b506102ed61048a366004614bc4565b6114e4565b34801561049b57600080fd5b506102ed6104aa366004614d59565b611504565b3480156104bb57600080fd5b5061025e6104ca366004614b98565b61151c565b3480156104db57600080fd5b5061025e611553565b3480156104f057600080fd5b506102886104ff3660046147d6565b611574565b34801561051057600080fd5b506102b561051f3660046147d6565b6124b5565b34801561053057600080fd5b5061028861053f366004614d59565b6124c0565b34801561055057600080fd5b5061038260285481565b34801561056657600080fd5b506102886128e2565b34801561057b57600080fd5b5061038261058a366004614d8d565b612970565b34801561059b57600080fd5b506102ed6129be565b3480156105b057600080fd5b506102ed6105bf366004614daa565b6129d2565b3480156105d057600080fd5b506102ed6105df366004614ee8565b612b67565b3480156105f057600080fd5b506103826105ff366004614b98565b612bce565b34801561061057600080fd5b506102b5612de7565b34801561062557600080fd5b50610288612df6565b34801561063a57600080fd5b506102ed610649366004614f2e565b612e05565b34801561065a57600080fd5b506102ed610669366004614f50565b612e90565b34801561067a57600080fd5b5061038260295481565b34801561069057600080fd5b506106a461069f366004614f7c565b612f25565b60405161026a9190614ff0565b3480156106bd57600080fd5b506102886106cc366004615052565b613019565b3480156106dd57600080fd5b506102ed6106ec366004615096565b61335c565b3480156106fd57600080fd5b506026546102b5906001600160a01b031681565b34801561071d57600080fd5b5061028861072c3660046147d6565b6133a0565b34801561073d57600080fd5b50610382611c5e81565b34801561075357600080fd5b506102ed610762366004614b98565b613666565b34801561077357600080fd5b506102ed6107823660046150f5565b6136ac565b34801561079357600080fd5b50610288613796565b3480156107a857600080fd5b5061025e6107b7366004615130565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b3480156107f157600080fd5b506027546102b5906001600160a01b031681565b34801561081157600080fd5b50610382610820366004614d8d565b6001600160a01b031660009081526012602052604090205490565b34801561084757600080fd5b506102ed610856366004614d8d565b6137f4565b34801561086757600080fd5b506102ed610876366004614ee8565b61386f565b34801561088757600080fd5b506102ed610896366004614f2e565b6138a1565b60006301ffc9a760e01b6001600160e01b0319831614806108cc57506380ac58cd60e01b6001600160e01b03198316145b806108e75750635b5e139f60e01b6001600160e01b03198316145b92915050565b6060600280546108fc90615169565b80601f016020809104026020016040519081016040528092919081815260200182805461092890615169565b80156109755780601f1061094a57610100808354040283529160200191610975565b820191906000526020600020905b81548152906001019060200180831161095857829003601f168201915b5050505050905090565b600061098a82613901565b6109a7576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b60006109ce826124b5565b9050336001600160a01b03821614610a07576109ea81336107b7565b610a07576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b33610a6d856124b5565b6001600160a01b031614610a8057600080fd5b6000848152601060205260409020610a9884826151e3565b506000848152601060205260409020600101610ab483826151e3565b506000848152601060205260409020600201610ad082826151e3565b50600083610add86613937565b604051602001610aee9291906152a2565b60408051601f198184030181529181526000878152601060205220909150600301610b1982826151e3565b507fb8981c9fcfec39b56f5caf88846acca9b61e75401e68da165ef541e81991d8b68585858585604051610b519594939291906152de565b60405180910390a15050505050565b610b68613986565b80518190602c908190610b7b90826151e3565b5060208201516001820190610b9090826151e3565b5060408201516002820190610ba590826151e3565b5060608201516003820190610bba90826151e3565b5060808201516004820190610bcf90826151e3565b5060a0820151600582015560c08201516006820190610bee90826151e3565b50505050565b6026546000906001600160a01b0316331480610c8557506026546040516331a9108f60e11b8152600481018690526001600160a01b03878116921690636352211e90602401602060405180830381865afa158015610c56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c7a919061533d565b6001600160a01b0316145b610c8e57600080fd5b6001600160a01b0385166000908152601260205260408120805491610cb283615370565b90915550630a85bd0160e11b979650505050505050565b610cd2826124b5565b6001600160a01b0316336001600160a01b031614610cef57600080fd5b6000828152600f6020908152604091829020805460ff19168415159081179091558251858152918201527fafec4b400a28d8bdfacc6b65e3c25cc07399c2c20eeb817256f6413c7e84687c91015b60405180910390a15050565b6000610d54826139e5565b9050836001600160a01b0316816001600160a01b031614610d875760405162a1148160e81b815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b03881690911417610dd457610db786336107b7565b610dd457604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b038516610dfb57604051633a954ecd60e21b815260040160405180910390fd5b8015610e0657600082555b6001600160a01b03808716600090815260056020526040808220805460001901905591871681522080546001019055610e4f85610e44888287613a5c565b600160e11b17613a7f565b600085815260046020526040812091909155600160e11b84169003610ea457600184016000818152600460205260408120549003610ea2576000548114610ea25760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b0316600080516020615f1783398151915260405160405180910390a45b505050505050565b610ee5826124b5565b6001600160a01b0316336001600160a01b031614610f0257600080fd5b60005b600f811015610f6557818181518110610f2057610f20615389565b6020908102919091018101516000858152600d8352604080822085835290935291909120805460ff191691151591909117905580610f5d81615370565b915050610f05565b507f6feffc52172e0d2f7273caf08349169b161ca5e8e463fa548b2dc2258c54cce38282604051610d3d92919061539f565b6000610fa1613a94565b610fa9611553565b610fb257600080fd5b6000610fbc613aed565b33600090815260156020526040902054909150606490610fdd9085906153ef565b1115610fe857600080fd5b60148311158015610ff95750600083115b61100257600080fd5b611c5e61100f84836153ef565b111561101a57600080fd5b33321461102657600080fd5b3360009081526012602052604081205480156110ec5784811161108d57806029546110519190615402565b915081602854866110629190615402565b61106c9190615419565b34101561107857600080fd5b33600090815260126020526040812055611105565b8460295461109b9190615402565b915081602854866110ac9190615402565b6110b69190615419565b3410156110c257600080fd5b33600090815260126020526040812080548792906110e1908490615419565b909155506111059050565b6028546110f99086615402565b34101561110557600080fd5b33600090815260156020526040812080548792906111249084906153ef565b9091555061113490503386613af8565b5050600160085592915050565b919050565b602c8054819061115590615169565b80601f016020809104026020016040519081016040528092919081815260200182805461118190615169565b80156111ce5780601f106111a3576101008083540402835291602001916111ce565b820191906000526020600020905b8154815290600101906020018083116111b157829003601f168201915b5050505050908060010180546111e390615169565b80601f016020809104026020016040519081016040528092919081815260200182805461120f90615169565b801561125c5780601f106112315761010080835404028352916020019161125c565b820191906000526020600020905b81548152906001019060200180831161123f57829003601f168201915b50505050509080600201805461127190615169565b80601f016020809104026020016040519081016040528092919081815260200182805461129d90615169565b80156112ea5780601f106112bf576101008083540402835291602001916112ea565b820191906000526020600020905b8154815290600101906020018083116112cd57829003601f168201915b5050505050908060030180546112ff90615169565b80601f016020809104026020016040519081016040528092919081815260200182805461132b90615169565b80156113785780601f1061134d57610100808354040283529160200191611378565b820191906000526020600020905b81548152906001019060200180831161135b57829003601f168201915b50505050509080600401805461138d90615169565b80601f01602080910402602001604051908101604052809291908181526020018280546113b990615169565b80156114065780601f106113db57610100808354040283529160200191611406565b820191906000526020600020905b8154815290600101906020018083116113e957829003601f168201915b50505050509080600501549080600601805461142190615169565b80601f016020809104026020016040519081016040528092919081815260200182805461144d90615169565b801561149a5780601f1061146f5761010080835404028352916020019161149a565b820191906000526020600020905b81548152906001019060200180831161147d57829003601f168201915b5050505050905087565b47806114af57600080fd5b6033546114c5906001600160a01b031682613bd5565b50565b6114d0613986565b602b805460ff19811660ff90911615179055565b6114ff8383836040518060200160405280600081525061335c565b505050565b61150c613986565b602a61151882826151e3565b5050565b6000811561153c575060008281526014602052604090205460ff166108e7565b505060009081526013602052604090205460ff1690565b6000611c5e611560613aed565b10801561156f5750602b5460ff165b905090565b606061157f82613901565b61158857600080fd5b600061159e611599600f6004615402565b613ceb565b60408051600f808252610200820190925291925060009190602082016101e08036833701905050905060005b600f8110156123845760008282815181106115e7576115e7615389565b6020026020010151905060006002836116009190615442565b11801561162757506000868152600e6020908152604080832085845290915290205460ff16155b15611670576001601683600f811061164157611641615389565b015461164d9190615419565b83838151811061165f5761165f615389565b602002602001018181525050612371565b600061167b87613d08565b6060015162ffffff1690506000611c5e828961169787826153ef565b60408051602081019490945283019190915260608201526080016040516020818303038152906040528051906020012060001c6116d49190615442565b90506116e08185613d21565b9250828585815181106116f5576116f5615389565b60200260200101818152505060006001601686600f811061171857611718615389565b01546117249190615419565b60008a8152600d6020908152604080832089845290915290205490915060ff161515600103611f545784600a148015611776575085858151811061176a5761176a615389565b6020026020010151600a145b156117e8578086868151811061178e5761178e615389565b60209081029190910181019190915260008a8152600d82526040808220600283529092529081205460ff16151590036117e357600f866002815181106117d6576117d6615389565b6020026020010181815250505b61236d565b84600e148015611811575085858151811061180557611805615389565b60200260200101516000145b15611871578086868151811061182957611829615389565b60209081029190910181019190915260008a8152600d82526040808220600883529092529081205460ff16151590036117e3576005866008815181106117d6576117d6615389565b84600e14801561189a575085858151811061188e5761188e615389565b60200260200101516002145b1561198a57808686815181106118b2576118b2615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff161515900361190757600186600a815181106118fa576118fa615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff161515900361194f5760008660088151811061194257611942615389565b6020026020010181815250505b6000898152600d602090815260408083206004845290915281205460ff16151590036117e3576001866004815181106117d6576117d6615389565b84600e1480156119b357508585815181106119a7576119a7615389565b60200260200101516004145b15611a5b57808686815181106119cb576119cb615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff1615159003611a2057600886600a81518110611a1357611a13615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff16151590036117e3576009866008815181106117d6576117d6615389565b84600e148015611a845750858581518110611a7857611a78615389565b60200260200101516005145b15611b2c5780868681518110611a9c57611a9c615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff1615159003611af157600686600a81518110611ae457611ae4615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff16151590036117e3576007866008815181106117d6576117d6615389565b84600e148015611b555750858581518110611b4957611b49615389565b60200260200101516006145b15611bfd5780868681518110611b6d57611b6d615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff1615159003611bc257600786600a81518110611bb557611bb5615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff16151590036117e3576008866008815181106117d6576117d6615389565b84600e148015611c265750858581518110611c1a57611c1a615389565b60200260200101516007145b15611cce5780868681518110611c3e57611c3e615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff1615159003611c9357600286600a81518110611c8657611c86615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff16151590036117e3576004866008815181106117d6576117d6615389565b84600e148015611cf75750858581518110611ceb57611ceb615389565b60200260200101516009145b15611d9f5780868681518110611d0f57611d0f615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff1615159003611d6457600586600a81518110611d5757611d57615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff16151590036117e3576001866008815181106117d6576117d6615389565b84600e148015611dc85750858581518110611dbc57611dbc615389565b6020026020010151600a145b15611e705780868681518110611de057611de0615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff1615159003611e3557600486600a81518110611e2857611e28615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff16151590036117e3576002866008815181106117d6576117d6615389565b84600e148015611e995750858581518110611e8d57611e8d615389565b6020026020010151600b145b15611f415780868681518110611eb157611eb1615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff1615159003611f0657600386600a81518110611ef957611ef9615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff16151590036117e3576003866008815181106117d6576117d6615389565b808686815181106117d6576117d6615389565b84600a148015611f7e575085600a81518110611f7257611f72615389565b6020026020010151600a145b15611fcb576000898152600d602090815260408083206002845290915281205460ff1615159003611fcb57600f86600281518110611fbe57611fbe615389565b6020026020010181815250505b84600e0361236d5785600e81518110611fe657611fe6615389565b6020026020010151600003612030576000898152600d602090815260408083206008845290915281205460ff16151590036117e3576005866008815181106117d6576117d6615389565b85600e8151811061204357612043615389565b602002602001015160020361208d576000898152600d60209081526040808320600a845290915281205460ff161515900361190757600186600a815181106118fa576118fa615389565b85600e815181106120a0576120a0615389565b60200260200101516004036120ea576000898152600d60209081526040808320600a845290915281205460ff1615159003611a2057600886600a81518110611a1357611a13615389565b85600e815181106120fd576120fd615389565b6020026020010151600503612147576000898152600d60209081526040808320600a845290915281205460ff1615159003611af157600686600a81518110611ae457611ae4615389565b85600e8151811061215a5761215a615389565b60200260200101516006036121a4576000898152600d60209081526040808320600a845290915281205460ff1615159003611bc257600786600a81518110611bb557611bb5615389565b85600e815181106121b7576121b7615389565b6020026020010151600703612201576000898152600d60209081526040808320600a845290915281205460ff1615159003611c9357600286600a81518110611c8657611c86615389565b85600e8151811061221457612214615389565b602002602001015160090361225e576000898152600d60209081526040808320600a845290915281205460ff1615159003611d6457600586600a81518110611d5757611d57615389565b85600e8151811061227157612271615389565b6020026020010151600a036122bb576000898152600d60209081526040808320600a845290915281205460ff1615159003611e3557600486600a81518110611e2857611e28615389565b85600e815181106122ce576122ce615389565b6020026020010151600b0361236d576000898152600d60209081526040808320600a845290915281205460ff161515900361232557600386600a8151811061231857612318615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff161515900361236d5760038660088151811061236057612360615389565b6020026020010181815250505b5050505b508061237c81615370565b9150506115ca565b5060005b81518110156124ac57600a8282815181106123a5576123a5615389565b602002602001015110156123dc57604080518082019091526002815261030360f41b60208201526123d7908490613de7565b612421565b60648282815181106123f0576123f0615389565b60200260200101511015612421576040805180820190915260018152600360fc1b6020820152612421908490613de7565b6103e782828151811061243657612436615389565b6020026020010151111561246e5760408051808201909152600381526239393960e81b6020820152612469908490613de7565b61249a565b61249a61249383838151811061248657612486615389565b6020026020010151613937565b8490613de7565b806124a481615370565b915050612388565b50909392505050565b60006108e7826139e5565b606060006124d062020000613ceb565b90506124fe604051806040016040528060018152602001605b60f81b81525082613de790919063ffffffff16565b600b600081815260209190915260037fe8056e2ed8943b7f61a5f0dc88c79a5a6cec2bb36a7bd11ce130f2961c6320b98261254461253f8860216024613e6c565b613f38565b60ff168152602001908152602001600020600001805461256390615169565b600c6000908152600b60205292119250600390507f765e72d9703c9804ad76c7d0af52f5313041ea56bb31a328e17fea205151b5ea826125a961253f8960246027613e6c565b60ff16815260200190815260200160002060000180546125c890615169565b600d6000908152600b60205292119250600390507f0a2216aa9bbf8764f3bfb9fafcef7f625aba82383c1a9d14d721124ff30595818261260e61253f8a6027602a613e6c565b60ff168152602001908152602001600020600001805461262d90615169565b600e6000908152600b60205292119250600390507f7ae97ffc8b2fe6ed730ad82f8c44cc0285c7a97ac189e2d88c56200fe9a501ab8261267361253f8b602a602d613e6c565b60ff168152602001908152602001600020600001805461269290615169565b905010905060005b600f8110156128d65760006126d261253f8a6126b7856003615402565b6126c2866003615402565b6126cd9060036153ef565b613e6c565b6000838152600b6020908152604080832060ff94909416808452939091529020805491925060029161270390615169565b905011156128c3576127696025838154811061272157612721615389565b60009182526020808320868452600b82526040808520878652835293849020935161275294939091019291016154c9565b60408051601f198184030181529190528890613de7565b81600a148015612790575085801561277e5750845b80156127875750835b80156127905750825b156127bd576040805180820190915260018152605d60f81b60208201526127b8908890613de7565b6128c3565b81600b1480156127db57508480156127d25750835b80156127db5750825b15612803576040805180820190915260018152605d60f81b60208201526127b8908890613de7565b81600c14801561281857508380156128185750825b15612840576040805180820190915260018152605d60f81b60208201526127b8908890613de7565b81600d14801561284d5750825b15612875576040805180820190915260018152605d60f81b60208201526127b8908890613de7565b81600e036128a0576040805180820190915260018152605d60f81b60208201526127b8908890613de7565b6040805180820190915260018152600b60fa1b60208201526128c3908890613de7565b50806128ce81615370565b91505061269a565b50939695505050505050565b602a80546128ef90615169565b80601f016020809104026020016040519081016040528092919081815260200182805461291b90615169565b80156129685780601f1061293d57610100808354040283529160200191612968565b820191906000526020600020905b81548152906001019060200180831161294b57829003601f168201915b505050505081565b60006001600160a01b038216612999576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b6129c6613986565b6129d06000613ff6565b565b6129da613986565b8051601683600f81106129ef576129ef615389565b0154146129fb57600080fd5b600081516001600160401b03811115612a1657612a16614830565b604051908082528060200260200182016040528015612a3f578160200160208202803683370190505b50905060005b8251811015612b4757612a74838281518110612a6357612a63615389565b602002602001015160400151614048565b828281518110612a8657612a86615389565b60200260200101906001600160a01b031690816001600160a01b0316815250506040518060400160405280848381518110612ac357612ac3615389565b6020026020010151600001518152602001848381518110612ae657612ae6615389565b6020908102919091018101518101519091526000868152600b825260408082208583529092522081518190612b1b90826151e3565b5060208201516001820190612b3090826151e3565b509050508080612b3f90615370565b915050612a45565b506000838152600a602090815260409091208251610bee9284019061469f565b33612b71836124b5565b6001600160a01b031614612b8457600080fd5b6000828152601160205260409020612b9c82826151e3565b507f81b1bf653f53dc046b08a20dc605eed2195235db792f342a6a722e1b5480f9548282604051610d3d92919061551f565b6000612bd8613a94565b612be0611553565b612be957600080fd5b6000612bf3613aed565b90508215612ce15760008481526014602052604090205460ff1615612c1757600080fd5b6027546040516331a9108f60e11b8152600481018690526001600160a01b0390911690636352211e90602401602060405180830381865afa158015612c60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c84919061533d565b6001600160a01b0316336001600160a01b031614612ca157600080fd5b611c5e612caf8260016153ef565b1115612cba57600080fd5b6000848152601460205260409020805460ff19166001908117909155612ce1903390613af8565b82612ddb576103e8841115612cf557600080fd5b60008481526013602052604090205460ff1615612d1157600080fd5b6026546040516331a9108f60e11b8152600481018690526001600160a01b0390911690636352211e90602401602060405180830381865afa158015612d5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d7e919061533d565b6001600160a01b0316336001600160a01b031614612d9b57600080fd5b611c5e612da98260016153ef565b1115612db457600080fd5b6000848152601360205260409020805460ff19166001908117909155612ddb903390613af8565b90506108e76001600855565b6009546001600160a01b031690565b6060600380546108fc90615169565b600f8110612e1257600080fd5b612e1b826124b5565b6001600160a01b0316336001600160a01b031614612e3857600080fd5b6000828152600e60209081526040808320848452825291829020805460ff1916600117905581518481529081018390527f4c652a0da724e2e441d4269d925eb66c004118aea8f9d00f7cfd6c906f908d229101610d3d565b336001600160a01b03831603612eb95760405163b06307db60e01b815260040160405180910390fd5b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6060816001600160401b03811115612f3f57612f3f614830565b604051908082528060200260200182016040528015612f7257816020015b6060815260200190600190039081612f5d5790505b50905060005b8281101561301257612fe230858584818110612f9657612f96615389565b9050602002810190612fa89190615538565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506140ad92505050565b828281518110612ff457612ff4615389565b6020026020010181905250808061300a90615370565b915050612f78565b5092915050565b60606000806040518060400160405280600681526020016531433135333160d01b8152509050600060116000868152602001908152602001600020805461305f90615169565b90501115613101576000848152601160205260409020805461308090615169565b80601f01602080910402602001604051908101604052809291908181526020018280546130ac90615169565b80156130f95780601f106130ce576101008083540402835291602001916130f9565b820191906000526020600020905b8154815290600101906020018083116130dc57829003601f168201915b505050505090505b600061310f62020000613ceb565b90506131346040518060c0016040528060838152602001615e2d608391398290613de7565b61315f826040516020016131489190615585565b60408051601f198184030181529190528290613de7565b60005b61316e6001600f615419565b81101561327c576000613182600283615442565b1180156131a957506000868152600e6020908152604080832084845290915290205460ff16155b61326a576131ca61253f886131bf846003615402565b6126c2856003615402565b60ff16935061326a600b6000838152602001908152602001600020600086815260200190815260200160002060010161324261323d600a6000868152602001908152602001600020888154811061322357613223615389565b6000918252602090912001546001600160a01b03166140d2565b6140e2565b6040516020016132539291906155bf565b60408051601f198184030181529190528390613de7565b8061327481615370565b915050613162565b506132a761253f876003613291600f82615402565b61329b9190615419565b6126cd600f6003615402565b60ff169250613329600b60006132bf6001600f615419565b8152602001908152602001600020600085815260200190815260200160002060010161331861323d600a60006001600f6132f99190615419565b8152602001908152602001600020878154811061322357613223615389565b604051602001613148929190615619565b613332816140e2565b604051602001613342919061577d565b604051602081830303815290604052935050505092915050565b613367848484610d49565b6001600160a01b0383163b15610bee5761338384848484614234565b610bee576040516368d2bf6b60e11b815260040160405180910390fd5b60606133ab82613901565b6133b457600080fd5b60008052600a6020527f13da86008ba1c6922daee3e07db95305ef49ebced9f5467a0b8613fcc6b343e3546133e857600080fd5b60006133f383611574565b9050600061340362020000613ceb565b60008581526010602052604081208054929350909161342190615169565b9050111561345257600084815260106020908152604091829020915161344d92613148929091016157bf565b613489565b6040805180820190915260158152747b226e616d65223a224f6e436861696e416c70686160581b6020820152613489908290613de7565b6134a861349585613937565b6040516131489190602d906020016157dd565b6000602a80546134b790615169565b90501180156134d457506000848152600c602052604090205460ff165b156134fd576134f8602a6134e786613937565b604051602001613148929190615838565b613619565b60408051602080820183526000808352878152600f909152919091205460ff16156135aa57600061352e8487613019565b905061355881604051602001613544919061586f565b6040516020818303038152906040526140e2565b604051602001613568919061577d565b60405160208183030381529060405291506135a48160405160200161358d919061597a565b60408051601f198184030181529190528490613de7565b50613603565b60006135b68487613019565b90506135cc8160405160200161354491906159c1565b6040516020016135dc919061577d565b60405160208183030381529060405291506136018160405160200161358d919061597a565b505b613617816040516020016132539190615a9a565b505b613635613625836124c0565b6040516020016131489190615add565b61363e816140e2565b60405160200161364e9190615b1e565b60405160208183030381529060405292505050919050565b61366f826124b5565b6001600160a01b0316336001600160a01b03161461368c57600080fd5b6000918252600c6020526040909120805460ff1916911515919091179055565b6136b5846124b5565b6001600160a01b0316336001600160a01b0316146136d257600080fd5b600084815260106020526040902060060154808410613713576000858152601060205260408120600601805492955085929161370d83615370565b91905055505b6000858152601060209081526040808320878452600401909152902061373984826151e3565b506000858152601060209081526040808320878452600501909152902061376083826151e3565b507fca3ccd3f553ac426b514af81e9a960872e7c86a7a0260f8e8b244ce916776e7285858585604051610b519493929190615b63565b6031546060906137d090602c90602d90602e90602f906030906137b890613937565b60405161354496959493929190603290602001615b9f565b6040516020016137e09190615b1e565b604051602081830303815290604052905090565b6137fc613986565b6001600160a01b0381166138665760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b6114c581613ff6565b613877613986565b806025838154811061388b5761388b615389565b9060005260206000200190816114ff91906151e3565b6138a9613986565b60008183116138b857816138ba565b825b90506138c58161431f565b6138d86138d38260016153ef565b613901565b156138f0576138f06138eb8260016153ef565b61431f565b6114ff816138fc61434f565b6143bb565b60008161010611158015613916575060005482105b80156108e7575050600090815260046020526040902054600160e01b161590565b604080516080810191829052607f0190826030600a8206018353600a90045b801561397457600183039250600a81066030018353600a9004613956565b50819003601f19909101908152919050565b3361398f612de7565b6001600160a01b0316146129d05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161385d565b6000818061010611613a4357600054811015613a435760008181526004602052604081205490600160e01b82169003613a41575b80600003613a3a575060001901600081815260046020526040902054613a19565b9392505050565b505b604051636f96cda160e11b815260040160405180910390fd5b600060e882811c90613a6f868684614410565b62ffffff16901b95945050505050565b4260a01b176001600160a01b03919091161790565b600260085403613ae65760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161385d565b6002600855565b600054610105190190565b6000546001600160a01b038316613b2157604051622e076360e81b815260040160405180910390fd5b81600003613b425760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038316600090815260056020526040812080546001600160401b018502019055613b87908490613b7a908281613a5c565b6001851460e11b17613a7f565b600082815260046020526040902055808281015b6040516001830192906001600160a01b03871690600090600080516020615f17833981519152908290a4808210613b9b5760005550505050565b80471015613c255760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015260640161385d565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114613c72576040519150601f19603f3d011682016040523d82523d6000602084013e613c77565b606091505b50509050806114ff5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c20726044820152791958da5c1a595b9d081b585e481a185d99481c995d995c9d195960321b606482015260840161385d565b604080518281016060018252910181526000602090910190815290565b613d10614704565b6108e7613d1c836139e5565b61442f565b600080805b601684600f8110613d3957613d39615389565b0154811015613dbd576000601685600f8110613d5757613d57615389565b018281548110613d6957613d69615389565b90600052602060002001549050828610158015613d8e5750613d8b81846153ef565b86105b15613d9d575091506108e79050565b613da781846153ef565b9250508080613db590615370565b915050613d26565b506001601684600f8110613dd357613dd3615389565b0154613ddf9190615419565b949350505050565b601f1982015182518251603f19909201918290613e0490836153ef565b1115613e625760405162461bcd60e51b815260206004820152602760248201527f44796e616d69634275666665723a20417070656e64696e67206f7574206f66206044820152663137bab732399760c91b606482015260840161385d565b610bee8484614472565b6060836000613e7b8585615419565b6001600160401b03811115613e9257613e92614830565b6040519080825280601f01601f191660200182016040528015613ebc576020820181803683370190505b509050845b84811015613f2e57828181518110613edb57613edb615389565b01602001516001600160f81b03191682613ef58884615419565b81518110613f0557613f05615389565b60200101906001600160f81b031916908160001a90535080613f2681615370565b915050613ec1565b5095945050505050565b60008181805b82518160ff161015613fee576030838260ff1681518110613f6157613f61615389565b016020015160f81c10801590613f9457506039838260ff1681518110613f8957613f89615389565b016020015160f81c11155b15613fdc57613fa4600a83615cc8565b91506030838260ff1681518110613fbd57613fbd615389565b0160200151613fcf919060f81c615ce4565b613fd99083615cfd565b91505b80613fe681615d16565b915050613f3e565b509392505050565b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000806140738360405160200161405f9190615d35565b6040516020818303038152906040526144a8565b90508051602082016000f091506001600160a01b0382166140a75760405163046a55db60e11b815260040160405180910390fd5b50919050565b6060613a3a8383604051806060016040528060278152602001615ef0602791396144d4565b60606108e782600160001961454c565b6060815160000361410157505060408051602081019091526000815290565b6000604051806060016040528060408152602001615eb0604091399050600060038451600261413091906153ef565b61413a9190615d5b565b614145906004615402565b6001600160401b0381111561415c5761415c614830565b6040519080825280601f01601f191660200182016040528015614186576020820181803683370190505b509050600182016020820185865187015b808210156141f2576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250614197565b505060038651066001811461420e576002811461422157614229565b603d6001830353603d6002830353614229565b603d60018303535b509195945050505050565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290614269903390899088908890600401615d6f565b6020604051808303816000875af19250505080156142a4575060408051601f3d908101601f191682019092526142a191810190615da2565b60015b614302573d8080156142d2576040519150601f19603f3d011682016040523d82523d6000602084013e6142d7565b606091505b5080516000036142fa576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b60008181526004602052604081205490036114c55761433d816139e5565b60008281526004602052604090205550565b6000803a434244614361600184615419565b6040805160208101969096528501939093526060808501929092526080840152904060a083015233901b6001600160601b03191660c082015260d40160408051601f19818403018152919052805160209091012092915050565b600082815260046020526040812054908190036143ea5760405162d5815360e01b815260040160405180910390fd5b6000928352600460205260409092206001600160e81b039290921660e89190911b179055565b60006001600160a01b038416156144275781613ddf565b613ddf61434f565b614437614704565b6001600160a01b03821681526001600160401b0360a083901c166020820152600160e01b82161515604082015260e89190911c606082015290565b8051602082019150808201602084510184015b8184101561449d578351815260209384019301614485565b505082510190915250565b60608151826040516020016144be929190615dbf565b6040516020818303038152906040529050919050565b6060600080856001600160a01b0316856040516144f19190615e10565b600060405180830381855af49150503d806000811461452c576040519150601f19603f3d011682016040523d82523d6000602084013e614531565b606091505b509150915061454286838387614601565b9695505050505050565b6060833b600081900361456f575050604080516020810190915260008152613a3a565b8084111561458d575050604080516020810190915260008152613a3a565b838310156145bf5760405163162544fd60e11b815260048101829052602481018590526044810184905260640161385d565b83830384820360008282106145d457826145d6565b815b60408051603f8301601f19168101909152818152955090508087602087018a3c505050509392505050565b60608315614670578251600003614669576001600160a01b0385163b6146695760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161385d565b5081613ddf565b613ddf83838151156146855781518083602001fd5b8060405162461bcd60e51b815260040161385d91906147c3565b8280548282559060005260206000209081019282156146f4579160200282015b828111156146f457825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906146bf565b5061470092915061472b565b5090565b60408051608081018252600080825260208201819052918101829052606081019190915290565b5b80821115614700576000815560010161472c565b6001600160e01b0319811681146114c557600080fd5b60006020828403121561476857600080fd5b8135613a3a81614740565b60005b8381101561478e578181015183820152602001614776565b50506000910152565b600081518084526147af816020860160208601614773565b601f01601f19169290920160200192915050565b602081526000613a3a6020830184614797565b6000602082840312156147e857600080fd5b5035919050565b6001600160a01b03811681146114c557600080fd5b6000806040838503121561481757600080fd5b8235614822816147ef565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b60405160e081016001600160401b038111828210171561486857614868614830565b60405290565b604051606081016001600160401b038111828210171561486857614868614830565b604051601f8201601f191681016001600160401b03811182821017156148b8576148b8614830565b604052919050565b600082601f8301126148d157600080fd5b81356001600160401b038111156148ea576148ea614830565b6148fd601f8201601f1916602001614890565b81815284602083860101111561491257600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000806080858703121561494557600080fd5b8435935060208501356001600160401b038082111561496357600080fd5b61496f888389016148c0565b9450604087013591508082111561498557600080fd5b614991888389016148c0565b935060608701359150808211156149a757600080fd5b506149b4878288016148c0565b91505092959194509250565b6000602082840312156149d257600080fd5b81356001600160401b03808211156149e957600080fd5b9083019060e082860312156149fd57600080fd5b614a05614846565b823582811115614a1457600080fd5b614a20878286016148c0565b825250602083013582811115614a3557600080fd5b614a41878286016148c0565b602083015250604083013582811115614a5957600080fd5b614a65878286016148c0565b604083015250606083013582811115614a7d57600080fd5b614a89878286016148c0565b606083015250608083013582811115614aa157600080fd5b614aad878286016148c0565b60808301525060a083013560a082015260c083013582811115614acf57600080fd5b614adb878286016148c0565b60c08301525095945050505050565b600080600080600060808688031215614b0257600080fd5b8535614b0d816147ef565b94506020860135614b1d816147ef565b93506040860135925060608601356001600160401b0380821115614b4057600080fd5b818801915088601f830112614b5457600080fd5b813581811115614b6357600080fd5b896020828501011115614b7557600080fd5b9699959850939650602001949392505050565b8035801515811461114157600080fd5b60008060408385031215614bab57600080fd5b82359150614bbb60208401614b88565b90509250929050565b600080600060608486031215614bd957600080fd5b8335614be4816147ef565b92506020840135614bf4816147ef565b929592945050506040919091013590565b60006001600160401b03821115614c1e57614c1e614830565b5060051b60200190565b60008060408385031215614c3b57600080fd5b823591506020808401356001600160401b03811115614c5957600080fd5b8401601f81018613614c6a57600080fd5b8035614c7d614c7882614c05565b614890565b81815260059190911b82018301908381019088831115614c9c57600080fd5b928401925b82841015614cc157614cb284614b88565b82529284019290840190614ca1565b80955050505050509250929050565b60e081526000614ce360e083018a614797565b8281036020840152614cf5818a614797565b90508281036040840152614d098189614797565b90508281036060840152614d1d8188614797565b90508281036080840152614d318187614797565b90508460a084015282810360c0840152614d4b8185614797565b9a9950505050505050505050565b600060208284031215614d6b57600080fd5b81356001600160401b03811115614d8157600080fd5b613ddf848285016148c0565b600060208284031215614d9f57600080fd5b8135613a3a816147ef565b60008060408385031215614dbd57600080fd5b823591506020808401356001600160401b0380821115614ddc57600080fd5b818601915086601f830112614df057600080fd5b8135614dfe614c7882614c05565b81815260059190911b83018401908481019089831115614e1d57600080fd5b8585015b83811015614ed757803585811115614e395760008081fd5b86016060818d03601f1901811315614e515760008081fd5b614e5961486e565b8983013588811115614e6b5760008081fd5b614e798f8c838701016148c0565b825250604083013588811115614e8f5760008081fd5b614e9d8f8c838701016148c0565b828c015250908201359087821115614eb55760008081fd5b614ec38e8b848601016148c0565b604082015285525050918601918601614e21565b508096505050505050509250929050565b60008060408385031215614efb57600080fd5b8235915060208301356001600160401b03811115614f1857600080fd5b614f24858286016148c0565b9150509250929050565b60008060408385031215614f4157600080fd5b50508035926020909101359150565b60008060408385031215614f6357600080fd5b8235614f6e816147ef565b9150614bbb60208401614b88565b60008060208385031215614f8f57600080fd5b82356001600160401b0380821115614fa657600080fd5b818501915085601f830112614fba57600080fd5b813581811115614fc957600080fd5b8660208260051b8501011115614fde57600080fd5b60209290920196919550909350505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561504557603f19888603018452615033858351614797565b94509285019290850190600101615017565b5092979650505050505050565b6000806040838503121561506557600080fd5b82356001600160401b0381111561507b57600080fd5b615087858286016148c0565b95602094909401359450505050565b600080600080608085870312156150ac57600080fd5b84356150b7816147ef565b935060208501356150c7816147ef565b92506040850135915060608501356001600160401b038111156150e957600080fd5b6149b4878288016148c0565b6000806000806080858703121561510b57600080fd5b843593506020850135925060408501356001600160401b038082111561498557600080fd5b6000806040838503121561514357600080fd5b823561514e816147ef565b9150602083013561515e816147ef565b809150509250929050565b600181811c9082168061517d57607f821691505b6020821081036140a757634e487b7160e01b600052602260045260246000fd5b601f8211156114ff57600081815260208120601f850160051c810160208610156151c45750805b601f850160051c820191505b81811015610ed4578281556001016151d0565b81516001600160401b038111156151fc576151fc614830565b6152108161520a8454615169565b8461519d565b602080601f831160018114615245576000841561522d5750858301515b600019600386901b1c1916600185901b178555610ed4565b600085815260208120601f198616915b8281101561527457888601518255948401946001909101908401615255565b50858210156152925787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600083516152b4818460208801614773565b602360f81b90830190815283516152d2816001840160208801614773565b01600101949350505050565b85815260a0602082015260006152f760a0830187614797565b82810360408401526153098187614797565b9050828103606084015261531d8186614797565b905082810360808401526153318185614797565b98975050505050505050565b60006020828403121561534f57600080fd5b8151613a3a816147ef565b634e487b7160e01b600052601160045260246000fd5b6000600182016153825761538261535a565b5060010190565b634e487b7160e01b600052603260045260246000fd5b6000604082018483526020604081850152818551808452606086019150828701935060005b818110156153e25784511515835293830193918301916001016153c4565b5090979650505050505050565b808201808211156108e7576108e761535a565b80820281158282048414176108e7576108e761535a565b818103818111156108e7576108e761535a565b634e487b7160e01b600052601260045260246000fd5b6000826154515761545161542c565b500690565b6000815461546381615169565b6001828116801561547b5760018114615490576154bf565b60ff19841687528215158302870194506154bf565b8560005260208060002060005b858110156154b65781548a82015290840190820161549d565b50505082870194505b5050505092915050565b6e3d913a3930b4ba2fba3cb832911d1160891b815260006154ed600f830185615456565b6a1116113b30b63ab2911d1160a91b815261550b600b820185615456565b61227d60f01b815260020195945050505050565b828152604060208201526000613ddf6040830184614797565b6000808335601e1984360301811261554f57600080fd5b8301803591506001600160401b0382111561556957600080fd5b60200191503681900382131561557e57600080fd5b9250929050565b60008251615597818460208701614773565b75076c4c2c6d6cee4deeadcc85ad2dac2ceca74eae4d8560531b920191825250601601919050565b643230ba309d60d91b815260006155d96005830185615456565b670ed8985cd94d8d0b60c21b815283516155fa816008840160208801614773565b6505258eae4d8560d31b60089290910191820152600e01949350505050565b643230ba309d60d91b815260006156336005830185615456565b670ed8985cd94d8d0b60c21b81528351615654816008840160208801614773565b7f293b6261636b67726f756e642d7265706561743a6e6f2d7265706561743b6261600892909101918201527f636b67726f756e642d73697a653a636f6e7461696e3b6261636b67726f756e6460288201527f2d706f736974696f6e3a63656e7465723b696d6167652d72656e646572696e6760488201527f3a2d7765626b69742d6f7074696d697a652d636f6e74726173743b2d6d732d6960688201527f6e746572706f6c6174696f6e2d6d6f64653a6e6561726573742d6e656967686260888201527f6f723b696d6167652d72656e646572696e673a2d6d6f7a2d63726973702d656460a88201527f6765733b696d6167652d72656e646572696e673a706978656c617465643b223e60c8820152651e17b9bb339f60d11b60e882015260ee01949350505050565b7919185d184e9a5b5859d94bdcdd99cade1b5b0ed8985cd94d8d0b60321b8152600082516157b281601a850160208701614773565b91909101601a0192915050565b683d913730b6b2911d1160b91b81526000613a3a6009830184615456565b602360f81b8152600083516157f9816001850160208801614773565b701116113232b9b1b934b83a34b7b7111d1160791b6001918401918201526158246012820185615456565b61088b60f21b815260020195945050505050565b681134b6b0b3b2911d1160b91b815260006158566009830185615456565b8351615866818360208801614773565b01949350505050565b600080516020615f3783398151915281527f76696577426f783d223020302031323030203132303022207374796c653d226460208201527f6973706c61793a20626c6f636b3b207472616e73666f726d3a207363616c652860408201527f2d312c3129222076657273696f6e3d22312e322220786d6c6e733d226874747060608201527f3a2f2f7777772e77332e6f72672f323030302f737667223e3c696d616765207760808201527f696474683d223132303022206865696768743d22313230302220687265663d2260a0820152600082516159538160c0850160208701614773565b6f111f1e17b4b6b0b3b29f1e17b9bb339f60811b60c093909101928301525060d001919050565b711139bb33afb4b6b0b3b2afb230ba30911d1160711b815281516000906159a8816012850160208701614773565b61088b60f21b6012939091019283015250601401919050565b600080516020615f3783398151915281527f76696577426f783d2230203020313230302031323030222076657273696f6e3d60208201527f22312e322220786d6c6e733d22687474703a2f2f7777772e77332e6f72672f3260408201527f3030302f737667223e3c696d6167652077696474683d2231323030222068656960608201527033b43a1e91189918181110343932b31e9160791b608082015260008251615a73816091850160208701614773565b6f111f1e17b4b6b0b3b29f1e17b9bb339f60811b609193909101928301525060a101919050565b6d1134b6b0b3b2afb230ba30911d1160911b81528151600090615ac481600e850160208701614773565b61088b60f21b600e939091019283015250601001919050565b6c1130ba3a3934b13aba32b9911d60991b81528151600090615b0681600d850160208701614773565b607d60f81b600d939091019283015250600e01919050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000815260008251615b5681601d850160208701614773565b91909101601d0192915050565b848152836020820152608060408201526000615b826080830185614797565b8281036060840152615b948185614797565b979650505050505050565b683d913730b6b2911d1160b91b81526000615bbd600983018a615456565b701116113232b9b1b934b83a34b7b7111d1160791b8152615be1601182018a615456565b6a11161134b6b0b3b2911d1160a91b81529050615c01600b820189615456565b6b1116113130b73732b9111d1160a11b81529050615c22600c820188615456565b7211161132bc3a32b93730b62fb634b735911d1160691b81529050615c4a6013820187615456565b7b11161139b2b63632b92fb332b2afb130b9b4b9afb837b4b73a39911d60211b81528551909150615c8281601c840160208901614773565b7116113332b2afb932b1b4b834b2b73a111d1160711b601c9290910191820152615caf602e820185615456565b61227d60f01b81526002019a9950505050505050505050565b60ff81811683821602908116908181146130125761301261535a565b60ff82811682821603908111156108e7576108e761535a565b60ff81811683821601908111156108e7576108e761535a565b600060ff821660ff8103615d2c57615d2c61535a565b60010192915050565b6000815260008251615d4e816001850160208701614773565b9190910160010192915050565b600082615d6a57615d6a61542c565b500490565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061454290830184614797565b600060208284031215615db457600080fd5b8151613a3a81614740565b606360f81b815260e083901b6001600160e01b03191660018201526880600e6000396000f360b81b60058201528151600090615e0281600e850160208701614773565b91909101600e019392505050565b60008251615e22818460208701614773565b919091019291505056fe3c7376672077696474683d223136303022206865696768743d2231363030222076696577426f783d2230203020313630302031363030222076657273696f6e3d22312e322220786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f73766722207374796c653d226261636b67726f756e642d636f6c6f723a20234142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef3c7376672077696474683d223130302522206865696768743d22313030252220a264697066735822122020ca10d25cc2579867a12aa3307559f37a93dd8bba2ce9793f5ce20ade52099564736f6c634300081100334f6e2d436861696e20416c706861206973206120636f6c6c656374696f6e206f66203737373720637573746f6d697a61626c65206469676974616c206964656e7469747920746f6b656e732073746f72656420656e746972656c79206f6e2074686520457468657265756d20626c6f636b636861696e2e20546f6b656e20686f6c646572732063616e2076697369742068747470733a2f2f6f63612e676720746f20656e61626c652f64697361626c65206578697374696e67207472616974732c206368616e6765206261636b67726f756e6420636f6c6f722c20666c69702074686520696d6167652c20656e61626c652054776974746572206865782c20616e64206d6f72652061732077656c6c2061732072657665616c206e65772074726169742064726f707320746f2062652072656c656173656420696e20746865206675747572652e68747470733a2f2f7374617469632e666c6f6f7265644170652e696f2f6f63612f68747470733a2f2f697066732e696f2f697066732f516d646271374e35697a72617a6f59636277537578636d73326442656d78757862724c61467477326475666456362f62616e6e65722e706e6730783935373335364639343132383330633939324434363546463843446239623041413032333032306268747470733a2f2f697066732e696f2f697066732f516d646271374e35697a72617a6f59636277537578636d73326442656d78757862724c61467477326475666456362f636f6c6c656374696f6e2e676966
Deployed Bytecode
0x6080604052600436106102395760003560e01c806301ffc9a71461023e57806306fdde0314610273578063081812fc14610295578063095ea7b3146102cd5780630ea71cfc146102ef5780630f3debbe1461030f578063150b7a021461032f57806318160ddd1461036857806319c841fd1461039057806323b872dd146103b05780632437013d146103d05780632d6b6224146103f05780632db115441461040a5780633cca24201461041d5780633ccfd60b146104455780634047638d1461045a57806342842e0e1461046f57806355f804b31461048f57806357380daa146104af5780635b92ac0d146104cf578063621a1f74146104e45780636352211e1461050457806366e33870146105245780636817c76c146105445780636c0360eb1461055a57806370a082311461056f578063715018a61461058f578063716e43d7146105a45780637a75353a146105c45780638a8c0e0c146105e45780638da5cb5b1461060457806395d89b411461061957806397e2155d1461062e578063a22cb4651461064e578063a78c8a7a1461066e578063ac9650d814610684578063ad9adfe3146106b1578063b88d4fde146106d1578063c406ec72146106f1578063c87b56dd14610711578063d5abeb0114610731578063dbe9875f14610747578063e488627314610767578063e8a3d48514610787578063e985e9c51461079c578063ed39d98d146107e5578063f2f0dc0514610805578063f2fde38b1461083b578063fb38d2111461085b578063fd6b3cf51461087b575b600080fd5b34801561024a57600080fd5b5061025e610259366004614756565b61089b565b60405190151581526020015b60405180910390f35b34801561027f57600080fd5b506102886108ed565b60405161026a91906147c3565b3480156102a157600080fd5b506102b56102b03660046147d6565b61097f565b6040516001600160a01b03909116815260200161026a565b3480156102d957600080fd5b506102ed6102e8366004614804565b6109c3565b005b3480156102fb57600080fd5b506102ed61030a36600461492f565b610a63565b34801561031b57600080fd5b506102ed61032a3660046149c0565b610b60565b34801561033b57600080fd5b5061034f61034a366004614aea565b610bf4565b6040516001600160e01b0319909116815260200161026a565b34801561037457600080fd5b506001546000540361010519015b60405190815260200161026a565b34801561039c57600080fd5b506102ed6103ab366004614b98565b610cc9565b3480156103bc57600080fd5b506102ed6103cb366004614bc4565b610d49565b3480156103dc57600080fd5b506102ed6103eb366004614c28565b610edc565b3480156103fc57600080fd5b50602b5461025e9060ff1681565b6103826104183660046147d6565b610f97565b34801561042957600080fd5b50610432611146565b60405161026a9796959493929190614cd0565b34801561045157600080fd5b506102ed6114a4565b34801561046657600080fd5b506102ed6114c8565b34801561047b57600080fd5b506102ed61048a366004614bc4565b6114e4565b34801561049b57600080fd5b506102ed6104aa366004614d59565b611504565b3480156104bb57600080fd5b5061025e6104ca366004614b98565b61151c565b3480156104db57600080fd5b5061025e611553565b3480156104f057600080fd5b506102886104ff3660046147d6565b611574565b34801561051057600080fd5b506102b561051f3660046147d6565b6124b5565b34801561053057600080fd5b5061028861053f366004614d59565b6124c0565b34801561055057600080fd5b5061038260285481565b34801561056657600080fd5b506102886128e2565b34801561057b57600080fd5b5061038261058a366004614d8d565b612970565b34801561059b57600080fd5b506102ed6129be565b3480156105b057600080fd5b506102ed6105bf366004614daa565b6129d2565b3480156105d057600080fd5b506102ed6105df366004614ee8565b612b67565b3480156105f057600080fd5b506103826105ff366004614b98565b612bce565b34801561061057600080fd5b506102b5612de7565b34801561062557600080fd5b50610288612df6565b34801561063a57600080fd5b506102ed610649366004614f2e565b612e05565b34801561065a57600080fd5b506102ed610669366004614f50565b612e90565b34801561067a57600080fd5b5061038260295481565b34801561069057600080fd5b506106a461069f366004614f7c565b612f25565b60405161026a9190614ff0565b3480156106bd57600080fd5b506102886106cc366004615052565b613019565b3480156106dd57600080fd5b506102ed6106ec366004615096565b61335c565b3480156106fd57600080fd5b506026546102b5906001600160a01b031681565b34801561071d57600080fd5b5061028861072c3660046147d6565b6133a0565b34801561073d57600080fd5b50610382611c5e81565b34801561075357600080fd5b506102ed610762366004614b98565b613666565b34801561077357600080fd5b506102ed6107823660046150f5565b6136ac565b34801561079357600080fd5b50610288613796565b3480156107a857600080fd5b5061025e6107b7366004615130565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b3480156107f157600080fd5b506027546102b5906001600160a01b031681565b34801561081157600080fd5b50610382610820366004614d8d565b6001600160a01b031660009081526012602052604090205490565b34801561084757600080fd5b506102ed610856366004614d8d565b6137f4565b34801561086757600080fd5b506102ed610876366004614ee8565b61386f565b34801561088757600080fd5b506102ed610896366004614f2e565b6138a1565b60006301ffc9a760e01b6001600160e01b0319831614806108cc57506380ac58cd60e01b6001600160e01b03198316145b806108e75750635b5e139f60e01b6001600160e01b03198316145b92915050565b6060600280546108fc90615169565b80601f016020809104026020016040519081016040528092919081815260200182805461092890615169565b80156109755780601f1061094a57610100808354040283529160200191610975565b820191906000526020600020905b81548152906001019060200180831161095857829003601f168201915b5050505050905090565b600061098a82613901565b6109a7576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b60006109ce826124b5565b9050336001600160a01b03821614610a07576109ea81336107b7565b610a07576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b33610a6d856124b5565b6001600160a01b031614610a8057600080fd5b6000848152601060205260409020610a9884826151e3565b506000848152601060205260409020600101610ab483826151e3565b506000848152601060205260409020600201610ad082826151e3565b50600083610add86613937565b604051602001610aee9291906152a2565b60408051601f198184030181529181526000878152601060205220909150600301610b1982826151e3565b507fb8981c9fcfec39b56f5caf88846acca9b61e75401e68da165ef541e81991d8b68585858585604051610b519594939291906152de565b60405180910390a15050505050565b610b68613986565b80518190602c908190610b7b90826151e3565b5060208201516001820190610b9090826151e3565b5060408201516002820190610ba590826151e3565b5060608201516003820190610bba90826151e3565b5060808201516004820190610bcf90826151e3565b5060a0820151600582015560c08201516006820190610bee90826151e3565b50505050565b6026546000906001600160a01b0316331480610c8557506026546040516331a9108f60e11b8152600481018690526001600160a01b03878116921690636352211e90602401602060405180830381865afa158015610c56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c7a919061533d565b6001600160a01b0316145b610c8e57600080fd5b6001600160a01b0385166000908152601260205260408120805491610cb283615370565b90915550630a85bd0160e11b979650505050505050565b610cd2826124b5565b6001600160a01b0316336001600160a01b031614610cef57600080fd5b6000828152600f6020908152604091829020805460ff19168415159081179091558251858152918201527fafec4b400a28d8bdfacc6b65e3c25cc07399c2c20eeb817256f6413c7e84687c91015b60405180910390a15050565b6000610d54826139e5565b9050836001600160a01b0316816001600160a01b031614610d875760405162a1148160e81b815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b03881690911417610dd457610db786336107b7565b610dd457604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b038516610dfb57604051633a954ecd60e21b815260040160405180910390fd5b8015610e0657600082555b6001600160a01b03808716600090815260056020526040808220805460001901905591871681522080546001019055610e4f85610e44888287613a5c565b600160e11b17613a7f565b600085815260046020526040812091909155600160e11b84169003610ea457600184016000818152600460205260408120549003610ea2576000548114610ea25760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b0316600080516020615f1783398151915260405160405180910390a45b505050505050565b610ee5826124b5565b6001600160a01b0316336001600160a01b031614610f0257600080fd5b60005b600f811015610f6557818181518110610f2057610f20615389565b6020908102919091018101516000858152600d8352604080822085835290935291909120805460ff191691151591909117905580610f5d81615370565b915050610f05565b507f6feffc52172e0d2f7273caf08349169b161ca5e8e463fa548b2dc2258c54cce38282604051610d3d92919061539f565b6000610fa1613a94565b610fa9611553565b610fb257600080fd5b6000610fbc613aed565b33600090815260156020526040902054909150606490610fdd9085906153ef565b1115610fe857600080fd5b60148311158015610ff95750600083115b61100257600080fd5b611c5e61100f84836153ef565b111561101a57600080fd5b33321461102657600080fd5b3360009081526012602052604081205480156110ec5784811161108d57806029546110519190615402565b915081602854866110629190615402565b61106c9190615419565b34101561107857600080fd5b33600090815260126020526040812055611105565b8460295461109b9190615402565b915081602854866110ac9190615402565b6110b69190615419565b3410156110c257600080fd5b33600090815260126020526040812080548792906110e1908490615419565b909155506111059050565b6028546110f99086615402565b34101561110557600080fd5b33600090815260156020526040812080548792906111249084906153ef565b9091555061113490503386613af8565b5050600160085592915050565b919050565b602c8054819061115590615169565b80601f016020809104026020016040519081016040528092919081815260200182805461118190615169565b80156111ce5780601f106111a3576101008083540402835291602001916111ce565b820191906000526020600020905b8154815290600101906020018083116111b157829003601f168201915b5050505050908060010180546111e390615169565b80601f016020809104026020016040519081016040528092919081815260200182805461120f90615169565b801561125c5780601f106112315761010080835404028352916020019161125c565b820191906000526020600020905b81548152906001019060200180831161123f57829003601f168201915b50505050509080600201805461127190615169565b80601f016020809104026020016040519081016040528092919081815260200182805461129d90615169565b80156112ea5780601f106112bf576101008083540402835291602001916112ea565b820191906000526020600020905b8154815290600101906020018083116112cd57829003601f168201915b5050505050908060030180546112ff90615169565b80601f016020809104026020016040519081016040528092919081815260200182805461132b90615169565b80156113785780601f1061134d57610100808354040283529160200191611378565b820191906000526020600020905b81548152906001019060200180831161135b57829003601f168201915b50505050509080600401805461138d90615169565b80601f01602080910402602001604051908101604052809291908181526020018280546113b990615169565b80156114065780601f106113db57610100808354040283529160200191611406565b820191906000526020600020905b8154815290600101906020018083116113e957829003601f168201915b50505050509080600501549080600601805461142190615169565b80601f016020809104026020016040519081016040528092919081815260200182805461144d90615169565b801561149a5780601f1061146f5761010080835404028352916020019161149a565b820191906000526020600020905b81548152906001019060200180831161147d57829003601f168201915b5050505050905087565b47806114af57600080fd5b6033546114c5906001600160a01b031682613bd5565b50565b6114d0613986565b602b805460ff19811660ff90911615179055565b6114ff8383836040518060200160405280600081525061335c565b505050565b61150c613986565b602a61151882826151e3565b5050565b6000811561153c575060008281526014602052604090205460ff166108e7565b505060009081526013602052604090205460ff1690565b6000611c5e611560613aed565b10801561156f5750602b5460ff165b905090565b606061157f82613901565b61158857600080fd5b600061159e611599600f6004615402565b613ceb565b60408051600f808252610200820190925291925060009190602082016101e08036833701905050905060005b600f8110156123845760008282815181106115e7576115e7615389565b6020026020010151905060006002836116009190615442565b11801561162757506000868152600e6020908152604080832085845290915290205460ff16155b15611670576001601683600f811061164157611641615389565b015461164d9190615419565b83838151811061165f5761165f615389565b602002602001018181525050612371565b600061167b87613d08565b6060015162ffffff1690506000611c5e828961169787826153ef565b60408051602081019490945283019190915260608201526080016040516020818303038152906040528051906020012060001c6116d49190615442565b90506116e08185613d21565b9250828585815181106116f5576116f5615389565b60200260200101818152505060006001601686600f811061171857611718615389565b01546117249190615419565b60008a8152600d6020908152604080832089845290915290205490915060ff161515600103611f545784600a148015611776575085858151811061176a5761176a615389565b6020026020010151600a145b156117e8578086868151811061178e5761178e615389565b60209081029190910181019190915260008a8152600d82526040808220600283529092529081205460ff16151590036117e357600f866002815181106117d6576117d6615389565b6020026020010181815250505b61236d565b84600e148015611811575085858151811061180557611805615389565b60200260200101516000145b15611871578086868151811061182957611829615389565b60209081029190910181019190915260008a8152600d82526040808220600883529092529081205460ff16151590036117e3576005866008815181106117d6576117d6615389565b84600e14801561189a575085858151811061188e5761188e615389565b60200260200101516002145b1561198a57808686815181106118b2576118b2615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff161515900361190757600186600a815181106118fa576118fa615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff161515900361194f5760008660088151811061194257611942615389565b6020026020010181815250505b6000898152600d602090815260408083206004845290915281205460ff16151590036117e3576001866004815181106117d6576117d6615389565b84600e1480156119b357508585815181106119a7576119a7615389565b60200260200101516004145b15611a5b57808686815181106119cb576119cb615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff1615159003611a2057600886600a81518110611a1357611a13615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff16151590036117e3576009866008815181106117d6576117d6615389565b84600e148015611a845750858581518110611a7857611a78615389565b60200260200101516005145b15611b2c5780868681518110611a9c57611a9c615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff1615159003611af157600686600a81518110611ae457611ae4615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff16151590036117e3576007866008815181106117d6576117d6615389565b84600e148015611b555750858581518110611b4957611b49615389565b60200260200101516006145b15611bfd5780868681518110611b6d57611b6d615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff1615159003611bc257600786600a81518110611bb557611bb5615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff16151590036117e3576008866008815181106117d6576117d6615389565b84600e148015611c265750858581518110611c1a57611c1a615389565b60200260200101516007145b15611cce5780868681518110611c3e57611c3e615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff1615159003611c9357600286600a81518110611c8657611c86615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff16151590036117e3576004866008815181106117d6576117d6615389565b84600e148015611cf75750858581518110611ceb57611ceb615389565b60200260200101516009145b15611d9f5780868681518110611d0f57611d0f615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff1615159003611d6457600586600a81518110611d5757611d57615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff16151590036117e3576001866008815181106117d6576117d6615389565b84600e148015611dc85750858581518110611dbc57611dbc615389565b6020026020010151600a145b15611e705780868681518110611de057611de0615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff1615159003611e3557600486600a81518110611e2857611e28615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff16151590036117e3576002866008815181106117d6576117d6615389565b84600e148015611e995750858581518110611e8d57611e8d615389565b6020026020010151600b145b15611f415780868681518110611eb157611eb1615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff1615159003611f0657600386600a81518110611ef957611ef9615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff16151590036117e3576003866008815181106117d6576117d6615389565b808686815181106117d6576117d6615389565b84600a148015611f7e575085600a81518110611f7257611f72615389565b6020026020010151600a145b15611fcb576000898152600d602090815260408083206002845290915281205460ff1615159003611fcb57600f86600281518110611fbe57611fbe615389565b6020026020010181815250505b84600e0361236d5785600e81518110611fe657611fe6615389565b6020026020010151600003612030576000898152600d602090815260408083206008845290915281205460ff16151590036117e3576005866008815181106117d6576117d6615389565b85600e8151811061204357612043615389565b602002602001015160020361208d576000898152600d60209081526040808320600a845290915281205460ff161515900361190757600186600a815181106118fa576118fa615389565b85600e815181106120a0576120a0615389565b60200260200101516004036120ea576000898152600d60209081526040808320600a845290915281205460ff1615159003611a2057600886600a81518110611a1357611a13615389565b85600e815181106120fd576120fd615389565b6020026020010151600503612147576000898152600d60209081526040808320600a845290915281205460ff1615159003611af157600686600a81518110611ae457611ae4615389565b85600e8151811061215a5761215a615389565b60200260200101516006036121a4576000898152600d60209081526040808320600a845290915281205460ff1615159003611bc257600786600a81518110611bb557611bb5615389565b85600e815181106121b7576121b7615389565b6020026020010151600703612201576000898152600d60209081526040808320600a845290915281205460ff1615159003611c9357600286600a81518110611c8657611c86615389565b85600e8151811061221457612214615389565b602002602001015160090361225e576000898152600d60209081526040808320600a845290915281205460ff1615159003611d6457600586600a81518110611d5757611d57615389565b85600e8151811061227157612271615389565b6020026020010151600a036122bb576000898152600d60209081526040808320600a845290915281205460ff1615159003611e3557600486600a81518110611e2857611e28615389565b85600e815181106122ce576122ce615389565b6020026020010151600b0361236d576000898152600d60209081526040808320600a845290915281205460ff161515900361232557600386600a8151811061231857612318615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff161515900361236d5760038660088151811061236057612360615389565b6020026020010181815250505b5050505b508061237c81615370565b9150506115ca565b5060005b81518110156124ac57600a8282815181106123a5576123a5615389565b602002602001015110156123dc57604080518082019091526002815261030360f41b60208201526123d7908490613de7565b612421565b60648282815181106123f0576123f0615389565b60200260200101511015612421576040805180820190915260018152600360fc1b6020820152612421908490613de7565b6103e782828151811061243657612436615389565b6020026020010151111561246e5760408051808201909152600381526239393960e81b6020820152612469908490613de7565b61249a565b61249a61249383838151811061248657612486615389565b6020026020010151613937565b8490613de7565b806124a481615370565b915050612388565b50909392505050565b60006108e7826139e5565b606060006124d062020000613ceb565b90506124fe604051806040016040528060018152602001605b60f81b81525082613de790919063ffffffff16565b600b600081815260209190915260037fe8056e2ed8943b7f61a5f0dc88c79a5a6cec2bb36a7bd11ce130f2961c6320b98261254461253f8860216024613e6c565b613f38565b60ff168152602001908152602001600020600001805461256390615169565b600c6000908152600b60205292119250600390507f765e72d9703c9804ad76c7d0af52f5313041ea56bb31a328e17fea205151b5ea826125a961253f8960246027613e6c565b60ff16815260200190815260200160002060000180546125c890615169565b600d6000908152600b60205292119250600390507f0a2216aa9bbf8764f3bfb9fafcef7f625aba82383c1a9d14d721124ff30595818261260e61253f8a6027602a613e6c565b60ff168152602001908152602001600020600001805461262d90615169565b600e6000908152600b60205292119250600390507f7ae97ffc8b2fe6ed730ad82f8c44cc0285c7a97ac189e2d88c56200fe9a501ab8261267361253f8b602a602d613e6c565b60ff168152602001908152602001600020600001805461269290615169565b905010905060005b600f8110156128d65760006126d261253f8a6126b7856003615402565b6126c2866003615402565b6126cd9060036153ef565b613e6c565b6000838152600b6020908152604080832060ff94909416808452939091529020805491925060029161270390615169565b905011156128c3576127696025838154811061272157612721615389565b60009182526020808320868452600b82526040808520878652835293849020935161275294939091019291016154c9565b60408051601f198184030181529190528890613de7565b81600a148015612790575085801561277e5750845b80156127875750835b80156127905750825b156127bd576040805180820190915260018152605d60f81b60208201526127b8908890613de7565b6128c3565b81600b1480156127db57508480156127d25750835b80156127db5750825b15612803576040805180820190915260018152605d60f81b60208201526127b8908890613de7565b81600c14801561281857508380156128185750825b15612840576040805180820190915260018152605d60f81b60208201526127b8908890613de7565b81600d14801561284d5750825b15612875576040805180820190915260018152605d60f81b60208201526127b8908890613de7565b81600e036128a0576040805180820190915260018152605d60f81b60208201526127b8908890613de7565b6040805180820190915260018152600b60fa1b60208201526128c3908890613de7565b50806128ce81615370565b91505061269a565b50939695505050505050565b602a80546128ef90615169565b80601f016020809104026020016040519081016040528092919081815260200182805461291b90615169565b80156129685780601f1061293d57610100808354040283529160200191612968565b820191906000526020600020905b81548152906001019060200180831161294b57829003601f168201915b505050505081565b60006001600160a01b038216612999576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b6129c6613986565b6129d06000613ff6565b565b6129da613986565b8051601683600f81106129ef576129ef615389565b0154146129fb57600080fd5b600081516001600160401b03811115612a1657612a16614830565b604051908082528060200260200182016040528015612a3f578160200160208202803683370190505b50905060005b8251811015612b4757612a74838281518110612a6357612a63615389565b602002602001015160400151614048565b828281518110612a8657612a86615389565b60200260200101906001600160a01b031690816001600160a01b0316815250506040518060400160405280848381518110612ac357612ac3615389565b6020026020010151600001518152602001848381518110612ae657612ae6615389565b6020908102919091018101518101519091526000868152600b825260408082208583529092522081518190612b1b90826151e3565b5060208201516001820190612b3090826151e3565b509050508080612b3f90615370565b915050612a45565b506000838152600a602090815260409091208251610bee9284019061469f565b33612b71836124b5565b6001600160a01b031614612b8457600080fd5b6000828152601160205260409020612b9c82826151e3565b507f81b1bf653f53dc046b08a20dc605eed2195235db792f342a6a722e1b5480f9548282604051610d3d92919061551f565b6000612bd8613a94565b612be0611553565b612be957600080fd5b6000612bf3613aed565b90508215612ce15760008481526014602052604090205460ff1615612c1757600080fd5b6027546040516331a9108f60e11b8152600481018690526001600160a01b0390911690636352211e90602401602060405180830381865afa158015612c60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c84919061533d565b6001600160a01b0316336001600160a01b031614612ca157600080fd5b611c5e612caf8260016153ef565b1115612cba57600080fd5b6000848152601460205260409020805460ff19166001908117909155612ce1903390613af8565b82612ddb576103e8841115612cf557600080fd5b60008481526013602052604090205460ff1615612d1157600080fd5b6026546040516331a9108f60e11b8152600481018690526001600160a01b0390911690636352211e90602401602060405180830381865afa158015612d5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d7e919061533d565b6001600160a01b0316336001600160a01b031614612d9b57600080fd5b611c5e612da98260016153ef565b1115612db457600080fd5b6000848152601360205260409020805460ff19166001908117909155612ddb903390613af8565b90506108e76001600855565b6009546001600160a01b031690565b6060600380546108fc90615169565b600f8110612e1257600080fd5b612e1b826124b5565b6001600160a01b0316336001600160a01b031614612e3857600080fd5b6000828152600e60209081526040808320848452825291829020805460ff1916600117905581518481529081018390527f4c652a0da724e2e441d4269d925eb66c004118aea8f9d00f7cfd6c906f908d229101610d3d565b336001600160a01b03831603612eb95760405163b06307db60e01b815260040160405180910390fd5b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6060816001600160401b03811115612f3f57612f3f614830565b604051908082528060200260200182016040528015612f7257816020015b6060815260200190600190039081612f5d5790505b50905060005b8281101561301257612fe230858584818110612f9657612f96615389565b9050602002810190612fa89190615538565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506140ad92505050565b828281518110612ff457612ff4615389565b6020026020010181905250808061300a90615370565b915050612f78565b5092915050565b60606000806040518060400160405280600681526020016531433135333160d01b8152509050600060116000868152602001908152602001600020805461305f90615169565b90501115613101576000848152601160205260409020805461308090615169565b80601f01602080910402602001604051908101604052809291908181526020018280546130ac90615169565b80156130f95780601f106130ce576101008083540402835291602001916130f9565b820191906000526020600020905b8154815290600101906020018083116130dc57829003601f168201915b505050505090505b600061310f62020000613ceb565b90506131346040518060c0016040528060838152602001615e2d608391398290613de7565b61315f826040516020016131489190615585565b60408051601f198184030181529190528290613de7565b60005b61316e6001600f615419565b81101561327c576000613182600283615442565b1180156131a957506000868152600e6020908152604080832084845290915290205460ff16155b61326a576131ca61253f886131bf846003615402565b6126c2856003615402565b60ff16935061326a600b6000838152602001908152602001600020600086815260200190815260200160002060010161324261323d600a6000868152602001908152602001600020888154811061322357613223615389565b6000918252602090912001546001600160a01b03166140d2565b6140e2565b6040516020016132539291906155bf565b60408051601f198184030181529190528390613de7565b8061327481615370565b915050613162565b506132a761253f876003613291600f82615402565b61329b9190615419565b6126cd600f6003615402565b60ff169250613329600b60006132bf6001600f615419565b8152602001908152602001600020600085815260200190815260200160002060010161331861323d600a60006001600f6132f99190615419565b8152602001908152602001600020878154811061322357613223615389565b604051602001613148929190615619565b613332816140e2565b604051602001613342919061577d565b604051602081830303815290604052935050505092915050565b613367848484610d49565b6001600160a01b0383163b15610bee5761338384848484614234565b610bee576040516368d2bf6b60e11b815260040160405180910390fd5b60606133ab82613901565b6133b457600080fd5b60008052600a6020527f13da86008ba1c6922daee3e07db95305ef49ebced9f5467a0b8613fcc6b343e3546133e857600080fd5b60006133f383611574565b9050600061340362020000613ceb565b60008581526010602052604081208054929350909161342190615169565b9050111561345257600084815260106020908152604091829020915161344d92613148929091016157bf565b613489565b6040805180820190915260158152747b226e616d65223a224f6e436861696e416c70686160581b6020820152613489908290613de7565b6134a861349585613937565b6040516131489190602d906020016157dd565b6000602a80546134b790615169565b90501180156134d457506000848152600c602052604090205460ff165b156134fd576134f8602a6134e786613937565b604051602001613148929190615838565b613619565b60408051602080820183526000808352878152600f909152919091205460ff16156135aa57600061352e8487613019565b905061355881604051602001613544919061586f565b6040516020818303038152906040526140e2565b604051602001613568919061577d565b60405160208183030381529060405291506135a48160405160200161358d919061597a565b60408051601f198184030181529190528490613de7565b50613603565b60006135b68487613019565b90506135cc8160405160200161354491906159c1565b6040516020016135dc919061577d565b60405160208183030381529060405291506136018160405160200161358d919061597a565b505b613617816040516020016132539190615a9a565b505b613635613625836124c0565b6040516020016131489190615add565b61363e816140e2565b60405160200161364e9190615b1e565b60405160208183030381529060405292505050919050565b61366f826124b5565b6001600160a01b0316336001600160a01b03161461368c57600080fd5b6000918252600c6020526040909120805460ff1916911515919091179055565b6136b5846124b5565b6001600160a01b0316336001600160a01b0316146136d257600080fd5b600084815260106020526040902060060154808410613713576000858152601060205260408120600601805492955085929161370d83615370565b91905055505b6000858152601060209081526040808320878452600401909152902061373984826151e3565b506000858152601060209081526040808320878452600501909152902061376083826151e3565b507fca3ccd3f553ac426b514af81e9a960872e7c86a7a0260f8e8b244ce916776e7285858585604051610b519493929190615b63565b6031546060906137d090602c90602d90602e90602f906030906137b890613937565b60405161354496959493929190603290602001615b9f565b6040516020016137e09190615b1e565b604051602081830303815290604052905090565b6137fc613986565b6001600160a01b0381166138665760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b6114c581613ff6565b613877613986565b806025838154811061388b5761388b615389565b9060005260206000200190816114ff91906151e3565b6138a9613986565b60008183116138b857816138ba565b825b90506138c58161431f565b6138d86138d38260016153ef565b613901565b156138f0576138f06138eb8260016153ef565b61431f565b6114ff816138fc61434f565b6143bb565b60008161010611158015613916575060005482105b80156108e7575050600090815260046020526040902054600160e01b161590565b604080516080810191829052607f0190826030600a8206018353600a90045b801561397457600183039250600a81066030018353600a9004613956565b50819003601f19909101908152919050565b3361398f612de7565b6001600160a01b0316146129d05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161385d565b6000818061010611613a4357600054811015613a435760008181526004602052604081205490600160e01b82169003613a41575b80600003613a3a575060001901600081815260046020526040902054613a19565b9392505050565b505b604051636f96cda160e11b815260040160405180910390fd5b600060e882811c90613a6f868684614410565b62ffffff16901b95945050505050565b4260a01b176001600160a01b03919091161790565b600260085403613ae65760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161385d565b6002600855565b600054610105190190565b6000546001600160a01b038316613b2157604051622e076360e81b815260040160405180910390fd5b81600003613b425760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038316600090815260056020526040812080546001600160401b018502019055613b87908490613b7a908281613a5c565b6001851460e11b17613a7f565b600082815260046020526040902055808281015b6040516001830192906001600160a01b03871690600090600080516020615f17833981519152908290a4808210613b9b5760005550505050565b80471015613c255760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015260640161385d565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114613c72576040519150601f19603f3d011682016040523d82523d6000602084013e613c77565b606091505b50509050806114ff5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c20726044820152791958da5c1a595b9d081b585e481a185d99481c995d995c9d195960321b606482015260840161385d565b604080518281016060018252910181526000602090910190815290565b613d10614704565b6108e7613d1c836139e5565b61442f565b600080805b601684600f8110613d3957613d39615389565b0154811015613dbd576000601685600f8110613d5757613d57615389565b018281548110613d6957613d69615389565b90600052602060002001549050828610158015613d8e5750613d8b81846153ef565b86105b15613d9d575091506108e79050565b613da781846153ef565b9250508080613db590615370565b915050613d26565b506001601684600f8110613dd357613dd3615389565b0154613ddf9190615419565b949350505050565b601f1982015182518251603f19909201918290613e0490836153ef565b1115613e625760405162461bcd60e51b815260206004820152602760248201527f44796e616d69634275666665723a20417070656e64696e67206f7574206f66206044820152663137bab732399760c91b606482015260840161385d565b610bee8484614472565b6060836000613e7b8585615419565b6001600160401b03811115613e9257613e92614830565b6040519080825280601f01601f191660200182016040528015613ebc576020820181803683370190505b509050845b84811015613f2e57828181518110613edb57613edb615389565b01602001516001600160f81b03191682613ef58884615419565b81518110613f0557613f05615389565b60200101906001600160f81b031916908160001a90535080613f2681615370565b915050613ec1565b5095945050505050565b60008181805b82518160ff161015613fee576030838260ff1681518110613f6157613f61615389565b016020015160f81c10801590613f9457506039838260ff1681518110613f8957613f89615389565b016020015160f81c11155b15613fdc57613fa4600a83615cc8565b91506030838260ff1681518110613fbd57613fbd615389565b0160200151613fcf919060f81c615ce4565b613fd99083615cfd565b91505b80613fe681615d16565b915050613f3e565b509392505050565b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000806140738360405160200161405f9190615d35565b6040516020818303038152906040526144a8565b90508051602082016000f091506001600160a01b0382166140a75760405163046a55db60e11b815260040160405180910390fd5b50919050565b6060613a3a8383604051806060016040528060278152602001615ef0602791396144d4565b60606108e782600160001961454c565b6060815160000361410157505060408051602081019091526000815290565b6000604051806060016040528060408152602001615eb0604091399050600060038451600261413091906153ef565b61413a9190615d5b565b614145906004615402565b6001600160401b0381111561415c5761415c614830565b6040519080825280601f01601f191660200182016040528015614186576020820181803683370190505b509050600182016020820185865187015b808210156141f2576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250614197565b505060038651066001811461420e576002811461422157614229565b603d6001830353603d6002830353614229565b603d60018303535b509195945050505050565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290614269903390899088908890600401615d6f565b6020604051808303816000875af19250505080156142a4575060408051601f3d908101601f191682019092526142a191810190615da2565b60015b614302573d8080156142d2576040519150601f19603f3d011682016040523d82523d6000602084013e6142d7565b606091505b5080516000036142fa576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b60008181526004602052604081205490036114c55761433d816139e5565b60008281526004602052604090205550565b6000803a434244614361600184615419565b6040805160208101969096528501939093526060808501929092526080840152904060a083015233901b6001600160601b03191660c082015260d40160408051601f19818403018152919052805160209091012092915050565b600082815260046020526040812054908190036143ea5760405162d5815360e01b815260040160405180910390fd5b6000928352600460205260409092206001600160e81b039290921660e89190911b179055565b60006001600160a01b038416156144275781613ddf565b613ddf61434f565b614437614704565b6001600160a01b03821681526001600160401b0360a083901c166020820152600160e01b82161515604082015260e89190911c606082015290565b8051602082019150808201602084510184015b8184101561449d578351815260209384019301614485565b505082510190915250565b60608151826040516020016144be929190615dbf565b6040516020818303038152906040529050919050565b6060600080856001600160a01b0316856040516144f19190615e10565b600060405180830381855af49150503d806000811461452c576040519150601f19603f3d011682016040523d82523d6000602084013e614531565b606091505b509150915061454286838387614601565b9695505050505050565b6060833b600081900361456f575050604080516020810190915260008152613a3a565b8084111561458d575050604080516020810190915260008152613a3a565b838310156145bf5760405163162544fd60e11b815260048101829052602481018590526044810184905260640161385d565b83830384820360008282106145d457826145d6565b815b60408051603f8301601f19168101909152818152955090508087602087018a3c505050509392505050565b60608315614670578251600003614669576001600160a01b0385163b6146695760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161385d565b5081613ddf565b613ddf83838151156146855781518083602001fd5b8060405162461bcd60e51b815260040161385d91906147c3565b8280548282559060005260206000209081019282156146f4579160200282015b828111156146f457825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906146bf565b5061470092915061472b565b5090565b60408051608081018252600080825260208201819052918101829052606081019190915290565b5b80821115614700576000815560010161472c565b6001600160e01b0319811681146114c557600080fd5b60006020828403121561476857600080fd5b8135613a3a81614740565b60005b8381101561478e578181015183820152602001614776565b50506000910152565b600081518084526147af816020860160208601614773565b601f01601f19169290920160200192915050565b602081526000613a3a6020830184614797565b6000602082840312156147e857600080fd5b5035919050565b6001600160a01b03811681146114c557600080fd5b6000806040838503121561481757600080fd5b8235614822816147ef565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b60405160e081016001600160401b038111828210171561486857614868614830565b60405290565b604051606081016001600160401b038111828210171561486857614868614830565b604051601f8201601f191681016001600160401b03811182821017156148b8576148b8614830565b604052919050565b600082601f8301126148d157600080fd5b81356001600160401b038111156148ea576148ea614830565b6148fd601f8201601f1916602001614890565b81815284602083860101111561491257600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000806080858703121561494557600080fd5b8435935060208501356001600160401b038082111561496357600080fd5b61496f888389016148c0565b9450604087013591508082111561498557600080fd5b614991888389016148c0565b935060608701359150808211156149a757600080fd5b506149b4878288016148c0565b91505092959194509250565b6000602082840312156149d257600080fd5b81356001600160401b03808211156149e957600080fd5b9083019060e082860312156149fd57600080fd5b614a05614846565b823582811115614a1457600080fd5b614a20878286016148c0565b825250602083013582811115614a3557600080fd5b614a41878286016148c0565b602083015250604083013582811115614a5957600080fd5b614a65878286016148c0565b604083015250606083013582811115614a7d57600080fd5b614a89878286016148c0565b606083015250608083013582811115614aa157600080fd5b614aad878286016148c0565b60808301525060a083013560a082015260c083013582811115614acf57600080fd5b614adb878286016148c0565b60c08301525095945050505050565b600080600080600060808688031215614b0257600080fd5b8535614b0d816147ef565b94506020860135614b1d816147ef565b93506040860135925060608601356001600160401b0380821115614b4057600080fd5b818801915088601f830112614b5457600080fd5b813581811115614b6357600080fd5b896020828501011115614b7557600080fd5b9699959850939650602001949392505050565b8035801515811461114157600080fd5b60008060408385031215614bab57600080fd5b82359150614bbb60208401614b88565b90509250929050565b600080600060608486031215614bd957600080fd5b8335614be4816147ef565b92506020840135614bf4816147ef565b929592945050506040919091013590565b60006001600160401b03821115614c1e57614c1e614830565b5060051b60200190565b60008060408385031215614c3b57600080fd5b823591506020808401356001600160401b03811115614c5957600080fd5b8401601f81018613614c6a57600080fd5b8035614c7d614c7882614c05565b614890565b81815260059190911b82018301908381019088831115614c9c57600080fd5b928401925b82841015614cc157614cb284614b88565b82529284019290840190614ca1565b80955050505050509250929050565b60e081526000614ce360e083018a614797565b8281036020840152614cf5818a614797565b90508281036040840152614d098189614797565b90508281036060840152614d1d8188614797565b90508281036080840152614d318187614797565b90508460a084015282810360c0840152614d4b8185614797565b9a9950505050505050505050565b600060208284031215614d6b57600080fd5b81356001600160401b03811115614d8157600080fd5b613ddf848285016148c0565b600060208284031215614d9f57600080fd5b8135613a3a816147ef565b60008060408385031215614dbd57600080fd5b823591506020808401356001600160401b0380821115614ddc57600080fd5b818601915086601f830112614df057600080fd5b8135614dfe614c7882614c05565b81815260059190911b83018401908481019089831115614e1d57600080fd5b8585015b83811015614ed757803585811115614e395760008081fd5b86016060818d03601f1901811315614e515760008081fd5b614e5961486e565b8983013588811115614e6b5760008081fd5b614e798f8c838701016148c0565b825250604083013588811115614e8f5760008081fd5b614e9d8f8c838701016148c0565b828c015250908201359087821115614eb55760008081fd5b614ec38e8b848601016148c0565b604082015285525050918601918601614e21565b508096505050505050509250929050565b60008060408385031215614efb57600080fd5b8235915060208301356001600160401b03811115614f1857600080fd5b614f24858286016148c0565b9150509250929050565b60008060408385031215614f4157600080fd5b50508035926020909101359150565b60008060408385031215614f6357600080fd5b8235614f6e816147ef565b9150614bbb60208401614b88565b60008060208385031215614f8f57600080fd5b82356001600160401b0380821115614fa657600080fd5b818501915085601f830112614fba57600080fd5b813581811115614fc957600080fd5b8660208260051b8501011115614fde57600080fd5b60209290920196919550909350505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561504557603f19888603018452615033858351614797565b94509285019290850190600101615017565b5092979650505050505050565b6000806040838503121561506557600080fd5b82356001600160401b0381111561507b57600080fd5b615087858286016148c0565b95602094909401359450505050565b600080600080608085870312156150ac57600080fd5b84356150b7816147ef565b935060208501356150c7816147ef565b92506040850135915060608501356001600160401b038111156150e957600080fd5b6149b4878288016148c0565b6000806000806080858703121561510b57600080fd5b843593506020850135925060408501356001600160401b038082111561498557600080fd5b6000806040838503121561514357600080fd5b823561514e816147ef565b9150602083013561515e816147ef565b809150509250929050565b600181811c9082168061517d57607f821691505b6020821081036140a757634e487b7160e01b600052602260045260246000fd5b601f8211156114ff57600081815260208120601f850160051c810160208610156151c45750805b601f850160051c820191505b81811015610ed4578281556001016151d0565b81516001600160401b038111156151fc576151fc614830565b6152108161520a8454615169565b8461519d565b602080601f831160018114615245576000841561522d5750858301515b600019600386901b1c1916600185901b178555610ed4565b600085815260208120601f198616915b8281101561527457888601518255948401946001909101908401615255565b50858210156152925787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600083516152b4818460208801614773565b602360f81b90830190815283516152d2816001840160208801614773565b01600101949350505050565b85815260a0602082015260006152f760a0830187614797565b82810360408401526153098187614797565b9050828103606084015261531d8186614797565b905082810360808401526153318185614797565b98975050505050505050565b60006020828403121561534f57600080fd5b8151613a3a816147ef565b634e487b7160e01b600052601160045260246000fd5b6000600182016153825761538261535a565b5060010190565b634e487b7160e01b600052603260045260246000fd5b6000604082018483526020604081850152818551808452606086019150828701935060005b818110156153e25784511515835293830193918301916001016153c4565b5090979650505050505050565b808201808211156108e7576108e761535a565b80820281158282048414176108e7576108e761535a565b818103818111156108e7576108e761535a565b634e487b7160e01b600052601260045260246000fd5b6000826154515761545161542c565b500690565b6000815461546381615169565b6001828116801561547b5760018114615490576154bf565b60ff19841687528215158302870194506154bf565b8560005260208060002060005b858110156154b65781548a82015290840190820161549d565b50505082870194505b5050505092915050565b6e3d913a3930b4ba2fba3cb832911d1160891b815260006154ed600f830185615456565b6a1116113b30b63ab2911d1160a91b815261550b600b820185615456565b61227d60f01b815260020195945050505050565b828152604060208201526000613ddf6040830184614797565b6000808335601e1984360301811261554f57600080fd5b8301803591506001600160401b0382111561556957600080fd5b60200191503681900382131561557e57600080fd5b9250929050565b60008251615597818460208701614773565b75076c4c2c6d6cee4deeadcc85ad2dac2ceca74eae4d8560531b920191825250601601919050565b643230ba309d60d91b815260006155d96005830185615456565b670ed8985cd94d8d0b60c21b815283516155fa816008840160208801614773565b6505258eae4d8560d31b60089290910191820152600e01949350505050565b643230ba309d60d91b815260006156336005830185615456565b670ed8985cd94d8d0b60c21b81528351615654816008840160208801614773565b7f293b6261636b67726f756e642d7265706561743a6e6f2d7265706561743b6261600892909101918201527f636b67726f756e642d73697a653a636f6e7461696e3b6261636b67726f756e6460288201527f2d706f736974696f6e3a63656e7465723b696d6167652d72656e646572696e6760488201527f3a2d7765626b69742d6f7074696d697a652d636f6e74726173743b2d6d732d6960688201527f6e746572706f6c6174696f6e2d6d6f64653a6e6561726573742d6e656967686260888201527f6f723b696d6167652d72656e646572696e673a2d6d6f7a2d63726973702d656460a88201527f6765733b696d6167652d72656e646572696e673a706978656c617465643b223e60c8820152651e17b9bb339f60d11b60e882015260ee01949350505050565b7919185d184e9a5b5859d94bdcdd99cade1b5b0ed8985cd94d8d0b60321b8152600082516157b281601a850160208701614773565b91909101601a0192915050565b683d913730b6b2911d1160b91b81526000613a3a6009830184615456565b602360f81b8152600083516157f9816001850160208801614773565b701116113232b9b1b934b83a34b7b7111d1160791b6001918401918201526158246012820185615456565b61088b60f21b815260020195945050505050565b681134b6b0b3b2911d1160b91b815260006158566009830185615456565b8351615866818360208801614773565b01949350505050565b600080516020615f3783398151915281527f76696577426f783d223020302031323030203132303022207374796c653d226460208201527f6973706c61793a20626c6f636b3b207472616e73666f726d3a207363616c652860408201527f2d312c3129222076657273696f6e3d22312e322220786d6c6e733d226874747060608201527f3a2f2f7777772e77332e6f72672f323030302f737667223e3c696d616765207760808201527f696474683d223132303022206865696768743d22313230302220687265663d2260a0820152600082516159538160c0850160208701614773565b6f111f1e17b4b6b0b3b29f1e17b9bb339f60811b60c093909101928301525060d001919050565b711139bb33afb4b6b0b3b2afb230ba30911d1160711b815281516000906159a8816012850160208701614773565b61088b60f21b6012939091019283015250601401919050565b600080516020615f3783398151915281527f76696577426f783d2230203020313230302031323030222076657273696f6e3d60208201527f22312e322220786d6c6e733d22687474703a2f2f7777772e77332e6f72672f3260408201527f3030302f737667223e3c696d6167652077696474683d2231323030222068656960608201527033b43a1e91189918181110343932b31e9160791b608082015260008251615a73816091850160208701614773565b6f111f1e17b4b6b0b3b29f1e17b9bb339f60811b609193909101928301525060a101919050565b6d1134b6b0b3b2afb230ba30911d1160911b81528151600090615ac481600e850160208701614773565b61088b60f21b600e939091019283015250601001919050565b6c1130ba3a3934b13aba32b9911d60991b81528151600090615b0681600d850160208701614773565b607d60f81b600d939091019283015250600e01919050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000815260008251615b5681601d850160208701614773565b91909101601d0192915050565b848152836020820152608060408201526000615b826080830185614797565b8281036060840152615b948185614797565b979650505050505050565b683d913730b6b2911d1160b91b81526000615bbd600983018a615456565b701116113232b9b1b934b83a34b7b7111d1160791b8152615be1601182018a615456565b6a11161134b6b0b3b2911d1160a91b81529050615c01600b820189615456565b6b1116113130b73732b9111d1160a11b81529050615c22600c820188615456565b7211161132bc3a32b93730b62fb634b735911d1160691b81529050615c4a6013820187615456565b7b11161139b2b63632b92fb332b2afb130b9b4b9afb837b4b73a39911d60211b81528551909150615c8281601c840160208901614773565b7116113332b2afb932b1b4b834b2b73a111d1160711b601c9290910191820152615caf602e820185615456565b61227d60f01b81526002019a9950505050505050505050565b60ff81811683821602908116908181146130125761301261535a565b60ff82811682821603908111156108e7576108e761535a565b60ff81811683821601908111156108e7576108e761535a565b600060ff821660ff8103615d2c57615d2c61535a565b60010192915050565b6000815260008251615d4e816001850160208701614773565b9190910160010192915050565b600082615d6a57615d6a61542c565b500490565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061454290830184614797565b600060208284031215615db457600080fd5b8151613a3a81614740565b606360f81b815260e083901b6001600160e01b03191660018201526880600e6000396000f360b81b60058201528151600090615e0281600e850160208701614773565b91909101600e019392505050565b60008251615e22818460208701614773565b919091019291505056fe3c7376672077696474683d223136303022206865696768743d2231363030222076696577426f783d2230203020313630302031363030222076657273696f6e3d22312e322220786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f73766722207374796c653d226261636b67726f756e642d636f6c6f723a20234142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef3c7376672077696474683d223130302522206865696768743d22313030252220a264697066735822122020ca10d25cc2579867a12aa3307559f37a93dd8bba2ce9793f5ce20ade52099564736f6c63430008110033
Deployed Bytecode Sourcemap
1711:28903:21:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5655:607:16;;;;;;;;;;-1:-1:-1;5655:607:16;;;;;:::i;:::-;;:::i;:::-;;;565:14:22;;558:22;540:41;;528:2;513:18;5655:607:16;;;;;;;;11163:98;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;13050:200::-;;;;;;;;;;-1:-1:-1;13050:200:16;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1697:32:22;;;1679:51;;1667:2;1652:18;13050:200:16;1533:203:22;12613:376:16;;;;;;;;;;-1:-1:-1;12613:376:16;;;;;:::i;:::-;;:::i;:::-;;27917:690:21;;;;;;;;;;-1:-1:-1;27917:690:21;;;;;:::i;:::-;;:::i;27224:144::-;;;;;;;;;;-1:-1:-1;27224:144:21;;;;;:::i;:::-;;:::i;6909:429::-;;;;;;;;;;-1:-1:-1;6909:429:21;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;;7129:33:22;;;7111:52;;7099:2;7084:18;6909:429:21;6967:202:22;4738:309:16;;;;;;;;;;-1:-1:-1;5000:12:16;;4791:7;4984:13;:28;-1:-1:-1;;4984:46:16;4738:309;;;7320:25:22;;;7308:2;7293:18;4738:309:16;7174:177:22;29430:212:21;;;;;;;;;;-1:-1:-1;29430:212:21;;;;;:::i;:::-;;:::i;22057:2739:16:-;;;;;;;;;;-1:-1:-1;22057:2739:16;;;;;:::i;:::-;;:::i;29141:283:21:-;;;;;;;;;;-1:-1:-1;29141:283:21;;;;;:::i;:::-;;:::i;4607:38::-;;;;;;;;;;-1:-1:-1;4607:38:21;;;;;;;;7344:1036;;;;;;:::i;:::-;;:::i;4652:752::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;27500:168::-;;;;;;;;;;;;;:::i;26991:104::-;;;;;;;;;;;;;:::i;13914:179:16:-;;;;;;;;;;-1:-1:-1;13914:179:16;;;;;:::i;:::-;;:::i;27120:98:21:-;;;;;;;;;;-1:-1:-1;27120:98:21;;;;;:::i;:::-;;:::i;9213:219::-;;;;;;;;;;-1:-1:-1;9213:219:21;;;;;:::i;:::-;;:::i;26862:123::-;;;;;;;;;;;;;:::i;11245:6456::-;;;;;;;;;;-1:-1:-1;11245:6456:21;;;;;:::i;:::-;;:::i;10959:142:16:-;;;;;;;;;;-1:-1:-1;10959:142:16;;;;;:::i;:::-;;:::i;20073:2027:21:-;;;;;;;;;;-1:-1:-1;20073:2027:21;;;;;:::i;:::-;;:::i;4456:37::-;;;;;;;;;;;;;;;;4542:59;;;;;;;;;;;;;:::i;6321:221:16:-;;;;;;;;;;-1:-1:-1;6321:221:16;;;;;:::i;:::-;;:::i;1831:101:0:-;;;;;;;;;;;;;:::i;29661:570:21:-;;;;;;;;;;-1:-1:-1;29661:570:21;;;;;:::i;:::-;;:::i;27702:209::-;;;;;;;;;;-1:-1:-1;27702:209:21;;;;;:::i;:::-;;:::i;8386:821::-;;;;;;;;;;-1:-1:-1;8386:821:21;;;;;:::i;:::-;;:::i;1201:85:0:-;;;;;;;;;;;;;:::i;11325:102:16:-;;;;;;;;;;;;;:::i;30369:243:21:-;;;;;;;;;;-1:-1:-1;30369:243:21;;;;;:::i;:::-;;:::i;13317:303:16:-;;;;;;;;;;-1:-1:-1;13317:303:16;;;;;:::i;:::-;;:::i;4499:37:21:-;;;;;;;;;;;;;;;;407:308:9;;;;;;;;;;-1:-1:-1;407:308:9;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;17707:2360:21:-;;;;;;;;;;-1:-1:-1;17707:2360:21;;;;;:::i;:::-;;:::i;14159:388:16:-;;;;;;;;;;-1:-1:-1;14159:388:16;;;;;:::i;:::-;;:::i;4257:70:21:-;;;;;;;;;;-1:-1:-1;4257:70:21;;;;-1:-1:-1;;;;;4257:70:21;;;22106:3362;;;;;;;;;;-1:-1:-1;22106:3362:21;;;;;:::i;:::-;;:::i;4410:40::-;;;;;;;;;;;;4446:4;4410:40;;26569:204;;;;;;;;;;-1:-1:-1;26569:204:21;;;;;:::i;:::-;;:::i;28613:522::-;;;;;;;;;;-1:-1:-1;28613:522:21;;;;;:::i;:::-;;:::i;25474:1089::-;;;;;;;;;;;;;:::i;13686:162:16:-;;;;;;;;;;-1:-1:-1;13686:162:16;;;;;:::i;:::-;-1:-1:-1;;;;;13806:25:16;;;13783:4;13806:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;13686:162;4333:71:21;;;;;;;;;;-1:-1:-1;4333:71:21;;;;-1:-1:-1;;;;;4333:71:21;;;9438:109;;;;;;;;;;-1:-1:-1;9438:109:21;;;;;:::i;:::-;-1:-1:-1;;;;;9523:17:21;9497:7;9523:17;;;:7;:17;;;;;;;9438:109;2081:198:0;;;;;;;;;;-1:-1:-1;2081:198:0;;;;;:::i;:::-;;:::i;30237:126:21:-;;;;;;;;;;-1:-1:-1;30237:126:21;;;;;:::i;:::-;;:::i;10606:391::-;;;;;;;;;;-1:-1:-1;10606:391:21;;;;;:::i;:::-;;:::i;5655:607:16:-;5740:4;-1:-1:-1;;;;;;;;;6035:25:16;;;;:101;;-1:-1:-1;;;;;;;;;;6111:25:16;;;6035:101;:177;;;-1:-1:-1;;;;;;;;;;6187:25:16;;;6035:177;6016:196;5655:607;-1:-1:-1;;5655:607:16:o;11163:98::-;11217:13;11249:5;11242:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11163:98;:::o;13050:200::-;13118:7;13142:16;13150:7;13142;:16::i;:::-;13137:64;;13167:34;;-1:-1:-1;;;13167:34:16;;;;;;;;;;;13137:64;-1:-1:-1;13219:24:16;;;;:15;:24;;;;;;-1:-1:-1;;;;;13219:24:16;;13050:200::o;12613:376::-;12685:13;12701:16;12709:7;12701;:16::i;:::-;12685:32;-1:-1:-1;32962:10:16;-1:-1:-1;;;;;12732:28:16;;;12728:172;;12779:44;12796:5;32962:10;13686:162;:::i;12779:44::-;12774:126;;12850:35;;-1:-1:-1;;;12850:35:16;;;;;;;;;;;12774:126;12910:24;;;;:15;:24;;;;;;:29;;-1:-1:-1;;;;;;12910:29:16;-1:-1:-1;;;;;12910:29:16;;;;;;;;;12954:28;;12910:24;;12954:28;;;;;;;12675:314;12613:376;;:::o;27917:690:21:-;28111:10;28090:17;28098:8;28090:7;:17::i;:::-;-1:-1:-1;;;;;28090:31:21;;28082:40;;;;;;28133:18;;;;:8;:18;;;;;:52;28176:9;28133:18;:52;:::i;:::-;-1:-1:-1;28195:18:21;;;;:8;:18;;;;;:38;;:48;28236:7;28195:38;:48;:::i;:::-;-1:-1:-1;28253:18:21;;;;:8;:18;;;;;:39;;:50;28295:8;28253:39;:50;:::i;:::-;;28314:17;28358:9;28372:19;28382:8;28372:9;:19::i;:::-;28341:51;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;28341:51:21;;;;;;;;;28403:18;;;;:8;28341:51;28403:18;;28341:51;;-1:-1:-1;28403:43:21;;:49;28341:51;28403:43;:49;:::i;:::-;;28468:132;28499:8;28521:9;28544:7;28565:8;28587:3;28468:132;;;;;;;;;;:::i;:::-;;;;;;;;28072:535;27917:690;;;;:::o;27224:144::-;1094:13:0;:11;:13::i;:::-;27333:28:21;;27348:13;;27333:12:::1;::::0;;;:28:::1;::::0;:12;:28:::1;:::i;:::-;-1:-1:-1::0;27333:28:21::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;:::i;:::-;-1:-1:-1::0;27333:28:21::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;:::i;:::-;-1:-1:-1::0;27333:28:21::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;:::i;:::-;-1:-1:-1::0;27333:28:21::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;:::i;:::-;-1:-1:-1::0;27333:28:21::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;:::i;:::-;-1:-1:-1::0;;;;27224:144:21:o;6909:429::-;7121:10;;7068:6;;-1:-1:-1;;;;;7121:10:21;7107;:24;;:141;;-1:-1:-1;7158:10:21;;7151:73;;-1:-1:-1;;;7151:73:21;;;;;7320:25:22;;;-1:-1:-1;;;;;7151:97:21;;;;7158:10;;7151:26;;7293:18:22;;7151:73:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;7151:97:21;;7107:141;7086:172;;;;;;-1:-1:-1;;;;;7269:13:21;;;;;;:7;:13;;;;;:15;;;;;;:::i;:::-;;;;-1:-1:-1;;;;7301:30:21;6909:429;-1:-1:-1;;;;;;;6909:429:21:o;29430:212::-;29526:17;29534:8;29526:7;:17::i;:::-;-1:-1:-1;;;;;29512:31:21;:10;-1:-1:-1;;;;;29512:31:21;;29504:40;;;;;;29554:21;;;;:11;:21;;;;;;;;;:32;;-1:-1:-1;;29554:32:21;;;;;;;;;;29602:33;;22559:25:22;;;22600:18;;;22593:50;29602:33:21;;22532:18:22;29602:33:21;;;;;;;;29430:212;;:::o;22057:2739:16:-;22186:27;22216;22235:7;22216:18;:27::i;:::-;22186:57;;22299:4;-1:-1:-1;;;;;22258:45:16;22274:19;-1:-1:-1;;;;;22258:45:16;;22254:86;;22312:28;;-1:-1:-1;;;22312:28:16;;;;;;;;;;;22254:86;22352:27;20823:21;;;20654:15;20864:4;20857:36;20945:4;20929:21;;21033:26;;32962:10;21768:30;;;-1:-1:-1;;;;;21470:26:16;;21747:19;;;21744:55;22528:173;;22614:43;22631:4;32962:10;13686:162;:::i;22614:43::-;22609:92;;22666:35;;-1:-1:-1;;;22666:35:16;;;;;;;;;;;22609:92;-1:-1:-1;;;;;22716:16:16;;22712:52;;22741:23;;-1:-1:-1;;;22741:23:16;;;;;;;;;;;22712:52;22907:15;22904:157;;;23045:1;23024:19;23017:30;22904:157;-1:-1:-1;;;;;23431:24:16;;;;;;;:18;:24;;;;;;23429:26;;-1:-1:-1;;23429:26:16;;;23499:22;;;;;;23497:24;;23429:26;23497:24;;;23814:142;23518:2;23897:45;23450:4;23518:2;23922:19;23897:14;:45::i;:::-;-1:-1:-1;;;23870:72:16;23814:18;:142::i;:::-;23785:26;;;;:17;:26;;;;;:171;;;;-1:-1:-1;;;24073:46:16;;:51;;24069:616;;24176:1;24166:11;;24144:19;24297:30;;;:17;:30;;;;;;:35;;24293:378;;24433:13;;24418:11;:28;24414:239;;24578:30;;;;:17;:30;;;;;:52;;;24414:239;24126:559;24069:616;24729:7;24725:2;-1:-1:-1;;;;;24710:27:16;24719:4;-1:-1:-1;;;;;24710:27:16;-1:-1:-1;;;;;;;;;;;24710:27:16;;;;;;;;;24747:42;22176:2620;;;22057:2739;;;:::o;29141:283:21:-;29242:17;29250:8;29242:7;:17::i;:::-;-1:-1:-1;;;;;29228:31:21;:10;-1:-1:-1;;;;;29228:31:21;;29220:40;;;;;;29275:9;29270:101;3768:2;29290:1;:14;29270:101;;;29351:6;29358:1;29351:9;;;;;;;;:::i;:::-;;;;;;;;;;;;29325:20;;;;:10;:20;;;;;;:23;;;;;;;;;;:35;;-1:-1:-1;;29325:35:21;;;;;;;;;;:23;29306:3;29325:23;29306:3;:::i;:::-;;;;29270:101;;;;29386:31;29400:8;29410:6;29386:31;;;;;;;:::i;7344:1036::-;7434:7;2261:21:1;:19;:21::i;:::-;26823:14:21::1;:12;:14::i;:::-;26815:23;;;::::0;::::1;;7453:19:::2;7475:14;:12;:14::i;:::-;7513:10;7507:17;::::0;;;:5:::2;:17;::::0;;;;;7453:36;;-1:-1:-1;7537:3:21::2;::::0;7507:26:::2;::::0;7527:6;;7507:26:::2;:::i;:::-;:33;;7499:42;;;::::0;::::2;;3818:2;7559:6;:24;;:38;;;;;7596:1;7587:6;:10;7559:38;7551:47;;;::::0;::::2;;4446:4;7616:20;7630:6:::0;7616:11;:20:::2;:::i;:::-;:33;;7608:42;;;::::0;::::2;;7668:10;7682:9;7668:23;7660:32;;;::::0;::::2;;7755:10;7703:16;7747:19:::0;;;:7:::2;:19;::::0;;;;;7780:11;;7776:496:::2;;7822:6;7811:7;:17;7807:384;;7871:7;7859:9;;:19;;;;:::i;:::-;7848:30;;7940:8;7927:9;;7918:6;:18;;;;:::i;:::-;7917:31;;;;:::i;:::-;7904:9;:44;;7896:53;;;::::0;::::2;;7975:10;7989:1;7967:19:::0;;;:7:::2;:19;::::0;;;;:23;7776:496:::2;;7807:384;8052:6;8040:9;;:18;;;;:::i;:::-;8029:29;;8120:8;8107:9;;8098:6;:18;;;;:::i;:::-;8097:31;;;;:::i;:::-;8084:9;:44;;8076:53;;;::::0;::::2;;8155:10;8147:19;::::0;;;:7:::2;:19;::::0;;;;:29;;8170:6;;8147:19;:29:::2;::::0;8170:6;;8147:29:::2;:::i;:::-;::::0;;;-1:-1:-1;7776:496:21::2;::::0;-1:-1:-1;7776:496:21::2;;8251:9;::::0;8242:18:::2;::::0;:6;:18:::2;:::i;:::-;8229:9;:31;;8221:40;;;::::0;::::2;;8288:10;8282:17;::::0;;;:5:::2;:17;::::0;;;;:27;;8303:6;;8282:17;:27:::2;::::0;8303:6;;8282:27:::2;:::i;:::-;::::0;;;-1:-1:-1;8319:25:21::2;::::0;-1:-1:-1;8325:10:21::2;8337:6:::0;8319:5:::2;:25::i;:::-;-1:-1:-1::0;;1716:1:1;2809:7;:22;8362:11:21;7344:1036;-1:-1:-1;;7344:1036:21:o;2303:20:1:-;7344:1036:21;;;:::o;4652:752::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;27500:168::-;27557:21;27596:11;27588:20;;;;;;27644:6;;27618:43;;-1:-1:-1;;;;;27644:6:21;27653:7;27618:17;:43::i;:::-;27529:139;27500:168::o;26991:104::-;1094:13:0;:11;:13::i;:::-;27070:18:21::1;::::0;;-1:-1:-1;;27048:40:21;::::1;27070:18;::::0;;::::1;27069:19;27048:40;::::0;;26991:104::o;13914:179:16:-;14047:39;14064:4;14070:2;14074:7;14047:39;;;;;;;;;;;;:16;:39::i;:::-;13914:179;;;:::o;27120:98:21:-;1094:13:0;:11;:13::i;:::-;27193:7:21::1;:18;27203:8:::0;27193:7;:18:::1;:::i;:::-;;27120:98:::0;:::o;9213:219::-;9290:4;9308:11;9305:121;;;-1:-1:-1;9341:19:21;;;;:9;:19;;;;;;;;9334:26;;9305:121;-1:-1:-1;;9398:17:21;;;;:7;:17;;;;;;;;;9213:219::o;26862:123::-;26907:4;4446;26930:14;:12;:14::i;:::-;:26;:48;;;;-1:-1:-1;26960:18:21;;;;26930:48;26923:55;;26862:123;:::o;11245:6456::-;11331:13;11368:17;11376:8;11368:7;:17::i;:::-;11360:26;;;;;;11461:22;11486:38;11509:14;3768:2;11522:1;11509:14;:::i;:::-;11486:22;:38::i;:::-;11559:25;;;3768:2;11559:25;;;;;;;;;11461:63;;-1:-1:-1;11535:21:21;;11559:25;;;;;;;;;;;-1:-1:-1;11559:25:21;11535:49;;11600:9;11595:5651;3768:2;11615:1;:14;11595:5651;;;11650:18;11671:4;11676:1;11671:7;;;;;;;;:::i;:::-;;;;;;;11650:28;;11703:1;11699;11695;:5;;;;:::i;:::-;:9;:47;;;;-1:-1:-1;11708:22:21;;;;:12;:22;;;;;;;;:25;;;;;;;;;;;:34;11695:47;11692:5544;;;11789:1;11771:5;11777:1;11771:8;;;;;;;:::i;:::-;;:15;:19;;;;:::i;:::-;11761:4;11766:1;11761:7;;;;;;;;:::i;:::-;;;;;;:29;;;;;11692:5544;;;11829:22;11861;11874:8;11861:12;:22::i;:::-;:32;;;11829:65;;;-1:-1:-1;11912:18:21;4446:4;11829:65;12087:8;12125:12;12136:1;12087:8;12125:12;:::i;:::-;11997:166;;;;;;24374:19:22;;;;24409:12;;24402:28;;;;24446:12;;;24439:28;24483:12;;11997:166:21;;;;;;;;;;;;11962:223;;;;;;11933:270;;:282;;;;:::i;:::-;11912:303;;12247:24;12257:10;12269:1;12247:9;:24::i;:::-;12234:37;;12299:10;12289:4;12294:1;12289:7;;;;;;;;:::i;:::-;;;;;;:20;;;;;12327:10;12358:1;12340:5;12346:1;12340:8;;;;;;;:::i;:::-;;:15;:19;;;;:::i;:::-;12382:20;;;;:10;:20;;;;;;;;:23;;;;;;;;;12327:32;;-1:-1:-1;12382:23:21;;:31;;:23;:31;12378:4844;;12440:1;12445:2;12440:7;:24;;;;;12451:4;12456:1;12451:7;;;;;;;;:::i;:::-;;;;;;;12462:2;12451:13;12440:24;12436:2580;;;12501:5;12491:4;12496:1;12491:7;;;;;;;;:::i;:::-;;;;;;;;;;;:15;;;;12535:20;;;;:10;:20;;;;;;12556:1;12535:23;;;;;;;;;;;:32;;;;12532:51;;12579:2;12569:4;12574:1;12569:7;;;;;;;;:::i;:::-;;;;;;:12;;;;;12532:51;12378:4844;;12436:2580;12616:1;12621:2;12616:7;:23;;;;;12627:4;12632:1;12627:7;;;;;;;;:::i;:::-;;;;;;;12638:1;12627:12;12616:23;12612:2404;;;12677:5;12667:4;12672:1;12667:7;;;;;;;;:::i;:::-;;;;;;;;;;;:15;;;;12711:20;;;;:10;:20;;;;;;12732:1;12711:23;;;;;;;;;;;:32;;;;12708:50;;12755:1;12745:4;12750:1;12745:7;;;;;;;;:::i;12612:2404::-;12815:1;12820:2;12815:7;:23;;;;;12826:4;12831:1;12826:7;;;;;;;;:::i;:::-;;;;;;;12837:1;12826:12;12815:23;12811:2205;;;12876:5;12866:4;12871:1;12866:7;;;;;;;;:::i;:::-;;;;;;;;;;;:15;;;;12910:20;;;;:10;:20;;;;;;12931:2;12910:24;;;;;;;;;;;:33;;;;12907:52;;12956:1;12945:4;12950:2;12945:8;;;;;;;;:::i;:::-;;;;;;:12;;;;;12907:52;12987:20;;;;:10;:20;;;;;;;;13008:1;12987:23;;;;;;;;;;:32;;;;12984:50;;13031:1;13021:4;13026:1;13021:7;;;;;;;;:::i;:::-;;;;;;:11;;;;;12984:50;13062:20;;;;:10;:20;;;;;;;;13083:1;13062:23;;;;;;;;;;:32;;;;13059:50;;13106:1;13096:4;13101:1;13096:7;;;;;;;;:::i;12811:2205::-;13166:1;13171:2;13166:7;:23;;;;;13177:4;13182:1;13177:7;;;;;;;;:::i;:::-;;;;;;;13188:1;13177:12;13166:23;13162:1854;;;13227:5;13217:4;13222:1;13217:7;;;;;;;;:::i;:::-;;;;;;;;;;;:15;;;;13261:20;;;;:10;:20;;;;;;13282:2;13261:24;;;;;;;;;;;:33;;;;13258:52;;13307:1;13296:4;13301:2;13296:8;;;;;;;;:::i;:::-;;;;;;:12;;;;;13258:52;13338:20;;;;:10;:20;;;;;;;;13359:1;13338:23;;;;;;;;;;:32;;;;13335:50;;13382:1;13372:4;13377:1;13372:7;;;;;;;;:::i;13162:1854::-;13418:1;13423:2;13418:7;:23;;;;;13429:4;13434:1;13429:7;;;;;;;;:::i;:::-;;;;;;;13440:1;13429:12;13418:23;13414:1602;;;13479:5;13469:4;13474:1;13469:7;;;;;;;;:::i;:::-;;;;;;;;;;;:15;;;;13513:20;;;;:10;:20;;;;;;13534:2;13513:24;;;;;;;;;;;:33;;;;13510:52;;13559:1;13548:4;13553:2;13548:8;;;;;;;;:::i;:::-;;;;;;:12;;;;;13510:52;13590:20;;;;:10;:20;;;;;;;;13611:1;13590:23;;;;;;;;;;:32;;;;13587:50;;13634:1;13624:4;13629:1;13624:7;;;;;;;;:::i;13414:1602::-;13670:1;13675:2;13670:7;:23;;;;;13681:4;13686:1;13681:7;;;;;;;;:::i;:::-;;;;;;;13692:1;13681:12;13670:23;13666:1350;;;13731:5;13721:4;13726:1;13721:7;;;;;;;;:::i;:::-;;;;;;;;;;;:15;;;;13765:20;;;;:10;:20;;;;;;13786:2;13765:24;;;;;;;;;;;:33;;;;13762:52;;13811:1;13800:4;13805:2;13800:8;;;;;;;;:::i;:::-;;;;;;:12;;;;;13762:52;13842:20;;;;:10;:20;;;;;;;;13863:1;13842:23;;;;;;;;;;:32;;;;13839:50;;13886:1;13876:4;13881:1;13876:7;;;;;;;;:::i;13666:1350::-;13946:1;13951:2;13946:7;:23;;;;;13957:4;13962:1;13957:7;;;;;;;;:::i;:::-;;;;;;;13968:1;13957:12;13946:23;13942:1074;;;14007:5;13997:4;14002:1;13997:7;;;;;;;;:::i;:::-;;;;;;;;;;;:15;;;;14041:20;;;;:10;:20;;;;;;14062:2;14041:24;;;;;;;;;;;:33;;;;14038:52;;14087:1;14076:4;14081:2;14076:8;;;;;;;;:::i;:::-;;;;;;:12;;;;;14038:52;14118:20;;;;:10;:20;;;;;;;;14139:1;14118:23;;;;;;;;;;:32;;;;14115:50;;14162:1;14152:4;14157:1;14152:7;;;;;;;;:::i;13942:1074::-;14198:1;14203:2;14198:7;:23;;;;;14209:4;14214:1;14209:7;;;;;;;;:::i;:::-;;;;;;;14220:1;14209:12;14198:23;14194:822;;;14259:5;14249:4;14254:1;14249:7;;;;;;;;:::i;:::-;;;;;;;;;;;:15;;;;14293:20;;;;:10;:20;;;;;;14314:2;14293:24;;;;;;;;;;;:33;;;;14290:52;;14339:1;14328:4;14333:2;14328:8;;;;;;;;:::i;:::-;;;;;;:12;;;;;14290:52;14370:20;;;;:10;:20;;;;;;;;14391:1;14370:23;;;;;;;;;;:32;;;;14367:50;;14414:1;14404:4;14409:1;14404:7;;;;;;;;:::i;14194:822::-;14450:1;14455:2;14450:7;:24;;;;;14461:4;14466:1;14461:7;;;;;;;;:::i;:::-;;;;;;;14472:2;14461:13;14450:24;14446:570;;;14512:5;14502:4;14507:1;14502:7;;;;;;;;:::i;:::-;;;;;;;;;;;:15;;;;14546:20;;;;:10;:20;;;;;;14567:2;14546:24;;;;;;;;;;;:33;;;;14543:52;;14592:1;14581:4;14586:2;14581:8;;;;;;;;:::i;:::-;;;;;;:12;;;;;14543:52;14623:20;;;;:10;:20;;;;;;;;14644:1;14623:23;;;;;;;;;;:32;;;;14620:50;;14667:1;14657:4;14662:1;14657:7;;;;;;;;:::i;14446:570::-;14703:1;14708:2;14703:7;:24;;;;;14714:4;14719:1;14714:7;;;;;;;;:::i;:::-;;;;;;;14725:2;14714:13;14703:24;14699:317;;;14765:5;14755:4;14760:1;14755:7;;;;;;;;:::i;:::-;;;;;;;;;;;:15;;;;14799:20;;;;:10;:20;;;;;;14820:2;14799:24;;;;;;;;;;;:33;;;;14796:52;;14845:1;14834:4;14839:2;14834:8;;;;;;;;:::i;:::-;;;;;;:12;;;;;14796:52;14876:20;;;;:10;:20;;;;;;;;14897:1;14876:23;;;;;;;;;;:32;;;;14873:50;;14920:1;14910:4;14915:1;14910:7;;;;;;;;:::i;14699:317::-;14988:5;14978:4;14983:1;14978:7;;;;;;;;:::i;12378:4844::-;15088:1;15093:2;15088:7;:25;;;;;15099:4;15104:2;15099:8;;;;;;;;:::i;:::-;;;;;;;15111:2;15099:14;15088:25;15084:129;;;15143:20;;;;:10;:20;;;;;;;;15164:1;15143:23;;;;;;;;;;:32;;;;15140:51;;15187:2;15177:4;15182:1;15177:7;;;;;;;;:::i;:::-;;;;;;:12;;;;;15140:51;15238:1;15243:2;15238:7;15234:1970;;15276:4;15281:2;15276:8;;;;;;;;:::i;:::-;;;;;;;15288:1;15276:13;15272:1910;;15324:20;;;;:10;:20;;;;;;;;15345:1;15324:23;;;;;;;;;;:32;;;;15321:50;;15368:1;15358:4;15363:1;15358:7;;;;;;;;:::i;15272:1910::-;15407:4;15412:2;15407:8;;;;;;;;:::i;:::-;;;;;;;15419:1;15407:13;15403:1779;;15455:20;;;;:10;:20;;;;;;;;15476:2;15455:24;;;;;;;;;;:33;;;;15452:52;;15501:1;15490:4;15495:2;15490:8;;;;;;;;:::i;15403:1779::-;15699:4;15704:2;15699:8;;;;;;;;:::i;:::-;;;;;;;15711:1;15699:13;15695:1487;;15747:20;;;;:10;:20;;;;;;;;15768:2;15747:24;;;;;;;;;;:33;;;;15744:52;;15793:1;15782:4;15787:2;15782:8;;;;;;;;:::i;15695:1487::-;15912:4;15917:2;15912:8;;;;;;;;:::i;:::-;;;;;;;15924:1;15912:13;15908:1274;;15960:20;;;;:10;:20;;;;;;;;15981:2;15960:24;;;;;;;;;;:33;;;;15957:52;;16006:1;15995:4;16000:2;15995:8;;;;;;;;:::i;15908:1274::-;16125:4;16130:2;16125:8;;;;;;;;:::i;:::-;;;;;;;16137:1;16125:13;16121:1061;;16173:20;;;;:10;:20;;;;;;;;16194:2;16173:24;;;;;;;;;;:33;;;;16170:52;;16219:1;16208:4;16213:2;16208:8;;;;;;;;:::i;16121:1061::-;16338:4;16343:2;16338:8;;;;;;;;:::i;:::-;;;;;;;16350:1;16338:13;16334:848;;16386:20;;;;:10;:20;;;;;;;;16407:2;16386:24;;;;;;;;;;:33;;;;16383:52;;16432:1;16421:4;16426:2;16421:8;;;;;;;;:::i;16334:848::-;16551:4;16556:2;16551:8;;;;;;;;:::i;:::-;;;;;;;16563:1;16551:13;16547:635;;16599:20;;;;:10;:20;;;;;;;;16620:2;16599:24;;;;;;;;;;:33;;;;16596:52;;16645:1;16634:4;16639:2;16634:8;;;;;;;;:::i;16547:635::-;16764:4;16769:2;16764:8;;;;;;;;:::i;:::-;;;;;;;16776:2;16764:14;16760:422;;16813:20;;;;:10;:20;;;;;;;;16834:2;16813:24;;;;;;;;;;:33;;;;16810:52;;16859:1;16848:4;16853:2;16848:8;;;;;;;;:::i;16760:422::-;16978:4;16983:2;16978:8;;;;;;;;:::i;:::-;;;;;;;16990:2;16978:14;16974:208;;17027:20;;;;:10;:20;;;;;;;;17048:2;17027:24;;;;;;;;;;:33;;;;17024:52;;17073:1;17062:4;17067:2;17062:8;;;;;;;;:::i;:::-;;;;;;:12;;;;;17024:52;17108:20;;;;:10;:20;;;;;;;;17129:1;17108:23;;;;;;;;;;:32;;;;17105:50;;17152:1;17142:4;17147:1;17142:7;;;;;;;;:::i;:::-;;;;;;:11;;;;;17105:50;11811:5425;;;11692:5544;-1:-1:-1;11631:3:21;;;;:::i;:::-;;;;11595:5651;;;;17261:9;17256:404;17280:4;:11;17276:1;:15;17256:404;;;17326:2;17316:4;17321:1;17316:7;;;;;;;;:::i;:::-;;;;;;;:12;17312:160;;;17348:26;;;;;;;;;;;;-1:-1:-1;;;17348:26:21;;;;;;:9;;:20;:26::i;:::-;17312:160;;;17409:3;17399:4;17404:1;17399:7;;;;;;;;:::i;:::-;;;;;;;:13;17395:77;;;17432:25;;;;;;;;;;;;-1:-1:-1;;;17432:25:21;;;;;;:9;;:20;:25::i;:::-;17499:3;17489:4;17494:1;17489:7;;;;;;;;:::i;:::-;;;;;;;:13;17485:165;;;17522:27;;;;;;;;;;;;-1:-1:-1;;;17522:27:21;;;;;;:9;;:20;:27::i;:::-;17485:165;;;17588:47;17615:18;17625:4;17630:1;17625:7;;;;;;;;:::i;:::-;;;;;;;17615:9;:18::i;:::-;17588:9;;:20;:47::i;:::-;17293:3;;;;:::i;:::-;;;;17256:404;;;-1:-1:-1;17684:9:21;;11245:6456;-1:-1:-1;;;11245:6456:21:o;10959:142:16:-;11023:7;11065:27;11084:7;11065:18;:27::i;20073:2027:21:-;20163:13;20192:26;20221:34;20244:10;20221:22;:34::i;:::-;20192:63;;20265:29;;;;;;;;;;;;;;-1:-1:-1;;;20265:29:21;;;:13;:24;;:29;;;;:::i;:::-;20326:13;20305:12;20326:17;;;;;;;;20416:1;20326:17;20305:12;20344:55;20363:35;20384:5;20391:2;20395;20363:20;:35::i;:::-;20344:18;:55::i;:::-;20326:74;;;;;;;;;;;;;:79;;20320:93;;;;;:::i;:::-;20462:2;20427:12;20448:17;;;:13;:17;;20320:97;-1:-1:-1;20320:97:21;-1:-1:-1;20538:1:21;;-1:-1:-1;20448:17:21;20427:12;20466:55;20485:35;20506:5;20513:2;20517;20485:20;:35::i;20466:55::-;20448:74;;;;;;;;;;;;;:79;;20442:93;;;;;:::i;:::-;20584:2;20549:12;20570:17;;;:13;:17;;20442:97;-1:-1:-1;20442:97:21;-1:-1:-1;20660:1:21;;-1:-1:-1;20570:17:21;20549:12;20588:55;20607:35;20628:5;20635:2;20639;20607:20;:35::i;20588:55::-;20570:74;;;;;;;;;;;;;:79;;20564:93;;;;;:::i;:::-;20706:2;20671:12;20692:17;;;:13;:17;;20564:97;-1:-1:-1;20564:97:21;-1:-1:-1;20782:1:21;;-1:-1:-1;20692:17:21;20671:12;20710:55;20729:35;20750:5;20757:2;20761;20729:20;:35::i;20710:55::-;20692:74;;;;;;;;;;;;;:79;;20686:93;;;;;:::i;:::-;;;:97;20671:112;;20799:9;20794:1261;3768:2;20814:1;:14;20794:1261;;;20849:22;20874:99;20910:49;20931:5;20939;:1;20943;20939:5;:::i;:::-;20948;:1;20952;20948:5;:::i;:::-;20947:11;;20957:1;20947:11;:::i;:::-;20910:20;:49::i;20874:99::-;20997:16;;;;:13;:16;;;;;;;;20849:124;;;;;20997:32;;;;;;;;;20991:51;;20849:124;;-1:-1:-1;21045:1:21;;20991:51;;;:::i;:::-;;;:55;20987:1057;;;21067:317;21198:11;21210:1;21198:14;;;;;;;;:::i;:::-;;;;;;;;;21277:16;;;:13;:16;;;;;;:32;;;;;;;;;21113:253;;;;21198:14;;;;;21277:32;21113:253;;:::i;:::-;;;;-1:-1:-1;;21113:253:21;;;;;;;;;21067:13;;:24;:317::i;:::-;21407:1;21412:2;21407:7;:53;;;;;21419:7;:18;;;;;21430:7;21419:18;:29;;;;;21441:7;21419:29;:40;;;;;21452:7;21419:40;21403:627;;;21483:29;;;;;;;;;;;;-1:-1:-1;;;21483:29:21;;;;;;:13;;:24;:29::i;:::-;21403:627;;;21541:1;21546:2;21541:7;:42;;;;;21553:7;:18;;;;;21564:7;21553:18;:29;;;;;21575:7;21553:29;21537:493;;;21606:29;;;;;;;;;;;;-1:-1:-1;;;21606:29:21;;;;;;:13;;:24;:29::i;21537:493::-;21664:1;21669:2;21664:7;:31;;;;;21676:7;:18;;;;;21687:7;21676:18;21660:370;;;21718:29;;;;;;;;;;;;-1:-1:-1;;;21718:29:21;;;;;;:13;;:24;:29::i;21660:370::-;21776:1;21781:2;21776:7;:18;;;;;21787:7;21776:18;21772:258;;;21817:29;;;;;;;;;;;;-1:-1:-1;;;21817:29:21;;;;;;:13;;:24;:29::i;21772:258::-;21875:1;21880:2;21875:7;21871:159;;21906:29;;;;;;;;;;;;-1:-1:-1;;;21906:29:21;;;;;;:13;;:24;:29::i;21871:159::-;21982:29;;;;;;;;;;;;-1:-1:-1;;;21982:29:21;;;;;;:13;;:24;:29::i;:::-;-1:-1:-1;20830:3:21;;;;:::i;:::-;;;;20794:1261;;;-1:-1:-1;22079:13:21;;20073:2027;-1:-1:-1;;;;;;20073:2027:21:o;4542:59::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;6321:221:16:-;6385:7;-1:-1:-1;;;;;6408:19:16;;6404:60;;6436:28;;-1:-1:-1;;;6436:28:16;;;;;;;;;;;6404:60;-1:-1:-1;;;;;;6481:25:16;;;;;:18;:25;;;;;;-1:-1:-1;;;;;6481:54:16;;6321:221::o;1831:101:0:-;1094:13;:11;:13::i;:::-;1895:30:::1;1922:1;1895:18;:30::i;:::-;1831:101::o:0;29661:570:21:-;1094:13:0;:11;:13::i;:::-;29810:6:21::1;:13;29781:5;29787:11;29781:18;;;;;;;:::i;:::-;;:25:::0;:42:::1;29773:51;;;::::0;::::1;;29834:29;29880:6;:13;-1:-1:-1::0;;;;;29866:28:21::1;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;29866:28:21::1;;29834:60;;29909:9;29904:249;29928:6;:13;29924:1;:17;29904:249;;;29980:29;29994:6;30001:1;29994:9;;;;;;;;:::i;:::-;;;;;;;:14;;;29980:13;:29::i;:::-;29962:12;29975:1;29962:15;;;;;;;;:::i;:::-;;;;;;:47;-1:-1:-1::0;;;;;29962:47:21::1;;;-1:-1:-1::0;;;;;29962:47:21::1;;;::::0;::::1;30055:87;;;;;;;;30078:6;30085:1;30078:9;;;;;;;;:::i;:::-;;;;;;;:14;;;30055:87;;;;30110:6;30117:1;30110:9;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;:18;::::1;::::0;30055:87;;;30023:26:::1;::::0;;;:13:::1;:26:::0;;;;;;:29;;;;;;;:119;;:29;;:119:::1;::::0;:29;:119:::1;:::i;:::-;-1:-1:-1::0;30023:119:21::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;:::i;:::-;;;;;29943:3;;;;;:::i;:::-;;;;29904:249;;;-1:-1:-1::0;30162:31:21::1;::::0;;;:18:::1;:31;::::0;;;;;;;:46;;::::1;::::0;;::::1;::::0;::::1;:::i;27702:209::-:0;27810:10;27789:17;27797:8;27789:7;:17::i;:::-;-1:-1:-1;;;;;27789:31:21;;27781:40;;;;;;27831:17;;;;:7;:17;;;;;:28;27851:8;27831:17;:28;:::i;:::-;;27875:29;27885:8;27895;27875:29;;;;;;;:::i;8386:821::-;8487:7;2261:21:1;:19;:21::i;:::-;26823:14:21::1;:12;:14::i;:::-;26815:23;;;::::0;::::1;;8506:19:::2;8528:14;:12;:14::i;:::-;8506:36;;8555:11;8552:286;;;8589:19;::::0;;;:9:::2;:19;::::0;;;;;::::2;;:28;8581:37;;;::::0;::::2;;8661:11;::::0;8654:37:::2;::::0;-1:-1:-1;;;8654:37:21;;::::2;::::0;::::2;7320:25:22::0;;;-1:-1:-1;;;;;8661:11:21;;::::2;::::0;8654:27:::2;::::0;7293:18:22;;8654:37:21::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;8640:51:21::2;:10;-1:-1:-1::0;;;;;8640:51:21::2;;8632:60;;;::::0;::::2;;4446:4;8714:15;:11:::0;8728:1:::2;8714:15;:::i;:::-;:28;;8706:37;;;::::0;::::2;;8758:19;::::0;;;:9:::2;:19;::::0;;;;:26;;-1:-1:-1;;8758:26:21::2;8780:4;8758:26:::0;;::::2;::::0;;;8798:20:::2;::::0;8804:10:::2;::::0;8798:5:::2;:20::i;:::-;8852:11;8848:325;;8898:4;8886:8;:16;;8878:25;;;::::0;::::2;;8925:17;::::0;;;:7:::2;:17;::::0;;;;;::::2;;:26;8917:35;;;::::0;::::2;;8995:10;::::0;8988:36:::2;::::0;-1:-1:-1;;;8988:36:21;;::::2;::::0;::::2;7320:25:22::0;;;-1:-1:-1;;;;;8995:10:21;;::::2;::::0;8988:26:::2;::::0;7293:18:22;;8988:36:21::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;8974:50:21::2;:10;-1:-1:-1::0;;;;;8974:50:21::2;;8966:59;;;::::0;::::2;;4446:4;9047:15;:11:::0;9061:1:::2;9047:15;:::i;:::-;:28;;9039:37;;;::::0;::::2;;9091:17;::::0;;;:7:::2;:17;::::0;;;;:24;;-1:-1:-1;;9091:24:21::2;9111:4;9091:24:::0;;::::2;::::0;;;9129:20:::2;::::0;9135:10:::2;::::0;9129:5:::2;:20::i;:::-;9189:11:::0;-1:-1:-1;2303:20:1;1716:1;2809:7;:22;2629:209;1201:85:0;1273:6;;-1:-1:-1;;;;;1273:6:0;;1201:85::o;11325:102:16:-;11381:13;11413:7;11406:14;;;;;:::i;30369:243:21:-;30456:2;30447:6;:11;30439:20;;;;;;30491:17;30499:8;30491:7;:17::i;:::-;-1:-1:-1;;;;;30477:31:21;:10;-1:-1:-1;;;;;30477:31:21;;30469:40;;;;;;30520:22;;;;:12;:22;;;;;;;;:30;;;;;;;;;:37;;-1:-1:-1;;30520:37:21;30553:4;30520:37;;;30573:32;;26510:25:22;;;26551:18;;;26544:34;;;30573:32:21;;26483:18:22;30573:32:21;26336:248:22;13317:303:16;32962:10;-1:-1:-1;;;;;13415:31:16;;;13411:61;;13455:17;;-1:-1:-1;;;13455:17:16;;;;;;;;;;;13411:61;32962:10;13483:39;;;;:18;:39;;;;;;;;-1:-1:-1;;;;;13483:49:16;;;;;;;;;;;;:60;;-1:-1:-1;;13483:60:16;;;;;;;;;;13558:55;;540:41:22;;;13483:49:16;;32962:10;13558:55;;513:18:22;13558:55:16;;;;;;;13317:303;;:::o;407:308:9:-;475:22;531:4;-1:-1:-1;;;;;519:24:9;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;509:34;;558:9;553:132;573:15;;;553:132;;;622:52;659:4;666;;671:1;666:7;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;622:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;622:28:9;;-1:-1:-1;;;622:52:9:i;:::-;609:7;617:1;609:10;;;;;;;;:::i;:::-;;;;;;:65;;;;590:3;;;;;:::i;:::-;;;;553:132;;;;407:308;;;;:::o;17707:2360:21:-;17810:13;17839:22;17871;:33;;;;;;;;;;;;;-1:-1:-1;;;17871:33:21;;;;;17953:1;17925:7;:17;17933:8;17925:17;;;;;;;;;;;17919:31;;;;;:::i;:::-;;;:35;17915:94;;;17981:17;;;;:7;:17;;;;;17970:28;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17915:94;18019:21;18043:34;18066:10;18043:22;:34::i;:::-;18019:58;;18087:176;;;;;;;;;;;;;;;;;;:8;;:19;:176::i;:::-;18273:95;18323:8;18306:52;;;;;;;;:::i;:::-;;;;-1:-1:-1;;18306:52:21;;;;;;;;;18273:8;;:19;:95::i;:::-;18383:9;18378:711;18402:14;18415:1;3768:2;18402:14;:::i;:::-;18398:1;:18;18378:711;;;18450:1;18442:5;18446:1;18442;:5;:::i;:::-;:9;:47;;;;-1:-1:-1;18455:22:21;;;;:12;:22;;;;;;;;:25;;;;;;;;;;;:34;18442:47;18437:642;;18526:107;18566:49;18587:5;18595;:1;18599;18595:5;:::i;:::-;18604;:1;18608;18604:5;:::i;18526:107::-;18509:124;;;;18651:413;18767:13;:16;18781:1;18767:16;;;;;;;;;;;:32;18784:14;18767:32;;;;;;;;;;;:41;;18870:120;18913:51;18926:18;:21;18945:1;18926:21;;;;;;;;;;;18948:14;18926:37;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;18926:37:21;18913:12;:51::i;:::-;18870:13;:120::i;:::-;18692:354;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;18692:354:21;;;;;;;;;18651:8;;:19;:413::i;:::-;18418:3;;;;:::i;:::-;;;;18378:711;;;-1:-1:-1;19116:107:21;19148:65;19169:5;19195:1;19177:14;3768:2;19195:1;19177:14;:::i;:::-;19176:20;;;;:::i;:::-;19198:14;3768:2;19211:1;19198:14;:::i;19116:107::-;19099:124;;;-1:-1:-1;19234:629:21;19326:13;:29;19340:14;19353:1;3768:2;19340:14;:::i;:::-;19326:29;;;;;;;;;;;:45;19356:14;19326:45;;;;;;;;;;;:54;;19426:163;19461:110;19499:18;:34;19531:1;3768:2;19518:14;;;;:::i;:::-;19499:34;;;;;;;;;;;19534:14;19499:50;;;;;;;;:::i;19426:163::-;19267:586;;;;;;;;;:::i;19234:629::-;20005:23;20019:8;20005:13;:23::i;:::-;19917:129;;;;;;;;:::i;:::-;;;;;;;;;;;;;19874:186;;;;;17707:2360;;;;:::o;14159:388:16:-;14320:31;14333:4;14339:2;14343:7;14320:12;:31::i;:::-;-1:-1:-1;;;;;14365:14:16;;;:19;14361:180;;14403:56;14434:4;14440:2;14444:7;14453:5;14403:30;:56::i;:::-;14398:143;;14486:40;;-1:-1:-1;;;14486:40:16;;;;;;;;;;;22106:3362:21;22204:13;22241:17;22249:8;22241:7;:17::i;:::-;22233:26;;;;;;22308:1;22277:21;;:18;:21;;;:28;22269:41;;;;;;22321:23;22347;22361:8;22347:13;:23::i;:::-;22321:49;;22381:22;22406:34;22429:10;22406:22;:34::i;:::-;22511:1;22460:18;;;:8;:18;;;;;22454:54;;22381:59;;-1:-1:-1;22511:1:21;;22454:54;;;:::i;:::-;;;:58;22450:360;;;22644:18;;;;:8;:18;;;;;;;;;22566:136;;22528:188;;22566:136;;22644:18;;22566:136;;:::i;22528:188::-;22450:360;;;22747:52;;;;;;;;;;;;-1:-1:-1;;;22747:52:21;;;;;;:9;;:20;:52::i;:::-;22820:233;22909:19;22919:8;22909:9;:19::i;:::-;22854:189;;;;;22983:24;;22854:189;;;:::i;22820:233::-;23092:1;23074:7;23068:21;;;;;:::i;:::-;;;:25;:59;;;;-1:-1:-1;23097:30:21;;;;:20;:30;;;;;;;;23068:59;23064:2077;;;23143:111;23211:7;23220:19;23230:8;23220:9;:19::i;:::-;23181:59;;;;;;;;;:::i;23143:111::-;23064:2077;;;23285:26;;;;;;;;;:21;:26;;;23329:21;;;:11;:21;;;;;;;;;;23325:1690;;;23370:23;23396:30;23406:9;23417:8;23396:9;:30::i;:::-;23370:56;;23578:438;23899:9;23621:369;;;;;;;;:::i;:::-;;;;;;;;;;;;;23578:13;:438::i;:::-;23482:556;;;;;;;;:::i;:::-;;;;;;;;;;;;;23444:612;;24074:115;24155:9;24116:55;;;;;;;;:::i;:::-;;;;-1:-1:-1;;24116:55:21;;;;;;;;;24074:9;;:20;:115::i;:::-;23352:852;23325:1690;;;24228:23;24254:30;24264:9;24275:8;24254:9;:30::i;:::-;24228:56;;24436:391;24710:9;24479:322;;;;;;;;:::i;24436:391::-;24340:509;;;;;;;;:::i;:::-;;;;;;;;;;;;;24302:565;;24885:115;24966:9;24927:55;;;;;;;;:::i;24885:115::-;24210:805;23325:1690;25029:101;25102:7;25067:49;;;;;;;;:::i;25029:101::-;23271:1870;23064:2077;25151:109;25219:25;25234:9;25219:14;:25::i;:::-;25185:65;;;;;;;;:::i;25151:109::-;25405:24;25419:9;25405:13;:24::i;:::-;25314:133;;;;;;;;:::i;:::-;;;;;;;;;;;;;25271:190;;;;22106:3362;;;:::o;26569:204::-;26690:17;26698:8;26690:7;:17::i;:::-;-1:-1:-1;;;;;26676:31:21;:10;-1:-1:-1;;;;;26676:31:21;;26668:40;;;;;;26718:30;;;;:20;:30;;;;;;:48;;-1:-1:-1;;26718:48:21;;;;;;;;;;26569:204::o;28613:522::-;28757:17;28765:8;28757:7;:17::i;:::-;-1:-1:-1;;;;;28743:31:21;:10;-1:-1:-1;;;;;28743:31:21;;28735:40;;;;;;28785:10;28798:18;;;:8;:18;;;;;:29;;;28840:18;;;28837:109;;28904:18;;;;:8;:18;;;;;:29;;:31;;28885:5;;-1:-1:-1;28885:5:21;;28904:31;;;;:::i;:::-;;;;;;28837:109;28956:18;;;;:8;:18;;;;;;;;:36;;;:25;;:36;;;;;:45;28995:6;28956:36;:45;:::i;:::-;-1:-1:-1;29011:18:21;;;;:8;:18;;;;;;;;:36;;;:25;;:36;;;;;:45;29050:6;29011:36;:45;:::i;:::-;;29072:56;29092:8;29102:9;29113:6;29121;29072:56;;;;;;;;;:::i;25474:1089::-;26308:22;;25518:13;;25677:847;;25803:12;;25899:24;;25996:18;;26088:19;;26188:20;;26298:33;;:9;:33::i;:::-;25716:786;;;;;;;;;;26411:31;;25716:786;;;:::i;25677:847::-;25586:956;;;;;;;;:::i;:::-;;;;;;;;;;;;;25543:1013;;25474:1089;:::o;2081:198:0:-;1094:13;:11;:13::i;:::-;-1:-1:-1;;;;;2169:22:0;::::1;2161:73;;;::::0;-1:-1:-1;;;2161:73:0;;39659:2:22;2161:73:0::1;::::0;::::1;39641:21:22::0;39698:2;39678:18;;;39671:30;39737:34;39717:18;;;39710:62;-1:-1:-1;;;39788:18:22;;;39781:36;39834:19;;2161:73:0::1;;;;;;;;;2244:28;2263:8;2244:18;:28::i;30237:126:21:-:0;1094:13:0;:11;:13::i;:::-;30350:6:21::1;30325:11;30337:9;30325:22;;;;;;;;:::i;:::-;;;;;;;;:31;;;;;;:::i;10606:391::-:0;1094:13:0;:11;:13::i;:::-;10706:21:21::1;10741:8;10730;:19;:41;;10763:8;10730:41;;;10752:8;10730:41;10706:65;;10782:37;10805:13;10782:22;:37::i;:::-;10833:26;10841:17;:13:::0;10857:1:::1;10841:17;:::i;:::-;10833:7;:26::i;:::-;10829:98;;;10875:41;10898:17;:13:::0;10914:1:::1;10898:17;:::i;:::-;10875:22;:41::i;:::-;10937:53;10953:13;10968:21;:19;:21::i;:::-;10937:15;:53::i;14793:268:16:-:0;14850:4;14904:7;4358:3;14885:26;;:65;;;;;14937:13;;14927:7;:23;14885:65;:150;;;;-1:-1:-1;;14987:26:16;;;;:17;:26;;;;;;-1:-1:-1;;;14987:43:16;:48;;14793:268::o;33080:1920::-;33543:4;33537:11;;33550:3;33533:21;;33626:17;;;;34309:11;;;34190:5;34439:2;34453;34443:13;;34435:22;34309:11;34422:36;34493:2;34483:13;;34084:682;34511:4;34084:682;;;34697:1;34692:3;34688:11;34681:18;;34747:2;34741:4;34737:13;34733:2;34729:22;34724:3;34716:36;34604:2;34594:13;;34084:682;;;-1:-1:-1;34794:13:16;;;-1:-1:-1;;34907:12:16;;;34965:19;;;34907:12;33080:1920;-1:-1:-1;33080:1920:16:o;1359:130:0:-;32962:10:16;1422:7:0;:5;:7::i;:::-;-1:-1:-1;;;;;1422:23:0;;1414:68;;;;-1:-1:-1;;;1414:68:0;;40066:2:22;1414:68:0;;;40048:21:22;;;40085:18;;;40078:30;40144:34;40124:18;;;40117:62;40196:18;;1414:68:0;39864:356:22;7951:1105:16;8018:7;8052;;4358:3;8098:23;8094:898;;8150:13;;8143:4;:20;8139:853;;;8187:14;8204:23;;;:17;:23;;;;;;;-1:-1:-1;;;8291:23:16;;:28;;8287:687;;8802:111;8809:6;8819:1;8809:11;8802:111;;-1:-1:-1;;;8879:6:16;8861:25;;;;:17;:25;;;;;;8802:111;;;8945:6;7951:1105;-1:-1:-1;;;7951:1105:16:o;8287:687::-;8165:827;8139:853;9018:31;;-1:-1:-1;;;9018:31:16;;;;;;;;;;;30101:302;30232:7;2166:3;30277:40;;;;30343:31;30354:4;30360:2;30277:40;30343:10;:31::i;:::-;30335:40;;:61;;;30101:302;-1:-1:-1;;;;;30101:302:16:o;10462:440::-;10865:11;10841:22;10837:40;10834:51;-1:-1:-1;;;;;10696:27:16;;;;10824:62;;10462:440::o;2336:287:1:-;1759:1;2468:7;;:19;2460:63;;;;-1:-1:-1;;;2460:63:1;;40427:2:22;2460:63:1;;;40409:21:22;40466:2;40446:18;;;40439:30;40505:33;40485:18;;;40478:61;40556:18;;2460:63:1;40225:355:22;2460:63:1;1759:1;2598:7;:18;2336:287::o;5140:279:16:-;5187:7;5371:13;-1:-1:-1;;5371:31:16;;5140:279::o;16565:1492::-;16629:20;16652:13;-1:-1:-1;;;;;16679:16:16;;16675:48;;16704:19;;-1:-1:-1;;;16704:19:16;;;;;;;;;;;16675:48;16737:8;16749:1;16737:13;16733:44;;16759:18;;-1:-1:-1;;;16759:18:16;;;;;;;;;;;16733:44;-1:-1:-1;;;;;17252:22:16;;;;;;:18;:22;;1156:2;17252:22;;:70;;-1:-1:-1;;;;;17278:44:16;;17252:70;;;17592:136;;17271:2;;17681:33;;17271:2;17252:22;17681:14;:33::i;:::-;12537:1;12524:15;;12499:23;12495:45;17648:66;17592:18;:136::i;:::-;17558:31;;;;:17;:31;;;;;:170;17576:12;17801:23;;;17838:99;17864:35;;17889:9;;;;;-1:-1:-1;;;;;17864:35:16;;;17881:1;;-1:-1:-1;;;;;;;;;;;17864:35:16;17881:1;;17864:35;17932:3;17922:7;:13;17838:99;;17951:13;:19;-1:-1:-1;13914:179:16;;;:::o;2412:312:6:-;2526:6;2501:21;:31;;2493:73;;;;-1:-1:-1;;;2493:73:6;;40787:2:22;2493:73:6;;;40769:21:22;40826:2;40806:18;;;40799:30;40865:31;40845:18;;;40838:59;40914:18;;2493:73:6;40585:353:22;2493:73:6;2578:12;2596:9;-1:-1:-1;;;;;2596:14:6;2618:6;2596:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2577:52;;;2647:7;2639:78;;;;-1:-1:-1;;;2639:78:6;;41355:2:22;2639:78:6;;;41337:21:22;41394:2;41374:18;;;41367:30;41433:34;41413:18;;;41406:62;-1:-1:-1;;;41484:18:22;;;41477:56;41550:19;;2639:78:6;41153:422:22;1035:989:15;1243:4;1237:11;;1549:20;;;1118:19;1549:20;1586:25;;1719:19;;1755:25;;-1:-1:-1;1906:4:15;1891:20;;;1967:17;;;1891:20;1035:989::o;10228:156:16:-;10290:21;;:::i;:::-;10330:47;10349:27;10368:7;10349:18;:27::i;:::-;10330:18;:47::i;9553:573:21:-;9660:7;;;9722:351;9746:5;9752:11;9746:18;;;;;;;:::i;:::-;;:25;9742:29;;9722:351;;;9792:22;9817:5;9823:11;9817:18;;;;;;;:::i;:::-;;9836:1;9817:21;;;;;;;;:::i;:::-;;;;;;;;;9792:46;;9887:17;9873:10;:31;;:98;;;;-1:-1:-1;9937:34:21;9957:14;9937:17;:34;:::i;:::-;9924:10;:47;9873:98;9852:142;;;-1:-1:-1;9993:1:21;-1:-1:-1;9986:8:21;;-1:-1:-1;9986:8:21;9852:142;10028:34;10048:14;10028:17;:34;:::i;:::-;10008:54;;9778:295;9773:3;;;;;:::i;:::-;;;;9722:351;;;;10118:1;10090:5;10096:11;10090:18;;;;;;;:::i;:::-;;:25;:29;;;;:::i;:::-;10083:36;9553:573;-1:-1:-1;;;;9553:573:21:o;3501:424:15:-;-1:-1:-1;;3680:17:15;;3674:24;3728:13;;3791:11;;-1:-1:-1;;3670:35:15;;;;;;3782:20;;3728:13;3782:20;:::i;:::-;:32;;3761:118;;;;-1:-1:-1;;;3761:118:15;;41782:2:22;3761:118:15;;;41764:21:22;41821:2;41801:18;;;41794:30;41860:34;41840:18;;;41833:62;-1:-1:-1;;;41911:18:22;;;41904:37;41958:19;;3761:118:15;41580:403:22;3761:118:15;3889:29;3905:6;3913:4;3889:15;:29::i;574:409:17:-;704:13;759:3;729:21;805;816:10;805:8;:21;:::i;:::-;-1:-1:-1;;;;;795:32:17;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;795:32:17;-1:-1:-1;773:54:17;-1:-1:-1;854:10:17;837:109;870:8;866:1;:12;837:109;;;924:8;933:1;924:11;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;924:11:17;899:6;906:14;910:10;906:1;:14;:::i;:::-;899:22;;;;;;;;:::i;:::-;;;;:36;-1:-1:-1;;;;;899:36:17;;;;;;;;-1:-1:-1;880:3:17;;;;:::i;:::-;;;;837:109;;;-1:-1:-1;969:6:17;574:409;-1:-1:-1;;;;;574:409:17:o;82:486::-;165:16;226:2;165:16;;263:278;285:7;:14;281:1;:18;;;263:278;;;370:2;354:7;362:1;354:10;;;;;;;;;;:::i;:::-;;;;;;;342:30;;;;341:84;;;422:2;406:7;414:1;406:10;;;;;;;;;;:::i;:::-;;;;;;;394:30;;341:84;320:211;;;458:10;466:2;458:10;;:::i;:::-;;;514:2;500:7;508:1;500:10;;;;;;;;;;:::i;:::-;;;;;494:22;;;500:10;;494:22;:::i;:::-;486:30;;;;:::i;:::-;;;320:211;301:3;;;;:::i;:::-;;;;263:278;;;-1:-1:-1;557:4:17;82:486;-1:-1:-1;;;82:486:17:o;2433:187:0:-;2525:6;;;-1:-1:-1;;;;;2541:17:0;;;-1:-1:-1;;;;;;2541:17:0;;;;;;;2573:40;;2525:6;;;2541:17;2525:6;;2573:40;;2506:16;;2573:40;2496:124;2433:187;:::o;586:460:19:-;639:15;739:17;759:94;834:5;791:56;;;;;;;;:::i;:::-;;;;;;;;;;;;;759:24;:94::i;:::-;739:114;;949:4;943:11;938:2;932:4;928:13;925:1;918:37;907:48;-1:-1:-1;;;;;;999:21:19;;995:46;;1029:12;;-1:-1:-1;;;1029:12:19;;;;;;;;;;;995:46;656:390;586:460;;;:::o;6469:198:6:-;6552:12;6583:77;6604:6;6612:4;6583:77;;;;;;;;;;;;;;;;;:20;:77::i;1300:134:19:-;1355:12;1382:47;1398:8;1408:1;-1:-1:-1;;1382:15:19;:47::i;505:3026:7:-;563:13;795:4;:11;810:1;795:16;791:31;;-1:-1:-1;;813:9:7;;;;;;;;;-1:-1:-1;813:9:7;;;505:3026::o;791:31::-;872:19;894:6;;;;;;;;;;;;;;;;;872:28;;1303:20;1362:1;1343:4;:11;1357:1;1343:15;;;;:::i;:::-;1342:21;;;;:::i;:::-;1337:27;;:1;:27;:::i;:::-;-1:-1:-1;;;;;1326:39:7;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1326:39:7;;1303:62;;1540:1;1533:5;1529:13;1641:2;1633:6;1629:15;1748:4;1799;1793:11;1787:4;1783:22;1711:1403;1832:6;1823:7;1820:19;1711:1403;;;1934:1;1925:7;1921:15;1910:26;;1972:7;1966:14;2615:4;2607:5;2603:2;2599:14;2595:25;2585:8;2581:40;2575:47;2564:9;2556:67;2668:1;2657:9;2653:17;2640:30;;2758:4;2750:5;2746:2;2742:14;2738:25;2728:8;2724:40;2718:47;2707:9;2699:67;2811:1;2800:9;2796:17;2783:30;;2900:4;2892:5;2889:1;2885:13;2881:24;2871:8;2867:39;2861:46;2850:9;2842:66;2953:1;2942:9;2938:17;2925:30;;3034:4;3027:5;3023:16;3013:8;3009:31;3003:38;2992:9;2984:58;;3087:1;3076:9;3072:17;3059:30;;1711:1403;;;1715:104;;3272:1;3265:4;3259:11;3255:19;3292:1;3287:120;;;;3425:1;3420:71;;;;3248:243;;3287:120;3339:4;3335:1;3324:9;3320:17;3312:32;3388:4;3384:1;3373:9;3369:17;3361:32;3287:120;;3420:71;3472:4;3468:1;3457:9;3453:17;3445:32;3248:243;-1:-1:-1;3518:6:7;;505:3026;-1:-1:-1;;;;;505:3026:7:o;28651:697:16:-;28829:88;;-1:-1:-1;;;28829:88:16;;28809:4;;-1:-1:-1;;;;;28829:45:16;;;;;:88;;32962:10;;28896:4;;28902:7;;28911:5;;28829:88;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;28829:88:16;;;;;;;;-1:-1:-1;;28829:88:16;;;;;;;;;;;;:::i;:::-;;;28825:517;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29107:6;:13;29124:1;29107:18;29103:229;;29152:40;;-1:-1:-1;;;29152:40:16;;;;;;;;;;;29103:229;29292:6;29286:13;29277:6;29273:2;29269:15;29262:38;28825:517;-1:-1:-1;;;;;;28985:64:16;-1:-1:-1;;;28985:64:16;;-1:-1:-1;28651:697:16;;;;;;:::o;9848:184::-;9918:24;;;;:17;:24;;;;;;:29;;9914:112;;9990:25;10009:5;9990:18;:25::i;:::-;9963:24;;;;:17;:24;;;;;:52;9848:184;:::o;10132:468:21:-;10186:6;;10313:11;10346:12;10380:15;10417:16;10465;10480:1;10346:12;10465:16;:::i;:::-;10275:257;;;;;;44281:19:22;;;;44316:12;;44309:28;;;;44353:12;;;;44346:28;;;;44390:12;;;44383:28;10455:27:21;;44427:13:22;;;44420:29;10504:10:21;44484:15:22;;-1:-1:-1;;;;;;44480:45:22;44465:13;;;44458:68;44542:13;;10275:257:21;;;-1:-1:-1;;10275:257:21;;;;;;;;;10248:298;;10275:257;10248:298;;;;;10132:468;-1:-1:-1;;10132:468:21:o;29443:512:16:-;29520:14;29537:24;;;:17;:24;;;;;;;29575:11;;;29571:61;;29595:37;;-1:-1:-1;;;29595:37:16;;;;;;;;;;;29571:61;29642:23;29915:24;;;:17;:24;;;;;;-1:-1:-1;;;;;29825:38:16;;;;2166:3;29868:36;;;;29824:81;29915:33;;29443:512::o;11003:236:21:-;11145:6;-1:-1:-1;;;;;11170:18:21;;;:62;;11215:17;11170:62;;;11191:21;:19;:21::i;9145:358:16:-;9211:31;;:::i;:::-;-1:-1:-1;;;;;9254:41:16;;;;-1:-1:-1;;;;;1661:3:16;9339:32;;;9305:67;:24;;;:67;-1:-1:-1;;;9401:23:16;;:28;;9382:16;;;:47;2166:3;9468:27;;;;9439:19;;;:57;9254:9;9145:358::o;2289:976:15:-;2441:4;2435:11;2499:4;2493;2489:15;2481:23;;2546:6;2540:4;2536:17;2615:4;2606:6;2600:13;2596:24;2588:6;2584:37;2459:698;2645:7;2639:4;2636:17;2459:698;;;3131:11;;3116:27;;2690:4;2680:15;;;;2722:17;2459:698;;;-1:-1:-1;;3226:13:15;;3222:26;3207:42;;;-1:-1:-1;2289:976:15:o;378:700:14:-;446:12;1002:5;:12;1062:5;956:117;;;;;;;;;:::i;:::-;;;;;;;;;;;;;949:124;;378:700;;;:::o;6853:325:6:-;6994:12;7019;7033:23;7060:6;-1:-1:-1;;;;;7060:19:6;7080:4;7060:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7018:67;;;;7102:69;7129:6;7137:7;7146:10;7158:12;7102:26;:69::i;:::-;7095:76;6853:325;-1:-1:-1;;;;;;6853:325:6:o;1793:946:14:-;1877:18;1356;;1903:13;1944:10;;;1940:32;;-1:-1:-1;;1963:9:14;;;;;;;;;-1:-1:-1;1963:9:14;;1956:16;;1940:32;1992:5;1983:6;:14;1979:36;;;-1:-1:-1;;2006:9:14;;;;;;;;;-1:-1:-1;2006:9:14;;1999:16;;1979:36;2032:6;2025:4;:13;2021:65;;;2047:39;;-1:-1:-1;;;2047:39:14;;;;;45756:25:22;;;45797:18;;;45790:34;;;45840:18;;;45833:34;;;45729:18;;2047:39:14;45554:319:22;2021:65:14;2130:13;;;2169:14;;;2112:15;2207:17;;;:37;;2237:7;2207:37;;;2227:7;2207:37;2413:4;2407:11;;2501:26;;;-1:-1:-1;;2497:42:14;2486:54;;2473:68;;;2584:19;;;2407:11;-1:-1:-1;2192:52:14;-1:-1:-1;2192:52:14;2708:6;2515:4;2690:16;;2683:5;2671:50;2262:467;;;1897:842;1793:946;;;;;:::o;7466:628:6:-;7646:12;7674:7;7670:418;;;7701:10;:17;7722:1;7701:22;7697:286;;-1:-1:-1;;;;;1465:19:6;;;7908:60;;;;-1:-1:-1;;;7908:60:6;;46080:2:22;7908:60:6;;;46062:21:22;46119:2;46099:18;;;46092:30;46158:31;46138:18;;;46131:59;46207:18;;7908:60:6;45878:353:22;7908:60:6;-1:-1:-1;8003:10:6;7996:17;;7670:418;8044:33;8052:10;8064:12;8775:17;;:21;8771:379;;9003:10;8997:17;9059:15;9046:10;9042:2;9038:19;9031:44;8771:379;9126:12;9119:20;;-1:-1:-1;;;9119:20:6;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;14:131:22;-1:-1:-1;;;;;;88:32:22;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:250::-;677:1;687:113;701:6;698:1;695:13;687:113;;;777:11;;;771:18;758:11;;;751:39;723:2;716:10;687:113;;;-1:-1:-1;;834:1:22;816:16;;809:27;592:250::o;847:271::-;889:3;927:5;921:12;954:6;949:3;942:19;970:76;1039:6;1032:4;1027:3;1023:14;1016:4;1009:5;1005:16;970:76;:::i;:::-;1100:2;1079:15;-1:-1:-1;;1075:29:22;1066:39;;;;1107:4;1062:50;;847:271;-1:-1:-1;;847:271:22:o;1123:220::-;1272:2;1261:9;1254:21;1235:4;1292:45;1333:2;1322:9;1318:18;1310:6;1292:45;:::i;1348:180::-;1407:6;1460:2;1448:9;1439:7;1435:23;1431:32;1428:52;;;1476:1;1473;1466:12;1428:52;-1:-1:-1;1499:23:22;;1348:180;-1:-1:-1;1348:180:22:o;1741:131::-;-1:-1:-1;;;;;1816:31:22;;1806:42;;1796:70;;1862:1;1859;1852:12;1877:315;1945:6;1953;2006:2;1994:9;1985:7;1981:23;1977:32;1974:52;;;2022:1;2019;2012:12;1974:52;2061:9;2048:23;2080:31;2105:5;2080:31;:::i;:::-;2130:5;2182:2;2167:18;;;;2154:32;;-1:-1:-1;;;1877:315:22:o;2197:127::-;2258:10;2253:3;2249:20;2246:1;2239:31;2289:4;2286:1;2279:15;2313:4;2310:1;2303:15;2329:253;2401:2;2395:9;2443:4;2431:17;;-1:-1:-1;;;;;2463:34:22;;2499:22;;;2460:62;2457:88;;;2525:18;;:::i;:::-;2561:2;2554:22;2329:253;:::o;2587:::-;2659:2;2653:9;2701:4;2689:17;;-1:-1:-1;;;;;2721:34:22;;2757:22;;;2718:62;2715:88;;;2783:18;;:::i;2845:275::-;2916:2;2910:9;2981:2;2962:13;;-1:-1:-1;;2958:27:22;2946:40;;-1:-1:-1;;;;;3001:34:22;;3037:22;;;2998:62;2995:88;;;3063:18;;:::i;:::-;3099:2;3092:22;2845:275;;-1:-1:-1;2845:275:22:o;3125:531::-;3168:5;3221:3;3214:4;3206:6;3202:17;3198:27;3188:55;;3239:1;3236;3229:12;3188:55;3262:20;;-1:-1:-1;;;;;3294:26:22;;3291:52;;;3323:18;;:::i;:::-;3367:55;3410:2;3391:13;;-1:-1:-1;;3387:27:22;3416:4;3383:38;3367:55;:::i;:::-;3447:2;3438:7;3431:19;3493:3;3486:4;3481:2;3473:6;3469:15;3465:26;3462:35;3459:55;;;3510:1;3507;3500:12;3459:55;3575:2;3568:4;3560:6;3556:17;3549:4;3540:7;3536:18;3523:55;3623:1;3598:16;;;3616:4;3594:27;3587:38;;;;3602:7;3125:531;-1:-1:-1;;;3125:531:22:o;3661:812::-;3777:6;3785;3793;3801;3854:3;3842:9;3833:7;3829:23;3825:33;3822:53;;;3871:1;3868;3861:12;3822:53;3894:23;;;-1:-1:-1;3968:2:22;3953:18;;3940:32;-1:-1:-1;;;;;4021:14:22;;;4018:34;;;4048:1;4045;4038:12;4018:34;4071:50;4113:7;4104:6;4093:9;4089:22;4071:50;:::i;:::-;4061:60;;4174:2;4163:9;4159:18;4146:32;4130:48;;4203:2;4193:8;4190:16;4187:36;;;4219:1;4216;4209:12;4187:36;4242:52;4286:7;4275:8;4264:9;4260:24;4242:52;:::i;:::-;4232:62;;4347:2;4336:9;4332:18;4319:32;4303:48;;4376:2;4366:8;4363:16;4360:36;;;4392:1;4389;4382:12;4360:36;;4415:52;4459:7;4448:8;4437:9;4433:24;4415:52;:::i;:::-;4405:62;;;3661:812;;;;;;;:::o;4478:1543::-;4567:6;4620:2;4608:9;4599:7;4595:23;4591:32;4588:52;;;4636:1;4633;4626:12;4588:52;4663:23;;-1:-1:-1;;;;;4735:14:22;;;4732:34;;;4762:1;4759;4752:12;4732:34;4785:22;;;;4841:4;4823:16;;;4819:27;4816:47;;;4859:1;4856;4849:12;4816:47;4885:22;;:::i;:::-;4945:2;4932:16;4973:2;4963:8;4960:16;4957:36;;;4989:1;4986;4979:12;4957:36;5016:45;5053:7;5042:8;5038:2;5034:17;5016:45;:::i;:::-;5009:5;5002:60;;5108:2;5104;5100:11;5087:25;5137:2;5127:8;5124:16;5121:36;;;5153:1;5150;5143:12;5121:36;5189:45;5226:7;5215:8;5211:2;5207:17;5189:45;:::i;:::-;5184:2;5177:5;5173:14;5166:69;;5281:2;5277;5273:11;5260:25;5310:2;5300:8;5297:16;5294:36;;;5326:1;5323;5316:12;5294:36;5362:45;5399:7;5388:8;5384:2;5380:17;5362:45;:::i;:::-;5357:2;5350:5;5346:14;5339:69;;5454:2;5450;5446:11;5433:25;5483:2;5473:8;5470:16;5467:36;;;5499:1;5496;5489:12;5467:36;5535:45;5572:7;5561:8;5557:2;5553:17;5535:45;:::i;:::-;5530:2;5523:5;5519:14;5512:69;;5627:3;5623:2;5619:12;5606:26;5657:2;5647:8;5644:16;5641:36;;;5673:1;5670;5663:12;5641:36;5710:45;5747:7;5736:8;5732:2;5728:17;5710:45;:::i;:::-;5704:3;5697:5;5693:15;5686:70;;5810:3;5806:2;5802:12;5789:26;5783:3;5776:5;5772:15;5765:51;5862:3;5858:2;5854:12;5841:26;5892:2;5882:8;5879:16;5876:36;;;5908:1;5905;5898:12;5876:36;5945:45;5982:7;5971:8;5967:2;5963:17;5945:45;:::i;:::-;5939:3;5928:15;;5921:70;-1:-1:-1;5932:5:22;4478:1543;-1:-1:-1;;;;;4478:1543:22:o;6026:936::-;6123:6;6131;6139;6147;6155;6208:3;6196:9;6187:7;6183:23;6179:33;6176:53;;;6225:1;6222;6215:12;6176:53;6264:9;6251:23;6283:31;6308:5;6283:31;:::i;:::-;6333:5;-1:-1:-1;6390:2:22;6375:18;;6362:32;6403:33;6362:32;6403:33;:::i;:::-;6455:7;-1:-1:-1;6509:2:22;6494:18;;6481:32;;-1:-1:-1;6564:2:22;6549:18;;6536:32;-1:-1:-1;;;;;6617:14:22;;;6614:34;;;6644:1;6641;6634:12;6614:34;6682:6;6671:9;6667:22;6657:32;;6727:7;6720:4;6716:2;6712:13;6708:27;6698:55;;6749:1;6746;6739:12;6698:55;6789:2;6776:16;6815:2;6807:6;6804:14;6801:34;;;6831:1;6828;6821:12;6801:34;6876:7;6871:2;6862:6;6858:2;6854:15;6850:24;6847:37;6844:57;;;6897:1;6894;6887:12;6844:57;6026:936;;;;-1:-1:-1;6026:936:22;;-1:-1:-1;6928:2:22;6920:11;;6950:6;6026:936;-1:-1:-1;;;6026:936:22:o;7356:160::-;7421:20;;7477:13;;7470:21;7460:32;;7450:60;;7506:1;7503;7496:12;7521:248;7586:6;7594;7647:2;7635:9;7626:7;7622:23;7618:32;7615:52;;;7663:1;7660;7653:12;7615:52;7699:9;7686:23;7676:33;;7728:35;7759:2;7748:9;7744:18;7728:35;:::i;:::-;7718:45;;7521:248;;;;;:::o;7774:456::-;7851:6;7859;7867;7920:2;7908:9;7899:7;7895:23;7891:32;7888:52;;;7936:1;7933;7926:12;7888:52;7975:9;7962:23;7994:31;8019:5;7994:31;:::i;:::-;8044:5;-1:-1:-1;8101:2:22;8086:18;;8073:32;8114:33;8073:32;8114:33;:::i;:::-;7774:456;;8166:7;;-1:-1:-1;;;8220:2:22;8205:18;;;;8192:32;;7774:456::o;8235:180::-;8292:4;-1:-1:-1;;;;;8314:30:22;;8311:56;;;8347:18;;:::i;:::-;-1:-1:-1;8392:1:22;8388:14;8404:4;8384:25;;8235:180::o;8420:956::-;8510:6;8518;8571:2;8559:9;8550:7;8546:23;8542:32;8539:52;;;8587:1;8584;8577:12;8539:52;8610:23;;;-1:-1:-1;8652:2:22;8690:18;;;8677:32;-1:-1:-1;;;;;8721:30:22;;8718:50;;;8764:1;8761;8754:12;8718:50;8787:22;;8840:4;8832:13;;8828:27;-1:-1:-1;8818:55:22;;8869:1;8866;8859:12;8818:55;8905:2;8892:16;8928:57;8944:40;8981:2;8944:40;:::i;:::-;8928:57;:::i;:::-;9019:15;;;9101:1;9097:10;;;;9089:19;;9085:28;;;9050:12;;;;9125:19;;;9122:39;;;9157:1;9154;9147:12;9122:39;9181:11;;;;9201:145;9217:6;9212:3;9209:15;9201:145;;;9283:20;9299:3;9283:20;:::i;:::-;9271:33;;9234:12;;;;9324;;;;9201:145;;;9365:5;9355:15;;;;;;;8420:956;;;;;:::o;9381:1111::-;9798:3;9787:9;9780:22;9761:4;9825:46;9866:3;9855:9;9851:19;9843:6;9825:46;:::i;:::-;9919:9;9911:6;9907:22;9902:2;9891:9;9887:18;9880:50;9953:33;9979:6;9971;9953:33;:::i;:::-;9939:47;;10034:9;10026:6;10022:22;10017:2;10006:9;10002:18;9995:50;10068:33;10094:6;10086;10068:33;:::i;:::-;10054:47;;10149:9;10141:6;10137:22;10132:2;10121:9;10117:18;10110:50;10183:33;10209:6;10201;10183:33;:::i;:::-;10169:47;;10265:9;10257:6;10253:22;10247:3;10236:9;10232:19;10225:51;10299:33;10325:6;10317;10299:33;:::i;:::-;10285:47;;10369:6;10363:3;10352:9;10348:19;10341:35;10425:9;10417:6;10413:22;10407:3;10396:9;10392:19;10385:51;10453:33;10479:6;10471;10453:33;:::i;:::-;10445:41;9381:1111;-1:-1:-1;;;;;;;;;;9381:1111:22:o;10497:322::-;10566:6;10619:2;10607:9;10598:7;10594:23;10590:32;10587:52;;;10635:1;10632;10625:12;10587:52;10662:23;;-1:-1:-1;;;;;10697:30:22;;10694:50;;;10740:1;10737;10730:12;10694:50;10763;10805:7;10796:6;10785:9;10781:22;10763:50;:::i;10824:247::-;10883:6;10936:2;10924:9;10915:7;10911:23;10907:32;10904:52;;;10952:1;10949;10942:12;10904:52;10991:9;10978:23;11010:31;11035:5;11010:31;:::i;11076:2211::-;11195:6;11203;11256:2;11244:9;11235:7;11231:23;11227:32;11224:52;;;11272:1;11269;11262:12;11224:52;11295:23;;;-1:-1:-1;11337:2:22;11375:18;;;11362:32;-1:-1:-1;;;;;11443:14:22;;;11440:34;;;11470:1;11467;11460:12;11440:34;11508:6;11497:9;11493:22;11483:32;;11553:7;11546:4;11542:2;11538:13;11534:27;11524:55;;11575:1;11572;11565:12;11524:55;11611:2;11598:16;11634:57;11650:40;11687:2;11650:40;:::i;11634:57::-;11725:15;;;11807:1;11803:10;;;;11795:19;;11791:28;;;11756:12;;;;11831:19;;;11828:39;;;11863:1;11860;11853:12;11828:39;11895:2;11891;11887:11;11907:1350;11923:6;11918:3;11915:15;11907:1350;;;12009:3;11996:17;12045:2;12032:11;12029:19;12026:109;;;12089:1;12118:2;12114;12107:14;12026:109;12158:20;;12201:4;12229:16;;;-1:-1:-1;;12225:30:22;12221:39;-1:-1:-1;12218:129:22;;;12301:1;12330:2;12326;12319:14;12218:129;12373:22;;:::i;:::-;12445:2;12441;12437:11;12424:25;12478:2;12468:8;12465:16;12462:106;;;12522:1;12551:2;12547;12540:14;12462:106;12595:54;12641:7;12636:2;12625:8;12621:2;12617:17;12613:26;12595:54;:::i;:::-;12588:5;12581:69;;12700:2;12696;12692:11;12679:25;12733:2;12723:8;12720:16;12717:109;;;12778:1;12808:3;12803;12796:16;12717:109;12862:54;12908:7;12903:2;12892:8;12888:2;12884:17;12880:26;12862:54;:::i;:::-;12846:14;;;12839:78;-1:-1:-1;12959:11:22;;;12946:25;;12987:16;;;12984:109;;;13045:1;13075:3;13070;13063:16;12984:109;13129:54;13175:7;13170:2;13159:8;13155:2;13151:17;13147:26;13129:54;:::i;:::-;13124:2;13113:14;;13106:78;13197:18;;-1:-1:-1;;13235:12:22;;;;11940;;11907:1350;;;11911:3;13276:5;13266:15;;;;;;;;11076:2211;;;;;:::o;13292:390::-;13370:6;13378;13431:2;13419:9;13410:7;13406:23;13402:32;13399:52;;;13447:1;13444;13437:12;13399:52;13470:23;;;-1:-1:-1;13544:2:22;13529:18;;13516:32;-1:-1:-1;;;;;13560:30:22;;13557:50;;;13603:1;13600;13593:12;13557:50;13626;13668:7;13659:6;13648:9;13644:22;13626:50;:::i;:::-;13616:60;;;13292:390;;;;;:::o;13687:248::-;13755:6;13763;13816:2;13804:9;13795:7;13791:23;13787:32;13784:52;;;13832:1;13829;13822:12;13784:52;-1:-1:-1;;13855:23:22;;;13925:2;13910:18;;;13897:32;;-1:-1:-1;13687:248:22:o;13940:315::-;14005:6;14013;14066:2;14054:9;14045:7;14041:23;14037:32;14034:52;;;14082:1;14079;14072:12;14034:52;14121:9;14108:23;14140:31;14165:5;14140:31;:::i;:::-;14190:5;-1:-1:-1;14214:35:22;14245:2;14230:18;;14214:35;:::i;14260:626::-;14357:6;14365;14418:2;14406:9;14397:7;14393:23;14389:32;14386:52;;;14434:1;14431;14424:12;14386:52;14461:23;;-1:-1:-1;;;;;14533:14:22;;;14530:34;;;14560:1;14557;14550:12;14530:34;14598:6;14587:9;14583:22;14573:32;;14643:7;14636:4;14632:2;14628:13;14624:27;14614:55;;14665:1;14662;14655:12;14614:55;14705:2;14692:16;14731:2;14723:6;14720:14;14717:34;;;14747:1;14744;14737:12;14717:34;14800:7;14795:2;14785:6;14782:1;14778:14;14774:2;14770:23;14766:32;14763:45;14760:65;;;14821:1;14818;14811:12;14760:65;14852:2;14844:11;;;;;14874:6;;-1:-1:-1;14260:626:22;;-1:-1:-1;;;;14260:626:22:o;14891:801::-;15051:4;15080:2;15120;15109:9;15105:18;15150:2;15139:9;15132:21;15173:6;15208;15202:13;15239:6;15231;15224:22;15277:2;15266:9;15262:18;15255:25;;15339:2;15329:6;15326:1;15322:14;15311:9;15307:30;15303:39;15289:53;;15377:2;15369:6;15365:15;15398:1;15408:255;15422:6;15419:1;15416:13;15408:255;;;15515:2;15511:7;15499:9;15491:6;15487:22;15483:36;15478:3;15471:49;15543:40;15576:6;15567;15561:13;15543:40;:::i;:::-;15533:50;-1:-1:-1;15641:12:22;;;;15606:15;;;;15444:1;15437:9;15408:255;;;-1:-1:-1;15680:6:22;;14891:801;-1:-1:-1;;;;;;;14891:801:22:o;15697:390::-;15775:6;15783;15836:2;15824:9;15815:7;15811:23;15807:32;15804:52;;;15852:1;15849;15842:12;15804:52;15879:23;;-1:-1:-1;;;;;15914:30:22;;15911:50;;;15957:1;15954;15947:12;15911:50;15980;16022:7;16013:6;16002:9;15998:22;15980:50;:::i;:::-;15970:60;16077:2;16062:18;;;;16049:32;;-1:-1:-1;;;;15697:390:22:o;16092:666::-;16187:6;16195;16203;16211;16264:3;16252:9;16243:7;16239:23;16235:33;16232:53;;;16281:1;16278;16271:12;16232:53;16320:9;16307:23;16339:31;16364:5;16339:31;:::i;:::-;16389:5;-1:-1:-1;16446:2:22;16431:18;;16418:32;16459:33;16418:32;16459:33;:::i;:::-;16511:7;-1:-1:-1;16565:2:22;16550:18;;16537:32;;-1:-1:-1;16620:2:22;16605:18;;16592:32;-1:-1:-1;;;;;16636:30:22;;16633:50;;;16679:1;16676;16669:12;16633:50;16702;16744:7;16735:6;16724:9;16720:22;16702:50;:::i;16763:680::-;16869:6;16877;16885;16893;16946:3;16934:9;16925:7;16921:23;16917:33;16914:53;;;16963:1;16960;16953:12;16914:53;16986:23;;;-1:-1:-1;17056:2:22;17041:18;;17028:32;;-1:-1:-1;17111:2:22;17096:18;;17083:32;-1:-1:-1;;;;;17164:14:22;;;17161:34;;;17191:1;17188;17181:12;17448:388;17516:6;17524;17577:2;17565:9;17556:7;17552:23;17548:32;17545:52;;;17593:1;17590;17583:12;17545:52;17632:9;17619:23;17651:31;17676:5;17651:31;:::i;:::-;17701:5;-1:-1:-1;17758:2:22;17743:18;;17730:32;17771:33;17730:32;17771:33;:::i;:::-;17823:7;17813:17;;;17448:388;;;;;:::o;17841:380::-;17920:1;17916:12;;;;17963;;;17984:61;;18038:4;18030:6;18026:17;18016:27;;17984:61;18091:2;18083:6;18080:14;18060:18;18057:38;18054:161;;18137:10;18132:3;18128:20;18125:1;18118:31;18172:4;18169:1;18162:15;18200:4;18197:1;18190:15;18352:545;18454:2;18449:3;18446:11;18443:448;;;18490:1;18515:5;18511:2;18504:17;18560:4;18556:2;18546:19;18630:2;18618:10;18614:19;18611:1;18607:27;18601:4;18597:38;18666:4;18654:10;18651:20;18648:47;;;-1:-1:-1;18689:4:22;18648:47;18744:2;18739:3;18735:12;18732:1;18728:20;18722:4;18718:31;18708:41;;18799:82;18817:2;18810:5;18807:13;18799:82;;;18862:17;;;18843:1;18832:13;18799:82;;19073:1352;19193:10;;-1:-1:-1;;;;;19215:30:22;;19212:56;;;19248:18;;:::i;:::-;19277:97;19367:6;19327:38;19359:4;19353:11;19327:38;:::i;:::-;19321:4;19277:97;:::i;:::-;19429:4;;19493:2;19482:14;;19510:1;19505:663;;;;20212:1;20229:6;20226:89;;;-1:-1:-1;20281:19:22;;;20275:26;20226:89;-1:-1:-1;;19030:1:22;19026:11;;;19022:24;19018:29;19008:40;19054:1;19050:11;;;19005:57;20328:81;;19475:944;;19505:663;18299:1;18292:14;;;18336:4;18323:18;;-1:-1:-1;;19541:20:22;;;19659:236;19673:7;19670:1;19667:14;19659:236;;;19762:19;;;19756:26;19741:42;;19854:27;;;;19822:1;19810:14;;;;19689:19;;19659:236;;;19663:3;19923:6;19914:7;19911:19;19908:201;;;19984:19;;;19978:26;-1:-1:-1;;20067:1:22;20063:14;;;20079:3;20059:24;20055:37;20051:42;20036:58;20021:74;;19908:201;-1:-1:-1;;;;;20155:1:22;20139:14;;;20135:22;20122:36;;-1:-1:-1;19073:1352:22:o;20430:640::-;20710:3;20748:6;20742:13;20764:66;20823:6;20818:3;20811:4;20803:6;20799:17;20764:66;:::i;:::-;-1:-1:-1;;;20852:16:22;;;20877:18;;;20920:13;;20942:78;20920:13;21007:1;20996:13;;20989:4;20977:17;;20942:78;:::i;:::-;21040:20;21062:1;21036:28;;20430:640;-1:-1:-1;;;;20430:640:22:o;21075:783::-;21396:6;21385:9;21378:25;21439:3;21434:2;21423:9;21419:18;21412:31;21359:4;21466:46;21507:3;21496:9;21492:19;21484:6;21466:46;:::i;:::-;21560:9;21552:6;21548:22;21543:2;21532:9;21528:18;21521:50;21594:33;21620:6;21612;21594:33;:::i;:::-;21580:47;;21675:9;21667:6;21663:22;21658:2;21647:9;21643:18;21636:50;21709:33;21735:6;21727;21709:33;:::i;:::-;21695:47;;21791:9;21783:6;21779:22;21773:3;21762:9;21758:19;21751:51;21819:33;21845:6;21837;21819:33;:::i;:::-;21811:41;21075:783;-1:-1:-1;;;;;;;;21075:783:22:o;21863:251::-;21933:6;21986:2;21974:9;21965:7;21961:23;21957:32;21954:52;;;22002:1;21999;21992:12;21954:52;22034:9;22028:16;22053:31;22078:5;22053:31;:::i;22119:127::-;22180:10;22175:3;22171:20;22168:1;22161:31;22211:4;22208:1;22201:15;22235:4;22232:1;22225:15;22251:135;22290:3;22311:17;;;22308:43;;22331:18;;:::i;:::-;-1:-1:-1;22378:1:22;22367:13;;22251:135::o;22654:127::-;22715:10;22710:3;22706:20;22703:1;22696:31;22746:4;22743:1;22736:15;22770:4;22767:1;22760:15;22786:713;22950:4;22998:2;22987:9;22983:18;23028:6;23017:9;23010:25;23054:2;23092;23087;23076:9;23072:18;23065:30;23115:6;23150;23144:13;23181:6;23173;23166:22;23219:2;23208:9;23204:18;23197:25;;23257:2;23249:6;23245:15;23231:29;;23278:1;23288:185;23302:6;23299:1;23296:13;23288:185;;;23377:13;;23370:21;23363:29;23351:42;;23448:15;;;;23413:12;;;;23324:1;23317:9;23288:185;;;-1:-1:-1;23490:3:22;;22786:713;-1:-1:-1;;;;;;;22786:713:22:o;23504:125::-;23569:9;;;23590:10;;;23587:36;;;23603:18;;:::i;23634:168::-;23707:9;;;23738;;23755:15;;;23749:22;;23735:37;23725:71;;23776:18;;:::i;23807:128::-;23874:9;;;23895:11;;;23892:37;;;23909:18;;:::i;23940:127::-;24001:10;23996:3;23992:20;23989:1;23982:31;24032:4;24029:1;24022:15;24056:4;24053:1;24046:15;24072:112;24104:1;24130;24120:35;;24135:18;;:::i;:::-;-1:-1:-1;24169:9:22;;24072:112::o;24506:722::-;24556:3;24597:5;24591:12;24626:36;24652:9;24626:36;:::i;:::-;24681:1;24698:18;;;24725:133;;;;24872:1;24867:355;;;;24691:531;;24725:133;-1:-1:-1;;24758:24:22;;24746:37;;24831:14;;24824:22;24812:35;;24803:45;;;-1:-1:-1;24725:133:22;;24867:355;24898:5;24895:1;24888:16;24927:4;24972:2;24969:1;24959:16;24997:1;25011:165;25025:6;25022:1;25019:13;25011:165;;;25103:14;;25090:11;;;25083:35;25146:16;;;;25040:10;;25011:165;;;25015:3;;;25205:6;25200:3;25196:16;25189:23;;24691:531;;;;;24506:722;;;;:::o;25233:802::-;-1:-1:-1;;;25727:55:22;;25709:3;25801:47;25844:2;25835:12;;25827:6;25801:47;:::i;:::-;-1:-1:-1;;;25857:46:22;;25922;25964:2;25956:11;;25948:6;25922:46;:::i;:::-;-1:-1:-1;;;25977:26:22;;26027:1;26019:10;;25233:802;-1:-1:-1;;;;;25233:802:22:o;26040:291::-;26217:6;26206:9;26199:25;26260:2;26255;26244:9;26240:18;26233:30;26180:4;26280:45;26321:2;26310:9;26306:18;26298:6;26280:45;:::i;26589:521::-;26666:4;26672:6;26732:11;26719:25;26826:2;26822:7;26811:8;26795:14;26791:29;26787:43;26767:18;26763:68;26753:96;;26845:1;26842;26835:12;26753:96;26872:33;;26924:20;;;-1:-1:-1;;;;;;26956:30:22;;26953:50;;;26999:1;26996;26989:12;26953:50;27032:4;27020:17;;-1:-1:-1;27063:14:22;27059:27;;;27049:38;;27046:58;;;27100:1;27097;27090:12;27046:58;26589:521;;;;;:::o;27115:474::-;27347:3;27385:6;27379:13;27401:66;27460:6;27455:3;27448:4;27440:6;27436:17;27401:66;:::i;:::-;-1:-1:-1;;;27489:16:22;;27514:39;;;-1:-1:-1;27580:2:22;27569:14;;27115:474;-1:-1:-1;27115:474:22:o;27594:835::-;-1:-1:-1;;;28098:3:22;28091:20;28073:3;28130:46;28173:1;28168:3;28164:11;28156:6;28130:46;:::i;:::-;-1:-1:-1;;;28192:2:22;28185:22;28236:6;28230:13;28252:73;28318:6;28314:1;28310:2;28306:10;28299:4;28291:6;28287:17;28252:73;:::i;:::-;-1:-1:-1;;;28383:1:22;28344:15;;;;28375:10;;;28368:28;28420:2;28412:11;;27594:835;-1:-1:-1;;;;27594:835:22:o;28434:1321::-;-1:-1:-1;;;28938:3:22;28931:20;28913:3;28970:46;29013:1;29008:3;29004:11;28996:6;28970:46;:::i;:::-;-1:-1:-1;;;29032:2:22;29025:22;29076:6;29070:13;29092:73;29158:6;29154:1;29150:2;29146:10;29139:4;29131:6;29127:17;29092:73;:::i;:::-;29227:34;29223:1;29184:15;;;;29215:10;;;29208:54;29291:34;29286:2;29278:11;;29271:55;29355:34;29350:2;29342:11;;29335:55;29420:34;29414:3;29406:12;;29399:56;29485:34;29479:3;29471:12;;29464:56;29550:34;29544:3;29536:12;;29529:56;29615:66;29609:3;29601:12;;29594:88;-1:-1:-1;;;29706:3:22;29698:12;;29691:30;29745:3;29737:12;;28434:1321;-1:-1:-1;;;;28434:1321:22:o;29760:458::-;-1:-1:-1;;;30017:3:22;30010:41;29992:3;30080:6;30074:13;30096:75;30164:6;30159:2;30154:3;30150:12;30143:4;30135:6;30131:17;30096:75;:::i;:::-;30191:16;;;;30209:2;30187:25;;29760:458;-1:-1:-1;;29760:458:22:o;30223:358::-;-1:-1:-1;;;30470:43:22;;30452:3;30529:46;30572:1;30563:11;;30555:6;30529:46;:::i;30586:874::-;-1:-1:-1;;;31090:3:22;31083:16;31065:3;31128:6;31122:13;31144:74;31211:6;31207:1;31202:3;31198:11;31191:4;31183:6;31179:17;31144:74;:::i;:::-;-1:-1:-1;;;31277:1:22;31237:16;;;31269:10;;;31262:66;31347:46;31389:2;31381:11;;31373:6;31347:46;:::i;:::-;-1:-1:-1;;;31402:26:22;;31452:1;31444:10;;30586:874;-1:-1:-1;;;;;30586:874:22:o;31465:550::-;-1:-1:-1;;;31760:43:22;;31742:3;31822:46;31865:1;31856:11;;31848:6;31822:46;:::i;:::-;31897:6;31891:13;31913:65;31971:6;31967:2;31960:4;31952:6;31948:17;31913:65;:::i;:::-;31994:15;;31465:550;-1:-1:-1;;;;31465:550:22:o;32020:1148::-;-1:-1:-1;;;;;;;;;;;32378:3:22;32371:79;32480:66;32475:2;32470:3;32466:12;32459:88;32577:34;32572:2;32567:3;32563:12;32556:56;32642:66;32637:2;32632:3;32628:12;32621:88;32740:66;32734:3;32729;32725:13;32718:89;32838:66;32832:3;32827;32823:13;32816:89;32353:3;32934:6;32928:13;32950:74;33017:6;33011:3;33006;33002:13;32997:2;32989:6;32985:15;32950:74;:::i;:::-;-1:-1:-1;;;33083:3:22;33043:16;;;;33075:12;;;33068:66;-1:-1:-1;33158:3:22;33150:12;;32020:1148;-1:-1:-1;32020:1148:22:o;33173:644::-;-1:-1:-1;;;33524:61:22;;33608:13;;33506:3;;33630:75;33608:13;33693:2;33684:12;;33677:4;33665:17;;33630:75;:::i;:::-;-1:-1:-1;;;33764:2:22;33724:16;;;;33756:11;;;33749:35;-1:-1:-1;33808:2:22;33800:11;;33173:644;-1:-1:-1;33173:644:22:o;33822:1062::-;-1:-1:-1;;;;;;;;;;;34180:3:22;34173:79;34282:66;34277:2;34272:3;34268:12;34261:88;34379:66;34374:2;34369:3;34365:12;34358:88;34476:66;34471:2;34466:3;34462:12;34455:88;34583:36;34578:3;34574:46;34568:3;34563;34559:13;34552:69;34155:3;34650:6;34644:13;34666:74;34733:6;34727:3;34722;34718:13;34713:2;34705:6;34701:15;34666:74;:::i;:::-;-1:-1:-1;;;34799:3:22;34759:16;;;;34791:12;;;34784:66;-1:-1:-1;34874:3:22;34866:12;;33822:1062;-1:-1:-1;33822:1062:22:o;34889:636::-;-1:-1:-1;;;35240:53:22;;35316:13;;35222:3;;35338:75;35316:13;35401:2;35392:12;;35385:4;35373:17;;35338:75;:::i;:::-;-1:-1:-1;;;35472:2:22;35432:16;;;;35464:11;;;35457:35;-1:-1:-1;35516:2:22;35508:11;;34889:636;-1:-1:-1;34889:636:22:o;35530:623::-;-1:-1:-1;;;35881:51:22;;35955:13;;35863:3;;35977:75;35955:13;36040:2;36031:12;;36024:4;36012:17;;35977:75;:::i;:::-;-1:-1:-1;;;36111:2:22;36071:16;;;;36103:11;;;36096:24;-1:-1:-1;36144:2:22;36136:11;;35530:623;-1:-1:-1;35530:623:22:o;36158:461::-;36420:31;36415:3;36408:44;36390:3;36481:6;36475:13;36497:75;36565:6;36560:2;36555:3;36551:12;36544:4;36536:6;36532:17;36497:75;:::i;:::-;36592:16;;;;36610:2;36588:25;;36158:461;-1:-1:-1;;36158:461:22:o;36624:527::-;36877:6;36866:9;36859:25;36920:6;36915:2;36904:9;36900:18;36893:34;36963:3;36958:2;36947:9;36943:18;36936:31;36840:4;36990:46;37031:3;37020:9;37016:19;37008:6;36990:46;:::i;:::-;37084:9;37076:6;37072:22;37067:2;37056:9;37052:18;37045:50;37112:33;37138:6;37130;37112:33;:::i;:::-;37104:41;36624:527;-1:-1:-1;;;;;;;36624:527:22:o;37156:2296::-;-1:-1:-1;;;38383:43:22;;38365:3;38445:46;38488:1;38479:11;;38471:6;38445:46;:::i;:::-;-1:-1:-1;;;38500:58:22;;38577:46;38619:2;38611:11;;38603:6;38577:46;:::i;:::-;-1:-1:-1;;;38632:46:22;;38567:56;-1:-1:-1;38697:46:22;38739:2;38731:11;;38723:6;38697:46;:::i;:::-;-1:-1:-1;;;38752:48:22;;38687:56;-1:-1:-1;38819:46:22;38861:2;38853:11;;38845:6;38819:46;:::i;:::-;-1:-1:-1;;;38874:62:22;;38809:56;-1:-1:-1;38955:46:22;38997:2;38989:11;;38981:6;38955:46;:::i;:::-;-1:-1:-1;;;39010:79:22;;39112:13;;38945:56;;-1:-1:-1;39134:74:22;39112:13;39196:2;39188:11;;39181:4;39169:17;;39134:74;:::i;:::-;-1:-1:-1;;;39266:2:22;39227:15;;;;39258:11;;;39251:69;39339:46;39381:2;39373:11;;39365:6;39339:46;:::i;:::-;-1:-1:-1;;;39394:26:22;;39444:1;39436:10;;37156:2296;-1:-1:-1;;;;;;;;;;37156:2296:22:o;41988:225::-;42092:4;42071:12;;;42085;;;42067:31;42118:22;;;;42159:24;;;42149:58;;42187:18;;:::i;42218:151::-;42308:4;42301:12;;;42287;;;42283:31;;42326:14;;42323:40;;;42343:18;;:::i;42374:148::-;42462:4;42441:12;;;42455;;;42437:31;;42480:13;;42477:39;;;42496:18;;:::i;42527:175::-;42564:3;42608:4;42601:5;42597:16;42637:4;42628:7;42625:17;42622:43;;42645:18;;:::i;:::-;42694:1;42681:15;;42527:175;-1:-1:-1;;42527:175:22:o;42707:427::-;42967:1;42962:3;42955:14;42937:3;42998:6;42992:13;43014:74;43081:6;43077:1;43072:3;43068:11;43061:4;43053:6;43049:17;43014:74;:::i;:::-;43108:16;;;;43126:1;43104:24;;42707:427;-1:-1:-1;;42707:427:22:o;43139:120::-;43179:1;43205;43195:35;;43210:18;;:::i;:::-;-1:-1:-1;43244:9:22;;43139:120::o;43264:489::-;-1:-1:-1;;;;;43533:15:22;;;43515:34;;43585:15;;43580:2;43565:18;;43558:43;43632:2;43617:18;;43610:34;;;43680:3;43675:2;43660:18;;43653:31;;;43458:4;;43701:46;;43727:19;;43719:6;43701:46;:::i;43758:249::-;43827:6;43880:2;43868:9;43859:7;43855:23;43851:32;43848:52;;;43896:1;43893;43886:12;43848:52;43928:9;43922:16;43947:30;43971:5;43947:30;:::i;44566:691::-;-1:-1:-1;;;44941:16:22;;45012:3;44990:16;;;-1:-1:-1;;;;;;44986:43:22;44982:1;44973:11;;44966:64;-1:-1:-1;;;45055:1:22;45046:11;;45039:51;45113:13;;-1:-1:-1;;45135:75:22;45113:13;45198:2;45189:12;;45182:4;45170:17;;45135:75;:::i;:::-;45230:16;;;;45248:2;45226:25;;44566:691;-1:-1:-1;;;44566:691:22:o;45262:287::-;45391:3;45429:6;45423:13;45445:66;45504:6;45499:3;45492:4;45484:6;45480:17;45445:66;:::i;:::-;45527:16;;;;;45262:287;-1:-1:-1;;45262:287:22:o
Swarm Source
ipfs://20ca10d25cc2579867a12aa3307559f37a93dd8bba2ce9793f5ce20ade520995
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.