ERC-721
Overview
Max Total Supply
410 MFS
Holders
81
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
0 MFSLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Source Code Verified (Exact Match)
Contract Name:
MysticForest
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"; import "@openzeppelin/contracts/utils/math/SafeMath.sol"; contract MysticForest is ERC721, ERC721Enumerable, Ownable { using Counters for Counters.Counter; using SafeMath for uint256; Counters.Counter private _tokenIdCounter; uint256 private tokenPrice = 30000000000000000; //0.03 ETH uint256 private constant nftsNumber = 3333; constructor() ERC721("Mystic Forest", "MFS") { _tokenIdCounter.increment(); } function safeMint(address to) public onlyOwner { _safeMint(to, _tokenIdCounter.current()); _tokenIdCounter.increment(); } 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 getSun(uint256 num) internal pure returns (string memory) { uint256 suns; suns = 733410643314582114512314603012454017743510734712492414; if (num > 0) suns = suns / (100 ** (num*3)); return string(abi.encodePacked('cx="',toString(10*((suns/10000)%100)),'" cy="',toString(10*((suns/100)%100)), '" r="',toString(10*(suns%100)),'"')); } 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 toStringSgn(int256 value) internal pure returns (string memory) { if (value == 0) { return "0"; } int256 temp = value >= 0 ? value : -value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } if (value < 0) { digits++; } bytes memory buffer = new bytes(digits); if (value < 0) { //digits -= 1; value = -value; buffer[0] = bytes1(uint8(45)); } while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } function getPoints(uint256 num, uint256 dir) public pure returns (string memory ) { uint256[181]memory xtypes =[ 451793160510049142483918980479775049983908311004982111838287590179673737989, 14118699526057964743410206948092109528394018437505512525414365549665044271, 2990036367364346621795866131653571121699026289141046, 2846959607925562073345508372401376781316743025224824348287758227432596905387, 2992194365839321942769086036007447618697968584327369, 3753734288543931459086705196516412049375550376183621772483166746286184606530, 3597369614550173525007166796257012767273641370844282701925507925543792285476, 3075761135342858797770537856738277071188091692804336596343286722299200667402, 3271440244353497429621230532185176914974600625852871336223639350182882160947, 3567277993316903498903678063180104354953965719249179472654654856748081471205, 14116380865331896385391450086178179633152641401541680509438725334071115455, 2928482646864365553151142455467482501976710809299108047461350705223466036572, 3821675339075292395182255302395855070914232488246053891403721248044174656656, 3115984019240715960323244328181115455415043147489357163259133709542708861632, 3244496427842502701626018574735712370044808469909759174473139369101112483559, 2987353119357672916579205987982357504557173396589332, 2324379648625379036385613574183488699472078952337521869568077904426458695082, 1217389987403007936526409203484901692820865472055694339022933326868434208476, 2417010777913069026691127, 3441913708957137518381877344345889930126595129725057885264505170531043574126, 2917600651716002271669893996375613785659812323984791490780495802912166578946, 3708293718636760152364718089342064469940324999664627799228079694530507806907, 14110665356844149303507105224900996936092881811303175606715491365591308984, 3158444373777377413788230076701033876397915336301543208713906208600121680810, 2817275567468375932596139929010515239344556343459808531647085207214086288099, 6033198342414225328300838243277501079158001050375815138405344997606103814822, 511, 2720100494981947149539386702781528929757544005649907703010181904670973973504, 2408277705204458091040044302132094573526111473190295366598038857750651699947, 14107169532839929700752091609538676282944105693729639298668804927339193532, 1221861636475146439091757024136704920792770829275233582034370279380946780480, 1929745078649056008424622866595262801745570856914548905876583021709899361596, 4191612511679389882886921941088289735083347780575901480897275437039305163532, 4343672155361759899968976175801058502330943465806784759312473237134593393414, 3566948221669800087678086064374772626813770766313968875691818267877922725523, 2844054930834458621500612357249982365132495895267457727130737277089430495386, 2831495325425439623070653177758459898886181703506414534104480167890488760425, 1939784730250891792929893416777521507641579746635591985114370828684217120906, 710500672182797626540852971474592761735170912982147831611021980890913641100, 669528245421993200021192424975553018500427455508620586550532192993530410145, 2786907874801123243278384440540569289884967736012447883743896884908079991958, 783107716654838027593076735110698867723631140942751048784, 1223742098789066363086146454490327367432992460366389926123382679180957712679, 2989461533470413134394949618378485716466310952657952709026655806765503873313, 4078587196827700236148252441598457738652016331251713638460871880042585108753, 4093662014144226772182022731933318239401904060323200219570934945711682620714, 4418350303103987658838040236072521517526306626247445323272330839020818545973, 4643374242505799556552622217641105384457783205137552427483606424730257476378, 4486704919427852534038064683873585202257802529007438651353378708385046889726, 4499817856359707397730280519483643102692499149107402831319735562894054958274, 4485047847576554290163471944750006657681399132671410856687041433809695181498, 3339683520300060376447863508244732503262915016529560249180018002256610357913, 4314878010312732853382723482941746333872906915161246828553891387663095579798, 4074365359127156374762978298570824350410250584226094189806368457852740328077, 2436326669430798195291140631745346883464912839142971982342415690991918792828, 2844633605229433334766034265509774244631325963311003701214089162068265098949, 6021414796764815790125087145808661297551719617535403347668275848711477729927, 35115764503978, 2294397700659397197699685406473997836554794841367326523950238727322888134340, 2025283187394261770417930627778433871681276905838016306264739971388040888997, 2139603985908275075394494527883218115071698703519051893093505600987932723858, 1602149956337663419398244079233223101532761471563090164321742541338988053665, 738518038087913997980297120834578920434720559540340738145828685906757868759, 1021903637670771945756436204332950418418658165449833330825908986328191100032, 680321428688133661527588016944122147941545355974128538876479717265524186287, 2913459048355080754922760102631198697031511036604646793395992893426023029303, 3479130709408447676265801231112877966675791703322346548396001197341351923258, 3253854748105555120936084797666487228976513545459761200829578045966826558534, 1699189092874344557865822570537512574159152442335308490674709866561864328806, 667400986628054122756790148927330777523787572677566916314191737094336736856, 2873236813626440676171292303262262666143114256158109036142099440858322466905, 2463849106514764934759999084079940125420965362783417301190030635058228465285, 205438914033105927166860879746299341319617056510616058071714482, 1038298747581850190237060263176966035035230656825643754185710646059835386620, 3732457000988826922007756981740258362491522747964965354310174111752044251, 3438103229906894537734127924212645170137014733982627380114740921114531725405, 6026623316013678363917195968975149767749651216939496676609297726456481298556, 2241115314331019743849717121383702017708454573017073812756468592096814519488, 2681337874473351023978523739001495494271733781408597532984622975686384632096, 2001763240303821190799393538957491125291823459084909037776275767301748935526, 783413015098298932391713953208811102504075259788668508482, 2776969648718084143666140509500198189279833454686509566456828797242640011984, 2414986924677709585549545, 2464981860802702008248797613075615501215516799470075317970249081860416421077, 2790303763375407904938366532926037490714110175281242670150366813065796212937, 2465617633008893670180232371899505684333818314842213059041399293168815016146, 11401324657414517125554847765234191730741173982, 2007586617321629222923565623524787798034647400175032804774855609950202812116, 1672990505318255906211175434427645236074840599879267478213906817477142731280, 9209241678118184635, 3468278804203466157829532655206811853319359876474512079669760097188562518207, 3368092997782354757286082990925204154758011631855831233655982736879923093696, 3466927620119320294039074189203980316785782842647169496311690405307103440018, 5997944131679293691663553390168068182099797190984646160656605843082062729358, 166052324687270284571457507386895010, 3085920706480894367934793525780658400280345745353555300919491971404221773981, 3381923554997078344785988371461154782062075902541709693502099696739921014948, 3325992182572119952955425236755568253968694395336855696455540407431783377038, 3580226521759520107286065368001833307388687503078515293404116916742493691037, 9214447060903921835, 1264984556772872115799239535623524884253620648193824583495524875928754752372, 1518694096269015099096880765822086114228988044590962307891613193926223639292, 14108292701559715841792991169612211414500920245362129234577009518961809647, 4402309342509142896983013934442726920810334999082253451627659966777804363614, 5166666755085030868803444639761683845012503598362881109034321078214982796000, 5209789353333249880387445761925302865630999691231556305081968356544667639561, 4687711984736242421744479873093886204824147798593512993564205989451328829754, 633401437854182220628048116557, 4160112497456759832337992694410202976874104741130252497257247851041788420278, 3891799183155487259340119950380455072303927206702853094379188893373129184420, 4032319059663099998613520512820426697785970979928996764016646343459105024168, 6009124949811886177795131206969081357356598945839022389523915066407043351690, 4372824752384694282188496870332751107712575766430818661088545374422765321323, 511, 4572783505867648305281967398068273625119110075055536844749714995321564755266, 4911328827335463014379332819972782815283711440757324548670808260875358996733, 4954975634469296598514925777471018546955821345030274703468035996303540008180, 9218679515535855434, 3452321906512025464371802897836094518801199388935465272003231966772078459556, 3748795261402758157788885492974445466658083400195392878155357454986132445816, 3693223752333072151459562658612960597342516520193788012145779387957259162222, 166100478298923491154776583125472921, 4106912717246667397226625890641599430529090592382302926370216293486154887481, 3908087369193035517127117204590882787971039887165197271342261232177579172126, 4019730387115211301930848795814057164513472405301479405129673201161948762874, 4018018908936592607058282959488975987548663007885063821141157517257090944708, 4089300309602240007959434644505762866602904250751726411778648112543795920524, 4315071312289070109850147802022436970240917711138035951472706131873335498401, 4725202305958257607474266791898393255878424154030894468088061083124026994324, 4683680110174487984206714084092740316576662890866513069791112855826925306027, 4457910940450972001776820480444395513452836462258651691797388206013323572411, 5914901893015460913288455038769590541213807873541693763162803986498813334735, 5873017302155366219580613819295633263556778663954408054822111840194936602855, 4785246056814329393415455871264870088767110637544142448838340819902228544776, 53873736278750663526986526463830033766076938107653441239559073616152, 3961230583850472195613434616701520650168113370266317092807283110795912059980, 4159974300347659916450908224181423693787057029892764815291476147123686097536, 4696849232163410979886557344830309530276030548981272388554922402907907053214, 4555252517360058801235317977916661134159115037001481971805637241651654724760, 4555280178158998160895654468742184453035832431543937761396878704524961674893, 4682797599279848964386326277705955728837885892369600134905466615452314795661, 2991124662820466729985366582785995318337604215546002, 4094794229538461950196996980986282399454829575579897639099107199351723801495, 4488498896934177163671566746299360720998703618133128471784444635917868747625, 4870470494855650238260992884771850191437967751124123170685490486885430760267, 4996414205762082127019268313479351099601209822643463938109046716488425055526, 4374315480207661070076200965843976990402875250847505604199786248963436759813, 4993487853199467340812965741758286970078604087317064681517188962153421756119, 4611709501646942332033416691737330215799267808709507583702922506831535976105, 4553457678274957529173455164972517555198985209347470674437518245996323048065, 3983655792221959106678542874491535023802240994398748708194091973432699153987, 511, 2751764049184355665970427661834368826893000635972708917258254524379653095834, 3996762043688216515082017709646178332496394459296666445946293863156097062241, 3854557703404383100840836971486404259590598414489461376417567508339986407800, 3401413784224831724878919757846841118321199606089710978620901144409073395044, 4419424766817352224692370267239741687023769241515970830156920086838702632782, 3669119147830135099252246142986051209252166546386211128736251135120952430949, 4036708964316911879340196539985070616330457410477349779590474447422696063757, 4786904208120125539628028421123318453534542575865124491913205630904344135979, 4927010409629265575240327547968006977797442604613099202290221307456865605964, 4530848496956884285912366022076978316699445255927116468642440159401239554349, 4897830200248151060304598534559494633163927757987279030443661669629025228570, 4982141284371903555041559258627467217052791415694756268205937693649074559228, 5051104011357210160921999575117301746262595505134723231406126068278101469919, 4428758230533668701111108424422998856252086733747575715414198910256133618362, 4555916003654641992253243995961629462190195338819898436721465933797476443822, 4922316665112551244551227182538960607585056393399270553803496721819810573972, 4526017686709248224619740044776819724367225939391434944440434506284260568183, 3904388555610503058690726102571162509580816304148758661208200338363226694753, 4610329741180249610163619688882547569496715425741848059399482580093453349996, 4369816174511426972967861755239262887278514684876866413910128789616023209563, 3677346549089972577976174802446580897876944132670129399346325781540561909838, 3408261474405718409088466451838629603401564969655245534647691783341921921622, 165976556783559723167202694497953337, 2990235126345283631822877804924730718839988305133692, 43513319658703679254636568203538827443336, 43522980609105388572596600985827531712216, 43522146275689570242343825481909074813128, 11408759685182567224012020944406186655893315218, 11408934930604125130349902336635238117986951321 ]; uint256 i; uint256 first_index; uint256 cur_num; uint256 k; int256 dir_y; uint256 pos; string memory res; uint256 result; first_index = num < 3 ? num+1 : (xtypes[0] / (256 ** (num-3)))%256; if (dir==1) dir_y = 140; else dir_y = 900; res = ''; for(i = first_index; i<=181; 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) { if (dir==1) res = string(abi.encodePacked(res, toStringSgn(int256((result*3))-140), ',')); else res = string(abi.encodePacked(res, toStringSgn(1250-int256((result*3))), ',')); } else { res = string(abi.encodePacked(res, toStringSgn(int256((result*3*dir))-dir_y), ' ')); } k++; } if (result == 511) break; } return res; } function tokenURI(uint256 tokenId) pure public override(ERC721) returns (string memory) { uint256[19] memory xtypes; string[5] memory colors; string[15] memory parts; uint256[12] memory params; uint256 pos; uint256 rand = random(string(abi.encodePacked('Forest',toString(tokenId)))); params[0] = 1 + (rand % 36); // pallette= params[1] = 1 + ((rand/100) % 9);// mount params[2] = 1 + ((rand/1000) % 2); // savanna params[3] = 1 + ((rand/10000) % 2); // tree1 params[4] = 1 + ((rand/100000) % 2); // tree2 params[5] = 1 + ((rand/1000000) % 9); // animal params[6] = 1 + ((rand/10000000) % 9); // monster params[7] = 1 + ((rand/100000000) % 2); // grass params[8] = 1 + ((rand/1000000000) % 9); // sun params[9] = 1 + ((rand/10000000000) % 20); // METEOR if (((rand/10000000000) % 20) == 1) // rare palette params[0] = 37 + params[0]%2; xtypes[0] = 1380184997384756203389348097935548270238418335313894369135963045576512; xtypes[1] = 83202958701067158272510542586996495922438516550026878711368311707271070; xtypes[2] = 110890097058345544686991556799584296435994298503832019423597570805434368; xtypes[3] = 124747513234871200025641583470717623407926130169324315491794011723611968; xtypes[4] = 172545869938643596635233103058992932872987519665270880114754418406014784; xtypes[5] = 62901452128639038462844002121514286276591308821405480058892378347355968; xtypes[6] = 6906312258075195189521669129432903118929838785118276903637969883103134; xtypes[7] = 34644103446304817287021645401906549158943647054285149371488762479984448; xtypes[8] = 460428004036880295485476712922934712833987410898445681727580956905712; xtypes[9] = 165644650256154674906236099093466854341981357834224037341526031155019069; xtypes[10] = 568830213016122120965376512587328509977555256782756811911715291660190; xtypes[11] = 408475849166444685717692499863891921759522907256683076899882642964479; xtypes[12] = 138036611714692334195370901026278071274391887700961563656694752681606976; xtypes[13] = 138036611664120373689974417613175875397870210537061667156895429971376248; xtypes[14] = 164484919190898338221032560993011736145912193578603571776097733172223; xtypes[15] = 262270363244384067749521393870671431072564228073668465975395327494012736; xtypes[16] = 372697461957250082012985360966108567877767279094447770984938832788406080; xtypes[17] = 404941104510058468213265706796467786427704521430213011681667002136491; xtypes[18] = 33834578429608361535043529526350847219631511783612495748003004329; if (params[9] <= 7) { for(pos=0;pos<1+params[9]/2;pos++) { parts[14] = string(abi.encodePacked(parts[14], '<circle opacity="0.4" fill="#FFFF9E" cx="',toString(400 + pos*150),'" cy="-',toString((69+pos*200)%275),'" r="4"/>')); } parts[14] = string(abi.encodePacked('<g>',parts[14],'<animateMotion path="M 0 0 l ',(params[9]%2==0?'':'-'),'10000 10000 20 Z" dur="20s" repeatCount="indefinite" /> </g>')); } pos = (params[0]-1) * 5; colors[0] = toHashCode(xtypes[pos/10] / (16777216 ** (pos%10)) % 16777216); pos = (params[0]-1) * 5 + 1; colors[1] = toHashCode(xtypes[pos/10] / (16777216 ** (pos%10)) % 16777216); pos = (params[0]-1) * 5 + 2; colors[4] = toHashCode(xtypes[pos/10] / (16777216 ** (pos%10)) % 16777216); pos = (params[0]-1) * 5 + 3; colors[3] = toHashCode(xtypes[pos/10] / (16777216 ** (pos%10)) % 16777216); pos = (params[0]-1) * 5 + 4; colors[2] = toHashCode(xtypes[pos/10] / (16777216 ** (pos%10)) % 16777216); parts[0] = '<?xml version="1.0" encoding="utf-8"?> <svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="1000px" height="1000px" viewBox="0 0 1000 1000"> <linearGradient id="B" gradientUnits="userSpaceOnUse" x1="500" y1="1000" x2="500" y2="0"> <stop offset="0" style="stop-color:#'; // 1 parts[1] = '"/> <stop offset="0.5" style="stop-color:#'; // 2 parts[2] = '"/> <stop offset="1" style="stop-color:#'; // 1 parts[3] = string(abi.encodePacked('"/> </linearGradient> <rect fill="url(#B)" width="1000" height="1000"/> <radialGradient id="S" ',getSun(params[8]-1),' gradientUnits="userSpaceOnUse"> <stop offset="0.75" style="stop-color:#FFFF9E"/> <stop offset="1" style="stop-color:#')); // 2 parts[4] = string(abi.encodePacked('"/> </radialGradient> <circle opacity="0.9" fill="url(#S)" ',getSun(params[8]-1),'/> ',parts[14], '<polygon opacity="0.14" fill="#')); // 3 parts[5] = string(abi.encodePacked('" points="',getPoints(0+params[1]-1,1),'"/> <polygon opacity="0.6" fill="#')); // 3 parts[6] = string(abi.encodePacked('" points="',getPoints(9+params[2]-1,1),'"/> <polygon fill="#')); // 3 parts[7] = string(abi.encodePacked('" points="',getPoints(11+params[3]-1,1),'"> <animateMotion path="M 0 0 l 15 20 l 12 15 Z" dur="19s" repeatCount="indefinite" /> </polygon> <polygon fill="#')); // 3 parts[8] = string(abi.encodePacked('" points="',getPoints(11+params[4]-1,2),'"> <animateMotion path="M 0 0 l 15 19 l 13 14 Z" dur="17s" repeatCount="indefinite" /> </polygon> <polygon fill="#')); // 3 parts[9] = string(abi.encodePacked('" points="',getPoints(25+params[7]-1,1),'"> <animateMotion path="M 0 0 l 10 0Z" dur="16s" repeatCount="indefinite" /> </polygon> <rect opacity="0" fill="#')); // 3 parts[10] = string(abi.encodePacked('" width="1000" height="1100">',(params[6]<=3 ? '<animate attributeName="opacity" values="0;.3;.3;.4;.3;.3;0" dur="10s" repeatCount="1" begin="monster.end-10" restart="whenNotActive" />' : ''),'</rect><g opacity="0"> <polygon fill="#')); // 3 parts[11] = string(abi.encodePacked('" points="',getPoints((params[6]<=3 ? 22 : 13)+params[(params[6]<=3 ? 6 : 5)]-1 ,1),'"/> ')); // 3 if (params[6]<=3) parts[12] = string(abi.encodePacked('<polygon fill="#',colors[0],'" points="',getPoints(26+params[6]*2-1,1),'"> <animate attributeName="opacity" values="1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1" dur="3s" repeatCount="indefinite" begin="0s" /> </polygon> <polygon fill="#',colors[0],'" points="',getPoints(26+params[6]*2,1),'"> <animate attributeName="opacity" values="1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1" dur="3s" repeatCount="indefinite" begin="0s" /> </polygon>')); // 3 else parts[12] = '<rect opacity="0" x="250" y="250" width="500" height="500"/>'; parts[13] = '<animate attributeName="opacity" id="monster" values="0;1;1;1;1;0" dur="10s" repeatCount="1" begin="click" restart="whenNotActive" /><animate attributeName="opacity" values="0;1;0;0;0;0;0;0" dur="60s" repeatCount="indefinite" begin="30s" end="monster.start"/> <animateMotion path="M 0 0 l 0 -15Z" dur="30s" repeatCount="indefinite" /> </g></svg>'; string memory output = string(abi.encodePacked(parts[0],colors[4],parts[1],colors[3],parts[2])); output = string(abi.encodePacked(output,colors[4],parts[3],colors[3],parts[4])); output = string(abi.encodePacked(output,colors[2],parts[5],colors[2],parts[6])); output = string(abi.encodePacked(output,colors[2],parts[7],colors[2],parts[8])); output = string(abi.encodePacked(output,colors[2],parts[9],colors[2],parts[10])); output = string(abi.encodePacked(output,colors[2],parts[11],parts[12],parts[13])); parts[0] = '[{ "trait_type": "Far", "value": "'; parts[1] = toString(params[1]); parts[2] = '" }, { "trait_type": "Palette", "value": "'; parts[3] = toString(params[0]); parts[4] = '" }, { "trait_type": "Savanna", "value": "'; parts[5] = toString(params[7]*1000 + params[2] * 100 + params[3] * 10 + params[4]); if (params[6]<=3) { parts[6] = '" }, { "trait_type": "Monster", "value": "'; parts[7] = toString(params[6]); } else { parts[6] = '" }, { "trait_type": "Animal", "value": "'; parts[7] = toString(params[5]); } parts[8] = '" }, { "trait_type": "Sun", "value": "'; parts[9] = toString(params[8]); if (params[9]<=7) { parts[9] = string(abi.encodePacked(parts[9],'" }, { "trait_type": "Meteor", "value": "', toString(params[9]))); } parts[10] = '" }]'; string memory strparams = string(abi.encodePacked(parts[0], parts[1], parts[2], parts[3], parts[4], parts[5])); strparams = string(abi.encodePacked(strparams, parts[6], parts[7], parts[8], parts[9], parts[10])); string memory json = Base64.encode(bytes(string(abi.encodePacked('{"name": "Mystic Forest", "description": "Mystic Forest - interactive game, 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 claim() public { require(_tokenIdCounter.current() <= 300, "No more free tokens"); _safeMint(msg.sender, _tokenIdCounter.current()); _tokenIdCounter.increment(); } function withdraw() public onlyOwner { uint balance = address(this).balance; payable(msg.sender).transfer(balance); } function buyTokens(uint tokensNumber) public payable { require(tokensNumber > 0, "Wrong amount"); require(tokensNumber <= 30, "Not more 30"); require(_tokenIdCounter.current().add(tokensNumber) <= nftsNumber, "Sale finished"); require(tokenPrice.mul(tokensNumber) <= msg.value, "Need more ETH"); for(uint i = 0; i < tokensNumber; i++) { _safeMint(msg.sender, _tokenIdCounter.current()); _tokenIdCounter.increment(); } } } /// [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; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler * now has built in overflow checking. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { return a + b; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a % b; } } }
// 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":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokensNumber","type":"uint256"}],"name":"buyTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"num","type":"uint256"},{"internalType":"uint256","name":"dir","type":"uint256"}],"name":"getPoints","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"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":"to","type":"address"}],"name":"safeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"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"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6080604052666a94d74f430000600c553480156200001c57600080fd5b50604080518082018252600d81526c135e5cdd1a58c8119bdc995cdd609a1b6020808301918252835180850190945260038452624d465360e81b9084015281519192916200006d916000916200011c565b508051620000839060019060208401906200011c565b505050620000a06200009a620000bd60201b60201c565b620000c1565b620000b7600b6200011360201b6200380a1760201c565b620001ff565b3390565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80546001019055565b8280546200012a90620001c2565b90600052602060002090601f0160209004810192826200014e576000855562000199565b82601f106200016957805160ff191683800117855562000199565b8280016001018555821562000199579182015b82811115620001995782518255916020019190600101906200017c565b50620001a7929150620001ab565b5090565b5b80821115620001a75760008155600101620001ac565b600181811c90821680620001d757607f821691505b60208210811415620001f957634e487b7160e01b600052602260045260246000fd5b50919050565b615ff7806200020f6000396000f3fe60806040526004361061014b5760003560e01c80634e71d92d116100b657806395d89b411161006f57806395d89b4114610387578063a22cb4651461039c578063b88d4fde146103bc578063c87b56dd146103dc578063e985e9c5146103fc578063f2fde38b1461041c57600080fd5b80634e71d92d146102e85780634f6ccce7146102fd5780636352211e1461031d57806370a082311461033d578063715018a61461035d5780638da5cb5b1461037257600080fd5b80632f745c59116101085780632f745c59146102405780633610724e146102605780633ccfd60b1461027357806340d097c31461028857806342842e0e146102a85780634d4c71a3146102c857600080fd5b806301ffc9a71461015057806306fdde0314610185578063081812fc146101a7578063095ea7b3146101df57806318160ddd1461020157806323b872dd14610220575b600080fd5b34801561015c57600080fd5b5061017061016b36600461492f565b61043c565b60405190151581526020015b60405180910390f35b34801561019157600080fd5b5061019a61044d565b60405161017c91906156e7565b3480156101b357600080fd5b506101c76101c2366004614969565b6104df565b6040516001600160a01b03909116815260200161017c565b3480156101eb57600080fd5b506101ff6101fa366004614905565b61056c565b005b34801561020d57600080fd5b506008545b60405190815260200161017c565b34801561022c57600080fd5b506101ff61023b3660046147b1565b61067d565b34801561024c57600080fd5b5061021261025b366004614905565b6106ae565b6101ff61026e366004614969565b610744565b34801561027f57600080fd5b506101ff6108a4565b34801561029457600080fd5b506101ff6102a3366004614763565b610902565b3480156102b457600080fd5b506101ff6102c33660046147b1565b61094f565b3480156102d457600080fd5b5061019a6102e3366004614982565b61096a565b3480156102f457600080fd5b506101ff61249a565b34801561030957600080fd5b50610212610318366004614969565b612507565b34801561032957600080fd5b506101c7610338366004614969565b61259a565b34801561034957600080fd5b50610212610358366004614763565b612611565b34801561036957600080fd5b506101ff612698565b34801561037e57600080fd5b506101c76126d1565b34801561039357600080fd5b5061019a6126e0565b3480156103a857600080fd5b506101ff6103b73660046148c9565b6126ef565b3480156103c857600080fd5b506101ff6103d73660046147ed565b6127b0565b3480156103e857600080fd5b5061019a6103f7366004614969565b6127e8565b34801561040857600080fd5b5061017061041736600461477e565b61373f565b34801561042857600080fd5b506101ff610437366004614763565b61376d565b600061044782613813565b92915050565b60606000805461045c906159cf565b80601f0160208091040260200160405190810160405280929190818152602001828054610488906159cf565b80156104d55780601f106104aa576101008083540402835291602001916104d5565b820191906000526020600020905b8154815290600101906020018083116104b857829003601f168201915b5050505050905090565b60006104ea82613838565b6105505760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006105778261259a565b9050806001600160a01b0316836001600160a01b031614156105e55760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610547565b336001600160a01b03821614806106015750610601813361373f565b61066e5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776044820152771b995c881b9bdc88185c1c1c9bdd995908199bdc88185b1b60421b6064820152608401610547565b6106788383613855565b505050565b61068733826138c3565b6106a35760405162461bcd60e51b815260040161054790615781565b61067883838361398d565b60006106b983612611565b821061071b5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610547565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b600081116107835760405162461bcd60e51b815260206004820152600c60248201526b15dc9bdb99c8185b5bdd5b9d60a21b6044820152606401610547565b601e8111156107c25760405162461bcd60e51b815260206004820152600b60248201526a04e6f74206d6f72652033360ac1b6044820152606401610547565b610d056107d8826107d2600b5490565b90613b38565b11156108165760405162461bcd60e51b815260206004820152600d60248201526c14d85b1948199a5b9a5cda1959609a1b6044820152606401610547565b600c5434906108259083613b4b565b11156108635760405162461bcd60e51b815260206004820152600d60248201526c09ccacac840dadee4ca408aa89609b1b6044820152606401610547565b60005b818110156108a0576108803361087b600b5490565b613b57565b61088e600b80546001019055565b8061089881615a0a565b915050610866565b5050565b336108ad6126d1565b6001600160a01b0316146108d35760405162461bcd60e51b81526004016105479061574c565b6040514790339082156108fc029083906000818181858888f193505050501580156108a0573d6000803e3d6000fd5b3361090b6126d1565b6001600160a01b0316146109315760405162461bcd60e51b81526004016105479061574c565b61093e8161087b600b5490565b61094c600b80546001019055565b50565b610678838383604051806020016040528060008152506127b0565b60606000604051806116a001604052807effb4b3b2b1b0af988e877a76726c67645f5a575351493a2a1e1b1713100b0581526020017e07fdababd4eaf52005000198467a9a61c9f6f305ded179bae0af884c05c72f81526020017507fdddabd5eaf560079801a8c267355bd006cca5a53681526020017f064b5270e27fb9df2f7713f9b7168e44dd32470cc187365d5221d487ed811dab81526020017507ff57abd580000000021544727b9edca88772b580c981526020017f084c89cf1c734adef2e7bd31f94c7e525ff497fcfe273c7fcf1ff2f8b4d22b4281526020017f07f409ff017fbda24f482bc63aec7fbadfed79234646f18d4022f248748a172481526020017f06ccd1b1366c561cd4e72d29cf4a73cfde53d73ce9cf057bc15ef1f7fc85ff0a81526020017f073b91cec276b01cebf73ad5e4b373ac9cea96c279b0ad6d2b9b4b36c2e1b13381526020017f07e301febd7fac9fab07daa9eeaa7bb21ceca73b69eed87bbc5cef173ba1dee581526020017e07fd55aad4eab52005c001be878828240c08cb0a2cc484b1a14c47fb19febf81526020017f06797662759522272b3c338354e0d50000000000ad284f61a9194d465c052d5c81526020017f0872fdd8bc7d2e5d8b87225dc09d62a8934505f965be9e72a71c6937fa45c49081526020017f06e3959ee567b61dad676b419cd364ad5b2b3642c58ca470a81d4d376b49dac081526020017f072c51e50f74435d9047340d874e4dd6d9d0376415d8d675359cd0267bfd9ee781526020017507fc07aad56ab54ef9a42a21366652dc51a81c61cb1481526020017f05238d60e4633c9aee763bd962eb55bc973059b44e671e62551cd5e5ed8045aa81526020017f02b104b04a651a1fa949125e7ea6a12b5d6b175af5c8b26cacdb4b8602d146dc81526020016a01ffd26ab480000000483781526020017f079c0ddafe763d656f0773be02dfcab6b212c80cd9db296fccdd13c94519016e81526020017f06734daed3713699cdb68491af246fca9d32774c8df32075481dd18c443b0b0281526020017f0832d1e2b27daa714a5c3265f49b7ca65c29570a319c8f66ab5aab5692e598bb81526020017e07fc81aad56ab54000000000456822e107b8f227328ecab4df2c976305dab881526020017f06fb9dbcfa6abe9a30068c25af0c6dc4235248fc864b2967cc55d4b5052c23aa81526020017f063a857ea15eae1d0ba5f2f182ca633258ec466b119cc26eb05b8dc73385f2e381526020017f0d56ab540000000001b731cdf06c8b9e1c4816f229a68a6b275baa466aa192a681526020016101ff81526020017f060385b6dd603717ed45b33950cc52be163065946d55290cdcc37aad56ab540081526020017f05530970c45f33592cb69b0622bf8dbba650984471a9196241584f075bb582eb81526020017e07fc0000000002c25541517673791e99c7c6c2296090562653e9b502dd64bc81526020017f02b38c96f9183d460ff23c085b3a18b905af5003c000fa153f8451b0f504014081526020017f0444326f265bd29a74b984c6553b7c53ddf4c35d18bd412ad0c95423bcb46d3c81526020017f09445e5d18a043a6f196cc31a10964c29110041bf8feff273e497023d429030c81526020017f099a6e6ac09baaa84d0a1bc63ccba1bf686fd99bde38f69b40a1f0b97436830681526020017f07e2d236d47ba7a0aac93afe18a879a39f6828fa1e229e94a2e38b59627e5e9381526020017f0649ad946c669ade27f6a99daa67761ddf08076211ee8375a59e8c87a2b1e09a81526020017f064291cec461239a09c752a17e7e631c98a705f1e97861631c9ca9461181986981526020017f0449e1168649a952083451d5166c5a98d6a695d9fd767f5b21980b860271788a81526020017f0192210ea21ea00867c451b504783f22cfe99429e912724222d12a448acd128c81526020017f017af086dc1aaec4e8c1bab49ebf19268ded523a88beab2127072942826cf4a181526020017f0629557e4e5d9396a594b98122604518c0081002304e830f2ac4ecc122a04c968152602001771ff006ab55aad5000000000185404b4898126605112da45081526020017f02b49d0d3263cdda9356dd1da54954529194457d04f340204d0cd3110cb8012781526020017f069bf9ab126949c6f17004440116694a5a32d6a4d18f3641cc0b92600470012181526020017f090466072a774a9ad276b4a9e52c804b1fd2d6dcc9af2b6bc81bf206bc79b11181526020017f090cee3b378ccda353c8fcf9d745714f5eb396fce1bb347fcba072b97ca60d2a81526020017f09c4b299339f4c24f3197cd6913597cf25737954f6553892cd64d3d91cda3d3581526020017f0a440e8300a141a9909a1c2e8d0fa543e8f1aa14567910a3482952c9fc8e4b1a81526020017f09eb628ed5a932ea4d1a138e9adda935aa4e0a73f68cfba6c0a8cfda0bf284fe81526020017f09f2ce80b2a4ab284b4a52cea0a9a7ad6a4b2a92e290b894b1274c6a5b16a4c281526020017f09ea72769fa328a74a69caae86aa9dac25ca39729274b19cad67ab3a22ee8aba81526020017f076231a28c68239c88f7923e4a9b952864ea99c2727299a1a36929a9d25a729981526020017f098a22688d9d2226a8d9ca3a649096236548f982525e979925e589b95a7e449681526020017f090202528091a12508790a1a3c8b83219ae826aa16388e8d24a4c8f952425a8d81526020017f0562e97aac61a8db6a16327db47d771e232787c9d62c6d921d6267b8e9fe407c81526020017f064a016ca6522e564e357bd54f0a59be56ee459b5586d35934960c85c3195ec581526020017f0d500000000033068ac21aac72a920294f0a223a80b0963f22d868e622311a878152602001651ff006ab55aa81526020017f05129544a253aa542a550aa156b656aed46b0512a944a950aa142b451ae55ec481526020017f047a45088e40241068243219108d4421d208f4a29128a64baa5229050a8142a581526020017f04baf912a54a2b130b74c30148ea4e3016af45132152d34d2bd42b3402450a9281526020017f038ac8e4b945380ecb548b60f4af39ab0f89b3f2a522bf41298fc963fa5104a181526020017f01a1fc847e212089482241f8c2832b9f4f47a41204fc91362d8d4d739b90dcd781526020017f02426080952425092992626c969426a509a942b284b4a42a250fc9225208648081526020017f01810c5c4700118005512954247508a343cb81db94469837ba44c8e24aa0dcaf81526020017f0670f59a38270d0923f2e120a648248fcb220218c45c2b170c80032000d85a3781526020017f07b11e42438a9035444d50f5de388888598386791d48484f11d2a4946924ce3a81526020017f07319dd4737f9ca2c89829cb5466d51664a637e195e4578a16e1856d515f544681526020017f03c1b4fa583e960fe6d439b50658489b12c6b45961aa5878215c25872161e66681526020017f0179bc4e721d1608e682419c805625958e06d2e95cd45730970c8603795cee5881526020017f065a31c49d66a09d88a659d5cc736f19d526a281c0c2632d17c6e6d1f170785981526020017f05727d3a9a3d9e90679432151087439e530784e20144874d9dd72776aab98e858152602001797fd84ea5d35990e657ae9ace95cb0984c9592c952ab50a798ab281526020017f024ba8010200424a2ef2cba8d8e92fb98cce137354f0cf39338eec843b08eafc81526020017e021ccc864f9f5328f2a230668a0024800981da40ec964b26118b037ae8bedb81526020017f0799e5c0787f1a3543fd5005984346934d43d4e0e4c83716000320038148005d81526020017f0d52f2aab7622996ca964251be8e87202d48bd524f548b9d9f6187b67a31b87c81526020017f04f46d23154a3b13ad75535140d150b3d76c951b295cb263ab2cabcb8aff54c081526020017f05ed955d5c55525cd507f54e9b68c76ab21aaa6591ed4e54d19432458c89412081526020017f046cf5353b46ce521204c481515e516a951aa575857d69725a691aaa7ea9cb668152602001771ff336a901aa45d3d515e53d65174a46515474851515194281526020017f0623b5890352448c30c294b811a004e34bb014ec297cfe5c3a176dc6234192d081526020016a01ff64b4196d464b7988e981526020017f0573215acb523413a8852a3152965aa6156925321d388044000e6004aa253cd581526020017f062b4186d0613457aca61b1988c762b2188c962b218ac760b0d72c358b1958c981526020017f05737d78e5603918ae062b7d88dd623798ae05f37182d76136188d86235988d281526020017301ff40c9d11384249530f352bf536ef5235d5ede81526020017f047040f64a421ecdeaf302c0aaba2ab10aece2fb50bacc2f300d2c136af8d6d481526020017f03b2e10ab9432dd0ab443ab90aaa39ab9147b4216518654d1b51a62419295a108152602001677fcdcc837af4e6bb81526020017f07aaf9eaba7f2e1feb37face02b383abe12ab8a2aa32a58e26a809fa5abec0bf81526020017f077245e8a276289ceaa722a5c0ad71ac9cab1732c5ccb5742e1dabb76af9e0c081526020017f07aa3624867d21df4878a9f1f68072231c69075259d09180255fa977da6dec9281526020017f0d42b750a5a4a66a695b221e9e8ea2256b27ca223e8297a02621c9085a3a108e81526020016e1ffb02fea2aba428e9ca6b72b6aaa281526020017f06d291b8a66ea95bca67028dc29f72a79d6a17a299eaa979ab9c2c07b2c5f89d81526020017f077a19d48374a05d87e7b9f9f6807b9f5d87d741fdcc8373221b6996b279b0a481526020017f075a71e29b7b269ee9e7ba81f2997aa59d8977623de6937ba49f6917ea29e88e81526020017f07ea561e5a8892e4864909ca4e77919c64c638910a3c008400610597b291dc9d8152602001677fe04ac81ad208ab81526020017f02cbf4b4fc2d3ecbafd32bf4ccfd35bf0dd162a584936e23d447b3a21d508b7481526020017f035b8ce6d435380c8c034bb8c6ef2f3c0b8f22cbccaef52b3e0b2fa2cbe8b2fc81526020017e07fc29a91fea4b96a38c5cdcfb3a3e102f7413d8fcf540bd100f1393c4d8ef81526020017f09bb9e68e7963b64eec953ce56f996406610f97cce5d3b99d267150a0562975e81526020017f0b6c3ad110acc3ad104b5c0ee4fdb9bced0ffab41a94fea2bd680f0a1b9282e081526020017f0b84a2e321b6c92d729aecc69d29a7c929f16a9c5ed115b6c52e30fb8c1adf0981526020017f0a5d26a543ac512bb47b54eee335b8cbadb31b5cd6bd3ca84dea536ac4deb93a81526020016c07fea163acd8ea959a65467b4d81526020017f09328a4ca19528a56a4962824e9b94a5e5697962625898952a65cb49630660b681526020017f089aae26ac8baae32aa8d2aa38aa8faa644a892a9650a694aa254a995a9654a481526020017f08ea3632938ca66369d8ca7a329f8c27e2e9f89a7e249f89a8e26a489a9a28a881526020017f0d490b503dac996867b9b1ea627d9b1f2847e9b2226a879821e5a8993a22448a81526020017f09aaee5cac9aaba5aa998246668e9aa42808e9c22ab66dad1fea88cae202bc6b81526020016101ff81526020017f0a1c1a8f0ea8c4e9f1ea7486a12daac86ab1daac46b10bacc72ed3eb5502f54281526020017f0adbb6aef1aabb29ce7a6b969ae1a638296dfa2b8e88e5a23a292f2a4bd688fd81526020017f0af46ab4ffb13dab6faaf376bed7ac3fab107ab426ad06a9c0ea502aa3eab4f48152602001677fef542d3daf4f4a81526020017f07a1f1e87f749fdce8375205e8837a219d88a7a225ea8c7823dec8d8229a3aa481526020017f0849be3069a219a4466a615f5c6ad697a985280991ec75789cdea777a1e9da7881526020017f082a4a6294872423c8c99247589ad5a4e5e88d621f586a991de3877879ca526e81526020016e1ffd62c758a787a761c9caca6a169981526020017f09146e231c89c6a451989c662b16914662b148b44a2ef9953ca470a8ecc6313981526020017f08a3e6291285499f13284ca61b338649e1b2490c961d238847e43238847a211e81526020017f08e31636c28ab0234c38bb3632c99132632c88d31a3cd1913424cec8abda12fa81526020017f08e21e3c818d2120c8b8d21e40938f2a62aaa902b650bf92b163ecb8eb1a4ec481526020017f090a76429a95a7a429890a5e5c9591256449290a42609090a3e3e8d98a363e8c81526020017f098a3e6a85a020e6a82989de68859527250b39029e40a59628a40a390a7e56a181526020017f0a725ea690a5a5664bf97af65ab996a7a829096a6a60939a25a609198a466e9481526020017f0a5ade76b9a12b6a2ada12b288a9b42a68aa7a3296a4a5a3a8e989acfad340ab81526020017f09db1692cb9db0e84c1aab068ebfaaaef40cdcfb1aacb8adacaa8b89bb0674bb81526020017f0d13b740d2a6b4284d89d36688d59db568cd39e34690d19db3692d09d32294cf81526020017f0cfc028f00a2beea6f8a23e686f7adbca84f5a03baa0ed9fbb296ea9eba680e781526020017f0a945a71109c43ac30d9c4327104a141271039b3aa8b03a2c0e8709a4c0f3d0881526020017c01ff8fcc64d0e9744a4d09983b26d129ac7a7313d24b74b25adc62d11881526020017f08c1fa2075871de1e72871a6126b86982205a8a1222a548f1227843971269c4c81526020017f093276469d922824e9f8f2923caa8da963e978da3e348c8823a229486a2e428081526020017f0a62528c9ba0a7e7c9e9e2867ca29da8a70a09ba86649c98a7a669f9827e569e81526020017f0a122e7a8da2a327e8ea1a3a8290a4a3a8491a52428893a6a428a95a5a4a8c9881526020017f0a12327c8ca022e768a9ea2a6a899d22272889a226688a9e22a6e8b9fa2e768d81526020017f0a5a5e9893a4a5a9891a4a52988fa2a46968ea0a3e908da02368a8ca22327e8d81526020017507fe9c4cb110b2042c82568a849f21e8889a8236a09281526020017f090d92476b875d2597397dc65b76965ca4973946024d848b5da3d86815b23b9781526020017f09ec667d289b4aa7d29a254a71378fc66774b8dce279587cd4273609b5924b6981526020017f0ac496af29a046a9724a049e8129a749eab2ea8cce9f2aa74da933ca74ea934b81526020017f0b0bdec708b0c3ea8f7afc52bd15ab42e86feae45e8d12adc7ab520a748ea52681526020017f09abc65ad7a33d25ad29c3529ad19833eceb5a1b8ad4bbae39edcc1b4be6cb0581526020017f0b0a36c695af27eca9bb4abeb8a89bacaceb3973365acf94b464ed295b4656d781526020017f0a3222947ca7176b274a49f29080a99eea67ba2252ae85ae9f6ba7dac22aaea981526020017f0a112a6c45828e6724c9192a06539714e2a649e956428ea19768a80a120e8a8181526020017f08ceab55aad50025000990ea703d9e0c284419c0f220289a10668449b1166e4381526020016101ff81526020017f061571795d605859562615998b686759d8f6c695b5b5677cdc2097b72dce419a81526020017f08d6164f8d85d920f6587dda0f737f59db7557b5b9b96666d519f5d62d65956181526020017f08859a336a9ddb227708a5ce3773975c23b779a602518f93e32217e84dda217881526020017f078521c94b77d4deb5378565fb5a7cd7a09608159621668d57a7d6a95d96256481526020017f09c54e47469a55a7b638e55a3b468ad221f4386d2a03448153603487ad11ef4e81526020017f081ca5d91b7c4a5d7297e4b9bd3781cca11349ed4675539f54e7f58a6d7e916581526020017f08ecb24130964ce4f3491cda4d399ace25f3994cfa693f9bcfa774a84cbe030d81526020017f0a954ab150aad52793b9f4eaa544ab50e7f39994966930994b6512896cca492b81526020017f0ae496cd28b2cc2c72dadca2c739afcd6832ba54dec143a35129d49ab526994c81526020017f0a045e8f20a0c82731c9947a6f22a2c8a7d27a1ca69b24a9c929b28a44b6a92d81526020017f0ad412db09af41e8f0aa7c36d90ca24529f15b6436cf26af4929b17a8c82971a81526020017f0b03cac2f4b33caeae2b6c0eaae5aebd6b6f7af3dac0f9b2bfebcfaa1bce98fc81526020017f0b2ad2d4aab8b1aaabab432ae2ceb433294d4abb66d2daba35ab4e9b13a6eadf81526020017f09ca969caf9fada94b3a2aee98b5a5b06a2b1b0a9aacb4af2c2d2a4b4a9ebaba81526020017f0a128e9ca0b1a36c68db2a5ac695ada4eb295b126abc9aa4296a6a7b0a92a6ae81526020017f0ae1eeb87fa89f264829fa1ea489b0a1eae8aa02629497b022eb293aa24aae9481526020017f0a01a29e6aa79b6a66aad9a6b86eac9c68869a89d27677a31e6a876a81e6ac7781526020017f08a1ce3c73919ba4675951c25474991be68699a1a66a739f1b68062ab962a46181526020017f0a315aaa53ab15a7e609b966585998182585d909825066921923666911b2346c81526020017f09a93a72519715e7057a61228e4fa593e9e49aa93a844e9e14e80569e16a865b81526020017f08214dec618514a0e75861425c3e9a8f680419b106304c9313e724da511a784e81526020017f078901f43d7b90a04408011a20418a0ea46358a10a4a408413de24982145ea5681526020016e1ff746ab55aad5001e800728d5e63981526020017507fe007c7f1f2007f809f20a7c809edfc797f1ee007c8152602001707fdfc887f22e02877fa15fe8680a1dfc888152602001707fe70d2993725cdc98b6a64d999b6266d88152602001707fe66c79c33a6acb9b32e68ca9932660c881526020017301ff96236649199a56609598252629397a465e9281526020017301ff98266649997a765e9b9826a609a98a66609981525090506000806000806000806060600060038c106122d3576101006122ac60038e615975565b6122b89061010061586f565b8a516122c49190615818565b6122ce9190615a39565b6122de565b6122de8c60016157d2565b96508a600114156122f257608c93506122f8565b61038493505b6040518060200160405280600081525091508697505b60b5881161248b57888860b5811061232857612328615aac565b60200201516123365761248b565b888860b5811061234857612348615aac565b6020020151955060009450600092505b601b831161246a5761020061236d848261586f565b6123779088615818565b6123819190615a39565b9050806101ff14156123925761246a565b61239d600286615a39565b61240c578a600114156123f157816123ca608c6123bb846003615917565b6123c59190615936565b613b71565b6040516020016123db929190614af2565b604051602081830303815290604052915061244a565b816123ca612400836003615917565b6123c5906104e2615936565b81612427858d61241d856003615917565b6123bb9190615917565b604051602001612438929190614b2d565b60405160208183030381529060405291505b8461245481615a0a565b955050828061246290615a0a565b935050612358565b806101ff14156124795761248b565b8761248381615a0a565b98505061230e565b509a9950505050505050505050565b61012c6124a6600b5490565b11156124ea5760405162461bcd60e51b81526020600482015260136024820152724e6f206d6f7265206672656520746f6b656e7360681b6044820152606401610547565b6124f73361087b600b5490565b612505600b80546001019055565b565b600061251260085490565b82106125755760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610547565b6008828154811061258857612588615aac565b90600052602060002001549050919050565b6000818152600260205260408120546001600160a01b0316806104475760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610547565b60006001600160a01b03821661267c5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610547565b506001600160a01b031660009081526003602052604090205490565b336126a16126d1565b6001600160a01b0316146126c75760405162461bcd60e51b81526004016105479061574c565b6125056000613ce4565b600a546001600160a01b031690565b60606001805461045c906159cf565b6001600160a01b0382163314156127445760405162461bcd60e51b815260206004820152601960248201527822a9219b99189d1030b8383937bb32903a379031b0b63632b960391b6044820152606401610547565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6127ba33836138c3565b6127d65760405162461bcd60e51b815260040161054790615781565b6127e284848484613d36565b50505050565b60606127f26146c7565b6127fa6146e6565b61280261470d565b61280a614728565b60008061283d61281989613d69565b6040516020016128299190615378565b604051602081830303815290604052613e67565b905061284a602482615a39565b6128559060016157d2565b83526009612864606483615818565b61286e9190615a39565b6128799060016157d2565b6020840152600261288c6103e883615818565b6128969190615a39565b6128a19060016157d2565b604084015260026128b461271083615818565b6128be9190615a39565b6128c99060016157d2565b606084015260026128dd620186a083615818565b6128e79190615a39565b6128f29060016157d2565b60808401526009612906620f424083615818565b6129109190615a39565b61291b9060016157d2565b60a0840152600961292f6298968083615818565b6129399190615a39565b6129449060016157d2565b60c084015260026129596305f5e10083615818565b6129639190615a39565b61296e9060016157d2565b60e08401526009612983633b9aca0083615818565b61298d9190615a39565b6129989060016157d2565b61010084015260146129af6402540be40083615818565b6129b99190615a39565b6129c49060016157d2565b61012084015260146129db6402540be40083615818565b6129e59190615a39565b60011415612a095782516129fb90600290615a39565b612a069060256157d2565b83525b7c3331a3e080008277ffff9efff53f18283d1c8c94335582ffff9eff3f4086527d0c0e2b54bbffc200ccffffeaff88001e2900e0d78074a11affff9effff9e60208701527d1011246dcfc248667dffffeaff88000c0e2bff5454c200ccffffeaff880060408701527d1213247689942f354affff9eff3f401011246dcfc248667dffff9eff3f4060608701527d190014ff4c00870041ffff9eff3f400a0d00ffaa00004a01ffff9eff3f4060808701527d091d24ffff9e009e71ffff9effd080111c2b00c483004a61ffff9eff3f4060a08701527d01002b5b1d91731045ff3030ff30300c190a71bd46008037ffff9effff9e60c08701527d0505056e676a696969f0e8e4f0e8e41b002487003df02222ff5500ff3f4060e08701527c1114067a59005c4999f0e7ff993d00111427596b00809999d0f099d0f06101008701527d180019ff8c006900a6fff08cff8c0018001930579168248fffa6efff3d3d610120808801919091527c15195da69c5f969efff8c7fff8c70300197e91965f759eedebdaffff9e6101408801527c0f26b5c90000949effff9effffff121900c9a071939e5fffff9effffff6101608801527d14000fff7878bf0060ffffa8ff7878170000d4a200bf5300ffff9eff3f406101808801527d14000fff59002b00a1ffffa8ff590014000fe58ca1644aa1ffffa8ff78786101a08801527c0619e0b082a12848ffffebffb482000d1400c5db2840a1ffffeb3ddbff6101c08801527d260026007bffd40071ffc4c4ffc4c4260000ff4c00780002ffdc69ff3f406101e08801527d36001dffaa00ff0000ffed4fffed4f260006ff0000630035ffad4fff3f406102008801527c0f05254c00006330a7ff63a7ff63361900b090829c5454fff7abfff7ab6102208801527a523f4f523f4fd94141d9414100010f91007e00635a63ffa963ffa9610240880152830151600710612de557600091505b610120830151612cd990600290615818565b612ce49060016157d2565b821015612d70576101c0840151612d10612cff846096615917565b612d0b906101906157d2565b613d69565b612d36610113612d218660c8615917565b612d2c9060456157d2565b612d0b9190615a39565b604051602001612d4893929190614bd3565b60408051808303601f190181529190526101c085015281612d6881615a0a565b925050612cc7565b6101c0840151610120840151612d8890600290615a39565b15612dac57604051806040016040528060018152602001602d60f81b815250612dbd565b604051806020016040528060008152505b604051602001612dce929190614c7d565b60408051808303601f190181529190526101c08501525b8251612df390600190615975565b612dfe906005615917565b9150612e5b6301000000612e13600a85615a39565b612e2190630100000061586f565b88612e2d600a87615818565b60138110612e3d57612e3d615aac565b6020020151612e4c9190615818565b612e569190615a39565b613e98565b85528251612e6b90600190615975565b612e76906005615917565b612e819060016157d2565b9150612e966301000000612e13600a85615a39565b60208601528251612ea990600190615975565b612eb4906005615917565b612ebf9060026157d2565b9150612ed46301000000612e13600a85615a39565b60808601528251612ee790600190615975565b612ef2906005615917565b612efd9060036157d2565b9150612f126301000000612e13600a85615a39565b60608601528251612f2590600190615975565b612f30906005615917565b612f3b9060046157d2565b9150612f506301000000612e13600a85615a39565b60408087019190915280516101408101909152610115808252615bc9602083013984526040805160608101909152602a808252615b7760208301398460016020020181905250604051806060016040528060288152602001615ba1602891396040850152612fd160018460085b6020020151612fcc9190615975565b613f90565b604051602001612fe19190615255565b60408051808303601f1901815291905260608501526130036001846008612fbd565b6101c085015160405161301a929190602001615159565b60408051808303601f1901815291905260808501526020830151613057906001906130469060006157d2565b6130509190615975565b600161096a565b60405160200161306791906155b3565b60408051601f198184030181529190528460056020020152613097600184600260200201516130469060096157d2565b6040516020016130a79190615659565b60408051808303601f1901815291905260c085015260608301516130d39060019061304690600b6157d2565b6040516020016130e39190615504565b60408051808303601f1901815291905260e085015260808301516131209060019061310f90600b6157d2565b6131199190615975565b600261096a565b60405160200161313091906153a6565b60408051808303601f1901815291905261010085015260e083015161315d906001906130469060196157d2565b60405160200161316d9190615455565b60408051808303601f1901815291905261012085015260c0830151600310156131a557604051806020016040528060008152506131bf565b6040518060c0016040528060888152602001615aef608891395b6040516020016131cf9190614dbc565b60408051601f1981840301815291905284600a6020020152613243600184600381600660200201511115613204576005613207565b60065b60ff16600c811061321a5761321a615aac565b602002015160c08601516003101561323357600d613236565b60165b60ff1661304691906157d2565b6040516020016132539190615618565b60408051808303601f1901815291905261016085015260c08301516003106132e857845160c08401516132999060019061328e906002615917565b61304690601a6157d2565b865160c08601516132ba906132af906002615917565b61305090601a6157d2565b6040516020016132cd9493929190614e38565b60408051808303601f19018152919052610180850152613308565b6040518060600160405280603c8152602001615f16603c91396101808501525b6040518061018001604052806101598152602001615d0861015991396101a08501528351608086015160208087015160608901516040808a01519051600096613358969095909493929101614a08565b60408051808303601f19018152908290526080808901516060808a0151908b0151928a01519395506133939486949293919290602001614a08565b60408051808303601f190181528282529088015160a088015160c08901519294506133c49385938391602001614a08565b60408051808303601f190181528282529088015160e08801516101008901519294506133f69385938391602001614a08565b60408051808303601f19018152828252908801516101208801516101408901519294506134299385938391602001614a08565b60408051808303601f19018152828252908801516101608801516101808901516101a08a015193955061346194869490602001614a08565b60408051601f19818403018152606083019091526022808352909250615e61602083013985526134988460015b6020020151613d69565b85600160200201819052506040518060600160405280602a8152602001615cde602a913960408601526134cc84600061348e565b606080870191909152604080519182019052602a808252615f726020830139608080870191909152840151606085015161354b919061350c90600a615917565b604087015161351c906064615917565b60e088015161352d906103e8615917565b61353791906157d2565b61354191906157d2565b612d0b91906157d2565b60a086015260c084015160031061358f576040518060600160405280602a8152602001615ec3602a913960c086015261358584600661348e565b60e08601526135be565b604051806060016040528060298152602001615eed6029913960c08601526135b884600561348e565b60e08601525b604051806060016040528060268152602001615f9c602691396101008601526135e884600861348e565b856009602002015260078460096020020151116136385761012085015161361085600961348e565b604051602001613621929190614b68565b60408051808303601f190181529190526101208601525b604080518082018252600481526322207d5d60e01b6020808301919091526101408801919091528651878201518884015160608a015160808b015160a08c0151965160009761368997909101614a73565b60408051808303601f190181529082905260c088015160e08901516101008a01516101208b01516101408c01519496506136c895879590602001614a73565b6040516020818303038152906040529050600061370d826136e88561403f565b6040516020016136f992919061504e565b60405160208183030381529060405261403f565b9050806040516020016137209190615210565b60408051601f198184030181529190529b9a5050505050505050505050565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b336137766126d1565b6001600160a01b03161461379c5760405162461bcd60e51b81526004016105479061574c565b6001600160a01b0381166138015760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610547565b61094c81613ce4565b80546001019055565b60006001600160e01b0319821663780e9d6360e01b14806104475750610447826141a5565b6000908152600260205260409020546001600160a01b0316151590565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061388a8261259a565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006138ce82613838565b61392f5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610547565b600061393a8361259a565b9050806001600160a01b0316846001600160a01b031614806139755750836001600160a01b031661396a846104df565b6001600160a01b0316145b806139855750613985818561373f565b949350505050565b826001600160a01b03166139a08261259a565b6001600160a01b031614613a085760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610547565b6001600160a01b038216613a6a5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610547565b613a758383836141f5565b613a80600082613855565b6001600160a01b0383166000908152600360205260408120805460019290613aa9908490615975565b90915550506001600160a01b0382166000908152600360205260408120805460019290613ad79084906157d2565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000613b4482846157d2565b9392505050565b6000613b448284615917565b6108a0828260405180602001604052806000815250614200565b606081613b955750506040805180820190915260018152600360fc1b602082015290565b600080831215613bad57613ba883615a4d565b613baf565b825b905060005b8115613bda5780613bc481615a0a565b9150613bd39050600a836157ea565b9150613bb4565b6000841215613bf15780613bed81615a0a565b9150505b60008167ffffffffffffffff811115613c0c57613c0c615ac2565b6040519080825280601f01601f191660200182016040528015613c36576020820181803683370190505b5090506000851215613c7d57613c4b85615a4d565b9450602d60f81b81600081518110613c6557613c65615aac565b60200101906001600160f81b031916908160001a9053505b841561398557613c8e600183615975565b9150613c9b600a86615a25565b613ca69060306157d2565b60f81b818381518110613cbb57613cbb615aac565b60200101906001600160f81b031916908160001a905350613cdd600a866157ea565b9450613c7d565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b613d4184848461398d565b613d4d84848484614233565b6127e25760405162461bcd60e51b8152600401610547906156fa565b606081613d8d5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115613db75780613da181615a0a565b9150613db09050600a83615818565b9150613d91565b60008167ffffffffffffffff811115613dd257613dd2615ac2565b6040519080825280601f01601f191660200182016040528015613dfc576020820181803683370190505b5090505b841561398557613e11600183615975565b9150613e1e600a86615a39565b613e299060306157d2565b60f81b818381518110613e3e57613e3e615aac565b60200101906001600160f81b031916908160001a905350613e60600a86615818565b9450613e00565b600081604051602001613e7a91906149ec565b60408051601f19818403018152919052805160209091012092915050565b6040805180820190915260068082526503030303030360d41b60208301526060915b8115613b4457600a613ecd601086615a39565b1015613f2457613ede601085615a39565b613ee99060306157d2565b60f81b81613ef8600185615975565b81518110613f0857613f08615aac565b60200101906001600160f81b031916908160001a905350613f71565b613f2f601085615a39565b613f3a9060376157d2565b60f81b81613f49600185615975565b81518110613f5957613f59615aac565b60200101906001600160f81b031916908160001a9053505b613f7c601085615818565b935081613f88816159b8565b925050613eba565b60607607a83bed064745656509338218136736845df65e9e517e8215613fd357613fbb836003615917565b613fc690606461586f565b613fd09082615818565b90505b613ff96064613fe461271084615818565b613fee9190615a39565b612d0b90600a615917565b6140086064613fe48185615818565b614016613fee606485615a39565b60405160200161402893929190614d35565b604051602081830303815290604052915050919050565b80516060908061405f575050604080516020810190915260008152919050565b6000600361406e8360026157d2565b6140789190615818565b614083906004615917565b905060006140928260206157d2565b67ffffffffffffffff8111156140aa576140aa615ac2565b6040519080825280601f01601f1916602001820160405280156140d4576020820181803683370190505b5090506000604051806060016040528060408152602001615e83604091399050600181016020830160005b86811015614160576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b8352600490920191016140ff565b50600386066001811461417a576002811461418b57614197565b613d3d60f01b600119830152614197565b603d60f81b6000198301525b505050918152949350505050565b60006001600160e01b031982166380ac58cd60e01b14806141d657506001600160e01b03198216635b5e139f60e01b145b8061044757506301ffc9a760e01b6001600160e01b0319831614610447565b610678838383614340565b61420a83836143f8565b6142176000848484614233565b6106785760405162461bcd60e51b8152600401610547906156fa565b60006001600160a01b0384163b1561433557604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906142779033908990889088906004016156aa565b602060405180830381600087803b15801561429157600080fd5b505af19250505080156142c1575060408051601f3d908101601f191682019092526142be9181019061494c565b60015b61431b573d8080156142ef576040519150601f19603f3d011682016040523d82523d6000602084013e6142f4565b606091505b5080516143135760405162461bcd60e51b8152600401610547906156fa565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050613985565b506001949350505050565b6001600160a01b03831661439b5761439681600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b6143be565b816001600160a01b0316836001600160a01b0316146143be576143be8382614537565b6001600160a01b0382166143d557610678816145d4565b826001600160a01b0316826001600160a01b031614610678576106788282614683565b6001600160a01b03821661444e5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610547565b61445781613838565b156144a45760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610547565b6144b0600083836141f5565b6001600160a01b03821660009081526003602052604081208054600192906144d99084906157d2565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000600161454484612611565b61454e9190615975565b6000838152600760205260409020549091508082146145a1576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b6008546000906145e690600190615975565b6000838152600960205260408120546008805493945090928490811061460e5761460e615aac565b90600052602060002001549050806008838154811061462f5761462f615aac565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061466757614667615a96565b6001900381819060005260206000200160009055905550505050565b600061468e83612611565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6040518061026001604052806013906020820280368337509192915050565b6040518060a001604052806005905b60608152602001906001900390816146f55790505090565b604080516101e0810190915260608152600e602082016146f5565b604051806101800160405280600c906020820280368337509192915050565b80356001600160a01b038116811461475e57600080fd5b919050565b60006020828403121561477557600080fd5b613b4482614747565b6000806040838503121561479157600080fd5b61479a83614747565b91506147a860208401614747565b90509250929050565b6000806000606084860312156147c657600080fd5b6147cf84614747565b92506147dd60208501614747565b9150604084013590509250925092565b6000806000806080858703121561480357600080fd5b61480c85614747565b935061481a60208601614747565b925060408501359150606085013567ffffffffffffffff8082111561483e57600080fd5b818701915087601f83011261485257600080fd5b81358181111561486457614864615ac2565b604051601f8201601f19908116603f0116810190838211818310171561488c5761488c615ac2565b816040528281528a60208487010111156148a557600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b600080604083850312156148dc57600080fd5b6148e583614747565b9150602083013580151581146148fa57600080fd5b809150509250929050565b6000806040838503121561491857600080fd5b61492183614747565b946020939093013593505050565b60006020828403121561494157600080fd5b8135613b4481615ad8565b60006020828403121561495e57600080fd5b8151613b4481615ad8565b60006020828403121561497b57600080fd5b5035919050565b6000806040838503121561499557600080fd5b50508035926020909101359150565b600081518084526149bc81602086016020860161598c565b601f01601f19169290920160200192915050565b600081516149e281856020860161598c565b9290920192915050565b600082516149fe81846020870161598c565b9190910192915050565b60008651614a1a818460208b0161598c565b865190830190614a2e818360208b0161598c565b8651910190614a41818360208a0161598c565b8551910190614a5481836020890161598c565b8451910190614a6781836020880161598c565b01979650505050505050565b600087516020614a868285838d0161598c565b885191840191614a998184848d0161598c565b8851920191614aab8184848c0161598c565b8751920191614abd8184848b0161598c565b8651920191614acf8184848a0161598c565b8551920191614ae1818484890161598c565b919091019998505050505050505050565b60008351614b0481846020880161598c565b835190830190614b1881836020880161598c565b600b60fa1b9101908152600101949350505050565b60008351614b3f81846020880161598c565b835190830190614b5381836020880161598c565b600160fd1b9101908152600101949350505050565b60008351614b7a81846020880161598c565b80830190507f22207d2c207b202274726169745f74797065223a20224d6574656f72222c20228152683b30b63ab2911d101160b91b60208201528351614bc781602984016020880161598c565b01602901949350505050565b60008451614be581846020890161598c565b80830190507f3c636972636c65206f7061636974793d22302e34222066696c6c3d2223464646815268231ca2911031bc1e9160b91b60208201528451614c3281602984016020890161598c565b66222063793d222d60c81b602992909101918201528351614c5a81603084016020880161598c565b681110391e911a11179f60b91b6030929091019182015260390195945050505050565b621e339f60e91b815260008351614c9b81600385016020880161598c565b80830190507f3c616e696d6174654d6f74696f6e20706174683d224d20302030206c2000000060038201528351614cd981602084016020880161598c565b7f3130303030203130303030203230205a22206475723d22323073222072657065602092909101918201527f6174436f756e743d22696e646566696e69746522202f3e203c2f673e000000006040820152605c01949350505050565b6331bc1e9160e11b81528351600090614d5581600485016020890161598c565b65111031bc9e9160d11b6004918401918201528451614d7b81600a84016020890161598c565b641110391e9160d91b600a92909101918201528351614da181600f84016020880161598c565b601160f91b600f929091019182015260100195945050505050565b7f222077696474683d223130303022206865696768743d2231313030223e000000815260008251614df481601d85016020870161598c565b7f3c2f726563743e3c67206f7061636974793d2230223e203c706f6c79676f6e20601d9390910192830152506666696c6c3d222360c81b603d820152604401919050565b6f3c706f6c79676f6e2066696c6c3d222360801b81528451600090614e64816010850160208a0161598c565b6911103837b4b73a399e9160b11b6010918401918201528551614e8e81601a840160208a0161598c565b7f223e203c616e696d617465206174747269627574654e616d653d226f70616369601a92909101918201527f7479222076616c7565733d22313b313b313b313b303b313b313b313b313b313b603a8201527f313b313b313b313b313b313b313b313b313b313b3122206475723d2233732220605a8201527f726570656174436f756e743d22696e646566696e6974652220626567696e3d22607a8201527f307322202f3e203c2f706f6c79676f6e3e203c706f6c79676f6e2066696c6c3d609a82015261222360f01b60ba820152615043614f8e614f88614f7260bc8501896149d0565b6911103837b4b73a399e9160b11b8152600a0190565b866149d0565b7f223e203c616e696d617465206174747269627574654e616d653d226f7061636981527f7479222076616c7565733d22313b313b313b313b303b313b313b313b313b313b60208201527f313b313b313b313b313b313b313b313b313b313b3122206475723d223373222060408201527f726570656174436f756e743d22696e646566696e6974652220626567696e3d2260608201527018399110179f101e17b837b63cb3b7b71f60791b608082015260910190565b979650505050505050565b7f7b226e616d65223a20224d797374696320466f72657374222c2022646573637281527f697074696f6e223a20224d797374696320466f72657374202d20696e7465726160208201527f63746976652067616d652c20636f6d706c6574656c792067656e6572617465646040820152761027b721b430b4b711161130ba3a3934b13aba32b9911d60491b6060820152600083516150f281607785016020880161598c565b7f2c2022696d616765223a2022646174613a696d6167652f7376672b786d6c3b6260779184019182015265185cd94d8d0b60d21b6097820152835161513e81609d84016020880161598c565b61227d60f01b609d9290910191820152609f01949350505050565b7f222f3e203c2f72616469616c4772616469656e743e203c636972636c65206f7081527f61636974793d22302e39222066696c6c3d2275726c28235329222000000000006020820152600083516151b781603b85016020880161598c565b620179f160ed1b603b9184019182015283516151da81603e84016020880161598c565b7f3c706f6c79676f6e206f7061636974793d22302e3134222066696c6c3d222300603e9290910191820152605d01949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161524881601d85016020870161598c565b91909101601d0192915050565b7f222f3e203c2f6c696e6561724772616469656e743e203c726563742066696c6c81527f3d2275726c28234229222077696474683d223130303022206865696768743d2260208201527f31303030222f3e203c72616469616c4772616469656e742069643d22532220006040820152600082516152d981605f85016020870161598c565b7f206772616469656e74556e6974733d227573657253706163654f6e557365223e605f9390910192830152507f203c73746f70206f66667365743d22302e373522207374796c653d2273746f70607f8201527f2d636f6c6f723a23464646463945222f3e203c73746f70206f66667365743d22609f820152753122207374796c653d2273746f702d636f6c6f723a2360501b60bf82015260d501919050565b65119bdc995cdd60d21b81526000825161539981600685016020870161598c565b9190910160060192915050565b6911103837b4b73a399e9160b11b815281516000906153cc81600a85016020870161598c565b600080516020615f52833981519152600a9390910192830152507f3135203139206c203133203134205a22206475723d2231377322207265706561602a8201527f74436f756e743d22696e646566696e69746522202f3e203c2f706f6c79676f6e604a820152713e203c706f6c79676f6e2066696c6c3d222360701b606a820152607c01919050565b6911103837b4b73a399e9160b11b8152815160009061547b81600a85016020870161598c565b600080516020615f52833981519152600a9390910192830152507f313020305a22206475723d223136732220726570656174436f756e743d22696e602a8201527f646566696e69746522202f3e203c2f706f6c79676f6e3e20203c72656374206f604a820152717061636974793d2230222066696c6c3d222360701b606a820152607c01919050565b6911103837b4b73a399e9160b11b8152815160009061552a81600a85016020870161598c565b600080516020615f52833981519152600a9390910192830152507f3135203230206c203132203135205a22206475723d2231397322207265706561602a8201527f74436f756e743d22696e646566696e69746522202f3e203c2f706f6c79676f6e604a820152713e203c706f6c79676f6e2066696c6c3d222360701b606a820152607c01919050565b6911103837b4b73a399e9160b11b815281516000906155d981600a85016020870161598c565b7f222f3e203c706f6c79676f6e206f7061636974793d22302e36222066696c6c3d600a93909101928301525061222360f01b602a820152602c01919050565b6911103837b4b73a399e9160b11b8152815160009061563e81600a85016020870161598c565b63011179f160e51b600a939091019283015250600e01919050565b6911103837b4b73a399e9160b11b8152815160009061567f81600a85016020870161598c565b73222f3e203c706f6c79676f6e2066696c6c3d222360601b600a939091019283015250601e01919050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906156dd908301846149a4565b9695505050505050565b602081526000613b4460208301846149a4565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b600082198211156157e5576157e5615a6a565b500190565b6000826157f9576157f9615a80565b600160ff1b82146000198414161561581357615813615a6a565b500590565b60008261582757615827615a80565b500490565b600181815b8085111561586757816000190482111561584d5761584d615a6a565b8085161561585a57918102915b93841c9390800290615831565b509250929050565b6000613b44838360008261588557506001610447565b8161589257506000610447565b81600181146158a857600281146158b2576158ce565b6001915050610447565b60ff8411156158c3576158c3615a6a565b50506001821b610447565b5060208310610133831016604e8410600b84101617156158f1575081810a610447565b6158fb838361582c565b806000190482111561590f5761590f615a6a565b029392505050565b600081600019048311821515161561593157615931615a6a565b500290565b60008083128015600160ff1b85018412161561595457615954615a6a565b6001600160ff1b038401831381161561596f5761596f615a6a565b50500390565b60008282101561598757615987615a6a565b500390565b60005b838110156159a757818101518382015260200161598f565b838111156127e25750506000910152565b6000816159c7576159c7615a6a565b506000190190565b600181811c908216806159e357607f821691505b60208210811415615a0457634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415615a1e57615a1e615a6a565b5060010190565b600082615a3457615a34615a80565b500790565b600082615a4857615a48615a80565b500690565b6000600160ff1b821415615a6357615a63615a6a565b5060000390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b03198116811461094c57600080fdfe3c616e696d617465206174747269627574654e616d653d226f706163697479222076616c7565733d22303b2e333b2e333b2e343b2e333b2e333b3022206475723d223130732220726570656174436f756e743d22312220626567696e3d226d6f6e737465722e656e642d31302220726573746172743d227768656e4e6f7441637469766522202f3e222f3e203c73746f70206f66667365743d22302e3522207374796c653d2273746f702d636f6c6f723a23222f3e203c73746f70206f66667365743d223122207374796c653d2273746f702d636f6c6f723a233c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d227574662d38223f3e203c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f7376672220783d223070782220793d22307078222077696474683d2231303030707822206865696768743d22313030307078222076696577426f783d2230203020313030302031303030223e203c6c696e6561724772616469656e742069643d224222206772616469656e74556e6974733d227573657253706163654f6e557365222078313d22353030222079313d2231303030222078323d22353030222079323d2230223e203c73746f70206f66667365743d223022207374796c653d2273746f702d636f6c6f723a2322207d2c207b202274726169745f74797065223a202250616c65747465222c202276616c7565223a20223c616e696d617465206174747269627574654e616d653d226f706163697479222069643d226d6f6e73746572222076616c7565733d22303b313b313b313b313b3022206475723d223130732220726570656174436f756e743d22312220626567696e3d22636c69636b2220726573746172743d227768656e4e6f7441637469766522202f3e3c616e696d617465206174747269627574654e616d653d226f706163697479222076616c7565733d22303b313b303b303b303b303b303b3022206475723d223630732220726570656174436f756e743d22696e646566696e6974652220626567696e3d223330732220656e643d226d6f6e737465722e7374617274222f3e203c616e696d6174654d6f74696f6e20706174683d224d20302030206c2030202d31355a22206475723d223330732220726570656174436f756e743d22696e646566696e69746522202f3e203c2f673e3c2f7376673e5b7b202274726169745f74797065223a2022466172222c202276616c7565223a20224142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f22207d2c207b202274726169745f74797065223a20224d6f6e73746572222c202276616c7565223a202222207d2c207b202274726169745f74797065223a2022416e696d616c222c202276616c7565223a20223c72656374206f7061636974793d22302220783d223235302220793d22323530222077696474683d2235303022206865696768743d22353030222f3e223e203c616e696d6174654d6f74696f6e20706174683d224d20302030206c2022207d2c207b202274726169745f74797065223a2022536176616e6e61222c202276616c7565223a202222207d2c207b202274726169745f74797065223a202253756e222c202276616c7565223a2022a26469706673582212205e3aef1e70f659889240519774f4f261268438514c37a075020cfd2040c31c0e64736f6c63430008070033
Deployed Bytecode
0x60806040526004361061014b5760003560e01c80634e71d92d116100b657806395d89b411161006f57806395d89b4114610387578063a22cb4651461039c578063b88d4fde146103bc578063c87b56dd146103dc578063e985e9c5146103fc578063f2fde38b1461041c57600080fd5b80634e71d92d146102e85780634f6ccce7146102fd5780636352211e1461031d57806370a082311461033d578063715018a61461035d5780638da5cb5b1461037257600080fd5b80632f745c59116101085780632f745c59146102405780633610724e146102605780633ccfd60b1461027357806340d097c31461028857806342842e0e146102a85780634d4c71a3146102c857600080fd5b806301ffc9a71461015057806306fdde0314610185578063081812fc146101a7578063095ea7b3146101df57806318160ddd1461020157806323b872dd14610220575b600080fd5b34801561015c57600080fd5b5061017061016b36600461492f565b61043c565b60405190151581526020015b60405180910390f35b34801561019157600080fd5b5061019a61044d565b60405161017c91906156e7565b3480156101b357600080fd5b506101c76101c2366004614969565b6104df565b6040516001600160a01b03909116815260200161017c565b3480156101eb57600080fd5b506101ff6101fa366004614905565b61056c565b005b34801561020d57600080fd5b506008545b60405190815260200161017c565b34801561022c57600080fd5b506101ff61023b3660046147b1565b61067d565b34801561024c57600080fd5b5061021261025b366004614905565b6106ae565b6101ff61026e366004614969565b610744565b34801561027f57600080fd5b506101ff6108a4565b34801561029457600080fd5b506101ff6102a3366004614763565b610902565b3480156102b457600080fd5b506101ff6102c33660046147b1565b61094f565b3480156102d457600080fd5b5061019a6102e3366004614982565b61096a565b3480156102f457600080fd5b506101ff61249a565b34801561030957600080fd5b50610212610318366004614969565b612507565b34801561032957600080fd5b506101c7610338366004614969565b61259a565b34801561034957600080fd5b50610212610358366004614763565b612611565b34801561036957600080fd5b506101ff612698565b34801561037e57600080fd5b506101c76126d1565b34801561039357600080fd5b5061019a6126e0565b3480156103a857600080fd5b506101ff6103b73660046148c9565b6126ef565b3480156103c857600080fd5b506101ff6103d73660046147ed565b6127b0565b3480156103e857600080fd5b5061019a6103f7366004614969565b6127e8565b34801561040857600080fd5b5061017061041736600461477e565b61373f565b34801561042857600080fd5b506101ff610437366004614763565b61376d565b600061044782613813565b92915050565b60606000805461045c906159cf565b80601f0160208091040260200160405190810160405280929190818152602001828054610488906159cf565b80156104d55780601f106104aa576101008083540402835291602001916104d5565b820191906000526020600020905b8154815290600101906020018083116104b857829003601f168201915b5050505050905090565b60006104ea82613838565b6105505760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006105778261259a565b9050806001600160a01b0316836001600160a01b031614156105e55760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610547565b336001600160a01b03821614806106015750610601813361373f565b61066e5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776044820152771b995c881b9bdc88185c1c1c9bdd995908199bdc88185b1b60421b6064820152608401610547565b6106788383613855565b505050565b61068733826138c3565b6106a35760405162461bcd60e51b815260040161054790615781565b61067883838361398d565b60006106b983612611565b821061071b5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610547565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b600081116107835760405162461bcd60e51b815260206004820152600c60248201526b15dc9bdb99c8185b5bdd5b9d60a21b6044820152606401610547565b601e8111156107c25760405162461bcd60e51b815260206004820152600b60248201526a04e6f74206d6f72652033360ac1b6044820152606401610547565b610d056107d8826107d2600b5490565b90613b38565b11156108165760405162461bcd60e51b815260206004820152600d60248201526c14d85b1948199a5b9a5cda1959609a1b6044820152606401610547565b600c5434906108259083613b4b565b11156108635760405162461bcd60e51b815260206004820152600d60248201526c09ccacac840dadee4ca408aa89609b1b6044820152606401610547565b60005b818110156108a0576108803361087b600b5490565b613b57565b61088e600b80546001019055565b8061089881615a0a565b915050610866565b5050565b336108ad6126d1565b6001600160a01b0316146108d35760405162461bcd60e51b81526004016105479061574c565b6040514790339082156108fc029083906000818181858888f193505050501580156108a0573d6000803e3d6000fd5b3361090b6126d1565b6001600160a01b0316146109315760405162461bcd60e51b81526004016105479061574c565b61093e8161087b600b5490565b61094c600b80546001019055565b50565b610678838383604051806020016040528060008152506127b0565b60606000604051806116a001604052807effb4b3b2b1b0af988e877a76726c67645f5a575351493a2a1e1b1713100b0581526020017e07fdababd4eaf52005000198467a9a61c9f6f305ded179bae0af884c05c72f81526020017507fdddabd5eaf560079801a8c267355bd006cca5a53681526020017f064b5270e27fb9df2f7713f9b7168e44dd32470cc187365d5221d487ed811dab81526020017507ff57abd580000000021544727b9edca88772b580c981526020017f084c89cf1c734adef2e7bd31f94c7e525ff497fcfe273c7fcf1ff2f8b4d22b4281526020017f07f409ff017fbda24f482bc63aec7fbadfed79234646f18d4022f248748a172481526020017f06ccd1b1366c561cd4e72d29cf4a73cfde53d73ce9cf057bc15ef1f7fc85ff0a81526020017f073b91cec276b01cebf73ad5e4b373ac9cea96c279b0ad6d2b9b4b36c2e1b13381526020017f07e301febd7fac9fab07daa9eeaa7bb21ceca73b69eed87bbc5cef173ba1dee581526020017e07fd55aad4eab52005c001be878828240c08cb0a2cc484b1a14c47fb19febf81526020017f06797662759522272b3c338354e0d50000000000ad284f61a9194d465c052d5c81526020017f0872fdd8bc7d2e5d8b87225dc09d62a8934505f965be9e72a71c6937fa45c49081526020017f06e3959ee567b61dad676b419cd364ad5b2b3642c58ca470a81d4d376b49dac081526020017f072c51e50f74435d9047340d874e4dd6d9d0376415d8d675359cd0267bfd9ee781526020017507fc07aad56ab54ef9a42a21366652dc51a81c61cb1481526020017f05238d60e4633c9aee763bd962eb55bc973059b44e671e62551cd5e5ed8045aa81526020017f02b104b04a651a1fa949125e7ea6a12b5d6b175af5c8b26cacdb4b8602d146dc81526020016a01ffd26ab480000000483781526020017f079c0ddafe763d656f0773be02dfcab6b212c80cd9db296fccdd13c94519016e81526020017f06734daed3713699cdb68491af246fca9d32774c8df32075481dd18c443b0b0281526020017f0832d1e2b27daa714a5c3265f49b7ca65c29570a319c8f66ab5aab5692e598bb81526020017e07fc81aad56ab54000000000456822e107b8f227328ecab4df2c976305dab881526020017f06fb9dbcfa6abe9a30068c25af0c6dc4235248fc864b2967cc55d4b5052c23aa81526020017f063a857ea15eae1d0ba5f2f182ca633258ec466b119cc26eb05b8dc73385f2e381526020017f0d56ab540000000001b731cdf06c8b9e1c4816f229a68a6b275baa466aa192a681526020016101ff81526020017f060385b6dd603717ed45b33950cc52be163065946d55290cdcc37aad56ab540081526020017f05530970c45f33592cb69b0622bf8dbba650984471a9196241584f075bb582eb81526020017e07fc0000000002c25541517673791e99c7c6c2296090562653e9b502dd64bc81526020017f02b38c96f9183d460ff23c085b3a18b905af5003c000fa153f8451b0f504014081526020017f0444326f265bd29a74b984c6553b7c53ddf4c35d18bd412ad0c95423bcb46d3c81526020017f09445e5d18a043a6f196cc31a10964c29110041bf8feff273e497023d429030c81526020017f099a6e6ac09baaa84d0a1bc63ccba1bf686fd99bde38f69b40a1f0b97436830681526020017f07e2d236d47ba7a0aac93afe18a879a39f6828fa1e229e94a2e38b59627e5e9381526020017f0649ad946c669ade27f6a99daa67761ddf08076211ee8375a59e8c87a2b1e09a81526020017f064291cec461239a09c752a17e7e631c98a705f1e97861631c9ca9461181986981526020017f0449e1168649a952083451d5166c5a98d6a695d9fd767f5b21980b860271788a81526020017f0192210ea21ea00867c451b504783f22cfe99429e912724222d12a448acd128c81526020017f017af086dc1aaec4e8c1bab49ebf19268ded523a88beab2127072942826cf4a181526020017f0629557e4e5d9396a594b98122604518c0081002304e830f2ac4ecc122a04c968152602001771ff006ab55aad5000000000185404b4898126605112da45081526020017f02b49d0d3263cdda9356dd1da54954529194457d04f340204d0cd3110cb8012781526020017f069bf9ab126949c6f17004440116694a5a32d6a4d18f3641cc0b92600470012181526020017f090466072a774a9ad276b4a9e52c804b1fd2d6dcc9af2b6bc81bf206bc79b11181526020017f090cee3b378ccda353c8fcf9d745714f5eb396fce1bb347fcba072b97ca60d2a81526020017f09c4b299339f4c24f3197cd6913597cf25737954f6553892cd64d3d91cda3d3581526020017f0a440e8300a141a9909a1c2e8d0fa543e8f1aa14567910a3482952c9fc8e4b1a81526020017f09eb628ed5a932ea4d1a138e9adda935aa4e0a73f68cfba6c0a8cfda0bf284fe81526020017f09f2ce80b2a4ab284b4a52cea0a9a7ad6a4b2a92e290b894b1274c6a5b16a4c281526020017f09ea72769fa328a74a69caae86aa9dac25ca39729274b19cad67ab3a22ee8aba81526020017f076231a28c68239c88f7923e4a9b952864ea99c2727299a1a36929a9d25a729981526020017f098a22688d9d2226a8d9ca3a649096236548f982525e979925e589b95a7e449681526020017f090202528091a12508790a1a3c8b83219ae826aa16388e8d24a4c8f952425a8d81526020017f0562e97aac61a8db6a16327db47d771e232787c9d62c6d921d6267b8e9fe407c81526020017f064a016ca6522e564e357bd54f0a59be56ee459b5586d35934960c85c3195ec581526020017f0d500000000033068ac21aac72a920294f0a223a80b0963f22d868e622311a878152602001651ff006ab55aa81526020017f05129544a253aa542a550aa156b656aed46b0512a944a950aa142b451ae55ec481526020017f047a45088e40241068243219108d4421d208f4a29128a64baa5229050a8142a581526020017f04baf912a54a2b130b74c30148ea4e3016af45132152d34d2bd42b3402450a9281526020017f038ac8e4b945380ecb548b60f4af39ab0f89b3f2a522bf41298fc963fa5104a181526020017f01a1fc847e212089482241f8c2832b9f4f47a41204fc91362d8d4d739b90dcd781526020017f02426080952425092992626c969426a509a942b284b4a42a250fc9225208648081526020017f01810c5c4700118005512954247508a343cb81db94469837ba44c8e24aa0dcaf81526020017f0670f59a38270d0923f2e120a648248fcb220218c45c2b170c80032000d85a3781526020017f07b11e42438a9035444d50f5de388888598386791d48484f11d2a4946924ce3a81526020017f07319dd4737f9ca2c89829cb5466d51664a637e195e4578a16e1856d515f544681526020017f03c1b4fa583e960fe6d439b50658489b12c6b45961aa5878215c25872161e66681526020017f0179bc4e721d1608e682419c805625958e06d2e95cd45730970c8603795cee5881526020017f065a31c49d66a09d88a659d5cc736f19d526a281c0c2632d17c6e6d1f170785981526020017f05727d3a9a3d9e90679432151087439e530784e20144874d9dd72776aab98e858152602001797fd84ea5d35990e657ae9ace95cb0984c9592c952ab50a798ab281526020017f024ba8010200424a2ef2cba8d8e92fb98cce137354f0cf39338eec843b08eafc81526020017e021ccc864f9f5328f2a230668a0024800981da40ec964b26118b037ae8bedb81526020017f0799e5c0787f1a3543fd5005984346934d43d4e0e4c83716000320038148005d81526020017f0d52f2aab7622996ca964251be8e87202d48bd524f548b9d9f6187b67a31b87c81526020017f04f46d23154a3b13ad75535140d150b3d76c951b295cb263ab2cabcb8aff54c081526020017f05ed955d5c55525cd507f54e9b68c76ab21aaa6591ed4e54d19432458c89412081526020017f046cf5353b46ce521204c481515e516a951aa575857d69725a691aaa7ea9cb668152602001771ff336a901aa45d3d515e53d65174a46515474851515194281526020017f0623b5890352448c30c294b811a004e34bb014ec297cfe5c3a176dc6234192d081526020016a01ff64b4196d464b7988e981526020017f0573215acb523413a8852a3152965aa6156925321d388044000e6004aa253cd581526020017f062b4186d0613457aca61b1988c762b2188c962b218ac760b0d72c358b1958c981526020017f05737d78e5603918ae062b7d88dd623798ae05f37182d76136188d86235988d281526020017301ff40c9d11384249530f352bf536ef5235d5ede81526020017f047040f64a421ecdeaf302c0aaba2ab10aece2fb50bacc2f300d2c136af8d6d481526020017f03b2e10ab9432dd0ab443ab90aaa39ab9147b4216518654d1b51a62419295a108152602001677fcdcc837af4e6bb81526020017f07aaf9eaba7f2e1feb37face02b383abe12ab8a2aa32a58e26a809fa5abec0bf81526020017f077245e8a276289ceaa722a5c0ad71ac9cab1732c5ccb5742e1dabb76af9e0c081526020017f07aa3624867d21df4878a9f1f68072231c69075259d09180255fa977da6dec9281526020017f0d42b750a5a4a66a695b221e9e8ea2256b27ca223e8297a02621c9085a3a108e81526020016e1ffb02fea2aba428e9ca6b72b6aaa281526020017f06d291b8a66ea95bca67028dc29f72a79d6a17a299eaa979ab9c2c07b2c5f89d81526020017f077a19d48374a05d87e7b9f9f6807b9f5d87d741fdcc8373221b6996b279b0a481526020017f075a71e29b7b269ee9e7ba81f2997aa59d8977623de6937ba49f6917ea29e88e81526020017f07ea561e5a8892e4864909ca4e77919c64c638910a3c008400610597b291dc9d8152602001677fe04ac81ad208ab81526020017f02cbf4b4fc2d3ecbafd32bf4ccfd35bf0dd162a584936e23d447b3a21d508b7481526020017f035b8ce6d435380c8c034bb8c6ef2f3c0b8f22cbccaef52b3e0b2fa2cbe8b2fc81526020017e07fc29a91fea4b96a38c5cdcfb3a3e102f7413d8fcf540bd100f1393c4d8ef81526020017f09bb9e68e7963b64eec953ce56f996406610f97cce5d3b99d267150a0562975e81526020017f0b6c3ad110acc3ad104b5c0ee4fdb9bced0ffab41a94fea2bd680f0a1b9282e081526020017f0b84a2e321b6c92d729aecc69d29a7c929f16a9c5ed115b6c52e30fb8c1adf0981526020017f0a5d26a543ac512bb47b54eee335b8cbadb31b5cd6bd3ca84dea536ac4deb93a81526020016c07fea163acd8ea959a65467b4d81526020017f09328a4ca19528a56a4962824e9b94a5e5697962625898952a65cb49630660b681526020017f089aae26ac8baae32aa8d2aa38aa8faa644a892a9650a694aa254a995a9654a481526020017f08ea3632938ca66369d8ca7a329f8c27e2e9f89a7e249f89a8e26a489a9a28a881526020017f0d490b503dac996867b9b1ea627d9b1f2847e9b2226a879821e5a8993a22448a81526020017f09aaee5cac9aaba5aa998246668e9aa42808e9c22ab66dad1fea88cae202bc6b81526020016101ff81526020017f0a1c1a8f0ea8c4e9f1ea7486a12daac86ab1daac46b10bacc72ed3eb5502f54281526020017f0adbb6aef1aabb29ce7a6b969ae1a638296dfa2b8e88e5a23a292f2a4bd688fd81526020017f0af46ab4ffb13dab6faaf376bed7ac3fab107ab426ad06a9c0ea502aa3eab4f48152602001677fef542d3daf4f4a81526020017f07a1f1e87f749fdce8375205e8837a219d88a7a225ea8c7823dec8d8229a3aa481526020017f0849be3069a219a4466a615f5c6ad697a985280991ec75789cdea777a1e9da7881526020017f082a4a6294872423c8c99247589ad5a4e5e88d621f586a991de3877879ca526e81526020016e1ffd62c758a787a761c9caca6a169981526020017f09146e231c89c6a451989c662b16914662b148b44a2ef9953ca470a8ecc6313981526020017f08a3e6291285499f13284ca61b338649e1b2490c961d238847e43238847a211e81526020017f08e31636c28ab0234c38bb3632c99132632c88d31a3cd1913424cec8abda12fa81526020017f08e21e3c818d2120c8b8d21e40938f2a62aaa902b650bf92b163ecb8eb1a4ec481526020017f090a76429a95a7a429890a5e5c9591256449290a42609090a3e3e8d98a363e8c81526020017f098a3e6a85a020e6a82989de68859527250b39029e40a59628a40a390a7e56a181526020017f0a725ea690a5a5664bf97af65ab996a7a829096a6a60939a25a609198a466e9481526020017f0a5ade76b9a12b6a2ada12b288a9b42a68aa7a3296a4a5a3a8e989acfad340ab81526020017f09db1692cb9db0e84c1aab068ebfaaaef40cdcfb1aacb8adacaa8b89bb0674bb81526020017f0d13b740d2a6b4284d89d36688d59db568cd39e34690d19db3692d09d32294cf81526020017f0cfc028f00a2beea6f8a23e686f7adbca84f5a03baa0ed9fbb296ea9eba680e781526020017f0a945a71109c43ac30d9c4327104a141271039b3aa8b03a2c0e8709a4c0f3d0881526020017c01ff8fcc64d0e9744a4d09983b26d129ac7a7313d24b74b25adc62d11881526020017f08c1fa2075871de1e72871a6126b86982205a8a1222a548f1227843971269c4c81526020017f093276469d922824e9f8f2923caa8da963e978da3e348c8823a229486a2e428081526020017f0a62528c9ba0a7e7c9e9e2867ca29da8a70a09ba86649c98a7a669f9827e569e81526020017f0a122e7a8da2a327e8ea1a3a8290a4a3a8491a52428893a6a428a95a5a4a8c9881526020017f0a12327c8ca022e768a9ea2a6a899d22272889a226688a9e22a6e8b9fa2e768d81526020017f0a5a5e9893a4a5a9891a4a52988fa2a46968ea0a3e908da02368a8ca22327e8d81526020017507fe9c4cb110b2042c82568a849f21e8889a8236a09281526020017f090d92476b875d2597397dc65b76965ca4973946024d848b5da3d86815b23b9781526020017f09ec667d289b4aa7d29a254a71378fc66774b8dce279587cd4273609b5924b6981526020017f0ac496af29a046a9724a049e8129a749eab2ea8cce9f2aa74da933ca74ea934b81526020017f0b0bdec708b0c3ea8f7afc52bd15ab42e86feae45e8d12adc7ab520a748ea52681526020017f09abc65ad7a33d25ad29c3529ad19833eceb5a1b8ad4bbae39edcc1b4be6cb0581526020017f0b0a36c695af27eca9bb4abeb8a89bacaceb3973365acf94b464ed295b4656d781526020017f0a3222947ca7176b274a49f29080a99eea67ba2252ae85ae9f6ba7dac22aaea981526020017f0a112a6c45828e6724c9192a06539714e2a649e956428ea19768a80a120e8a8181526020017f08ceab55aad50025000990ea703d9e0c284419c0f220289a10668449b1166e4381526020016101ff81526020017f061571795d605859562615998b686759d8f6c695b5b5677cdc2097b72dce419a81526020017f08d6164f8d85d920f6587dda0f737f59db7557b5b9b96666d519f5d62d65956181526020017f08859a336a9ddb227708a5ce3773975c23b779a602518f93e32217e84dda217881526020017f078521c94b77d4deb5378565fb5a7cd7a09608159621668d57a7d6a95d96256481526020017f09c54e47469a55a7b638e55a3b468ad221f4386d2a03448153603487ad11ef4e81526020017f081ca5d91b7c4a5d7297e4b9bd3781cca11349ed4675539f54e7f58a6d7e916581526020017f08ecb24130964ce4f3491cda4d399ace25f3994cfa693f9bcfa774a84cbe030d81526020017f0a954ab150aad52793b9f4eaa544ab50e7f39994966930994b6512896cca492b81526020017f0ae496cd28b2cc2c72dadca2c739afcd6832ba54dec143a35129d49ab526994c81526020017f0a045e8f20a0c82731c9947a6f22a2c8a7d27a1ca69b24a9c929b28a44b6a92d81526020017f0ad412db09af41e8f0aa7c36d90ca24529f15b6436cf26af4929b17a8c82971a81526020017f0b03cac2f4b33caeae2b6c0eaae5aebd6b6f7af3dac0f9b2bfebcfaa1bce98fc81526020017f0b2ad2d4aab8b1aaabab432ae2ceb433294d4abb66d2daba35ab4e9b13a6eadf81526020017f09ca969caf9fada94b3a2aee98b5a5b06a2b1b0a9aacb4af2c2d2a4b4a9ebaba81526020017f0a128e9ca0b1a36c68db2a5ac695ada4eb295b126abc9aa4296a6a7b0a92a6ae81526020017f0ae1eeb87fa89f264829fa1ea489b0a1eae8aa02629497b022eb293aa24aae9481526020017f0a01a29e6aa79b6a66aad9a6b86eac9c68869a89d27677a31e6a876a81e6ac7781526020017f08a1ce3c73919ba4675951c25474991be68699a1a66a739f1b68062ab962a46181526020017f0a315aaa53ab15a7e609b966585998182585d909825066921923666911b2346c81526020017f09a93a72519715e7057a61228e4fa593e9e49aa93a844e9e14e80569e16a865b81526020017f08214dec618514a0e75861425c3e9a8f680419b106304c9313e724da511a784e81526020017f078901f43d7b90a04408011a20418a0ea46358a10a4a408413de24982145ea5681526020016e1ff746ab55aad5001e800728d5e63981526020017507fe007c7f1f2007f809f20a7c809edfc797f1ee007c8152602001707fdfc887f22e02877fa15fe8680a1dfc888152602001707fe70d2993725cdc98b6a64d999b6266d88152602001707fe66c79c33a6acb9b32e68ca9932660c881526020017301ff96236649199a56609598252629397a465e9281526020017301ff98266649997a765e9b9826a609a98a66609981525090506000806000806000806060600060038c106122d3576101006122ac60038e615975565b6122b89061010061586f565b8a516122c49190615818565b6122ce9190615a39565b6122de565b6122de8c60016157d2565b96508a600114156122f257608c93506122f8565b61038493505b6040518060200160405280600081525091508697505b60b5881161248b57888860b5811061232857612328615aac565b60200201516123365761248b565b888860b5811061234857612348615aac565b6020020151955060009450600092505b601b831161246a5761020061236d848261586f565b6123779088615818565b6123819190615a39565b9050806101ff14156123925761246a565b61239d600286615a39565b61240c578a600114156123f157816123ca608c6123bb846003615917565b6123c59190615936565b613b71565b6040516020016123db929190614af2565b604051602081830303815290604052915061244a565b816123ca612400836003615917565b6123c5906104e2615936565b81612427858d61241d856003615917565b6123bb9190615917565b604051602001612438929190614b2d565b60405160208183030381529060405291505b8461245481615a0a565b955050828061246290615a0a565b935050612358565b806101ff14156124795761248b565b8761248381615a0a565b98505061230e565b509a9950505050505050505050565b61012c6124a6600b5490565b11156124ea5760405162461bcd60e51b81526020600482015260136024820152724e6f206d6f7265206672656520746f6b656e7360681b6044820152606401610547565b6124f73361087b600b5490565b612505600b80546001019055565b565b600061251260085490565b82106125755760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610547565b6008828154811061258857612588615aac565b90600052602060002001549050919050565b6000818152600260205260408120546001600160a01b0316806104475760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610547565b60006001600160a01b03821661267c5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610547565b506001600160a01b031660009081526003602052604090205490565b336126a16126d1565b6001600160a01b0316146126c75760405162461bcd60e51b81526004016105479061574c565b6125056000613ce4565b600a546001600160a01b031690565b60606001805461045c906159cf565b6001600160a01b0382163314156127445760405162461bcd60e51b815260206004820152601960248201527822a9219b99189d1030b8383937bb32903a379031b0b63632b960391b6044820152606401610547565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6127ba33836138c3565b6127d65760405162461bcd60e51b815260040161054790615781565b6127e284848484613d36565b50505050565b60606127f26146c7565b6127fa6146e6565b61280261470d565b61280a614728565b60008061283d61281989613d69565b6040516020016128299190615378565b604051602081830303815290604052613e67565b905061284a602482615a39565b6128559060016157d2565b83526009612864606483615818565b61286e9190615a39565b6128799060016157d2565b6020840152600261288c6103e883615818565b6128969190615a39565b6128a19060016157d2565b604084015260026128b461271083615818565b6128be9190615a39565b6128c99060016157d2565b606084015260026128dd620186a083615818565b6128e79190615a39565b6128f29060016157d2565b60808401526009612906620f424083615818565b6129109190615a39565b61291b9060016157d2565b60a0840152600961292f6298968083615818565b6129399190615a39565b6129449060016157d2565b60c084015260026129596305f5e10083615818565b6129639190615a39565b61296e9060016157d2565b60e08401526009612983633b9aca0083615818565b61298d9190615a39565b6129989060016157d2565b61010084015260146129af6402540be40083615818565b6129b99190615a39565b6129c49060016157d2565b61012084015260146129db6402540be40083615818565b6129e59190615a39565b60011415612a095782516129fb90600290615a39565b612a069060256157d2565b83525b7c3331a3e080008277ffff9efff53f18283d1c8c94335582ffff9eff3f4086527d0c0e2b54bbffc200ccffffeaff88001e2900e0d78074a11affff9effff9e60208701527d1011246dcfc248667dffffeaff88000c0e2bff5454c200ccffffeaff880060408701527d1213247689942f354affff9eff3f401011246dcfc248667dffff9eff3f4060608701527d190014ff4c00870041ffff9eff3f400a0d00ffaa00004a01ffff9eff3f4060808701527d091d24ffff9e009e71ffff9effd080111c2b00c483004a61ffff9eff3f4060a08701527d01002b5b1d91731045ff3030ff30300c190a71bd46008037ffff9effff9e60c08701527d0505056e676a696969f0e8e4f0e8e41b002487003df02222ff5500ff3f4060e08701527c1114067a59005c4999f0e7ff993d00111427596b00809999d0f099d0f06101008701527d180019ff8c006900a6fff08cff8c0018001930579168248fffa6efff3d3d610120808801919091527c15195da69c5f969efff8c7fff8c70300197e91965f759eedebdaffff9e6101408801527c0f26b5c90000949effff9effffff121900c9a071939e5fffff9effffff6101608801527d14000fff7878bf0060ffffa8ff7878170000d4a200bf5300ffff9eff3f406101808801527d14000fff59002b00a1ffffa8ff590014000fe58ca1644aa1ffffa8ff78786101a08801527c0619e0b082a12848ffffebffb482000d1400c5db2840a1ffffeb3ddbff6101c08801527d260026007bffd40071ffc4c4ffc4c4260000ff4c00780002ffdc69ff3f406101e08801527d36001dffaa00ff0000ffed4fffed4f260006ff0000630035ffad4fff3f406102008801527c0f05254c00006330a7ff63a7ff63361900b090829c5454fff7abfff7ab6102208801527a523f4f523f4fd94141d9414100010f91007e00635a63ffa963ffa9610240880152830151600710612de557600091505b610120830151612cd990600290615818565b612ce49060016157d2565b821015612d70576101c0840151612d10612cff846096615917565b612d0b906101906157d2565b613d69565b612d36610113612d218660c8615917565b612d2c9060456157d2565b612d0b9190615a39565b604051602001612d4893929190614bd3565b60408051808303601f190181529190526101c085015281612d6881615a0a565b925050612cc7565b6101c0840151610120840151612d8890600290615a39565b15612dac57604051806040016040528060018152602001602d60f81b815250612dbd565b604051806020016040528060008152505b604051602001612dce929190614c7d565b60408051808303601f190181529190526101c08501525b8251612df390600190615975565b612dfe906005615917565b9150612e5b6301000000612e13600a85615a39565b612e2190630100000061586f565b88612e2d600a87615818565b60138110612e3d57612e3d615aac565b6020020151612e4c9190615818565b612e569190615a39565b613e98565b85528251612e6b90600190615975565b612e76906005615917565b612e819060016157d2565b9150612e966301000000612e13600a85615a39565b60208601528251612ea990600190615975565b612eb4906005615917565b612ebf9060026157d2565b9150612ed46301000000612e13600a85615a39565b60808601528251612ee790600190615975565b612ef2906005615917565b612efd9060036157d2565b9150612f126301000000612e13600a85615a39565b60608601528251612f2590600190615975565b612f30906005615917565b612f3b9060046157d2565b9150612f506301000000612e13600a85615a39565b60408087019190915280516101408101909152610115808252615bc9602083013984526040805160608101909152602a808252615b7760208301398460016020020181905250604051806060016040528060288152602001615ba1602891396040850152612fd160018460085b6020020151612fcc9190615975565b613f90565b604051602001612fe19190615255565b60408051808303601f1901815291905260608501526130036001846008612fbd565b6101c085015160405161301a929190602001615159565b60408051808303601f1901815291905260808501526020830151613057906001906130469060006157d2565b6130509190615975565b600161096a565b60405160200161306791906155b3565b60408051601f198184030181529190528460056020020152613097600184600260200201516130469060096157d2565b6040516020016130a79190615659565b60408051808303601f1901815291905260c085015260608301516130d39060019061304690600b6157d2565b6040516020016130e39190615504565b60408051808303601f1901815291905260e085015260808301516131209060019061310f90600b6157d2565b6131199190615975565b600261096a565b60405160200161313091906153a6565b60408051808303601f1901815291905261010085015260e083015161315d906001906130469060196157d2565b60405160200161316d9190615455565b60408051808303601f1901815291905261012085015260c0830151600310156131a557604051806020016040528060008152506131bf565b6040518060c0016040528060888152602001615aef608891395b6040516020016131cf9190614dbc565b60408051601f1981840301815291905284600a6020020152613243600184600381600660200201511115613204576005613207565b60065b60ff16600c811061321a5761321a615aac565b602002015160c08601516003101561323357600d613236565b60165b60ff1661304691906157d2565b6040516020016132539190615618565b60408051808303601f1901815291905261016085015260c08301516003106132e857845160c08401516132999060019061328e906002615917565b61304690601a6157d2565b865160c08601516132ba906132af906002615917565b61305090601a6157d2565b6040516020016132cd9493929190614e38565b60408051808303601f19018152919052610180850152613308565b6040518060600160405280603c8152602001615f16603c91396101808501525b6040518061018001604052806101598152602001615d0861015991396101a08501528351608086015160208087015160608901516040808a01519051600096613358969095909493929101614a08565b60408051808303601f19018152908290526080808901516060808a0151908b0151928a01519395506133939486949293919290602001614a08565b60408051808303601f190181528282529088015160a088015160c08901519294506133c49385938391602001614a08565b60408051808303601f190181528282529088015160e08801516101008901519294506133f69385938391602001614a08565b60408051808303601f19018152828252908801516101208801516101408901519294506134299385938391602001614a08565b60408051808303601f19018152828252908801516101608801516101808901516101a08a015193955061346194869490602001614a08565b60408051601f19818403018152606083019091526022808352909250615e61602083013985526134988460015b6020020151613d69565b85600160200201819052506040518060600160405280602a8152602001615cde602a913960408601526134cc84600061348e565b606080870191909152604080519182019052602a808252615f726020830139608080870191909152840151606085015161354b919061350c90600a615917565b604087015161351c906064615917565b60e088015161352d906103e8615917565b61353791906157d2565b61354191906157d2565b612d0b91906157d2565b60a086015260c084015160031061358f576040518060600160405280602a8152602001615ec3602a913960c086015261358584600661348e565b60e08601526135be565b604051806060016040528060298152602001615eed6029913960c08601526135b884600561348e565b60e08601525b604051806060016040528060268152602001615f9c602691396101008601526135e884600861348e565b856009602002015260078460096020020151116136385761012085015161361085600961348e565b604051602001613621929190614b68565b60408051808303601f190181529190526101208601525b604080518082018252600481526322207d5d60e01b6020808301919091526101408801919091528651878201518884015160608a015160808b015160a08c0151965160009761368997909101614a73565b60408051808303601f190181529082905260c088015160e08901516101008a01516101208b01516101408c01519496506136c895879590602001614a73565b6040516020818303038152906040529050600061370d826136e88561403f565b6040516020016136f992919061504e565b60405160208183030381529060405261403f565b9050806040516020016137209190615210565b60408051601f198184030181529190529b9a5050505050505050505050565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b336137766126d1565b6001600160a01b03161461379c5760405162461bcd60e51b81526004016105479061574c565b6001600160a01b0381166138015760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610547565b61094c81613ce4565b80546001019055565b60006001600160e01b0319821663780e9d6360e01b14806104475750610447826141a5565b6000908152600260205260409020546001600160a01b0316151590565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061388a8261259a565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006138ce82613838565b61392f5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610547565b600061393a8361259a565b9050806001600160a01b0316846001600160a01b031614806139755750836001600160a01b031661396a846104df565b6001600160a01b0316145b806139855750613985818561373f565b949350505050565b826001600160a01b03166139a08261259a565b6001600160a01b031614613a085760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610547565b6001600160a01b038216613a6a5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610547565b613a758383836141f5565b613a80600082613855565b6001600160a01b0383166000908152600360205260408120805460019290613aa9908490615975565b90915550506001600160a01b0382166000908152600360205260408120805460019290613ad79084906157d2565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000613b4482846157d2565b9392505050565b6000613b448284615917565b6108a0828260405180602001604052806000815250614200565b606081613b955750506040805180820190915260018152600360fc1b602082015290565b600080831215613bad57613ba883615a4d565b613baf565b825b905060005b8115613bda5780613bc481615a0a565b9150613bd39050600a836157ea565b9150613bb4565b6000841215613bf15780613bed81615a0a565b9150505b60008167ffffffffffffffff811115613c0c57613c0c615ac2565b6040519080825280601f01601f191660200182016040528015613c36576020820181803683370190505b5090506000851215613c7d57613c4b85615a4d565b9450602d60f81b81600081518110613c6557613c65615aac565b60200101906001600160f81b031916908160001a9053505b841561398557613c8e600183615975565b9150613c9b600a86615a25565b613ca69060306157d2565b60f81b818381518110613cbb57613cbb615aac565b60200101906001600160f81b031916908160001a905350613cdd600a866157ea565b9450613c7d565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b613d4184848461398d565b613d4d84848484614233565b6127e25760405162461bcd60e51b8152600401610547906156fa565b606081613d8d5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115613db75780613da181615a0a565b9150613db09050600a83615818565b9150613d91565b60008167ffffffffffffffff811115613dd257613dd2615ac2565b6040519080825280601f01601f191660200182016040528015613dfc576020820181803683370190505b5090505b841561398557613e11600183615975565b9150613e1e600a86615a39565b613e299060306157d2565b60f81b818381518110613e3e57613e3e615aac565b60200101906001600160f81b031916908160001a905350613e60600a86615818565b9450613e00565b600081604051602001613e7a91906149ec565b60408051601f19818403018152919052805160209091012092915050565b6040805180820190915260068082526503030303030360d41b60208301526060915b8115613b4457600a613ecd601086615a39565b1015613f2457613ede601085615a39565b613ee99060306157d2565b60f81b81613ef8600185615975565b81518110613f0857613f08615aac565b60200101906001600160f81b031916908160001a905350613f71565b613f2f601085615a39565b613f3a9060376157d2565b60f81b81613f49600185615975565b81518110613f5957613f59615aac565b60200101906001600160f81b031916908160001a9053505b613f7c601085615818565b935081613f88816159b8565b925050613eba565b60607607a83bed064745656509338218136736845df65e9e517e8215613fd357613fbb836003615917565b613fc690606461586f565b613fd09082615818565b90505b613ff96064613fe461271084615818565b613fee9190615a39565b612d0b90600a615917565b6140086064613fe48185615818565b614016613fee606485615a39565b60405160200161402893929190614d35565b604051602081830303815290604052915050919050565b80516060908061405f575050604080516020810190915260008152919050565b6000600361406e8360026157d2565b6140789190615818565b614083906004615917565b905060006140928260206157d2565b67ffffffffffffffff8111156140aa576140aa615ac2565b6040519080825280601f01601f1916602001820160405280156140d4576020820181803683370190505b5090506000604051806060016040528060408152602001615e83604091399050600181016020830160005b86811015614160576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b8352600490920191016140ff565b50600386066001811461417a576002811461418b57614197565b613d3d60f01b600119830152614197565b603d60f81b6000198301525b505050918152949350505050565b60006001600160e01b031982166380ac58cd60e01b14806141d657506001600160e01b03198216635b5e139f60e01b145b8061044757506301ffc9a760e01b6001600160e01b0319831614610447565b610678838383614340565b61420a83836143f8565b6142176000848484614233565b6106785760405162461bcd60e51b8152600401610547906156fa565b60006001600160a01b0384163b1561433557604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906142779033908990889088906004016156aa565b602060405180830381600087803b15801561429157600080fd5b505af19250505080156142c1575060408051601f3d908101601f191682019092526142be9181019061494c565b60015b61431b573d8080156142ef576040519150601f19603f3d011682016040523d82523d6000602084013e6142f4565b606091505b5080516143135760405162461bcd60e51b8152600401610547906156fa565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050613985565b506001949350505050565b6001600160a01b03831661439b5761439681600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b6143be565b816001600160a01b0316836001600160a01b0316146143be576143be8382614537565b6001600160a01b0382166143d557610678816145d4565b826001600160a01b0316826001600160a01b031614610678576106788282614683565b6001600160a01b03821661444e5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610547565b61445781613838565b156144a45760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610547565b6144b0600083836141f5565b6001600160a01b03821660009081526003602052604081208054600192906144d99084906157d2565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000600161454484612611565b61454e9190615975565b6000838152600760205260409020549091508082146145a1576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b6008546000906145e690600190615975565b6000838152600960205260408120546008805493945090928490811061460e5761460e615aac565b90600052602060002001549050806008838154811061462f5761462f615aac565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061466757614667615a96565b6001900381819060005260206000200160009055905550505050565b600061468e83612611565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6040518061026001604052806013906020820280368337509192915050565b6040518060a001604052806005905b60608152602001906001900390816146f55790505090565b604080516101e0810190915260608152600e602082016146f5565b604051806101800160405280600c906020820280368337509192915050565b80356001600160a01b038116811461475e57600080fd5b919050565b60006020828403121561477557600080fd5b613b4482614747565b6000806040838503121561479157600080fd5b61479a83614747565b91506147a860208401614747565b90509250929050565b6000806000606084860312156147c657600080fd5b6147cf84614747565b92506147dd60208501614747565b9150604084013590509250925092565b6000806000806080858703121561480357600080fd5b61480c85614747565b935061481a60208601614747565b925060408501359150606085013567ffffffffffffffff8082111561483e57600080fd5b818701915087601f83011261485257600080fd5b81358181111561486457614864615ac2565b604051601f8201601f19908116603f0116810190838211818310171561488c5761488c615ac2565b816040528281528a60208487010111156148a557600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b600080604083850312156148dc57600080fd5b6148e583614747565b9150602083013580151581146148fa57600080fd5b809150509250929050565b6000806040838503121561491857600080fd5b61492183614747565b946020939093013593505050565b60006020828403121561494157600080fd5b8135613b4481615ad8565b60006020828403121561495e57600080fd5b8151613b4481615ad8565b60006020828403121561497b57600080fd5b5035919050565b6000806040838503121561499557600080fd5b50508035926020909101359150565b600081518084526149bc81602086016020860161598c565b601f01601f19169290920160200192915050565b600081516149e281856020860161598c565b9290920192915050565b600082516149fe81846020870161598c565b9190910192915050565b60008651614a1a818460208b0161598c565b865190830190614a2e818360208b0161598c565b8651910190614a41818360208a0161598c565b8551910190614a5481836020890161598c565b8451910190614a6781836020880161598c565b01979650505050505050565b600087516020614a868285838d0161598c565b885191840191614a998184848d0161598c565b8851920191614aab8184848c0161598c565b8751920191614abd8184848b0161598c565b8651920191614acf8184848a0161598c565b8551920191614ae1818484890161598c565b919091019998505050505050505050565b60008351614b0481846020880161598c565b835190830190614b1881836020880161598c565b600b60fa1b9101908152600101949350505050565b60008351614b3f81846020880161598c565b835190830190614b5381836020880161598c565b600160fd1b9101908152600101949350505050565b60008351614b7a81846020880161598c565b80830190507f22207d2c207b202274726169745f74797065223a20224d6574656f72222c20228152683b30b63ab2911d101160b91b60208201528351614bc781602984016020880161598c565b01602901949350505050565b60008451614be581846020890161598c565b80830190507f3c636972636c65206f7061636974793d22302e34222066696c6c3d2223464646815268231ca2911031bc1e9160b91b60208201528451614c3281602984016020890161598c565b66222063793d222d60c81b602992909101918201528351614c5a81603084016020880161598c565b681110391e911a11179f60b91b6030929091019182015260390195945050505050565b621e339f60e91b815260008351614c9b81600385016020880161598c565b80830190507f3c616e696d6174654d6f74696f6e20706174683d224d20302030206c2000000060038201528351614cd981602084016020880161598c565b7f3130303030203130303030203230205a22206475723d22323073222072657065602092909101918201527f6174436f756e743d22696e646566696e69746522202f3e203c2f673e000000006040820152605c01949350505050565b6331bc1e9160e11b81528351600090614d5581600485016020890161598c565b65111031bc9e9160d11b6004918401918201528451614d7b81600a84016020890161598c565b641110391e9160d91b600a92909101918201528351614da181600f84016020880161598c565b601160f91b600f929091019182015260100195945050505050565b7f222077696474683d223130303022206865696768743d2231313030223e000000815260008251614df481601d85016020870161598c565b7f3c2f726563743e3c67206f7061636974793d2230223e203c706f6c79676f6e20601d9390910192830152506666696c6c3d222360c81b603d820152604401919050565b6f3c706f6c79676f6e2066696c6c3d222360801b81528451600090614e64816010850160208a0161598c565b6911103837b4b73a399e9160b11b6010918401918201528551614e8e81601a840160208a0161598c565b7f223e203c616e696d617465206174747269627574654e616d653d226f70616369601a92909101918201527f7479222076616c7565733d22313b313b313b313b303b313b313b313b313b313b603a8201527f313b313b313b313b313b313b313b313b313b313b3122206475723d2233732220605a8201527f726570656174436f756e743d22696e646566696e6974652220626567696e3d22607a8201527f307322202f3e203c2f706f6c79676f6e3e203c706f6c79676f6e2066696c6c3d609a82015261222360f01b60ba820152615043614f8e614f88614f7260bc8501896149d0565b6911103837b4b73a399e9160b11b8152600a0190565b866149d0565b7f223e203c616e696d617465206174747269627574654e616d653d226f7061636981527f7479222076616c7565733d22313b313b313b313b303b313b313b313b313b313b60208201527f313b313b313b313b313b313b313b313b313b313b3122206475723d223373222060408201527f726570656174436f756e743d22696e646566696e6974652220626567696e3d2260608201527018399110179f101e17b837b63cb3b7b71f60791b608082015260910190565b979650505050505050565b7f7b226e616d65223a20224d797374696320466f72657374222c2022646573637281527f697074696f6e223a20224d797374696320466f72657374202d20696e7465726160208201527f63746976652067616d652c20636f6d706c6574656c792067656e6572617465646040820152761027b721b430b4b711161130ba3a3934b13aba32b9911d60491b6060820152600083516150f281607785016020880161598c565b7f2c2022696d616765223a2022646174613a696d6167652f7376672b786d6c3b6260779184019182015265185cd94d8d0b60d21b6097820152835161513e81609d84016020880161598c565b61227d60f01b609d9290910191820152609f01949350505050565b7f222f3e203c2f72616469616c4772616469656e743e203c636972636c65206f7081527f61636974793d22302e39222066696c6c3d2275726c28235329222000000000006020820152600083516151b781603b85016020880161598c565b620179f160ed1b603b9184019182015283516151da81603e84016020880161598c565b7f3c706f6c79676f6e206f7061636974793d22302e3134222066696c6c3d222300603e9290910191820152605d01949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161524881601d85016020870161598c565b91909101601d0192915050565b7f222f3e203c2f6c696e6561724772616469656e743e203c726563742066696c6c81527f3d2275726c28234229222077696474683d223130303022206865696768743d2260208201527f31303030222f3e203c72616469616c4772616469656e742069643d22532220006040820152600082516152d981605f85016020870161598c565b7f206772616469656e74556e6974733d227573657253706163654f6e557365223e605f9390910192830152507f203c73746f70206f66667365743d22302e373522207374796c653d2273746f70607f8201527f2d636f6c6f723a23464646463945222f3e203c73746f70206f66667365743d22609f820152753122207374796c653d2273746f702d636f6c6f723a2360501b60bf82015260d501919050565b65119bdc995cdd60d21b81526000825161539981600685016020870161598c565b9190910160060192915050565b6911103837b4b73a399e9160b11b815281516000906153cc81600a85016020870161598c565b600080516020615f52833981519152600a9390910192830152507f3135203139206c203133203134205a22206475723d2231377322207265706561602a8201527f74436f756e743d22696e646566696e69746522202f3e203c2f706f6c79676f6e604a820152713e203c706f6c79676f6e2066696c6c3d222360701b606a820152607c01919050565b6911103837b4b73a399e9160b11b8152815160009061547b81600a85016020870161598c565b600080516020615f52833981519152600a9390910192830152507f313020305a22206475723d223136732220726570656174436f756e743d22696e602a8201527f646566696e69746522202f3e203c2f706f6c79676f6e3e20203c72656374206f604a820152717061636974793d2230222066696c6c3d222360701b606a820152607c01919050565b6911103837b4b73a399e9160b11b8152815160009061552a81600a85016020870161598c565b600080516020615f52833981519152600a9390910192830152507f3135203230206c203132203135205a22206475723d2231397322207265706561602a8201527f74436f756e743d22696e646566696e69746522202f3e203c2f706f6c79676f6e604a820152713e203c706f6c79676f6e2066696c6c3d222360701b606a820152607c01919050565b6911103837b4b73a399e9160b11b815281516000906155d981600a85016020870161598c565b7f222f3e203c706f6c79676f6e206f7061636974793d22302e36222066696c6c3d600a93909101928301525061222360f01b602a820152602c01919050565b6911103837b4b73a399e9160b11b8152815160009061563e81600a85016020870161598c565b63011179f160e51b600a939091019283015250600e01919050565b6911103837b4b73a399e9160b11b8152815160009061567f81600a85016020870161598c565b73222f3e203c706f6c79676f6e2066696c6c3d222360601b600a939091019283015250601e01919050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906156dd908301846149a4565b9695505050505050565b602081526000613b4460208301846149a4565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b600082198211156157e5576157e5615a6a565b500190565b6000826157f9576157f9615a80565b600160ff1b82146000198414161561581357615813615a6a565b500590565b60008261582757615827615a80565b500490565b600181815b8085111561586757816000190482111561584d5761584d615a6a565b8085161561585a57918102915b93841c9390800290615831565b509250929050565b6000613b44838360008261588557506001610447565b8161589257506000610447565b81600181146158a857600281146158b2576158ce565b6001915050610447565b60ff8411156158c3576158c3615a6a565b50506001821b610447565b5060208310610133831016604e8410600b84101617156158f1575081810a610447565b6158fb838361582c565b806000190482111561590f5761590f615a6a565b029392505050565b600081600019048311821515161561593157615931615a6a565b500290565b60008083128015600160ff1b85018412161561595457615954615a6a565b6001600160ff1b038401831381161561596f5761596f615a6a565b50500390565b60008282101561598757615987615a6a565b500390565b60005b838110156159a757818101518382015260200161598f565b838111156127e25750506000910152565b6000816159c7576159c7615a6a565b506000190190565b600181811c908216806159e357607f821691505b60208210811415615a0457634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415615a1e57615a1e615a6a565b5060010190565b600082615a3457615a34615a80565b500790565b600082615a4857615a48615a80565b500690565b6000600160ff1b821415615a6357615a63615a6a565b5060000390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b03198116811461094c57600080fdfe3c616e696d617465206174747269627574654e616d653d226f706163697479222076616c7565733d22303b2e333b2e333b2e343b2e333b2e333b3022206475723d223130732220726570656174436f756e743d22312220626567696e3d226d6f6e737465722e656e642d31302220726573746172743d227768656e4e6f7441637469766522202f3e222f3e203c73746f70206f66667365743d22302e3522207374796c653d2273746f702d636f6c6f723a23222f3e203c73746f70206f66667365743d223122207374796c653d2273746f702d636f6c6f723a233c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d227574662d38223f3e203c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f7376672220783d223070782220793d22307078222077696474683d2231303030707822206865696768743d22313030307078222076696577426f783d2230203020313030302031303030223e203c6c696e6561724772616469656e742069643d224222206772616469656e74556e6974733d227573657253706163654f6e557365222078313d22353030222079313d2231303030222078323d22353030222079323d2230223e203c73746f70206f66667365743d223022207374796c653d2273746f702d636f6c6f723a2322207d2c207b202274726169745f74797065223a202250616c65747465222c202276616c7565223a20223c616e696d617465206174747269627574654e616d653d226f706163697479222069643d226d6f6e73746572222076616c7565733d22303b313b313b313b313b3022206475723d223130732220726570656174436f756e743d22312220626567696e3d22636c69636b2220726573746172743d227768656e4e6f7441637469766522202f3e3c616e696d617465206174747269627574654e616d653d226f706163697479222076616c7565733d22303b313b303b303b303b303b303b3022206475723d223630732220726570656174436f756e743d22696e646566696e6974652220626567696e3d223330732220656e643d226d6f6e737465722e7374617274222f3e203c616e696d6174654d6f74696f6e20706174683d224d20302030206c2030202d31355a22206475723d223330732220726570656174436f756e743d22696e646566696e69746522202f3e203c2f673e3c2f7376673e5b7b202274726169745f74797065223a2022466172222c202276616c7565223a20224142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f22207d2c207b202274726169745f74797065223a20224d6f6e73746572222c202276616c7565223a202222207d2c207b202274726169745f74797065223a2022416e696d616c222c202276616c7565223a20223c72656374206f7061636974793d22302220783d223235302220793d22323530222077696474683d2235303022206865696768743d22353030222f3e223e203c616e696d6174654d6f74696f6e20706174683d224d20302030206c2022207d2c207b202274726169745f74797065223a2022536176616e6e61222c202276616c7565223a202222207d2c207b202274726169745f74797065223a202253756e222c202276616c7565223a2022a26469706673582212205e3aef1e70f659889240519774f4f261268438514c37a075020cfd2040c31c0e64736f6c63430008070033
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.