ERC-721
Overview
Max Total Supply
161 SNAV
Holders
62
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
5 SNAVLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
SandAvatars
Compiler Version
v0.8.7+commit.e28d00a7
Optimization Enabled:
Yes with 100 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.2; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; interface SandInterface { function ownerOf(uint256 tokenId) external view returns (address owner); function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId); } contract SandAvatars is ERC721, ERC721Enumerable, Ownable { bool public saleIsActive = false; bool public burned = false; address public SandAddress = 0xB90b34B41658aC20A0051874FeeE1933c3614fa7; SandInterface SandContract = SandInterface(SandAddress); constructor() ERC721("SandAvatars", "SNAV") { } function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal override(ERC721, ERC721Enumerable) { super._beforeTokenTransfer(from, to, tokenId); } function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC721Enumerable) returns (bool) { return super.supportsInterface(interfaceId); } function random(string memory input) internal pure returns (uint256) { return uint256(keccak256(abi.encodePacked(input))); } function toHashCode(uint256 value) internal pure returns (string memory) { uint256 i; bytes memory buffer = "000000"; for(i=6;i>0;i--) { if (value % 16 < 10) buffer[i-1] = bytes1(uint8(48 + uint256(value % 16))); else buffer[i-1] = bytes1(uint8(55 + uint256(value % 16))); value /= 16; } return string(buffer); } function toString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } function getPolygon(uint256 num, string memory color, string memory op) internal pure returns (string memory) { uint256[207]memory xtypes =[ 14121436260491623888573569494265958210382088460059485271557129702735745326, 3379687223624639408404345647054286820230943047769096274235841555659165627614, 4766529846908783929200657017927412346891862284447113714675691880753314010650, 2414848826299563751631584, 2415403168366050671711990, 165989458421190421426294049862974048, 2990041845436834032465436684735961822206490428694177, 205519767453372228188215768215336195851890616474781117116470017, 783342371240660400615497362662867695169835591505009495153, 3015605336097770010832060948773439899320263180355111271447081940574438532253, 1699410383171683060484640923082407994735009912351540698902523680158858963667, 2067439483755009076537239878613967120688171739225650558832839415147437291640, 2110285635025633850782162448438909787314249243868635101044081548977791378060, 1813537826634847775588271020849619009466237369690820983365919405283580390552, 1433165981178011733008463800384150766019695303333840710976987787175893725835, 1347834300580146900593882219877353796923237396140869764780512560971696623306, 1588291142145332360308884532736805401102486146533600217899801854658095932103, 1630640689404733378642505262896486732354314158877471864006247217340780175548, 1926975200976366162727790765948535744022368363806555952276809889580033045183, 2195729526611169200073088264115405134266050171528327914526689757427595025581, 2266183416249769109687683253195421600011544355208010500246994655874713467054, 1942021118171089200927872160880968143467387698704835635209143544230560220841, 2026692120635480416902954766191778704951595844413918284067846871351766098126, 2252931742901068372445672611749832774842961514843407512141469648329648975563, 2295116187662235110121913666276726987468444668928175066731688914204036246718, 2592194794286804437698157144159526339621523043225693230464121704378048799436, 2535270053559044811589912991644676175666664223951765667507672669824291794632, 2676810635330829446627987247531416732227338364894945326305024218158728837315, 2676507767503271220336019071355421318369328191959582692781556145107637730497, 2860260185232810836874932161100098492177796172019734599621174229889736083643, 2704583530546838355578889545793450502804454913237751059045251025304634622638, 2732605051757189469738771911402128307348469092831311049021474868234958504110, 2689896882341260570152089198804438177341639211772304451963188924944556062881, 2874339369183394173601732921210730487262146816407635719706621996970437346462, 134063278, 11401402070285144550100871971896250052146431669, 11401442479798540347354564667579758730284697744, 2010405393385468769754390500839040943260313875155174100691674881837603800274, 53852718675364590822474638051961946119679634989037219218611160268927, 2873152535253068203115307214512935299514021674337530122812293448446001082573, 632967951439172729344733328545, 2703590214691199062276704278272662481619631230524746364075007852563519075527, 3142100272699584422061276135492595947566116804089604574541184736671832567449, 2989437538194262125706135904879775746659906037333659, 2732882416327165001845161696611165857660612391574224505373154795372861555376, 511, 2407752739435277468182135965268740961167067564356323244993211865623229981385, 2718635756548816077094781045246157570894954467225593574078410329624519202986, 205426318550813624678543263541887184093338878840179569528765611, 783755749980388114187626910565273421423263977749007664810, 2548935505955974898918714072113448954440083838302132660405920669118189609678, 2620798165283744002906637766862406499463773050371800692306162182138139601596, 511, 3072227530827800386450195294804395741003464330979216039104110948505046855347, 134062774, 2492699542259379918880031894535889655400300980491640244623151733365212783310, 3439125500424588101080488050237853159581039880613797914734533628447204922543, 35140538584256, 3242094284692887871609116300080036303492460653890804351075462070651154177202, 511, 1770013146521665037408692954108461375963030202334087742099350891873277133542, 2416417129151844328456352, 205354787381561677649152221282543919859758865255427095704153723, 4554618901733828934554583591157904263166577235187268654483446904656196608231, 205399677480996743294400265142671549319989067471689792870214765, 1687649379406570998776343934026219620523553877468665929082612794343857930982, 35146584669401, 43490082804405313463985993646168051869873, 682778994860606022295232778088851114906462078344796921178050393667028676812, 924784587014537063152182727386123816934642400149158636683653472794560994908, 511, 740975772651252457144836420278673397610254157186597222250099236134980751977, 2414117941576320369311410, 632708923678708594065717615261, 1458925500838540507418926026561993567301703685253672786264170589214896329935, 1362215544816844226291935252053426049015218768525540613182698930612617390203, 205358079224472907756417989573029084098844703882026101090076869, 783366263800606206590835024970459678702881525236644753005, 11400184790511075841139148509544386174780755664, 165862180158385183703562576710887618, 1953753321857745697879799949839981476218506366288294591805006875595925160150, 9209770061908476534, 9208258027669985499, 1007024817493647344034072868464098635223782697202574437333574124131465880276, 978311935401717486461471199063926706147737078905916884262441267563763117176, 1744463536117297771199500556841754719200382694378654872668579678780200630368, 511, 1744601465411721296895678703119841194368939717120234214930076101190129364598, 11401222567826577545303997980370987807270047450, 9208989541913880222, 1092826092546994839469209809358617178552720724428088672892094552082176036544, 632684934038491608715134540950, 14115595813093446524490909446834395552161017956518832857934551862262970508, 632986958806261141854888479370, 632977282640443796338332746377, 2052946140791500114938153887393848933442548125195317854590544344108166871666, 134024309, 2414284504605938271190647, 2414432961303085847740591, 1840619951669604201410879954770232798770635410344762643704857699299414045884, 2054740440345882338413182726751774799923504795098535273396345647260901121653, 11401099814810876640669013063882522770837151408, 2251164459629472805890764632980280277423766955907349854903606843989721679987, 35133399578745, 632965160288698604399670134412, 632963006881331930588495022277, 1786344573953401262130609349327547713072556579231105641242862738580471876815, 2038589805006897792509112007954350735573250959223795959103614935773248814209, 53842228122476702495773295789384926848390152018530179498957340490361, 2111666526756141710963288250158183316620790909592475932262883279353406879950, 134025936, 165907096476797172510820836217519220, 165907184370672188268528709397970124, 1658082137457338989675227097692720737868293871022172673441890803106526591693, 1883024388535656625284391916361025676073851550858069989271493020769645815925, 1926920472707949547012838945053378431215376612467398300984843403947283124847, 35131542532261, 2024594198579077053330764490684944254136592945947480819607862982763103974004, 35131923427956, 165909021475966603241960532792900752, 165909083373204686735841121470840002, 1885618862360980679350640322437473822248060842137738006611198105431721960658, 1742173066023287913099403968227517944924073894310750451819876872377331939012, 1614407666257820487363169021269399758278734125660509710128450889567286921848, 1744464615782850979964182648476765026166962618378931230221541869862448329839, 134014162, 11401182764097204976827754137621811304469167267, 1771877757361298981460197733359093436404203289488771558972277815195612811459, 35133957411001, 2010266548816189564479104322685517328153080461434873302541240831931155540179, 1304683555199795152622005937938311831570780363298831092900867642675445952117, 1969021876408794075999015047652559943941859790002927827734170938252782778009, 43490414745042222856303808090815535583909, 2180572158151246410001024254246908758834719272846442894189196745760436466396, 1673403802771746401375198818222556837670706048123256272574605586619058958977, 1885288008633175329315918003045024399639454063428632155870688280191534429897, 1416905731959046147692107590348875820999182264648841806339526292113423404216, 1997291483260239039461852812345115693394643947621579986309362922487406451834, 783558446483948923466464176747535046874779770473507527338, 14115978838654814715707104984262644478936595142475981459604830162147428033, 633107969808034801031089073827, 2633578470602599440322905773949466446156875479267007458201540814813565895350, 632977495378512133649644484776, 165929986036551556547801149694623415, 2989025485403311877817610573034810975450514052426906, 205407434988195293878750642328847735295359291050132879493903533, 11404056456687223639749243846043887237610963095, 2989675086510346121999155662963669593588724326309475, 43500872086127607303759630063956263790259, 43501704123066862598939503992370536738999, 11405895771622953147234522950227641433617192204, 633135015023432504038451692802, 1798132692690596179620705189163856188119368407084938759745728243059276205742, 2989220037414416967977113123657014036013879774232178, 165937578388141905202686021359195820, 2414727696459509174196890, 2414691127125256287900332, 165915365962175250832669694316052105, 165910991072664731647969066886692541, 165915364714563768096814076148908681, 632905030222108565907283182269, 14120708005514235896398854230464658906875090178430929295545649270898687532, 3337199960013931773256446509889229036480433598974937326816702961831104073785, 3605596203950561889636721869696093579010718870466811845253629283825091211308, 633155812478473693991465778734, 9213733475672780801, 3167748284762293053715838884979026074229237355454641984176617526858699095095, 9213067443423788601, 205469983996266401852074125388687431408097597551877715399396883, 3351113016766149477002540489062003105409306561172428804040580041473100728372, 9213383966672673328, 43512465521962263479832723055980780052022, 3520125028586159092693396574728389547239517587975760695831987336475883987511, 3534756679028325853283430757339694332274937217738686833232855861131381961745, 633170324347821347278826632744, 3576139438807138707926215165472039742119299231360549960477337344216086985298, 9213737944048074266, 14119204143756774178704498797963472268374854012663999297240300317580833876, 2415408463281380994969144, 3365166644055540638233802210399874078674695627002040277764271603049931312166, 165988148429214389023346425638543400, 1887746225632730957138348290686608844568954207126319086712163562729765690710, 1915600863297605383381527809737518613446657499530049954771583968952018611994, 2113322577499690111671980382294985200037260660369180400997101761556814565131, 2296689143527392781842689264020699383608121252820658176192302688260167906561, 1660566289916744597573142969784638710355914531095542918433558190781161095928, 2534082095414892391686150036943765103020588807891018485576253045401890385141, 633024223136024389052689114166, 2241391978884043179921934352810270624406243989287534804133301471739814963539, 14116875255364126381735783362239064288396228655148828240929468015891006244, 2193355749223663387186473805456239874894208331871277368480859777693891256633, 2403831831909932078863419000029126387693398488022480060606911847939131651161, 632995175865805100776593642529, 1995274819321270135644234375868044978329361002748554918878840054020430981452, 2375396906030561049849552299865999851499367560653426663546240001308245435983, 35139812415002, 2235677420740099074517491835994945260329291511134955606995441301360674695509, 14116911062155530733820699789705328612116920974874452489152294027973179472, 2678770361965612704120099657034866152680834834755057279760189508348235082564, 3287203733699690768233314741557537574339684689442054036487386010876555637992, 4064839512598947773653950189688692616236907353206181272213310648298450050346, 4120828199034495056757676173705786195371723329918666661524593207136859074328, 2415394844344362282141479, 36325149170812693104873872163691011689991992041050311830217183986701738246657, 64478519805822442329262443918803540875483425373278030259456266971945429652305, 86726949164196919860061327850596874826858820280533989768291036578610410590608, 4291282370 ]; uint256 i; uint256 first_index; uint256 cur_num; uint256 k; uint256 pos; uint256 part; string memory res; uint256 result; part = (xtypes[203+(num/32)] / (256**(num%32))); first_index = part%256; res = ''; for(i = first_index-1; i<=250; i++) { if (xtypes[i] == 0) break; cur_num= xtypes[i]; k=0; for(pos=0;pos<=27;pos++) { result = (cur_num / (512 ** pos)) % 512; if (result == 511) break; if (k%2 == 0) { res = string(abi.encodePacked(res, toString(result*3), ',')); } else { res = string(abi.encodePacked(res, toString(result*3), ' ')); } k++; } if (result == 511) break; } return string(abi.encodePacked('<polygon opacity="',op,'" points="', res, '" fill="#',color,'" />')); } function tokenURI(uint256 tokenId) pure public override(ERC721) returns (string memory) { uint256[19] memory xtypes; string[6] memory colors; string memory output; uint256[12] memory params; uint256 pos; uint256 i; uint256 rand = random(string(abi.encodePacked('SandMan',toString(tokenId)))); params[0] = 1 + (rand % 30); // pallette= params[1] = 1 + ((rand/100) % 5);// beard params[2] = 1 + ((rand/1000) % 6); // cap params[3] = 1 + ((rand/10000) % 5); // glasses params[4] = 1 + ((rand/100000) % 4); // tube params[5] = 1 + ((rand/1000000) % 6); // object params[6] = 1 + ((rand/100000000) % 6); // far params[7] = 1 + ((rand/1000000000) % 10); // Band - aid xtypes[0] = 1765300933158159279126365688755849989787469680610145113308712138382768895; xtypes[1] = 1764921079952145254276332071479222557911241288448461372909069781721677547; xtypes[2] = 1501679087584470838161589003975082910140105054122807965032669773169688478; xtypes[3] = 1764781974038155230893998203428071971942131358905837942209321033418145694; xtypes[4] = 1764351442057709576512408600184270815014492966481600074584100303563390699; xtypes[5] = 1764513942681239813290380170455237895030536670527749966108226146279030779; xtypes[6] = 1765083764856076636672938774629519978791146014135139882458135528892006302; xtypes[7] = 1763024496842125922962385602205943197321056192857025632119827849480763839; xtypes[8] = 1675710049990272911441037604203877133533668492266557815129548233759518128; xtypes[9] = 1551233773361696239304903403895808160934653895059654415324688197841582071; xtypes[10] = 1625636607414481457642678052301313971780849938445042085056482070100953889; xtypes[11] = 1722512524339940313921309205786012536301170577779571168786046988462044871; xtypes[12] = 1766836768210894802335784057954424698551920770841938248704295415987566568; xtypes[13] = 442714978489977024950392528240390319461857033012516340293718171539472383; xtypes[14] = 1198354148602851882454841352599916552948941833809782804420285718256091136; xtypes[15] = 1765862763184508503075712492699913383911672107677599518220277459367559248; for(i=0;i<=4;i++) { pos = (params[0]-1) * 5 + i; colors[i] = toHashCode(xtypes[pos/10] / (16777216 ** (pos%10)) % 16777216); } output = string(abi.encodePacked('<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" width="1000px" height="1000px" viewBox="0 0 1000 1000"><linearGradient id="g" gradientUnits="userSpaceOnUse" x2="0" y2="1000"><stop offset="0.1" style="stop-color:#',colors[2],'"/><stop offset="0.5" style="stop-color:#',colors[1],'"/><stop offset="1" style="stop-color:#',colors[2],'"/></linearGradient><rect x="0" y="0" fill="url(#g)" width="1000" height="1000"/>', '<circle opacity="0.09" fill="#FFFFFF" cx="726" cy="380" r="151"/><radialGradient id="s" cx="44" cy="723" r="99" gradientTransform="matrix(1 0 0 -1 662 1118)" gradientUnits="userSpaceOnUse"><stop offset="0.6" style="stop-color:#FFFFFF"/><stop offset="1" style="stop-color:#',colors[1],'"/></radialGradient><circle opacity="0.8" fill="url(#s)" cx="706" cy="395" r="99"/>', getPolygon(92 +params[6], colors[2], '0.08'))); output = string(abi.encodePacked(output,'<g><path opacity="0.11" fill="#FFFFFF" d="M668,533c0,0,313,0,303-28s-397-48,15-46c301,2,196,46,460,43c258-3,484-60,485-17s-290,24-290,50s288,9,478,12c189,3,341-83,535-26c194,56,322,32,517,5c194-27,140,0,427,0s1180,0,1180,0v-31H3607c0,0-137-11-283-10c-146,0-162,33-394-7c-232-41-312-43-420-24c-107,18-255,68-395,74s-397,18-398,7c-1-10,447-26,446-65c-1-38-176-42-391-25c-215,16-395-14-568-19c-172-4-626-8-627,25s323,25,322,50c0,9-593,3-593,3H-36v27h478C442,531,553,533,668,533"/><path opacity="0.11" fill="#FFFFFF" d="M668,514c0,0,322,12,312-15c-10-28-804-56,8-62c301-2,239,37,503,34c258-3,565-42,569,1c2,29-381,32-417,61c-23,18,273,12,470,7c189-5,513-94,714-52c212,44,184,46,379,18c194-27,188,1,475,1s1096,0,1096,0v-20c0,0-1102,0-1175,0s-137-13-284-13c-146,0-161,25-393-16s-315-31-422-12c-107,18-250,68-389,74s-432,24-432,13c0-13,458-25,473-71c12-37-172-54-387-38s-395-14-568-19c-172-4-620,7-621,41s319,32,321,51c0,9-598-12-598-12H-36v27h478C442,513,553,514,668,514z"/><animateMotion path="M 0 0 L -3750 40 Z" dur="150s" repeatCount="indefinite" /></g>', getPolygon(80 +params[5]*2-1, colors[2], '0.1'), getPolygon(80 +params[5]*2, colors[2], '0.4'))); output = string(abi.encodePacked(output, getPolygon(0, colors[2], '1'), getPolygon(1, colors[1], '1'), getPolygon(2, colors[0], '0.2'), getPolygon(3, colors[2], '0.3'), getPolygon(4, colors[2], '0.3'), getPolygon(5, colors[0], '0.2'))); output = string(abi.encodePacked(output, getPolygon(6, colors[4], '1'), getPolygon(7, colors[3], '1'), getPolygon(8, 'FFFFFF', '0.9'), getPolygon(9, 'FFFFFF', '0.9'), '<circle fill="#',colors[2],'" cx="566" cy="406" r="7.3"/><circle opacity="0.66" fill="#FFFFFF" cx="570" cy="404" r="3"/><circle fill="#',colors[2],'" cx="414" cy="407" r="7.3"/><circle opacity="0.66" fill="#FFFFFF" cx="418" cy="404" r="3"/><g>')); output = string(abi.encodePacked(output, getPolygon(77, colors[3],'1'), getPolygon(78, colors[3], '1'), getPolygon(79, colors[4], '1'), getPolygon(80, colors[4], '1'), '<animate attributeName="opacity" values="0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0" dur="4s" repeatCount="indefinite" begin="0s"/></g>')); if (params[7] == 1) { output = string(abi.encodePacked(output, getPolygon(38, colors[0],'1'), getPolygon(39, colors[3], '1'), getPolygon(40, colors[3], '1'))); } output = string(abi.encodePacked(output, getPolygon(9 +params[1]*2-1, colors[3], '1'), getPolygon(9 +params[1]*2, colors[2], '0.66'), getPolygon(19 +params[2]*3-2, colors[2], '1'), getPolygon(19 +params[2]*3-1, colors[1], '0.6'), getPolygon(19 +params[2]*3, colors[1], '0.6'))); output = string(abi.encodePacked(output, getPolygon(40 +params[3]*4-3, colors[3], '0.92'), getPolygon(40 +params[3]*4-2, colors[0], '0.25'), getPolygon(40 +params[3]*4-1, colors[0], '0.25'), getPolygon(40 +params[3]*4, colors[2], '1'))); output = string(abi.encodePacked(output, getPolygon(60 +params[4]*4-3, colors[2], '1'), getPolygon(60 +params[4]*4-2, colors[1], '0.5'), getPolygon(60 +params[4]*4-1, colors[1], '0.5'), getPolygon(60 +params[4]*4, colors[1], '1'), '<g>', getPolygon(98, colors[2], '1'), '<animateMotion path="M0,0 C5,-5 12,-5 15,-12Z" dur="10s" repeatCount="indefinite"/></g></svg> ')); string memory strparams; strparams = string(abi.encodePacked('[{ "trait_type": "Palette", "value": "', toString(params[0]), '" }, { "trait_type": "Beard", "value": "', toString(params[1]), '" }, { "trait_type": "Cap", "value": "', toString(params[2]))); strparams = string(abi.encodePacked(strparams, '" }, { "trait_type": "Glasses", "value": "', toString(params[3]), '" }, { "trait_type": "Tube", "value": "', toString(params[4]), '" }, { "trait_type": "Object", "value": "', toString(params[5]))); if (params[7] == 1) { strparams = string(abi.encodePacked(strparams, '" }, { "trait_type": "Band - aid", "value": "1')); } strparams = string(abi.encodePacked(strparams, '" }, { "trait_type": "Far", "value": "', toString(params[6]), '" }]')); string memory json = Base64.encode(bytes(string(abi.encodePacked('{"name": "Onchain Sandman", "description": "Onchain Sandman - beautiful avatar, completely generated OnChain","attributes":', strparams, ', "image": "data:image/svg+xml;base64,', Base64.encode(bytes(output)), '"}')))); output = string(abi.encodePacked('data:application/json;base64,', json)); return output; } function flipSaleState() public onlyOwner { saleIsActive = !saleIsActive; } function burnAll() public onlyOwner { burned = true; } function directMint(address to, uint256 tokenId) public onlyOwner { require(!burned, "Burned!"); _safeMint(to, tokenId); } function mintMany(uint32[] memory ids) public { require(!burned, "Burned!"); require(saleIsActive, "Sale must be active to mint tokens"); for (uint i = 0; i < ids.length; i++) { require(SandContract.ownerOf(ids[i]) == msg.sender, "Must own a Sand to mint token"); _safeMint(msg.sender, ids[i]); } } function mintToken(uint tokenId) public { require(!burned, "Burned!"); require(saleIsActive, "Sale must be active to mint tokens"); require(SandContract.ownerOf(tokenId) == msg.sender, "Must own a Sand to mint token"); _safeMint(msg.sender, tokenId); } } /// [MIT License] /// @title Base64 /// @notice Provides a function for encoding some bytes in base64 /// @author Brecht Devos <[email protected]> library Base64 { bytes internal constant TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /// @notice Encodes some bytes to the base64 representation function encode(bytes memory data) internal pure returns (string memory) { uint256 len = data.length; if (len == 0) return ""; // multiply by 4/3 rounded up uint256 encodedLen = 4 * ((len + 2) / 3); // Add some extra buffer at the end bytes memory result = new bytes(encodedLen + 32); bytes memory table = TABLE; assembly { let tablePtr := add(table, 1) let resultPtr := add(result, 32) for { let i := 0 } lt(i, len) { } { i := add(i, 3) let input := and(mload(add(data, i)), 0xffffff) let out := mload(add(tablePtr, and(shr(18, input), 0x3F))) out := shl(8, out) out := add(out, and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF)) out := shl(8, out) out := add(out, and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF)) out := shl(8, out) out := add(out, and(mload(add(tablePtr, and(input, 0x3F))), 0xFF)) out := shl(224, out) mstore(resultPtr, out) resultPtr := add(resultPtr, 4) } switch mod(len, 3) case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) } case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) } mstore(result, encodedLen) } return string(result); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } }
// SPDX-License-Identifier: MIT 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() { _setOwner(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _setOwner(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"); _setOwner(newOwner); } function _setOwner(address newOwner) private { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../ERC721.sol"; import "./IERC721Enumerable.sol"; /** * @dev This implements an optional extension of {ERC721} defined in the EIP that adds * enumerability of all the token ids in the contract as well as all token ids owned by each * account. */ abstract contract ERC721Enumerable is ERC721, IERC721Enumerable { // Mapping from owner to list of owned token IDs mapping(address => mapping(uint256 => uint256)) private _ownedTokens; // Mapping from token ID to index of the owner tokens list mapping(uint256 => uint256) private _ownedTokensIndex; // Array with all token ids, used for enumeration uint256[] private _allTokens; // Mapping from token id to position in the allTokens array mapping(uint256 => uint256) private _allTokensIndex; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) { return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds"); return _ownedTokens[owner][index]; } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _allTokens.length; } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual override returns (uint256) { require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds"); return _allTokens[index]; } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` cannot be the zero address. * - `to` cannot be the zero address. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual override { super._beforeTokenTransfer(from, to, tokenId); if (from == address(0)) { _addTokenToAllTokensEnumeration(tokenId); } else if (from != to) { _removeTokenFromOwnerEnumeration(from, tokenId); } if (to == address(0)) { _removeTokenFromAllTokensEnumeration(tokenId); } else if (to != from) { _addTokenToOwnerEnumeration(to, tokenId); } } /** * @dev Private function to add a token to this extension's ownership-tracking data structures. * @param to address representing the new owner of the given token ID * @param tokenId uint256 ID of the token to be added to the tokens list of the given address */ function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { uint256 length = ERC721.balanceOf(to); _ownedTokens[to][length] = tokenId; _ownedTokensIndex[tokenId] = length; } /** * @dev Private function to add a token to this extension's token tracking data structures. * @param tokenId uint256 ID of the token to be added to the tokens list */ function _addTokenToAllTokensEnumeration(uint256 tokenId) private { _allTokensIndex[tokenId] = _allTokens.length; _allTokens.push(tokenId); } /** * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for * gas optimizations e.g. when performing a transfer operation (avoiding double writes). * This has O(1) time complexity, but alters the order of the _ownedTokens array. * @param from address representing the previous owner of the given token ID * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address */ function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = ERC721.balanceOf(from) - 1; uint256 tokenIndex = _ownedTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary if (tokenIndex != lastTokenIndex) { uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index } // This also deletes the contents at the last position of the array delete _ownedTokensIndex[tokenId]; delete _ownedTokens[from][lastTokenIndex]; } /** * @dev Private function to remove a token from this extension's token tracking data structures. * This has O(1) time complexity, but alters the order of the _allTokens array. * @param tokenId uint256 ID of the token to be removed from the tokens list */ function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = _allTokens.length - 1; uint256 tokenIndex = _allTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding // an 'if' statement (like in _removeTokenFromOwnerEnumeration) uint256 lastTokenId = _allTokens[lastTokenIndex]; _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index // This also deletes the contents at the last position of the array delete _allTokensIndex[tokenId]; _allTokens.pop(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IERC721.sol"; import "./IERC721Receiver.sol"; import "./extensions/IERC721Metadata.sol"; import "../../utils/Address.sol"; import "../../utils/Context.sol"; import "../../utils/Strings.sol"; import "../../utils/introspection/ERC165.sol"; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: balance query for the zero address"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _owners[tokenId]; require(owner != address(0), "ERC721: owner query for nonexistent token"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overriden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not owner nor approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { require(_exists(tokenId), "ERC721: approved query for nonexistent token"); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { require(operator != _msgSender(), "ERC721: approve to caller"); _operatorApprovals[_msgSender()][operator] = approved; emit ApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _safeTransfer(from, to, tokenId, _data); } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * `_data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer( address from, address to, uint256 tokenId, bytes memory _data ) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _owners[tokenId] != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { require(_exists(tokenId), "ERC721: operator query for nonexistent token"); address owner = ERC721.ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory _data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId); _balances[to] += 1; _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); _balances[owner] -= 1; delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); } /** * @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 of token that is not own"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); // Clear approvals from the previous owner _approve(address(0), tokenId); _balances[from] -= 1; _balances[to] += 1; _owners[tokenId] = to; emit Transfer(from, to, tokenId); } /** * @dev Approve `to` to operate on `tokenId` * * Emits a {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param _data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); }
// SPDX-License-Identifier: MIT 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 pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } }
// SPDX-License-Identifier: MIT 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 pragma solidity ^0.8.0; /** * @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 * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT 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 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 `IERC721.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT 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`, 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 Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @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 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); /** * @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; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
{ "optimizer": { "enabled": true, "runs": 100 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"SandAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","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":"burnAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"burned","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"directMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"flipSaleState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32[]","name":"ids","type":"uint32[]"}],"name":"mintMany","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"mintToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"saleIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","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":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","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"}]
Contract Creation Code
6080604052600a805461ffff60a01b19169055600b805473b90b34b41658ac20a0051874feee1933c3614fa76001600160a01b03199182168117909255600c805490911690911790553480156200005557600080fd5b50604080518082018252600b81526a53616e644176617461727360a81b60208083019182528351808501909452600484526329a720ab60e11b908401528151919291620000a59160009162000134565b508051620000bb90600190602084019062000134565b505050620000d8620000d2620000de60201b60201c565b620000e2565b62000217565b3390565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b8280546200014290620001da565b90600052602060002090601f016020900481019282620001665760008555620001b1565b82601f106200018157805160ff1916838001178555620001b1565b82800160010185558215620001b1579182015b82811115620001b157825182559160200191906001019062000194565b50620001bf929150620001c3565b5090565b5b80821115620001bf5760008155600101620001c4565b600181811c90821680620001ef57607f821691505b602082108114156200021157634e487b7160e01b600052602260045260246000fd5b50919050565b615e4680620002276000396000f3fe608060405234801561001057600080fd5b50600436106101795760003560e01c806370a08231116100d9578063a22cb46511610087578063a22cb465146102f4578063b88d4fde14610307578063c634d0321461031a578063c87b56dd1461032d578063e985e9c514610340578063eb8d244414610353578063f2fde38b1461036757600080fd5b806370a082311461029a578063715018a6146102ad57806373f42561146102b55780638da5cb5b146102c957806395d89b41146102d15780639975038c146102d95780639a5d0893146102e157600080fd5b806323b872dd1161013657806323b872dd146102205780632f745c59146102335780632f8bd8911461024657806334918dfd1461025957806342842e0e146102615780634f6ccce7146102745780636352211e1461028757600080fd5b806301ffc9a71461017e57806306fdde03146101a6578063081812fc146101bb578063095ea7b3146101e657806318160ddd146101fb5780631960669d1461020d575b600080fd5b61019161018c366004614471565b61037a565b60405190151581526020015b60405180910390f35b6101ae61038b565b60405161019d9190615987565b6101ce6101c93660046144ab565b61041d565b6040516001600160a01b03909116815260200161019d565b6101f96101f4366004614384565b6104aa565b005b6008545b60405190815260200161019d565b600b546101ce906001600160a01b031681565b6101f961022e36600461424c565b6105bb565b6101ff610241366004614384565b6105ec565b6101f9610254366004614384565b610682565b6101f96106e9565b6101f961026f36600461424c565b610739565b6101ff6102823660046144ab565b610754565b6101ce6102953660046144ab565b6107e7565b6101ff6102a83660046141d9565b61085e565b6101f96108e5565b600a5461019190600160a81b900460ff1681565b6101ce610920565b6101ae61092f565b6101f961093e565b6101f96102ef3660046143b0565b610982565b6101f9610302366004614351565b610aeb565b6101f961031536600461428d565b610bac565b6101f96103283660046144ab565b610be4565b6101ae61033b3660046144ab565b610ce6565b61019161034e366004614213565b6119eb565b600a5461019190600160a01b900460ff1681565b6101f96103753660046141d9565b611a19565b600061038582611ab6565b92915050565b60606000805461039a90615ccd565b80601f01602080910402602001604051908101604052809291908181526020018280546103c690615ccd565b80156104135780601f106103e857610100808354040283529160200191610413565b820191906000526020600020905b8154815290600101906020018083116103f657829003601f168201915b5050505050905090565b600061042882611adb565b61048e5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006104b5826107e7565b9050806001600160a01b0316836001600160a01b031614156105235760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610485565b336001600160a01b038216148061053f575061053f81336119eb565b6105ac5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776044820152771b995c881b9bdc88185c1c1c9bdd995908199bdc88185b1b60421b6064820152608401610485565b6105b68383611af8565b505050565b6105c53382611b66565b6105e15760405162461bcd60e51b815260040161048590615abb565b6105b6838383611c30565b60006105f78361085e565b82106106595760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610485565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b3361068b610920565b6001600160a01b0316146106b15760405162461bcd60e51b815260040161048590615a44565b600a54600160a81b900460ff16156106db5760405162461bcd60e51b8152600401610485906159d1565b6106e58282611ddb565b5050565b336106f2610920565b6001600160a01b0316146107185760405162461bcd60e51b815260040161048590615a44565b600a805460ff60a01b198116600160a01b9182900460ff1615909102179055565b6105b683838360405180602001604052806000815250610bac565b600061075f60085490565b82106107c25760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610485565b600882815481106107d5576107d5615d79565b90600052602060002001549050919050565b6000818152600260205260408120546001600160a01b0316806103855760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610485565b60006001600160a01b0382166108c95760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610485565b506001600160a01b031660009081526003602052604090205490565b336108ee610920565b6001600160a01b0316146109145760405162461bcd60e51b815260040161048590615a44565b61091e6000611df5565b565b600a546001600160a01b031690565b60606001805461039a90615ccd565b33610947610920565b6001600160a01b03161461096d5760405162461bcd60e51b815260040161048590615a44565b600a805460ff60a81b1916600160a81b179055565b600a54600160a81b900460ff16156109ac5760405162461bcd60e51b8152600401610485906159d1565b600a54600160a01b900460ff166109d55760405162461bcd60e51b815260040161048590615a79565b60005b81518110156106e557600c54825133916001600160a01b031690636352211e90859085908110610a0a57610a0a615d79565b60200260200101516040518263ffffffff1660e01b8152600401610a3a919063ffffffff91909116815260200190565b60206040518083038186803b158015610a5257600080fd5b505afa158015610a66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8a91906141f6565b6001600160a01b031614610ab05760405162461bcd60e51b81526004016104859061599a565b610ad933838381518110610ac657610ac6615d79565b602002602001015163ffffffff16611ddb565b80610ae381615d08565b9150506109d8565b6001600160a01b038216331415610b405760405162461bcd60e51b815260206004820152601960248201527822a9219b99189d1030b8383937bb32903a379031b0b63632b960391b6044820152606401610485565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b610bb63383611b66565b610bd25760405162461bcd60e51b815260040161048590615abb565b610bde84848484611e47565b50505050565b600a54600160a81b900460ff1615610c0e5760405162461bcd60e51b8152600401610485906159d1565b600a54600160a01b900460ff16610c375760405162461bcd60e51b815260040161048590615a79565b600c546040516331a9108f60e11b81526004810183905233916001600160a01b031690636352211e9060240160206040518083038186803b158015610c7b57600080fd5b505afa158015610c8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb391906141f6565b6001600160a01b031614610cd95760405162461bcd60e51b81526004016104859061599a565b610ce33382611ddb565b50565b6060610cf0614174565b610cf8614193565b6060610d026141ba565b6000806000610d37610d138a611e7a565b604051602001610d239190615756565b604051602081830303815290604052611f78565b9050610d44601e82615d23565b610d4f906001615b3d565b84526005610d5e606483615b55565b610d689190615d23565b610d73906001615b3d565b60208501526006610d866103e883615b55565b610d909190615d23565b610d9b906001615b3d565b60408501526005610dae61271083615b55565b610db89190615d23565b610dc3906001615b3d565b60608501526004610dd7620186a083615b55565b610de19190615d23565b610dec906001615b3d565b60808501526006610e00620f424083615b55565b610e0a9190615d23565b610e15906001615b3d565b60a08501526006610e2a6305f5e10083615b55565b610e349190615d23565b610e3f906001615b3d565b60c0850152600a610e54633b9aca0083615b55565b610e5e9190615d23565b610e69906001615b3d565b60e0808601919091527dffc6a69a3a93560094ff9191fffeebc9c789204da90013704fa4ffebfaff88527dffb88fae3c23780000ff9757ffff9effed9e9a3a93560094ffd28afffeeb60208901527dd9945f8230462f0075ff7700ffff9eeb9a5bae3000780000ff7700ffff9e60408901527dffb366ca7d56a64324ffd3a1fffeebed975aca300ba60000ff771cffff9e60608901527dffa36ea5382578000ee88d48ffecd6e6b59ab395888f6559e3cfbdfffeeb60808901527dffa975ae5a6f780066ffe17dffffffd98b83653d9a7800664898e8d6fffb60a08901527dffbe987754671d0073ffd154fff9bfdbd18832836d0031367dffc0ffff9e60c08901527dff72368c15333f0045ff3419ffda61ff997a8c2a463f0045ff6947fff9bf908801527df2cb8a4d4b7e1a003b9abbe3f7f7f7f2bb61864c0a360000ffbe19ffedb06101008801527de0c275626c67000a3bf6ffa8fffdf2d9be91404664000a3ba1a1a1f7f7f76101208801527deb8a368923113b001aff5703ffd342db64357c0101240000ff0303ffcb216101408801527df9938a5e2776060019e261fffff2d9e6c58f66acc2007599ffffff8bb6c76101608801527dffff9e3a6e52001f3391e581f2ff7affbf7566565c000330ffd29efff7e86101808801527d40253612001c0000002d0047523ea3c29c76454545000000adadadffffff6101a08801527dada16d006062008a8a002226008a836920202200000a0000470000a300006101c08801527dffdb7d7f5e542a0042ffec6efff4c7cf795d63328a5e003c6b7cff5900506101e0880152600091505b6004821161116e57835182906110d390600190615c73565b6110de906005615c54565b6110e89190615b3d565b925061114563010000006110fd600a86615d23565b61110b906301000000615bac565b89611117600a88615b55565b6013811061112757611127615d79565b60200201516111369190615b55565b6111409190615d23565b611fa9565b86836006811061115757611157615d79565b60200201528161116681615d08565b9250506110bb565b6040860151602087015160c0860151829082906111b59061119090605c615b3d565b6040808d0151815180830190925260048252630605c60760e31b6020830152906120a8565b6040516020016111c9959493929190615348565b60408051601f1981840301815291905294508461122d600186600560200201516111f4906002615c54565b6111ff906050615b3d565b6112099190615c73565b6040808a015181518083019092526003825262302e3160e81b6020830152906120a8565b60a086015161127090611241906002615c54565b61124c906050615b3d565b6040808b0151815180830190925260038252620c0b8d60ea1b6020830152906120a8565b60405160200161128293929190614bf8565b60408051601f198184030181529190529450846112c260008860025b6020020151604051806040016040528060018152602001603160f81b8152506120a8565b6112ce6001898161129e565b6112fd60028a60005b60200201516040518060400160405280600381526020016218171960e91b8152506120a8565b61132c60038b60025b602002015160405180604001604052806003815260200162302e3360e81b8152506120a8565b61133960048c6002611306565b61134660058d60006112d7565b60405160200161135c9796959493929190614669565b60408051601f1981840301815291905294508461137c600688600461129e565b611389600789600361129e565b6113ce60086040518060400160405280600681526020016523232323232360d11b81525060405180604001604052806003815260200162302e3960e81b8152506120a8565b61141360096040518060400160405280600681526020016523232323232360d11b81525060405180604001604052806003815260200162302e3960e81b8152506120a8565b6040808c0151905161142f9695949392919081906020016147fc565b60408051601f1981840301815291905294508461144f604d88600361129e565b61145c604e89600361129e565b611469604f8a600461129e565b61147660508b600461129e565b60405160200161148a9594939291906149a1565b60408051808303601f1901815291905260e0850151909550600114156114f757846114b8602688600061129e565b6114c5602789600361129e565b6114d260288a600361129e565b6040516020016114e59493929190614528565b60405160208183030381529060405294505b8461152c60018681602002015161150f906002615c54565b61151a906009615b3d565b6115249190615c73565b88600361129e565b602086015161157090611540906002615c54565b61154b906009615b3d565b6040808b01518151808301909252600482526318171b1b60e11b6020830152906120a8565b6115a4600288816020020151611587906003615c54565b611592906013615b3d565b61159c9190615c73565b8a600261129e565b6115fb600189600260200201516115bc906003615c54565b6115c7906013615b3d565b6115d19190615c73565b8b60015b60200201516040518060400160405280600381526020016218171b60e91b8152506120a8565b60408901516116229061160f906003615c54565b61161a906013615b3d565b8c60016115d5565b604051602001611637969594939291906145ea565b60408051601f1981840301815291905294508461169b600386816020020151611661906004615c54565b61166c906028615b3d565b6116769190615c73565b606089015160408051808201909152600481526318171c9960e11b60208201526120a8565b6116f3600287600360200201516116b3906004615c54565b6116be906028615b3d565b6116c89190615c73565b8960005b602002015160405180604001604052806004815260200163302e323560e01b8152506120a8565b6117286001886003602002015161170b906004615c54565b611716906028615b3d565b6117209190615c73565b8a60006116cc565b606088015161174f9061173c906004615c54565b611747906028615b3d565b8b600261129e565b60405160200161176395949392919061457f565b60408051601f198184030181529190529450846117ab6003866004602002015161178e906004615c54565b61179990603c615b3d565b6117a39190615c73565b88600261129e565b611802600287600460200201516117c3906004615c54565b6117ce90603c615b3d565b6117d89190615c73565b8960015b602002015160405180604001604052806003815260200162302e3560e81b8152506120a8565b6118376001886004602002015161181a906004615c54565b61182590603c615b3d565b61182f9190615c73565b8a60016117dc565b608088015161185e9061184b906004615c54565b61185690603c615b3d565b8b600161129e565b61186b60628c600261129e565b604051602001611880969594939291906146fb565b60408051601f19818403018152919052945060606118a58560005b6020020151611e7a565b6118b086600161189b565b6118bb87600261189b565b6040516020016118cd9392919061586a565b60408051601f198184030181529190529050806118eb86600361189b565b6118f687600461189b565b61190188600561189b565b604051602001611914949392919061512b565b60408051808303601f1901815291905260e08601519091506001141561195757806040516020016119459190614b27565b60405160208183030381529060405290505b8061196386600661189b565b604051602001611974929190614b7f565b604051602081830303815290604052905060006119b98261199489613aec565b6040516020016119a5929190615237565b604051602081830303815290604052613aec565b9050806040516020016119cc9190615825565b60408051601f198184030181529190529b9a5050505050505050505050565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b33611a22610920565b6001600160a01b031614611a485760405162461bcd60e51b815260040161048590615a44565b6001600160a01b038116611aad5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610485565b610ce381611df5565b60006001600160e01b0319821663780e9d6360e01b1480610385575061038582613c52565b6000908152600260205260409020546001600160a01b0316151590565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611b2d826107e7565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611b7182611adb565b611bd25760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610485565b6000611bdd836107e7565b9050806001600160a01b0316846001600160a01b03161480611c185750836001600160a01b0316611c0d8461041d565b6001600160a01b0316145b80611c285750611c2881856119eb565b949350505050565b826001600160a01b0316611c43826107e7565b6001600160a01b031614611cab5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610485565b6001600160a01b038216611d0d5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610485565b611d18838383613ca2565b611d23600082611af8565b6001600160a01b0383166000908152600360205260408120805460019290611d4c908490615c73565b90915550506001600160a01b0382166000908152600360205260408120805460019290611d7a908490615b3d565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6106e5828260405180602001604052806000815250613cad565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b611e52848484611c30565b611e5e84848484613ce0565b610bde5760405162461bcd60e51b8152600401610485906159f2565b606081611e9e5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115611ec85780611eb281615d08565b9150611ec19050600a83615b55565b9150611ea2565b60008167ffffffffffffffff811115611ee357611ee3615d8f565b6040519080825280601f01601f191660200182016040528015611f0d576020820181803683370190505b5090505b8415611c2857611f22600183615c73565b9150611f2f600a86615d23565b611f3a906030615b3d565b60f81b818381518110611f4f57611f4f615d79565b60200101906001600160f81b031916908160001a905350611f71600a86615b55565b9450611f11565b600081604051602001611f8b919061450c565b60408051601f19818403018152919052805160209091012092915050565b6040805180820190915260068082526503030303030360d41b60208301526060915b81156120a157600a611fde601086615d23565b101561203557611fef601085615d23565b611ffa906030615b3d565b60f81b81612009600185615c73565b8151811061201957612019615d79565b60200101906001600160f81b031916908160001a905350612082565b612040601085615d23565b61204b906037615b3d565b60f81b8161205a600185615c73565b8151811061206a5761206a615d79565b60200101906001600160f81b031916908160001a9053505b61208d601085615b55565b93508161209981615cb6565b925050611fcb565b9392505050565b60606000604051806119e001604052807e07fe112eadce2b20f778d5c85663965707158b4d70e4663a1b2e573c5e112e81526020017f0778d5ce5f6817990605f9d9b0777425dc6ba6b34ddacc6eb6990d65c35574de81526020017f0a89c2a2418229206ba98249fcd1809e9fa608c0d20e7583a1aa23ea9022161a81526020016a01ff5d37996e070b79eae081526020016a01ff7b44a412779c51d6f681526020016e1ff7e982c62f84309d2da79b25fa6081526020017507fddea17b1b1d46d661858e64619d19067779c9dea18152602001797fe5301aebba56fb91b12bab0ae9ae6e9ba0ac23ebc8c3aa53018152602001771ff279d884832431d0ad359b41a8b06a26d8e83589d0cc7181526020017f06aac5aa9b642096473509c9386c409a9006d429d52a74529f5647a62a15a49d81526020017f03c1d50a75411c0e46f2c1bc847d1d25084c92f348f8d33f35d32d64f34d6ad381526020017f049221187e411d5147d439f4fe75431f5067c3e1d5047c409f0fc793c9d4f87881526020017f04aa611c924a261249746a51229747a5d18954725d189745a5918974525d228c81526020017f04026d109c4f26d3a984b2453a994f2693a9a49241369a4c2611e904ba612c9881526020017f032b24a8b931b20c0c7292e4bec62e3189eba2d3149ec122a10a077361d4f28b81526020017f02fad8e0c737b20bab737320dcc92e2e0d8c936324b4b935b28d4ca2c2e4ceca81526020017f0382f0e0bc3b308ecc3342d8eac43a314c8b63a314e8c539b18c4b639318e2c781526020017f039ae8f0bf3c300e4ba3c300eec1382ecf4a63d278e6853ba84e0bb35adce0bc81526020017f0442a11aad452b10ea9452b10eab432a90eab422ad00ab3d2f8ecba3caf8f2bf81526020017f04dabd26a74d2bd30af4c2bd1ea74babd2aae46a9d28ae48ab516a8482b51cad81526020017f05029d46a9512ad3ca7512b144ae4e2a542ae4fab934a94fab93aae4baa538ae81526020017f044b251ec34a2e93eb7542a956a953a954c9450a5d48a551a9d42a451a9d46a981526020017f047b112ccb4ab311cc54a33126cc46b1926cd4933516c74933520ce4532520ce81526020017f04fb1d3ac74a2fd3ac84e32124c04db2534c948b0532c94c32920c34c3292ecb81526020017f0512fd5ecc5632d3ebf5532950c94eb014cc951b2132bf5131d40c64fb192cbe81526020017f05bb2158bf5b3256ac9552fd6aca5a32d4ebf59b2d66cc5330164cc5933562cc81526020017f059ae978c35db1162bb5db1174c557af172c55cb195cbd5c31970c756af56ec881526020017f05eb0568ba5aae166ab5aa91689e5e23d609e58a9162a95a2e968ba5eb0978c381526020017f05ead986bc612f578b7612f582be5d2e182be602fd6eb75fb017ec05b2e57cc181526020017f0652d992b760ac190b763ae182b263ae18cb9602d18cba62ae97cb562aed88bb81526020017f05fabd72aa5fac17cb15c2b57cb25eacd70af5e2cd7ab3612b196b4652d582ae81526020017f060a9982a75da8982a860aa974a45d29182aa602b174a6602b180ae5d2a580ae81526020017f05f26d7c9b6127d84a05ea757a9d6128584a35ea797a9f6128d84a55e28578a181526020017f065ad184ac62a9d8ca060a5d849960261809861269849c5fa697e9a61271849e81526020016307fda4ae81526020017301ff41ad500c14131918c347af516b4432c906b581526020017301ff422410c94462491e8945a01067e40a19089081526020017f0471d960815525156a1562fd6eba5a2957e8e5fa396ca55cae124cb31328c4d281526020017c01ff5cb51b6be6a2edb8b8722799e8063201947b5b1b4b070269f0c07f81526020017f065a258e8e65a398c9367249809b6825996b35f30164c357abd5ec44d338f0cd81526020016c07fd3ad15b33d82c867af9b4a181526020017f05fa2d86885fa196e8c59a416a9258a4d569755a8158aa552bd60b458aed74c781526020017f06f25da09363a5592975ea5580a45f2ad78b4652c59eb25f3096ab45a2a56e9981526020017507fd74c7682c9a8b36dac5bca972295bea070a7dbe9b81526020017f060ac1b2ad6e2a1b4a26d2a1ae9f6c2a1aaa36b2a990ac64a9d849962a9d82b081526020016101ff81526020017f0552bd60b458aed58bd563016abc5ead182ac63ab596b3632e96ec45ab2162c981526020017f0602b17cb25aae968a95ba65788f5a2195c875aa356a9258a4d569755a8158aa8152602001797fd64cf6dac5bca96da75a69a6320d62776223d90a15fa857cab8152602001771ff6cab5baa86ba7db0a86aa8dacaa65aa192a46229186aa81526020017f05a2a5789060a31888f6427992b5632e974bf5aaed5eb5562f558bf55b1122ce81526020017f05cb51b6be6a2edb8b86e21d6c6d4b9b91e73529ed6a9255a5d58aa552c16abc81526020016101ff81526020017f06cad1b4895d1d5a28965221a48d692499e9369255a6a467299a6a6652adaeb381526020016307fda2b681526020017f0582d164bd592f964be592fd6aba5a2a56e995da2d7c886223d90a561af122ce81526020017f079a79de9773a59d4926ea0d6c6d4b9b91e735ba056c8a55a5d56a0562a954af8152602001651ff5cb51ccc081526020017f072af5d89e71251bc8b6ba25a2836f2a5aa946f2c5b2aa6dac196a86dad99cb281526020016101ff81526020017f03e9cabc7fae934ee5c389549c4f1d984667e1225854d525b9cc6e349bad42e681526020016a01ffb23c2c6cf3bb2cc0a08152602001797fcae7b299ec96ab269e88c7a212647e7b1c9f470c32b318ae7b81526020017f0a11d2ac71881b2785e3d985006c3a1a8e0633121cd67a2d280c6c93137d20e78152602001797fd20e751b86d8e59db54e6d436af8e2d531378d6ca2da80ec6d81526020017f03bb2cfa953e9c9427147970ee5c389549c4f1225854d525b9cc6e349bad42e68152602001651ff733b1bcd98152602001707fce4d469384dadc4839cc2df3734ce8b181526020017f018270707914a685ece1c2f870cb1eb34a2a62d9d0c8763624cbec521b5470cc81526020017f020b68d6c83b250de722a9c4949c1cb2c74ba20ab49c62369792c684717c9e5c81526020016101ff81526020017f01a3609eef2d3acc2e43b39cf8dd46b6116d237b3ca6a52da00d4763f9d1126981526020016a01ff35988946a181fc3eb281526020016c07fc648e182bca2e516ac45a9d81526020017f0339b8fa693a998c66d279b07c761b2086c9a1e1f494762c1dc8e85202c894cf81526020017f0302fc96c622ac0a6ab2829088a622a8ca4a129a648c9a25214b0812e1eca87b8152602001797fcb6df30b7d0cd440b4cbadc29b50d2ce3231ca0cf27b34c8c58152602001771ff2b9b4787516a6464c22033c9cd334b50d878399b8ae6d81526020017301ff33b40c875221f864a2201e8ae70351c4ced081526020016e1ff1a30886cb2f3449ed220b3868c281526020017f0451c902623416cc05a2d180866d1c9ec62941627464ac1ab1c92dc3239100d68152602001677fcfad136b1502768152602001677fca4de3836898db81526020017f0239f4b2782c1d88c6e289a0dc682e9fcaca32dac0acaa30b34bebf32334e2d481526020017f0229b4767b17a706aaf1bb1ca49c1b2b864a222a30609b1b2308e792b1d8ac7881526020017f03db54d4c735a18f67236accd8c43f9acd08234310cec333204f2683f9a0b86081526020016101ff81526020017f03db68d0dc2b37c7ed612b0444ab14a4c4884191e87e69239a8da63471ad2e7681526020017301ff3f9dcd6812ea109e9527ab0e0c647b450eda8152602001677fcce7327210669e81526020017f026a8484a41d2c490c127300bcc8292e0c6c4463490ad83e360acda203504ec081526020016c07fc50b6172b45cb6192ac9c9681526020017e07fd388c50a35409051a41488d55235548a52a254a865121942894ea21388c81526020016c07fd4a8a52a31528d522354a8a81526020016c07fd428950a31388c50231428981526020017f0489ed248648259029b402a522af49ae922cb47b34fad23e2d4fe9c3da14fa7281526020016307fd0c7581526020016a01ff3ea010079461e4fe7781526020016a01ff46ac502b13faf100af81526020017f0411c10475469e5228847a5102983ea10fc73419d5026e3e1b4f2843ea8cf4bc81526020017f048af11ecb41b3908d14833d26cb4aaed24ae4129d049f48a612888499e91e7581526020017301ff3e35104d34234506ce3f33cfabe402ad1eb081526020017f04fa1d2a994227104a5422b12ab04e2e93ec54cb3d0ad24133100ba409ed08738152602001651ff421cd387981526020016c07fd38824ea1d328e4225d068c81526020016c07fd36ba4e2f538c443b3908c581526020017f03f30902cf3eb4d0cd34333d0ccf40b0904af432b528b04eaf13ac64cb350ccf81526020017f0481cd0a6f421d1367b4f21d289843a69049840a090874429bcfc6f409c8fc8181526020017c01ff4334d1ed34db3d40c74fae92aae44aad08a4442752a9b5021d3a7981526020017f04ab2930b1442852e8f4a9dd12703d9c8e8793ba710e9e43a8ceea43ab18f8ce81526020016307fd12d081526020016e1ff3d9f4fa9243a68f49a3c1ecfc7481526020016e1ff3db10faae43a9cf4a63c318fccc81526020017f03aa70f4a042a7d0aa13da84f69f3d27cf4a13aa90e8cb3db650cd742338facd81526020017f0429c10870421c914714a1e12c8f4426cf09b3b1e8fa73429c90c6a3d99ce87581526020017f0442992cb14a32514cf4233908d144b452eca4d2c516a445a7934904b9d9126f8152602001651ff3b31cf0a581526020017f0479e1348a47a711eab4d2e526ca3cb4ce8c3402b918ab46a6d00973aa14f2748152602001651ff3c9d0f27481526020016e1ff3f240fc90402150e7c3f214fc9081526020016e1ff3f308fcc2402dd0eae3f2dcfcc281526020017f042b38f2d23b30cf6c43e314fab6432b518ae46aad06ab3c2d0e6c33b348e4d281526020017f03da08f685431ed227d4c22d269645a6116ae48abd30b948b250ccb3db04f6c481526020017f0391b8ec7439a0cf09241a6d189b462610c993ea40f8813da08ec833c9d10a7881526020017f03db54fcd33f34d1ecf4db1534b448aad229b4d2493681479dcfc733f1ccf46f81526020016307fce4d281526020017301ff3f28d468a4e9ccda7c37b2d3ed1522f8fca381526020017f03ead8e6c23aaa0f8a23f26d34893da58f69c39a80e48438288e6c44032510c38152602001651ff4430d10b981526020017f0471c5427951a1d448b4027500a9512ed46bf50b311cd43bb44e4c93832ce8d381526020017f02e26cbaad2dab8b6b330ad4c29435a74d4ab33ab4dcca37b14daa2381fcee7581526020017f045a6d488c52a1d4476481b8e873379f8da7c33a5cc48e32a1cbe872da3cb6998152602001707fce8d34836144d052afd48ba42a9d12a581526020017f04d228fc9c3e28cfca94d2ed32c44a32108ca4136112da4936528d84bb7532dc81526020017f03b31cecc73b2f0f8b4432e110b73f2c8ecb538b00dea339201007a4a1f5328181526020017f042b0902c63eb1cf4c33d2f8fcba412ed0ac3432f908b93eadcf0bd3c310f6c981526020017f0321f0b28f2c28cb2b732324dccc38348e8d641b6108ca44b1514bb442dd0cb881526020017f046a6d4a8b53a0d4a77509cd246c449ad006d36998d8683e9b8e870381d0dc7a8152602001771ff4bb5d32d64db6d38da4db5542d352b394ec252ae91aaa81526020017e07fd46c15c33594c67028d98815e1e146854b1b1206b4fa25169c45aa946c181526020016c07fdaea366301bca466a21aea381526020017f05d28d769d61a798e965d209428f4fa75529d5ea3572a35eae152a84faa142b681526020016c07fd42b65d30d8eaf61a9d78a881526020016e1ff4fadd22a14aa5d1c9d472a93eb781526020017507fd2c9a521c98e59731a9eeaa6dbb180e94aab92c9a8152602001797fd34ad543015c9a5731d66cd6518d88675e9f5706f571d934ad81526020017301ff6025da6da6fa61e4a8732b1ace662b51809781526020017507fd9e63711b9d2876f9c9a26865a559cb7632599e638152602001707fd66b373c41d1107543168ad59abd66b38152602001707fd70b75d2ddc90171405c3045bae570b781526020017301ff75431d30d71c15cf0d70c15cf1074441d50c81526020016c07fdc50272409d50c74c31c50281526020017f03f9b5006f4f1d54e8254a3952995426d4c9b53a8152a054aa14ea9532b14eae81526020017507fd4eae55ab95cab57a815c9956a655a8e552053e7281526020016e1ff55ab158ab5523154a7542b156ac81526020016a01ff56a695ca4572815a9a81526020016a01ff54ab156a855ab152ac81526020016e1ff44255208d4821d167e411f8fe8981526020016e1ff40b1d18c447af51eb6432c4febd81526020016e1ff44251188d4621d1281419fd028981526020016c07fd06c54530d18b843acd02bd81526020017e07fdf62b7c051f40c7d04dfc2b8001a0a028101a041985846021d7f8b9fe2c81526020017f0760c9ca2d758cdce37678e9bc396e8e9b63f6f8e5ce397191dbc547211dd03981526020017f07f8b1f42a77885dc127687dca186e05da8106d05d9a1671865c01e72869f02c81526020016c07fdd6367a8c9e63b7c0c5fe2e8152602001677fddc1c79899f00181526020017f0700e1ca3779899d81777041d21773891c2266f891bc29700a1c82e718c5bc378152602001677fdb6406e0fdbe398152602001797fdd41c7606dd6207709dea1b7d809f01c768c1da2a758a9ce1381526020017f0768a9aa226684da0215a05daa26690b5b227728b1b637660d1b03b62949c8348152602001677fdc83e730cdda308152602001707fdf2407c0d9fa2e83001f6017707dde3681526020017f07c851f6127c099f4257e88dfc127d83dda1f7487dcc276d09dc82d740d5e23781526020017f07d099f4267d8a5ec307a0b9e82a7b099ee267c061ee1777885ec177b055f41181526020016c07fde2377c901ec357d0bdf62881526020017f07e805f0057a035da12720cdb2336b8d5ce3c6e8fdd6417813ddc546f939ba528152602001677fddc5d7f885fe1a81526020017e07fdbe637697dfe227f869e41e78891e629778bda430680e5b0486e935b45481526020016a01ff7b8e1f63e81001ee3881526020017f07709de82466899902463889a2176d059a0156108978215f8a18026618a18c2681526020016e1ff7d8f9f6386e8b5d42c6b0a9e02881526020017f042c6d2f1c4c471311c4fc794b1f5348957235649d572955cb1612d58d0d5d5681526020017f043c31110b474311d0d47c312f0c4bc39310d4d435310e49c511d1549c592f1a81526020017f04ac1923074ac1d2f094bc252f0a47c2d1d094742d110b43c290f0b4242d0f0b81526020017f0513e146f950be936fa4d3e934fa453ed34fb4d3f136fc4fbf13cfd4fbfd350181526020017f03abd8e2f63abd8ecf73bbd900f7403e102f7463dd1af9473e13ef7503e542f881526020017f059a3d58f2543d142f4503cd3ef5473d51af4463d502f6403d100f63bbd8ecf581526020016c07fd695d5a005661657071643681526020017f04f49539244bc9d2d294acb931304e4c13d2e504b9433153cd1553858cf1695381526020017e07fd680158831623154109645857b8126fc4f415330b52451471f50c85432481526020017f04d965365b4e16d385f4f97d3e65509954e6b563894aec56c05531c50cb1613981526020017f0550854629508c538344e8d92c3b4990120404791d24494a9392c534d155345981526020016c07fd51565a53d680255085542181526020017f0469491852461551a55469691c5b471952265569bd60f353c35632157ca5694c81526020017f05406d5024480ad1a2c468f5163d4590526465591d56494712d564c55941264f8152602001651ff5a009561a81526020017f04f1593c664d9ad36734b9e548b5523513ad95037936e54d3bd46ec53d55695581526020017e07fd69555a00152004f84936184e08130264b8d126384911d2c4c4b945385081526020017f05ec215b0760c2d9513694618b1a6bc6dd12579d01d53a724b9cf396d4c5eb4481526020017f07447dcb1375c05c90e6e3a5c1066ac01c30d71c75a314643fd991165c4534e881526020017f08fc9e1d378648e173b7fd21f53f82c89fb2f7e48df7337bce9e12e7dc65dd2a81526020017f091c4e5d0491c3a44f4904623109823e21f0382c1625068b42e411f8fc862f1881526020016a01ff7ad11f34d81d36472781526020017f504f4e4b4a48454442403f3d3b383633322f2d2a282625240a0908070605020181526020017f8e8d8c8682807f7a7978767271706e6b6a6967646362605f5e5d5b5a5854535181526020017fbfbdb6b4b3b2b0adacaaa9a7a6a3a2a1a09f9e9d9c9b99989796959493929190815260200163ffc7c5c281525090506000806000806000806060600060208d6139019190615d23565b61390d90610100615bac565b8960208f61391b9190615b55565b6139269060cb615b3d565b60cf811061393657613936615d79565b60200201516139459190615b55565b925061395361010084615d23565b6040805160208101909152600081529097509150613972600188615c73565b97505b60fa8811613ab657888860cf811061398f5761398f615d79565b602002015161399d57613ab6565b888860cf81106139af576139af615d79565b6020020151955060009450600093505b601b8411613a95576102006139d48582615bac565b6139de9088615b55565b6139e89190615d23565b9050806101ff14156139f957613a95565b613a04600286615d23565b613a435781613a1c613a17836003615c54565b611e7a565b604051602001613a2d929190614ab1565b6040516020818303038152906040529150613a75565b81613a52613a17836003615c54565b604051602001613a63929190614aec565b60405160208183030381529060405291505b84613a7f81615d08565b9550508380613a8d90615d08565b9450506139bf565b806101ff1415613aa457613ab6565b87613aae81615d08565b985050613975565b8a828d604051602001613acb93929190615785565b60405160208183030381529060405299505050505050505050509392505050565b805160609080613b0c575050604080516020810190915260008152919050565b60006003613b1b836002615b3d565b613b259190615b55565b613b30906004615c54565b90506000613b3f826020615b3d565b67ffffffffffffffff811115613b5757613b57615d8f565b6040519080825280601f01601f191660200182016040528015613b81576020820181803683370190505b5090506000604051806060016040528060408152602001615dd1604091399050600181016020830160005b86811015613c0d576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b835260049092019101613bac565b506003860660018114613c275760028114613c3857613c44565b613d3d60f01b600119830152613c44565b603d60f81b6000198301525b505050918152949350505050565b60006001600160e01b031982166380ac58cd60e01b1480613c8357506001600160e01b03198216635b5e139f60e01b145b8061038557506301ffc9a760e01b6001600160e01b0319831614610385565b6105b6838383613ded565b613cb78383613ea5565b613cc46000848484613ce0565b6105b65760405162461bcd60e51b8152600401610485906159f2565b60006001600160a01b0384163b15613de257604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290613d24903390899088908890600401615954565b602060405180830381600087803b158015613d3e57600080fd5b505af1925050508015613d6e575060408051601f3d908101601f19168201909252613d6b9181019061448e565b60015b613dc8573d808015613d9c576040519150601f19603f3d011682016040523d82523d6000602084013e613da1565b606091505b508051613dc05760405162461bcd60e51b8152600401610485906159f2565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611c28565b506001949350505050565b6001600160a01b038316613e4857613e4381600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b613e6b565b816001600160a01b0316836001600160a01b031614613e6b57613e6b8382613fe4565b6001600160a01b038216613e82576105b681614081565b826001600160a01b0316826001600160a01b0316146105b6576105b68282614130565b6001600160a01b038216613efb5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610485565b613f0481611adb565b15613f515760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610485565b613f5d60008383613ca2565b6001600160a01b0382166000908152600360205260408120805460019290613f86908490615b3d565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001613ff18461085e565b613ffb9190615c73565b60008381526007602052604090205490915080821461404e576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60085460009061409390600190615c73565b600083815260096020526040812054600880549394509092849081106140bb576140bb615d79565b9060005260206000200154905080600883815481106140dc576140dc615d79565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061411457614114615d63565b6001900381819060005260206000200160009055905550505050565b600061413b8361085e565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6040518061026001604052806013906020820280368337509192915050565b6040518060c001604052806006905b60608152602001906001900390816141a25790505090565b604051806101800160405280600c906020820280368337509192915050565b6000602082840312156141eb57600080fd5b81356120a181615da5565b60006020828403121561420857600080fd5b81516120a181615da5565b6000806040838503121561422657600080fd5b823561423181615da5565b9150602083013561424181615da5565b809150509250929050565b60008060006060848603121561426157600080fd5b833561426c81615da5565b9250602084013561427c81615da5565b929592945050506040919091013590565b600080600080608085870312156142a357600080fd5b84356142ae81615da5565b93506020858101356142bf81615da5565b935060408601359250606086013567ffffffffffffffff808211156142e357600080fd5b818801915088601f8301126142f757600080fd5b81358181111561430957614309615d8f565b61431b601f8201601f19168501615b0c565b9150808252898482850101111561433157600080fd5b808484018584013760008482840101525080935050505092959194509250565b6000806040838503121561436457600080fd5b823561436f81615da5565b91506020830135801515811461424157600080fd5b6000806040838503121561439757600080fd5b82356143a281615da5565b946020939093013593505050565b600060208083850312156143c357600080fd5b823567ffffffffffffffff808211156143db57600080fd5b818501915085601f8301126143ef57600080fd5b81358181111561440157614401615d8f565b8060051b9150614412848301615b0c565b8181528481019084860184860187018a101561442d57600080fd5b600095508594505b8385101561446457803563ffffffff81168114614450578687fd5b835260019490940193918601918601614435565b5098975050505050505050565b60006020828403121561448357600080fd5b81356120a181615dba565b6000602082840312156144a057600080fd5b81516120a181615dba565b6000602082840312156144bd57600080fd5b5035919050565b600081518084526144dc816020860160208601615c8a565b601f01601f19169290920160200192915050565b60008151614502818560208601615c8a565b9290920192915050565b6000825161451e818460208701615c8a565b9190910192915050565b6000855161453a818460208a01615c8a565b85519083019061454e818360208a01615c8a565b8551910190614561818360208901615c8a565b8451910190614574818360208801615c8a565b019695505050505050565b60008651614591818460208b01615c8a565b8651908301906145a5818360208b01615c8a565b86519101906145b8818360208a01615c8a565b85519101906145cb818360208901615c8a565b84519101906145de818360208801615c8a565b01979650505050505050565b6000875160206145fd8285838d01615c8a565b8851918401916146108184848d01615c8a565b88519201916146228184848c01615c8a565b87519201916146348184848b01615c8a565b86519201916146468184848a01615c8a565b85519201916146588184848901615c8a565b919091019998505050505050505050565b60008851602061467c8285838e01615c8a565b89519184019161468f8184848e01615c8a565b89519201916146a18184848d01615c8a565b88519201916146b38184848c01615c8a565b87519201916146c58184848b01615c8a565b86519201916146d78184848a01615c8a565b85519201916146e98184848901615c8a565b919091019a9950505050505050505050565b60008751602061470e8285838d01615c8a565b8851918401916147218184848d01615c8a565b88519201916147338184848c01615c8a565b87519201916147458184848b01615c8a565b86519201916147578184848a01615c8a565b621e339f60e91b920191825284516147758160038501848901615c8a565b7f3c616e696d6174654d6f74696f6e20706174683d224d302c302043352c2d352060039390910192830152507f31322c2d352031352c2d31325a22206475723d2231307322207265706561744360238201527f6f756e743d22696e646566696e697465222f3e3c2f673e3c2f7376673e200000604382015260610198975050505050505050565b60008851602061480f8285838e01615c8a565b8951918401916148228184848e01615c8a565b89519201916148348184848d01615c8a565b88519201916148468184848c01615c8a565b87519201916148588184848b01615c8a565b6e3c636972636c652066696c6c3d222360881b9201918252855161488281600f8501848a01615c8a565b7f222063783d22353636222063793d223430362220723d22372e33222f3e3c6369600f9390910192830152507f72636c65206f7061636974793d22302e3636222066696c6c3d22234646464646602f8201527f46222063783d22353730222063793d223430342220723d2233222f3e3c636972604f8201526a636c652066696c6c3d222360a81b606f82015261499361491e607a8301866144f0565b7f222063783d22343134222063793d223430372220723d22372e33222f3e3c636981527f72636c65206f7061636974793d22302e3636222066696c6c3d2223464646464660208201527f46222063783d22343138222063793d223430342220723d2233222f3e3c673e006040820152605f0190565b9a9950505050505050505050565b6000865160206149b48285838c01615c8a565b8751918401916149c78184848c01615c8a565b87519201916149d98184848b01615c8a565b86519201916149eb8184848a01615c8a565b85519201916149fd8184848901615c8a565b7f3c616e696d617465206174747269627574654e616d653d226f7061636974792292019182527f2076616c7565733d22303b303b303b303b303b303b303b303b303b303b303b30908201527f3b313b303b303b303b303b303b303b303b3022206475723d223473222072657060408201527f656174436f756e743d22696e646566696e6974652220626567696e3d22307322606082015265179f1e17b39f60d11b6080820152608601979650505050505050565b60008351614ac3818460208801615c8a565b835190830190614ad7818360208801615c8a565b600b60fa1b9101908152600101949350505050565b60008351614afe818460208801615c8a565b835190830190614b12818360208801615c8a565b600160fd1b9101908152600101949350505050565b60008251614b39818460208701615c8a565b7f22207d2c207b202274726169745f74797065223a202242616e64202d206169649201918252506d222c202276616c7565223a20223160901b6020820152602e01919050565b60008351614b91818460208801615c8a565b80830190507f22207d2c207b202274726169745f74797065223a2022466172222c202276616c8152653ab2911d101160d11b60208201528351614bdb816026840160208801615c8a565b6322207d5d60e01b60269290910191820152602a01949350505050565b60008451614c0a818460208901615c8a565b7f3c673e3c70617468206f7061636974793d22302e3131222066696c6c3d2223469083019081527f46464646462220643d224d3636382c35333363302c302c3331332c302c33303360208201527f2d3238732d3339372d34382c31352d3436633330312c322c3139362c34362c3460408201527f36302c3433633235382d332c3438342d36302c3438352d3137732d3239302c3260608201527f342d3239302c3530733238382c392c3437382c3132633138392c332c3334312d60808201527f38332c3533352d3236633139342c35362c3332322c33322c3531372c3563313960a08201527f342d32372c3134302c302c3432372c3073313138302c302c313138302c30762d60c08201527f3331483336303763302c302d3133372d31312d3238332d3130632d3134362c3060e08201527f2d3136322c33332d3339342d37632d3233322d34312d3331322d34332d3432306101008201527f2d3234632d3130372c31382d3235352c36382d3339352c3734732d3339372c316101208201527f382d3339382c37632d312d31302c3434372d32362c3434362d3635632d312d336101408201527f382d3137362d34322d3339312d3235632d3231352c31362d3339352d31342d356101608201527f36382d3139632d3137322d342d3632362d382d3632372c3235733332332c32356101808201527f2c3332322c353063302c392d3539332c332d3539332c33482d333676323768346101a08201527f3738433434322c3533312c3535332c3533332c3636382c353333222f3e3c70616101c08201527f7468206f7061636974793d22302e3131222066696c6c3d2223464646464646226101e08201527f20643d224d3636382c35313463302c302c3332322c31322c3331322d3135632d6102008201527f31302d32382d3830342d35362c382d3632633330312d322c3233392c33372c356102208201527f30332c3334633235382d332c3536352d34322c3536392c3163322c32392d33386102408201527f312c33322d3431372c3631632d32332c31382c3237332c31322c3437302c37636102608201527f3138392d352c3531332d39342c3731342d3532633231322c34342c3138342c346102808201527f362c3337392c3138633139342d32372c3138382c312c3437352c3173313039366102a08201527f2c302c313039362c30762d323063302c302d313130322c302d313137352c30736102c08201527f2d3133372d31332d3238342d3133632d3134362c302d3136312c32352d3339336102e08201527f2d3136732d3331352d33312d3432322d3132632d3130372c31382d3235302c366103008201527f382d3338392c3734732d3433322c32342d3433322c313363302d31332c3435386103208201527f2d32352c3437332d37316331322d33372d3137322d35342d3338372d3338732d6103408201527f3339352d31342d3536382d3139632d3137322d342d3632302c372d3632312c346103608201527f31733331392c33322c3332312c353163302c392d3539382d31322d3539382d316103808201527f32482d333676323768343738433434322c3531332c3535332c3531342c3636386103a08201527f2c3531347a222f3e3c616e696d6174654d6f74696f6e20706174683d224d20306103c08201527f2030204c202d33373530203430205a22206475723d22313530732220726570656103e08201527f6174436f756e743d22696e646566696e69746522202f3e3c2f673e000000000061040082015261512161511b61041b8301876144f0565b856144f0565b9695505050505050565b6000855161513d818460208a01615c8a565b80830190507f22207d2c207b202274726169745f74797065223a2022476c6173736573222c20815269113b30b63ab2911d101160b11b6020820152855161518b81602a840160208a01615c8a565b7f22207d2c207b202274726169745f74797065223a202254756265222c20227661602a929091019182015266363ab2911d101160c91b604a82015284516151d9816051840160208901615c8a565b7f22207d2c207b202274726169745f74797065223a20224f626a656374222c202260519290910191820152683b30b63ab2911d101160b91b6071820152835161522981607a840160208801615c8a565b01607a019695505050505050565b7f7b226e616d65223a20224f6e636861696e2053616e646d616e222c202264657381527f6372697074696f6e223a20224f6e636861696e2053616e646d616e202d20626560208201527f6175746966756c206176617461722c20636f6d706c6574656c792067656e657260408201527f61746564204f6e436861696e222c2261747472696275746573223a00000000006060820152600083516152e181607b850160208801615c8a565b7f2c2022696d616765223a2022646174613a696d6167652f7376672b786d6c3b62607b9184019182015265185cd94d8d0b60d21b609b820152835161532d8160a1840160208801615c8a565b61227d60f01b60a1929091019182015260a301949350505050565b7f3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d22757481527f662d38223f3e3c73766720786d6c6e733d22687474703a2f2f7777772e77332e60208201527f6f72672f323030302f737667222077696474683d22313030307078222068656960408201527f6768743d22313030307078222076696577426f783d223020302031303030203160608201527f303030223e3c6c696e6561724772616469656e742069643d226722206772616460808201527f69656e74556e6974733d227573657253706163654f6e557365222078323d223060a08201527f222079323d2231303030223e3c73746f70206f66667365743d22302e3122207360c08201527174796c653d2273746f702d636f6c6f723a2360701b60e08201526000865161547f8160f2850160208b01615c8a565b61574a61511b6156df6156d961558961552061551a6154e16154db60f28a8d01017f222f3e3c73746f70206f66667365743d22302e3522207374796c653d2273746f815268702d636f6c6f723a2360b81b602082015260290190565b8f6144f0565b7f222f3e3c73746f70206f66667365743d223122207374796c653d2273746f702d815266636f6c6f723a2360c81b602082015260270190565b8c6144f0565b7f222f3e3c2f6c696e6561724772616469656e743e3c7265637420783d2230222081527f793d2230222066696c6c3d2275726c28236729222077696474683d223130303060208201527011103432b4b3b43a1e911898181811179f60791b604082015260510190565b7f3c636972636c65206f7061636974793d22302e3039222066696c6c3d2223464681527f46464646222063783d22373236222063793d223338302220723d22313531222f60208201527f3e3c72616469616c4772616469656e742069643d2273222063783d223434222060408201527f63793d223732332220723d22393922206772616469656e745472616e73666f7260608201527f6d3d226d6174726978283120302030202d31203636322031313138292220677260808201527f616469656e74556e6974733d227573657253706163654f6e557365223e3c737460a08201527f6f7020206f66667365743d22302e3622207374796c653d2273746f702d636f6c60c08201527f6f723a23464646464646222f3e3c73746f7020206f66667365743d223122207360e08201527174796c653d2273746f702d636f6c6f723a2360701b6101008201526101120190565b886144f0565b7f222f3e3c2f72616469616c4772616469656e743e3c636972636c65206f70616381527f6974793d22302e38222066696c6c3d2275726c28237329222063783d22373036602082015272111031bc9e91199c9a9110391e911c9c91179f60691b604082015260530190565b98975050505050505050565b6629b0b73226b0b760c91b815260008251615778816007850160208701615c8a565b9190910160070192915050565b711e3837b63cb3b7b71037b830b1b4ba3c9e9160711b815283516000906157b3816012850160208901615c8a565b6911103837b4b73a399e9160b11b60129184019182015284516157dd81601c840160208901615c8a565b68222066696c6c3d222360b81b601c92909101918201528351615807816025840160208801615c8a565b631110179f60e11b6025929091019182015260290195945050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161585d81601d850160208701615c8a565b91909101601d0192915050565b7f5b7b202274726169745f74797065223a202250616c65747465222c202276616c81526000653ab2911d101160d11b80602084015285516158b2816026860160208a01615c8a565b7f22207d2c207b202274726169745f74797065223a20224265617264222c2022766026918501918201526730b63ab2911d101160c11b6046820152855161590081604e840160208a01615c8a565b8082019150507f22207d2c207b202274726169745f74797065223a2022436170222c202276616c604e82015281606e82015284519150615947826074830160208801615c8a565b0160740195945050505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090615121908301846144c4565b6020815260006120a160208301846144c4565b6020808252601d908201527f4d757374206f776e20612053616e6420746f206d696e7420746f6b656e000000604082015260600190565b6020808252600790820152664275726e65642160c81b604082015260600190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526022908201527f53616c65206d7573742062652061637469766520746f206d696e7420746f6b656040820152616e7360f01b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b604051601f8201601f1916810167ffffffffffffffff81118282101715615b3557615b35615d8f565b604052919050565b60008219821115615b5057615b50615d37565b500190565b600082615b6457615b64615d4d565b500490565b600181815b80851115615ba4578160001904821115615b8a57615b8a615d37565b80851615615b9757918102915b93841c9390800290615b6e565b509250929050565b60006120a18383600082615bc257506001610385565b81615bcf57506000610385565b8160018114615be55760028114615bef57615c0b565b6001915050610385565b60ff841115615c0057615c00615d37565b50506001821b610385565b5060208310610133831016604e8410600b8410161715615c2e575081810a610385565b615c388383615b69565b8060001904821115615c4c57615c4c615d37565b029392505050565b6000816000190483118215151615615c6e57615c6e615d37565b500290565b600082821015615c8557615c85615d37565b500390565b60005b83811015615ca5578181015183820152602001615c8d565b83811115610bde5750506000910152565b600081615cc557615cc5615d37565b506000190190565b600181811c90821680615ce157607f821691505b60208210811415615d0257634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415615d1c57615d1c615d37565b5060010190565b600082615d3257615d32615d4d565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610ce357600080fd5b6001600160e01b031981168114610ce357600080fdfe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa26469706673582212208ac7e8b1afc848fda1c3608a7db5a5d9db7f9b3f2a39d836be7ff172b7d338a264736f6c63430008070033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101795760003560e01c806370a08231116100d9578063a22cb46511610087578063a22cb465146102f4578063b88d4fde14610307578063c634d0321461031a578063c87b56dd1461032d578063e985e9c514610340578063eb8d244414610353578063f2fde38b1461036757600080fd5b806370a082311461029a578063715018a6146102ad57806373f42561146102b55780638da5cb5b146102c957806395d89b41146102d15780639975038c146102d95780639a5d0893146102e157600080fd5b806323b872dd1161013657806323b872dd146102205780632f745c59146102335780632f8bd8911461024657806334918dfd1461025957806342842e0e146102615780634f6ccce7146102745780636352211e1461028757600080fd5b806301ffc9a71461017e57806306fdde03146101a6578063081812fc146101bb578063095ea7b3146101e657806318160ddd146101fb5780631960669d1461020d575b600080fd5b61019161018c366004614471565b61037a565b60405190151581526020015b60405180910390f35b6101ae61038b565b60405161019d9190615987565b6101ce6101c93660046144ab565b61041d565b6040516001600160a01b03909116815260200161019d565b6101f96101f4366004614384565b6104aa565b005b6008545b60405190815260200161019d565b600b546101ce906001600160a01b031681565b6101f961022e36600461424c565b6105bb565b6101ff610241366004614384565b6105ec565b6101f9610254366004614384565b610682565b6101f96106e9565b6101f961026f36600461424c565b610739565b6101ff6102823660046144ab565b610754565b6101ce6102953660046144ab565b6107e7565b6101ff6102a83660046141d9565b61085e565b6101f96108e5565b600a5461019190600160a81b900460ff1681565b6101ce610920565b6101ae61092f565b6101f961093e565b6101f96102ef3660046143b0565b610982565b6101f9610302366004614351565b610aeb565b6101f961031536600461428d565b610bac565b6101f96103283660046144ab565b610be4565b6101ae61033b3660046144ab565b610ce6565b61019161034e366004614213565b6119eb565b600a5461019190600160a01b900460ff1681565b6101f96103753660046141d9565b611a19565b600061038582611ab6565b92915050565b60606000805461039a90615ccd565b80601f01602080910402602001604051908101604052809291908181526020018280546103c690615ccd565b80156104135780601f106103e857610100808354040283529160200191610413565b820191906000526020600020905b8154815290600101906020018083116103f657829003601f168201915b5050505050905090565b600061042882611adb565b61048e5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006104b5826107e7565b9050806001600160a01b0316836001600160a01b031614156105235760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610485565b336001600160a01b038216148061053f575061053f81336119eb565b6105ac5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776044820152771b995c881b9bdc88185c1c1c9bdd995908199bdc88185b1b60421b6064820152608401610485565b6105b68383611af8565b505050565b6105c53382611b66565b6105e15760405162461bcd60e51b815260040161048590615abb565b6105b6838383611c30565b60006105f78361085e565b82106106595760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610485565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b3361068b610920565b6001600160a01b0316146106b15760405162461bcd60e51b815260040161048590615a44565b600a54600160a81b900460ff16156106db5760405162461bcd60e51b8152600401610485906159d1565b6106e58282611ddb565b5050565b336106f2610920565b6001600160a01b0316146107185760405162461bcd60e51b815260040161048590615a44565b600a805460ff60a01b198116600160a01b9182900460ff1615909102179055565b6105b683838360405180602001604052806000815250610bac565b600061075f60085490565b82106107c25760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610485565b600882815481106107d5576107d5615d79565b90600052602060002001549050919050565b6000818152600260205260408120546001600160a01b0316806103855760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610485565b60006001600160a01b0382166108c95760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610485565b506001600160a01b031660009081526003602052604090205490565b336108ee610920565b6001600160a01b0316146109145760405162461bcd60e51b815260040161048590615a44565b61091e6000611df5565b565b600a546001600160a01b031690565b60606001805461039a90615ccd565b33610947610920565b6001600160a01b03161461096d5760405162461bcd60e51b815260040161048590615a44565b600a805460ff60a81b1916600160a81b179055565b600a54600160a81b900460ff16156109ac5760405162461bcd60e51b8152600401610485906159d1565b600a54600160a01b900460ff166109d55760405162461bcd60e51b815260040161048590615a79565b60005b81518110156106e557600c54825133916001600160a01b031690636352211e90859085908110610a0a57610a0a615d79565b60200260200101516040518263ffffffff1660e01b8152600401610a3a919063ffffffff91909116815260200190565b60206040518083038186803b158015610a5257600080fd5b505afa158015610a66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8a91906141f6565b6001600160a01b031614610ab05760405162461bcd60e51b81526004016104859061599a565b610ad933838381518110610ac657610ac6615d79565b602002602001015163ffffffff16611ddb565b80610ae381615d08565b9150506109d8565b6001600160a01b038216331415610b405760405162461bcd60e51b815260206004820152601960248201527822a9219b99189d1030b8383937bb32903a379031b0b63632b960391b6044820152606401610485565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b610bb63383611b66565b610bd25760405162461bcd60e51b815260040161048590615abb565b610bde84848484611e47565b50505050565b600a54600160a81b900460ff1615610c0e5760405162461bcd60e51b8152600401610485906159d1565b600a54600160a01b900460ff16610c375760405162461bcd60e51b815260040161048590615a79565b600c546040516331a9108f60e11b81526004810183905233916001600160a01b031690636352211e9060240160206040518083038186803b158015610c7b57600080fd5b505afa158015610c8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb391906141f6565b6001600160a01b031614610cd95760405162461bcd60e51b81526004016104859061599a565b610ce33382611ddb565b50565b6060610cf0614174565b610cf8614193565b6060610d026141ba565b6000806000610d37610d138a611e7a565b604051602001610d239190615756565b604051602081830303815290604052611f78565b9050610d44601e82615d23565b610d4f906001615b3d565b84526005610d5e606483615b55565b610d689190615d23565b610d73906001615b3d565b60208501526006610d866103e883615b55565b610d909190615d23565b610d9b906001615b3d565b60408501526005610dae61271083615b55565b610db89190615d23565b610dc3906001615b3d565b60608501526004610dd7620186a083615b55565b610de19190615d23565b610dec906001615b3d565b60808501526006610e00620f424083615b55565b610e0a9190615d23565b610e15906001615b3d565b60a08501526006610e2a6305f5e10083615b55565b610e349190615d23565b610e3f906001615b3d565b60c0850152600a610e54633b9aca0083615b55565b610e5e9190615d23565b610e69906001615b3d565b60e0808601919091527dffc6a69a3a93560094ff9191fffeebc9c789204da90013704fa4ffebfaff88527dffb88fae3c23780000ff9757ffff9effed9e9a3a93560094ffd28afffeeb60208901527dd9945f8230462f0075ff7700ffff9eeb9a5bae3000780000ff7700ffff9e60408901527dffb366ca7d56a64324ffd3a1fffeebed975aca300ba60000ff771cffff9e60608901527dffa36ea5382578000ee88d48ffecd6e6b59ab395888f6559e3cfbdfffeeb60808901527dffa975ae5a6f780066ffe17dffffffd98b83653d9a7800664898e8d6fffb60a08901527dffbe987754671d0073ffd154fff9bfdbd18832836d0031367dffc0ffff9e60c08901527dff72368c15333f0045ff3419ffda61ff997a8c2a463f0045ff6947fff9bf908801527df2cb8a4d4b7e1a003b9abbe3f7f7f7f2bb61864c0a360000ffbe19ffedb06101008801527de0c275626c67000a3bf6ffa8fffdf2d9be91404664000a3ba1a1a1f7f7f76101208801527deb8a368923113b001aff5703ffd342db64357c0101240000ff0303ffcb216101408801527df9938a5e2776060019e261fffff2d9e6c58f66acc2007599ffffff8bb6c76101608801527dffff9e3a6e52001f3391e581f2ff7affbf7566565c000330ffd29efff7e86101808801527d40253612001c0000002d0047523ea3c29c76454545000000adadadffffff6101a08801527dada16d006062008a8a002226008a836920202200000a0000470000a300006101c08801527dffdb7d7f5e542a0042ffec6efff4c7cf795d63328a5e003c6b7cff5900506101e0880152600091505b6004821161116e57835182906110d390600190615c73565b6110de906005615c54565b6110e89190615b3d565b925061114563010000006110fd600a86615d23565b61110b906301000000615bac565b89611117600a88615b55565b6013811061112757611127615d79565b60200201516111369190615b55565b6111409190615d23565b611fa9565b86836006811061115757611157615d79565b60200201528161116681615d08565b9250506110bb565b6040860151602087015160c0860151829082906111b59061119090605c615b3d565b6040808d0151815180830190925260048252630605c60760e31b6020830152906120a8565b6040516020016111c9959493929190615348565b60408051601f1981840301815291905294508461122d600186600560200201516111f4906002615c54565b6111ff906050615b3d565b6112099190615c73565b6040808a015181518083019092526003825262302e3160e81b6020830152906120a8565b60a086015161127090611241906002615c54565b61124c906050615b3d565b6040808b0151815180830190925260038252620c0b8d60ea1b6020830152906120a8565b60405160200161128293929190614bf8565b60408051601f198184030181529190529450846112c260008860025b6020020151604051806040016040528060018152602001603160f81b8152506120a8565b6112ce6001898161129e565b6112fd60028a60005b60200201516040518060400160405280600381526020016218171960e91b8152506120a8565b61132c60038b60025b602002015160405180604001604052806003815260200162302e3360e81b8152506120a8565b61133960048c6002611306565b61134660058d60006112d7565b60405160200161135c9796959493929190614669565b60408051601f1981840301815291905294508461137c600688600461129e565b611389600789600361129e565b6113ce60086040518060400160405280600681526020016523232323232360d11b81525060405180604001604052806003815260200162302e3960e81b8152506120a8565b61141360096040518060400160405280600681526020016523232323232360d11b81525060405180604001604052806003815260200162302e3960e81b8152506120a8565b6040808c0151905161142f9695949392919081906020016147fc565b60408051601f1981840301815291905294508461144f604d88600361129e565b61145c604e89600361129e565b611469604f8a600461129e565b61147660508b600461129e565b60405160200161148a9594939291906149a1565b60408051808303601f1901815291905260e0850151909550600114156114f757846114b8602688600061129e565b6114c5602789600361129e565b6114d260288a600361129e565b6040516020016114e59493929190614528565b60405160208183030381529060405294505b8461152c60018681602002015161150f906002615c54565b61151a906009615b3d565b6115249190615c73565b88600361129e565b602086015161157090611540906002615c54565b61154b906009615b3d565b6040808b01518151808301909252600482526318171b1b60e11b6020830152906120a8565b6115a4600288816020020151611587906003615c54565b611592906013615b3d565b61159c9190615c73565b8a600261129e565b6115fb600189600260200201516115bc906003615c54565b6115c7906013615b3d565b6115d19190615c73565b8b60015b60200201516040518060400160405280600381526020016218171b60e91b8152506120a8565b60408901516116229061160f906003615c54565b61161a906013615b3d565b8c60016115d5565b604051602001611637969594939291906145ea565b60408051601f1981840301815291905294508461169b600386816020020151611661906004615c54565b61166c906028615b3d565b6116769190615c73565b606089015160408051808201909152600481526318171c9960e11b60208201526120a8565b6116f3600287600360200201516116b3906004615c54565b6116be906028615b3d565b6116c89190615c73565b8960005b602002015160405180604001604052806004815260200163302e323560e01b8152506120a8565b6117286001886003602002015161170b906004615c54565b611716906028615b3d565b6117209190615c73565b8a60006116cc565b606088015161174f9061173c906004615c54565b611747906028615b3d565b8b600261129e565b60405160200161176395949392919061457f565b60408051601f198184030181529190529450846117ab6003866004602002015161178e906004615c54565b61179990603c615b3d565b6117a39190615c73565b88600261129e565b611802600287600460200201516117c3906004615c54565b6117ce90603c615b3d565b6117d89190615c73565b8960015b602002015160405180604001604052806003815260200162302e3560e81b8152506120a8565b6118376001886004602002015161181a906004615c54565b61182590603c615b3d565b61182f9190615c73565b8a60016117dc565b608088015161185e9061184b906004615c54565b61185690603c615b3d565b8b600161129e565b61186b60628c600261129e565b604051602001611880969594939291906146fb565b60408051601f19818403018152919052945060606118a58560005b6020020151611e7a565b6118b086600161189b565b6118bb87600261189b565b6040516020016118cd9392919061586a565b60408051601f198184030181529190529050806118eb86600361189b565b6118f687600461189b565b61190188600561189b565b604051602001611914949392919061512b565b60408051808303601f1901815291905260e08601519091506001141561195757806040516020016119459190614b27565b60405160208183030381529060405290505b8061196386600661189b565b604051602001611974929190614b7f565b604051602081830303815290604052905060006119b98261199489613aec565b6040516020016119a5929190615237565b604051602081830303815290604052613aec565b9050806040516020016119cc9190615825565b60408051601f198184030181529190529b9a5050505050505050505050565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b33611a22610920565b6001600160a01b031614611a485760405162461bcd60e51b815260040161048590615a44565b6001600160a01b038116611aad5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610485565b610ce381611df5565b60006001600160e01b0319821663780e9d6360e01b1480610385575061038582613c52565b6000908152600260205260409020546001600160a01b0316151590565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611b2d826107e7565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611b7182611adb565b611bd25760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610485565b6000611bdd836107e7565b9050806001600160a01b0316846001600160a01b03161480611c185750836001600160a01b0316611c0d8461041d565b6001600160a01b0316145b80611c285750611c2881856119eb565b949350505050565b826001600160a01b0316611c43826107e7565b6001600160a01b031614611cab5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610485565b6001600160a01b038216611d0d5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610485565b611d18838383613ca2565b611d23600082611af8565b6001600160a01b0383166000908152600360205260408120805460019290611d4c908490615c73565b90915550506001600160a01b0382166000908152600360205260408120805460019290611d7a908490615b3d565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6106e5828260405180602001604052806000815250613cad565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b611e52848484611c30565b611e5e84848484613ce0565b610bde5760405162461bcd60e51b8152600401610485906159f2565b606081611e9e5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115611ec85780611eb281615d08565b9150611ec19050600a83615b55565b9150611ea2565b60008167ffffffffffffffff811115611ee357611ee3615d8f565b6040519080825280601f01601f191660200182016040528015611f0d576020820181803683370190505b5090505b8415611c2857611f22600183615c73565b9150611f2f600a86615d23565b611f3a906030615b3d565b60f81b818381518110611f4f57611f4f615d79565b60200101906001600160f81b031916908160001a905350611f71600a86615b55565b9450611f11565b600081604051602001611f8b919061450c565b60408051601f19818403018152919052805160209091012092915050565b6040805180820190915260068082526503030303030360d41b60208301526060915b81156120a157600a611fde601086615d23565b101561203557611fef601085615d23565b611ffa906030615b3d565b60f81b81612009600185615c73565b8151811061201957612019615d79565b60200101906001600160f81b031916908160001a905350612082565b612040601085615d23565b61204b906037615b3d565b60f81b8161205a600185615c73565b8151811061206a5761206a615d79565b60200101906001600160f81b031916908160001a9053505b61208d601085615b55565b93508161209981615cb6565b925050611fcb565b9392505050565b60606000604051806119e001604052807e07fe112eadce2b20f778d5c85663965707158b4d70e4663a1b2e573c5e112e81526020017f0778d5ce5f6817990605f9d9b0777425dc6ba6b34ddacc6eb6990d65c35574de81526020017f0a89c2a2418229206ba98249fcd1809e9fa608c0d20e7583a1aa23ea9022161a81526020016a01ff5d37996e070b79eae081526020016a01ff7b44a412779c51d6f681526020016e1ff7e982c62f84309d2da79b25fa6081526020017507fddea17b1b1d46d661858e64619d19067779c9dea18152602001797fe5301aebba56fb91b12bab0ae9ae6e9ba0ac23ebc8c3aa53018152602001771ff279d884832431d0ad359b41a8b06a26d8e83589d0cc7181526020017f06aac5aa9b642096473509c9386c409a9006d429d52a74529f5647a62a15a49d81526020017f03c1d50a75411c0e46f2c1bc847d1d25084c92f348f8d33f35d32d64f34d6ad381526020017f049221187e411d5147d439f4fe75431f5067c3e1d5047c409f0fc793c9d4f87881526020017f04aa611c924a261249746a51229747a5d18954725d189745a5918974525d228c81526020017f04026d109c4f26d3a984b2453a994f2693a9a49241369a4c2611e904ba612c9881526020017f032b24a8b931b20c0c7292e4bec62e3189eba2d3149ec122a10a077361d4f28b81526020017f02fad8e0c737b20bab737320dcc92e2e0d8c936324b4b935b28d4ca2c2e4ceca81526020017f0382f0e0bc3b308ecc3342d8eac43a314c8b63a314e8c539b18c4b639318e2c781526020017f039ae8f0bf3c300e4ba3c300eec1382ecf4a63d278e6853ba84e0bb35adce0bc81526020017f0442a11aad452b10ea9452b10eab432a90eab422ad00ab3d2f8ecba3caf8f2bf81526020017f04dabd26a74d2bd30af4c2bd1ea74babd2aae46a9d28ae48ab516a8482b51cad81526020017f05029d46a9512ad3ca7512b144ae4e2a542ae4fab934a94fab93aae4baa538ae81526020017f044b251ec34a2e93eb7542a956a953a954c9450a5d48a551a9d42a451a9d46a981526020017f047b112ccb4ab311cc54a33126cc46b1926cd4933516c74933520ce4532520ce81526020017f04fb1d3ac74a2fd3ac84e32124c04db2534c948b0532c94c32920c34c3292ecb81526020017f0512fd5ecc5632d3ebf5532950c94eb014cc951b2132bf5131d40c64fb192cbe81526020017f05bb2158bf5b3256ac9552fd6aca5a32d4ebf59b2d66cc5330164cc5933562cc81526020017f059ae978c35db1162bb5db1174c557af172c55cb195cbd5c31970c756af56ec881526020017f05eb0568ba5aae166ab5aa91689e5e23d609e58a9162a95a2e968ba5eb0978c381526020017f05ead986bc612f578b7612f582be5d2e182be602fd6eb75fb017ec05b2e57cc181526020017f0652d992b760ac190b763ae182b263ae18cb9602d18cba62ae97cb562aed88bb81526020017f05fabd72aa5fac17cb15c2b57cb25eacd70af5e2cd7ab3612b196b4652d582ae81526020017f060a9982a75da8982a860aa974a45d29182aa602b174a6602b180ae5d2a580ae81526020017f05f26d7c9b6127d84a05ea757a9d6128584a35ea797a9f6128d84a55e28578a181526020017f065ad184ac62a9d8ca060a5d849960261809861269849c5fa697e9a61271849e81526020016307fda4ae81526020017301ff41ad500c14131918c347af516b4432c906b581526020017301ff422410c94462491e8945a01067e40a19089081526020017f0471d960815525156a1562fd6eba5a2957e8e5fa396ca55cae124cb31328c4d281526020017c01ff5cb51b6be6a2edb8b8722799e8063201947b5b1b4b070269f0c07f81526020017f065a258e8e65a398c9367249809b6825996b35f30164c357abd5ec44d338f0cd81526020016c07fd3ad15b33d82c867af9b4a181526020017f05fa2d86885fa196e8c59a416a9258a4d569755a8158aa552bd60b458aed74c781526020017f06f25da09363a5592975ea5580a45f2ad78b4652c59eb25f3096ab45a2a56e9981526020017507fd74c7682c9a8b36dac5bca972295bea070a7dbe9b81526020017f060ac1b2ad6e2a1b4a26d2a1ae9f6c2a1aaa36b2a990ac64a9d849962a9d82b081526020016101ff81526020017f0552bd60b458aed58bd563016abc5ead182ac63ab596b3632e96ec45ab2162c981526020017f0602b17cb25aae968a95ba65788f5a2195c875aa356a9258a4d569755a8158aa8152602001797fd64cf6dac5bca96da75a69a6320d62776223d90a15fa857cab8152602001771ff6cab5baa86ba7db0a86aa8dacaa65aa192a46229186aa81526020017f05a2a5789060a31888f6427992b5632e974bf5aaed5eb5562f558bf55b1122ce81526020017f05cb51b6be6a2edb8b86e21d6c6d4b9b91e73529ed6a9255a5d58aa552c16abc81526020016101ff81526020017f06cad1b4895d1d5a28965221a48d692499e9369255a6a467299a6a6652adaeb381526020016307fda2b681526020017f0582d164bd592f964be592fd6aba5a2a56e995da2d7c886223d90a561af122ce81526020017f079a79de9773a59d4926ea0d6c6d4b9b91e735ba056c8a55a5d56a0562a954af8152602001651ff5cb51ccc081526020017f072af5d89e71251bc8b6ba25a2836f2a5aa946f2c5b2aa6dac196a86dad99cb281526020016101ff81526020017f03e9cabc7fae934ee5c389549c4f1d984667e1225854d525b9cc6e349bad42e681526020016a01ffb23c2c6cf3bb2cc0a08152602001797fcae7b299ec96ab269e88c7a212647e7b1c9f470c32b318ae7b81526020017f0a11d2ac71881b2785e3d985006c3a1a8e0633121cd67a2d280c6c93137d20e78152602001797fd20e751b86d8e59db54e6d436af8e2d531378d6ca2da80ec6d81526020017f03bb2cfa953e9c9427147970ee5c389549c4f1225854d525b9cc6e349bad42e68152602001651ff733b1bcd98152602001707fce4d469384dadc4839cc2df3734ce8b181526020017f018270707914a685ece1c2f870cb1eb34a2a62d9d0c8763624cbec521b5470cc81526020017f020b68d6c83b250de722a9c4949c1cb2c74ba20ab49c62369792c684717c9e5c81526020016101ff81526020017f01a3609eef2d3acc2e43b39cf8dd46b6116d237b3ca6a52da00d4763f9d1126981526020016a01ff35988946a181fc3eb281526020016c07fc648e182bca2e516ac45a9d81526020017f0339b8fa693a998c66d279b07c761b2086c9a1e1f494762c1dc8e85202c894cf81526020017f0302fc96c622ac0a6ab2829088a622a8ca4a129a648c9a25214b0812e1eca87b8152602001797fcb6df30b7d0cd440b4cbadc29b50d2ce3231ca0cf27b34c8c58152602001771ff2b9b4787516a6464c22033c9cd334b50d878399b8ae6d81526020017301ff33b40c875221f864a2201e8ae70351c4ced081526020016e1ff1a30886cb2f3449ed220b3868c281526020017f0451c902623416cc05a2d180866d1c9ec62941627464ac1ab1c92dc3239100d68152602001677fcfad136b1502768152602001677fca4de3836898db81526020017f0239f4b2782c1d88c6e289a0dc682e9fcaca32dac0acaa30b34bebf32334e2d481526020017f0229b4767b17a706aaf1bb1ca49c1b2b864a222a30609b1b2308e792b1d8ac7881526020017f03db54d4c735a18f67236accd8c43f9acd08234310cec333204f2683f9a0b86081526020016101ff81526020017f03db68d0dc2b37c7ed612b0444ab14a4c4884191e87e69239a8da63471ad2e7681526020017301ff3f9dcd6812ea109e9527ab0e0c647b450eda8152602001677fcce7327210669e81526020017f026a8484a41d2c490c127300bcc8292e0c6c4463490ad83e360acda203504ec081526020016c07fc50b6172b45cb6192ac9c9681526020017e07fd388c50a35409051a41488d55235548a52a254a865121942894ea21388c81526020016c07fd4a8a52a31528d522354a8a81526020016c07fd428950a31388c50231428981526020017f0489ed248648259029b402a522af49ae922cb47b34fad23e2d4fe9c3da14fa7281526020016307fd0c7581526020016a01ff3ea010079461e4fe7781526020016a01ff46ac502b13faf100af81526020017f0411c10475469e5228847a5102983ea10fc73419d5026e3e1b4f2843ea8cf4bc81526020017f048af11ecb41b3908d14833d26cb4aaed24ae4129d049f48a612888499e91e7581526020017301ff3e35104d34234506ce3f33cfabe402ad1eb081526020017f04fa1d2a994227104a5422b12ab04e2e93ec54cb3d0ad24133100ba409ed08738152602001651ff421cd387981526020016c07fd38824ea1d328e4225d068c81526020016c07fd36ba4e2f538c443b3908c581526020017f03f30902cf3eb4d0cd34333d0ccf40b0904af432b528b04eaf13ac64cb350ccf81526020017f0481cd0a6f421d1367b4f21d289843a69049840a090874429bcfc6f409c8fc8181526020017c01ff4334d1ed34db3d40c74fae92aae44aad08a4442752a9b5021d3a7981526020017f04ab2930b1442852e8f4a9dd12703d9c8e8793ba710e9e43a8ceea43ab18f8ce81526020016307fd12d081526020016e1ff3d9f4fa9243a68f49a3c1ecfc7481526020016e1ff3db10faae43a9cf4a63c318fccc81526020017f03aa70f4a042a7d0aa13da84f69f3d27cf4a13aa90e8cb3db650cd742338facd81526020017f0429c10870421c914714a1e12c8f4426cf09b3b1e8fa73429c90c6a3d99ce87581526020017f0442992cb14a32514cf4233908d144b452eca4d2c516a445a7934904b9d9126f8152602001651ff3b31cf0a581526020017f0479e1348a47a711eab4d2e526ca3cb4ce8c3402b918ab46a6d00973aa14f2748152602001651ff3c9d0f27481526020016e1ff3f240fc90402150e7c3f214fc9081526020016e1ff3f308fcc2402dd0eae3f2dcfcc281526020017f042b38f2d23b30cf6c43e314fab6432b518ae46aad06ab3c2d0e6c33b348e4d281526020017f03da08f685431ed227d4c22d269645a6116ae48abd30b948b250ccb3db04f6c481526020017f0391b8ec7439a0cf09241a6d189b462610c993ea40f8813da08ec833c9d10a7881526020017f03db54fcd33f34d1ecf4db1534b448aad229b4d2493681479dcfc733f1ccf46f81526020016307fce4d281526020017301ff3f28d468a4e9ccda7c37b2d3ed1522f8fca381526020017f03ead8e6c23aaa0f8a23f26d34893da58f69c39a80e48438288e6c44032510c38152602001651ff4430d10b981526020017f0471c5427951a1d448b4027500a9512ed46bf50b311cd43bb44e4c93832ce8d381526020017f02e26cbaad2dab8b6b330ad4c29435a74d4ab33ab4dcca37b14daa2381fcee7581526020017f045a6d488c52a1d4476481b8e873379f8da7c33a5cc48e32a1cbe872da3cb6998152602001707fce8d34836144d052afd48ba42a9d12a581526020017f04d228fc9c3e28cfca94d2ed32c44a32108ca4136112da4936528d84bb7532dc81526020017f03b31cecc73b2f0f8b4432e110b73f2c8ecb538b00dea339201007a4a1f5328181526020017f042b0902c63eb1cf4c33d2f8fcba412ed0ac3432f908b93eadcf0bd3c310f6c981526020017f0321f0b28f2c28cb2b732324dccc38348e8d641b6108ca44b1514bb442dd0cb881526020017f046a6d4a8b53a0d4a77509cd246c449ad006d36998d8683e9b8e870381d0dc7a8152602001771ff4bb5d32d64db6d38da4db5542d352b394ec252ae91aaa81526020017e07fd46c15c33594c67028d98815e1e146854b1b1206b4fa25169c45aa946c181526020016c07fdaea366301bca466a21aea381526020017f05d28d769d61a798e965d209428f4fa75529d5ea3572a35eae152a84faa142b681526020016c07fd42b65d30d8eaf61a9d78a881526020016e1ff4fadd22a14aa5d1c9d472a93eb781526020017507fd2c9a521c98e59731a9eeaa6dbb180e94aab92c9a8152602001797fd34ad543015c9a5731d66cd6518d88675e9f5706f571d934ad81526020017301ff6025da6da6fa61e4a8732b1ace662b51809781526020017507fd9e63711b9d2876f9c9a26865a559cb7632599e638152602001707fd66b373c41d1107543168ad59abd66b38152602001707fd70b75d2ddc90171405c3045bae570b781526020017301ff75431d30d71c15cf0d70c15cf1074441d50c81526020016c07fdc50272409d50c74c31c50281526020017f03f9b5006f4f1d54e8254a3952995426d4c9b53a8152a054aa14ea9532b14eae81526020017507fd4eae55ab95cab57a815c9956a655a8e552053e7281526020016e1ff55ab158ab5523154a7542b156ac81526020016a01ff56a695ca4572815a9a81526020016a01ff54ab156a855ab152ac81526020016e1ff44255208d4821d167e411f8fe8981526020016e1ff40b1d18c447af51eb6432c4febd81526020016e1ff44251188d4621d1281419fd028981526020016c07fd06c54530d18b843acd02bd81526020017e07fdf62b7c051f40c7d04dfc2b8001a0a028101a041985846021d7f8b9fe2c81526020017f0760c9ca2d758cdce37678e9bc396e8e9b63f6f8e5ce397191dbc547211dd03981526020017f07f8b1f42a77885dc127687dca186e05da8106d05d9a1671865c01e72869f02c81526020016c07fdd6367a8c9e63b7c0c5fe2e8152602001677fddc1c79899f00181526020017f0700e1ca3779899d81777041d21773891c2266f891bc29700a1c82e718c5bc378152602001677fdb6406e0fdbe398152602001797fdd41c7606dd6207709dea1b7d809f01c768c1da2a758a9ce1381526020017f0768a9aa226684da0215a05daa26690b5b227728b1b637660d1b03b62949c8348152602001677fdc83e730cdda308152602001707fdf2407c0d9fa2e83001f6017707dde3681526020017f07c851f6127c099f4257e88dfc127d83dda1f7487dcc276d09dc82d740d5e23781526020017f07d099f4267d8a5ec307a0b9e82a7b099ee267c061ee1777885ec177b055f41181526020016c07fde2377c901ec357d0bdf62881526020017f07e805f0057a035da12720cdb2336b8d5ce3c6e8fdd6417813ddc546f939ba528152602001677fddc5d7f885fe1a81526020017e07fdbe637697dfe227f869e41e78891e629778bda430680e5b0486e935b45481526020016a01ff7b8e1f63e81001ee3881526020017f07709de82466899902463889a2176d059a0156108978215f8a18026618a18c2681526020016e1ff7d8f9f6386e8b5d42c6b0a9e02881526020017f042c6d2f1c4c471311c4fc794b1f5348957235649d572955cb1612d58d0d5d5681526020017f043c31110b474311d0d47c312f0c4bc39310d4d435310e49c511d1549c592f1a81526020017f04ac1923074ac1d2f094bc252f0a47c2d1d094742d110b43c290f0b4242d0f0b81526020017f0513e146f950be936fa4d3e934fa453ed34fb4d3f136fc4fbf13cfd4fbfd350181526020017f03abd8e2f63abd8ecf73bbd900f7403e102f7463dd1af9473e13ef7503e542f881526020017f059a3d58f2543d142f4503cd3ef5473d51af4463d502f6403d100f63bbd8ecf581526020016c07fd695d5a005661657071643681526020017f04f49539244bc9d2d294acb931304e4c13d2e504b9433153cd1553858cf1695381526020017e07fd680158831623154109645857b8126fc4f415330b52451471f50c85432481526020017f04d965365b4e16d385f4f97d3e65509954e6b563894aec56c05531c50cb1613981526020017f0550854629508c538344e8d92c3b4990120404791d24494a9392c534d155345981526020016c07fd51565a53d680255085542181526020017f0469491852461551a55469691c5b471952265569bd60f353c35632157ca5694c81526020017f05406d5024480ad1a2c468f5163d4590526465591d56494712d564c55941264f8152602001651ff5a009561a81526020017f04f1593c664d9ad36734b9e548b5523513ad95037936e54d3bd46ec53d55695581526020017e07fd69555a00152004f84936184e08130264b8d126384911d2c4c4b945385081526020017f05ec215b0760c2d9513694618b1a6bc6dd12579d01d53a724b9cf396d4c5eb4481526020017f07447dcb1375c05c90e6e3a5c1066ac01c30d71c75a314643fd991165c4534e881526020017f08fc9e1d378648e173b7fd21f53f82c89fb2f7e48df7337bce9e12e7dc65dd2a81526020017f091c4e5d0491c3a44f4904623109823e21f0382c1625068b42e411f8fc862f1881526020016a01ff7ad11f34d81d36472781526020017f504f4e4b4a48454442403f3d3b383633322f2d2a282625240a0908070605020181526020017f8e8d8c8682807f7a7978767271706e6b6a6967646362605f5e5d5b5a5854535181526020017fbfbdb6b4b3b2b0adacaaa9a7a6a3a2a1a09f9e9d9c9b99989796959493929190815260200163ffc7c5c281525090506000806000806000806060600060208d6139019190615d23565b61390d90610100615bac565b8960208f61391b9190615b55565b6139269060cb615b3d565b60cf811061393657613936615d79565b60200201516139459190615b55565b925061395361010084615d23565b6040805160208101909152600081529097509150613972600188615c73565b97505b60fa8811613ab657888860cf811061398f5761398f615d79565b602002015161399d57613ab6565b888860cf81106139af576139af615d79565b6020020151955060009450600093505b601b8411613a95576102006139d48582615bac565b6139de9088615b55565b6139e89190615d23565b9050806101ff14156139f957613a95565b613a04600286615d23565b613a435781613a1c613a17836003615c54565b611e7a565b604051602001613a2d929190614ab1565b6040516020818303038152906040529150613a75565b81613a52613a17836003615c54565b604051602001613a63929190614aec565b60405160208183030381529060405291505b84613a7f81615d08565b9550508380613a8d90615d08565b9450506139bf565b806101ff1415613aa457613ab6565b87613aae81615d08565b985050613975565b8a828d604051602001613acb93929190615785565b60405160208183030381529060405299505050505050505050509392505050565b805160609080613b0c575050604080516020810190915260008152919050565b60006003613b1b836002615b3d565b613b259190615b55565b613b30906004615c54565b90506000613b3f826020615b3d565b67ffffffffffffffff811115613b5757613b57615d8f565b6040519080825280601f01601f191660200182016040528015613b81576020820181803683370190505b5090506000604051806060016040528060408152602001615dd1604091399050600181016020830160005b86811015613c0d576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b835260049092019101613bac565b506003860660018114613c275760028114613c3857613c44565b613d3d60f01b600119830152613c44565b603d60f81b6000198301525b505050918152949350505050565b60006001600160e01b031982166380ac58cd60e01b1480613c8357506001600160e01b03198216635b5e139f60e01b145b8061038557506301ffc9a760e01b6001600160e01b0319831614610385565b6105b6838383613ded565b613cb78383613ea5565b613cc46000848484613ce0565b6105b65760405162461bcd60e51b8152600401610485906159f2565b60006001600160a01b0384163b15613de257604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290613d24903390899088908890600401615954565b602060405180830381600087803b158015613d3e57600080fd5b505af1925050508015613d6e575060408051601f3d908101601f19168201909252613d6b9181019061448e565b60015b613dc8573d808015613d9c576040519150601f19603f3d011682016040523d82523d6000602084013e613da1565b606091505b508051613dc05760405162461bcd60e51b8152600401610485906159f2565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611c28565b506001949350505050565b6001600160a01b038316613e4857613e4381600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b613e6b565b816001600160a01b0316836001600160a01b031614613e6b57613e6b8382613fe4565b6001600160a01b038216613e82576105b681614081565b826001600160a01b0316826001600160a01b0316146105b6576105b68282614130565b6001600160a01b038216613efb5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610485565b613f0481611adb565b15613f515760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610485565b613f5d60008383613ca2565b6001600160a01b0382166000908152600360205260408120805460019290613f86908490615b3d565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001613ff18461085e565b613ffb9190615c73565b60008381526007602052604090205490915080821461404e576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60085460009061409390600190615c73565b600083815260096020526040812054600880549394509092849081106140bb576140bb615d79565b9060005260206000200154905080600883815481106140dc576140dc615d79565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061411457614114615d63565b6001900381819060005260206000200160009055905550505050565b600061413b8361085e565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6040518061026001604052806013906020820280368337509192915050565b6040518060c001604052806006905b60608152602001906001900390816141a25790505090565b604051806101800160405280600c906020820280368337509192915050565b6000602082840312156141eb57600080fd5b81356120a181615da5565b60006020828403121561420857600080fd5b81516120a181615da5565b6000806040838503121561422657600080fd5b823561423181615da5565b9150602083013561424181615da5565b809150509250929050565b60008060006060848603121561426157600080fd5b833561426c81615da5565b9250602084013561427c81615da5565b929592945050506040919091013590565b600080600080608085870312156142a357600080fd5b84356142ae81615da5565b93506020858101356142bf81615da5565b935060408601359250606086013567ffffffffffffffff808211156142e357600080fd5b818801915088601f8301126142f757600080fd5b81358181111561430957614309615d8f565b61431b601f8201601f19168501615b0c565b9150808252898482850101111561433157600080fd5b808484018584013760008482840101525080935050505092959194509250565b6000806040838503121561436457600080fd5b823561436f81615da5565b91506020830135801515811461424157600080fd5b6000806040838503121561439757600080fd5b82356143a281615da5565b946020939093013593505050565b600060208083850312156143c357600080fd5b823567ffffffffffffffff808211156143db57600080fd5b818501915085601f8301126143ef57600080fd5b81358181111561440157614401615d8f565b8060051b9150614412848301615b0c565b8181528481019084860184860187018a101561442d57600080fd5b600095508594505b8385101561446457803563ffffffff81168114614450578687fd5b835260019490940193918601918601614435565b5098975050505050505050565b60006020828403121561448357600080fd5b81356120a181615dba565b6000602082840312156144a057600080fd5b81516120a181615dba565b6000602082840312156144bd57600080fd5b5035919050565b600081518084526144dc816020860160208601615c8a565b601f01601f19169290920160200192915050565b60008151614502818560208601615c8a565b9290920192915050565b6000825161451e818460208701615c8a565b9190910192915050565b6000855161453a818460208a01615c8a565b85519083019061454e818360208a01615c8a565b8551910190614561818360208901615c8a565b8451910190614574818360208801615c8a565b019695505050505050565b60008651614591818460208b01615c8a565b8651908301906145a5818360208b01615c8a565b86519101906145b8818360208a01615c8a565b85519101906145cb818360208901615c8a565b84519101906145de818360208801615c8a565b01979650505050505050565b6000875160206145fd8285838d01615c8a565b8851918401916146108184848d01615c8a565b88519201916146228184848c01615c8a565b87519201916146348184848b01615c8a565b86519201916146468184848a01615c8a565b85519201916146588184848901615c8a565b919091019998505050505050505050565b60008851602061467c8285838e01615c8a565b89519184019161468f8184848e01615c8a565b89519201916146a18184848d01615c8a565b88519201916146b38184848c01615c8a565b87519201916146c58184848b01615c8a565b86519201916146d78184848a01615c8a565b85519201916146e98184848901615c8a565b919091019a9950505050505050505050565b60008751602061470e8285838d01615c8a565b8851918401916147218184848d01615c8a565b88519201916147338184848c01615c8a565b87519201916147458184848b01615c8a565b86519201916147578184848a01615c8a565b621e339f60e91b920191825284516147758160038501848901615c8a565b7f3c616e696d6174654d6f74696f6e20706174683d224d302c302043352c2d352060039390910192830152507f31322c2d352031352c2d31325a22206475723d2231307322207265706561744360238201527f6f756e743d22696e646566696e697465222f3e3c2f673e3c2f7376673e200000604382015260610198975050505050505050565b60008851602061480f8285838e01615c8a565b8951918401916148228184848e01615c8a565b89519201916148348184848d01615c8a565b88519201916148468184848c01615c8a565b87519201916148588184848b01615c8a565b6e3c636972636c652066696c6c3d222360881b9201918252855161488281600f8501848a01615c8a565b7f222063783d22353636222063793d223430362220723d22372e33222f3e3c6369600f9390910192830152507f72636c65206f7061636974793d22302e3636222066696c6c3d22234646464646602f8201527f46222063783d22353730222063793d223430342220723d2233222f3e3c636972604f8201526a636c652066696c6c3d222360a81b606f82015261499361491e607a8301866144f0565b7f222063783d22343134222063793d223430372220723d22372e33222f3e3c636981527f72636c65206f7061636974793d22302e3636222066696c6c3d2223464646464660208201527f46222063783d22343138222063793d223430342220723d2233222f3e3c673e006040820152605f0190565b9a9950505050505050505050565b6000865160206149b48285838c01615c8a565b8751918401916149c78184848c01615c8a565b87519201916149d98184848b01615c8a565b86519201916149eb8184848a01615c8a565b85519201916149fd8184848901615c8a565b7f3c616e696d617465206174747269627574654e616d653d226f7061636974792292019182527f2076616c7565733d22303b303b303b303b303b303b303b303b303b303b303b30908201527f3b313b303b303b303b303b303b303b303b3022206475723d223473222072657060408201527f656174436f756e743d22696e646566696e6974652220626567696e3d22307322606082015265179f1e17b39f60d11b6080820152608601979650505050505050565b60008351614ac3818460208801615c8a565b835190830190614ad7818360208801615c8a565b600b60fa1b9101908152600101949350505050565b60008351614afe818460208801615c8a565b835190830190614b12818360208801615c8a565b600160fd1b9101908152600101949350505050565b60008251614b39818460208701615c8a565b7f22207d2c207b202274726169745f74797065223a202242616e64202d206169649201918252506d222c202276616c7565223a20223160901b6020820152602e01919050565b60008351614b91818460208801615c8a565b80830190507f22207d2c207b202274726169745f74797065223a2022466172222c202276616c8152653ab2911d101160d11b60208201528351614bdb816026840160208801615c8a565b6322207d5d60e01b60269290910191820152602a01949350505050565b60008451614c0a818460208901615c8a565b7f3c673e3c70617468206f7061636974793d22302e3131222066696c6c3d2223469083019081527f46464646462220643d224d3636382c35333363302c302c3331332c302c33303360208201527f2d3238732d3339372d34382c31352d3436633330312c322c3139362c34362c3460408201527f36302c3433633235382d332c3438342d36302c3438352d3137732d3239302c3260608201527f342d3239302c3530733238382c392c3437382c3132633138392c332c3334312d60808201527f38332c3533352d3236633139342c35362c3332322c33322c3531372c3563313960a08201527f342d32372c3134302c302c3432372c3073313138302c302c313138302c30762d60c08201527f3331483336303763302c302d3133372d31312d3238332d3130632d3134362c3060e08201527f2d3136322c33332d3339342d37632d3233322d34312d3331322d34332d3432306101008201527f2d3234632d3130372c31382d3235352c36382d3339352c3734732d3339372c316101208201527f382d3339382c37632d312d31302c3434372d32362c3434362d3635632d312d336101408201527f382d3137362d34322d3339312d3235632d3231352c31362d3339352d31342d356101608201527f36382d3139632d3137322d342d3632362d382d3632372c3235733332332c32356101808201527f2c3332322c353063302c392d3539332c332d3539332c33482d333676323768346101a08201527f3738433434322c3533312c3535332c3533332c3636382c353333222f3e3c70616101c08201527f7468206f7061636974793d22302e3131222066696c6c3d2223464646464646226101e08201527f20643d224d3636382c35313463302c302c3332322c31322c3331322d3135632d6102008201527f31302d32382d3830342d35362c382d3632633330312d322c3233392c33372c356102208201527f30332c3334633235382d332c3536352d34322c3536392c3163322c32392d33386102408201527f312c33322d3431372c3631632d32332c31382c3237332c31322c3437302c37636102608201527f3138392d352c3531332d39342c3731342d3532633231322c34342c3138342c346102808201527f362c3337392c3138633139342d32372c3138382c312c3437352c3173313039366102a08201527f2c302c313039362c30762d323063302c302d313130322c302d313137352c30736102c08201527f2d3133372d31332d3238342d3133632d3134362c302d3136312c32352d3339336102e08201527f2d3136732d3331352d33312d3432322d3132632d3130372c31382d3235302c366103008201527f382d3338392c3734732d3433322c32342d3433322c313363302d31332c3435386103208201527f2d32352c3437332d37316331322d33372d3137322d35342d3338372d3338732d6103408201527f3339352d31342d3536382d3139632d3137322d342d3632302c372d3632312c346103608201527f31733331392c33322c3332312c353163302c392d3539382d31322d3539382d316103808201527f32482d333676323768343738433434322c3531332c3535332c3531342c3636386103a08201527f2c3531347a222f3e3c616e696d6174654d6f74696f6e20706174683d224d20306103c08201527f2030204c202d33373530203430205a22206475723d22313530732220726570656103e08201527f6174436f756e743d22696e646566696e69746522202f3e3c2f673e000000000061040082015261512161511b61041b8301876144f0565b856144f0565b9695505050505050565b6000855161513d818460208a01615c8a565b80830190507f22207d2c207b202274726169745f74797065223a2022476c6173736573222c20815269113b30b63ab2911d101160b11b6020820152855161518b81602a840160208a01615c8a565b7f22207d2c207b202274726169745f74797065223a202254756265222c20227661602a929091019182015266363ab2911d101160c91b604a82015284516151d9816051840160208901615c8a565b7f22207d2c207b202274726169745f74797065223a20224f626a656374222c202260519290910191820152683b30b63ab2911d101160b91b6071820152835161522981607a840160208801615c8a565b01607a019695505050505050565b7f7b226e616d65223a20224f6e636861696e2053616e646d616e222c202264657381527f6372697074696f6e223a20224f6e636861696e2053616e646d616e202d20626560208201527f6175746966756c206176617461722c20636f6d706c6574656c792067656e657260408201527f61746564204f6e436861696e222c2261747472696275746573223a00000000006060820152600083516152e181607b850160208801615c8a565b7f2c2022696d616765223a2022646174613a696d6167652f7376672b786d6c3b62607b9184019182015265185cd94d8d0b60d21b609b820152835161532d8160a1840160208801615c8a565b61227d60f01b60a1929091019182015260a301949350505050565b7f3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d22757481527f662d38223f3e3c73766720786d6c6e733d22687474703a2f2f7777772e77332e60208201527f6f72672f323030302f737667222077696474683d22313030307078222068656960408201527f6768743d22313030307078222076696577426f783d223020302031303030203160608201527f303030223e3c6c696e6561724772616469656e742069643d226722206772616460808201527f69656e74556e6974733d227573657253706163654f6e557365222078323d223060a08201527f222079323d2231303030223e3c73746f70206f66667365743d22302e3122207360c08201527174796c653d2273746f702d636f6c6f723a2360701b60e08201526000865161547f8160f2850160208b01615c8a565b61574a61511b6156df6156d961558961552061551a6154e16154db60f28a8d01017f222f3e3c73746f70206f66667365743d22302e3522207374796c653d2273746f815268702d636f6c6f723a2360b81b602082015260290190565b8f6144f0565b7f222f3e3c73746f70206f66667365743d223122207374796c653d2273746f702d815266636f6c6f723a2360c81b602082015260270190565b8c6144f0565b7f222f3e3c2f6c696e6561724772616469656e743e3c7265637420783d2230222081527f793d2230222066696c6c3d2275726c28236729222077696474683d223130303060208201527011103432b4b3b43a1e911898181811179f60791b604082015260510190565b7f3c636972636c65206f7061636974793d22302e3039222066696c6c3d2223464681527f46464646222063783d22373236222063793d223338302220723d22313531222f60208201527f3e3c72616469616c4772616469656e742069643d2273222063783d223434222060408201527f63793d223732332220723d22393922206772616469656e745472616e73666f7260608201527f6d3d226d6174726978283120302030202d31203636322031313138292220677260808201527f616469656e74556e6974733d227573657253706163654f6e557365223e3c737460a08201527f6f7020206f66667365743d22302e3622207374796c653d2273746f702d636f6c60c08201527f6f723a23464646464646222f3e3c73746f7020206f66667365743d223122207360e08201527174796c653d2273746f702d636f6c6f723a2360701b6101008201526101120190565b886144f0565b7f222f3e3c2f72616469616c4772616469656e743e3c636972636c65206f70616381527f6974793d22302e38222066696c6c3d2275726c28237329222063783d22373036602082015272111031bc9e91199c9a9110391e911c9c91179f60691b604082015260530190565b98975050505050505050565b6629b0b73226b0b760c91b815260008251615778816007850160208701615c8a565b9190910160070192915050565b711e3837b63cb3b7b71037b830b1b4ba3c9e9160711b815283516000906157b3816012850160208901615c8a565b6911103837b4b73a399e9160b11b60129184019182015284516157dd81601c840160208901615c8a565b68222066696c6c3d222360b81b601c92909101918201528351615807816025840160208801615c8a565b631110179f60e11b6025929091019182015260290195945050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161585d81601d850160208701615c8a565b91909101601d0192915050565b7f5b7b202274726169745f74797065223a202250616c65747465222c202276616c81526000653ab2911d101160d11b80602084015285516158b2816026860160208a01615c8a565b7f22207d2c207b202274726169745f74797065223a20224265617264222c2022766026918501918201526730b63ab2911d101160c11b6046820152855161590081604e840160208a01615c8a565b8082019150507f22207d2c207b202274726169745f74797065223a2022436170222c202276616c604e82015281606e82015284519150615947826074830160208801615c8a565b0160740195945050505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090615121908301846144c4565b6020815260006120a160208301846144c4565b6020808252601d908201527f4d757374206f776e20612053616e6420746f206d696e7420746f6b656e000000604082015260600190565b6020808252600790820152664275726e65642160c81b604082015260600190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526022908201527f53616c65206d7573742062652061637469766520746f206d696e7420746f6b656040820152616e7360f01b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b604051601f8201601f1916810167ffffffffffffffff81118282101715615b3557615b35615d8f565b604052919050565b60008219821115615b5057615b50615d37565b500190565b600082615b6457615b64615d4d565b500490565b600181815b80851115615ba4578160001904821115615b8a57615b8a615d37565b80851615615b9757918102915b93841c9390800290615b6e565b509250929050565b60006120a18383600082615bc257506001610385565b81615bcf57506000610385565b8160018114615be55760028114615bef57615c0b565b6001915050610385565b60ff841115615c0057615c00615d37565b50506001821b610385565b5060208310610133831016604e8410600b8410161715615c2e575081810a610385565b615c388383615b69565b8060001904821115615c4c57615c4c615d37565b029392505050565b6000816000190483118215151615615c6e57615c6e615d37565b500290565b600082821015615c8557615c85615d37565b500390565b60005b83811015615ca5578181015183820152602001615c8d565b83811115610bde5750506000910152565b600081615cc557615cc5615d37565b506000190190565b600181811c90821680615ce157607f821691505b60208210811415615d0257634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415615d1c57615d1c615d37565b5060010190565b600082615d3257615d32615d4d565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610ce357600080fd5b6001600160e01b031981168114610ce357600080fdfe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa26469706673582212208ac7e8b1afc848fda1c3608a7db5a5d9db7f9b3f2a39d836be7ff172b7d338a264736f6c63430008070033
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.