ETH Price: $3,621.75 (+9.00%)

Contract

0xeE62411c55e8057Df2bdb956b67Eae23141CF274
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Approve210802352024-10-30 18:27:1128 days ago1730312831IN
0xeE62411c...3141CF274
0 ETH0.0007110715.21186775
Approve210237542024-10-22 21:18:2335 days ago1729631903IN
0xeE62411c...3141CF274
0 ETH0.000456419.76392374
Approve210117102024-10-21 4:57:4737 days ago1729486667IN
0xeE62411c...3141CF274
0 ETH0.000143795.88376329
Safe Transfer Fr...209973992024-10-19 5:02:5939 days ago1729314179IN
0xeE62411c...3141CF274
0 ETH0.00070758.77912292
Safe Transfer Fr...209973952024-10-19 5:02:1139 days ago1729314131IN
0xeE62411c...3141CF274
0 ETH0.001287829.5
Approve209179632024-10-08 2:47:2350 days ago1728355643IN
0xeE62411c...3141CF274
0 ETH0.00024559.14513349
Approve209179612024-10-08 2:46:5950 days ago1728355619IN
0xeE62411c...3141CF274
0 ETH0.000428879.17487736
Approve208954912024-10-04 23:36:4753 days ago1728085007IN
0xeE62411c...3141CF274
0 ETH0.00014523.10632791
Set Approval For...208801612024-10-02 20:19:3556 days ago1727900375IN
0xeE62411c...3141CF274
0 ETH0.0007492116.20198783
Set Approval For...206740012024-09-04 1:42:1184 days ago1725414131IN
0xeE62411c...3141CF274
0 ETH0.000232855.04472989
Set Approval For...206717672024-09-03 18:12:5985 days ago1725387179IN
0xeE62411c...3141CF274
0 ETH0.000085181.84206414
Approve206296512024-08-28 21:03:4790 days ago1724879027IN
0xeE62411c...3141CF274
0 ETH0.000216074.62238853
Approve206224252024-08-27 20:50:5991 days ago1724791859IN
0xeE62411c...3141CF274
0 ETH0.000121692.6
Approve203896012024-07-26 8:42:35124 days ago1721983355IN
0xeE62411c...3141CF274
0 ETH0.000110392.36170459
Set Approval For...203451222024-07-20 3:41:47130 days ago1721446907IN
0xeE62411c...3141CF274
0 ETH0.000101792.20533958
Set Approval For...203451212024-07-20 3:41:35130 days ago1721446895IN
0xeE62411c...3141CF274
0 ETH0.000104012.24934404
Approve202829662024-07-11 11:28:35139 days ago1720697315IN
0xeE62411c...3141CF274
0 ETH0.000088183.60823142
Approve202533012024-07-07 8:00:11143 days ago1720339211IN
0xeE62411c...3141CF274
0 ETH0.000108262.3161457
Approve201303142024-06-20 3:39:11160 days ago1718854751IN
0xeE62411c...3141CF274
0 ETH0.00026335.62564616
Approve201133572024-06-17 18:41:23163 days ago1718649683IN
0xeE62411c...3141CF274
0 ETH0.0008659418.52480329
Approve201108012024-06-17 10:06:35163 days ago1718618795IN
0xeE62411c...3141CF274
0 ETH0.000308926.60874099
Collect All Trad...200411322024-06-07 16:25:59173 days ago1717777559IN
0xeE62411c...3141CF274
0 ETH0.0764766623.7120688
Approve200336572024-06-06 15:23:47174 days ago1717687427IN
0xeE62411c...3141CF274
0 ETH0.0011934425.53092651
Approve199693192024-05-28 15:39:59183 days ago1716910799IN
0xeE62411c...3141CF274
0 ETH0.0005724621.2774145
Approve199693172024-05-28 15:39:35183 days ago1716910775IN
0xeE62411c...3141CF274
0 ETH0.00098721.08750169
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
192647142024-02-19 22:22:11281 days ago1708381331
0xeE62411c...3141CF274
0.2 ETH
192647142024-02-19 22:22:11281 days ago1708381331
0xeE62411c...3141CF274
0.1 ETH
192647142024-02-19 22:22:11281 days ago1708381331
0xeE62411c...3141CF274
0.3 ETH
192647142024-02-19 22:22:11281 days ago1708381331
0xeE62411c...3141CF274
1 ETH
192647142024-02-19 22:22:11281 days ago1708381331
0xeE62411c...3141CF274
0.1 ETH
192647132024-02-19 22:21:59281 days ago1708381319
0xeE62411c...3141CF274
0.1 ETH
192647132024-02-19 22:21:59281 days ago1708381319
0xeE62411c...3141CF274
5 ETH
192647132024-02-19 22:21:59281 days ago1708381319
0xeE62411c...3141CF274
5 ETH
192647122024-02-19 22:21:47281 days ago1708381307
0xeE62411c...3141CF274
5 ETH
192647122024-02-19 22:21:47281 days ago1708381307
0xeE62411c...3141CF274
0.2 ETH
192647122024-02-19 22:21:47281 days ago1708381307
0xeE62411c...3141CF274
0.2 ETH
192647122024-02-19 22:21:47281 days ago1708381307
0xeE62411c...3141CF274
0.3 ETH
192647112024-02-19 22:21:35281 days ago1708381295
0xeE62411c...3141CF274
0.1 ETH
192647112024-02-19 22:21:35281 days ago1708381295
0xeE62411c...3141CF274
0.1 ETH
192647112024-02-19 22:21:35281 days ago1708381295
0xeE62411c...3141CF274
1 ETH
192647112024-02-19 22:21:35281 days ago1708381295
0xeE62411c...3141CF274
1 ETH
192647112024-02-19 22:21:35281 days ago1708381295
0xeE62411c...3141CF274
0.1 ETH
192647112024-02-19 22:21:35281 days ago1708381295
0xeE62411c...3141CF274
0.1 ETH
192647112024-02-19 22:21:35281 days ago1708381295
0xeE62411c...3141CF274
0.4 ETH
192647102024-02-19 22:21:23281 days ago1708381283
0xeE62411c...3141CF274
0.5 ETH
192647102024-02-19 22:21:23281 days ago1708381283
0xeE62411c...3141CF274
1.5 ETH
192647102024-02-19 22:21:23281 days ago1708381283
0xeE62411c...3141CF274
0.1 ETH
192647102024-02-19 22:21:23281 days ago1708381283
0xeE62411c...3141CF274
0.1 ETH
192647102024-02-19 22:21:23281 days ago1708381283
0xeE62411c...3141CF274
0.1 ETH
192647092024-02-19 22:21:11281 days ago1708381271
0xeE62411c...3141CF274
0.2 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Automatons

Compiler Version
v0.8.24+commit.e11b9ed9

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 3 : Automatons.sol
//
// Automatons xNFT (AUTO)
// The first collection to use the xNFT hybrid standard.
// Created by the CellMates team.
//
// - 4096 total supply
// - 3 LPs created on deployment:
//  - 256 AUTO + 4 ETH v2 liquidity
//  - 256 AUTO + 0 wCELL v3 single sided LP
//  - 1280 AUTO + 0 ETH v3 single sided LP
// - 1792 AUTO free airdrop claim for CELL/wCELL holders
// - 512 AUTO @ 0.1 ETH public mint from contract price
// - sellable on both Uniswap and Opensea
// - fully on-chain artwork based on cellular automata
//
// https://auto.cellmates.io
// https://discord.com/invite/cellmates
// https://twitter.com/CellMatesERC
//

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "./xNFT.sol";
import "./Metadata.sol";

interface RouterV2 {
	function factory() external pure returns (address);
	function addLiquidityETH(address, uint256, uint256, uint256, address, uint256) external payable returns (uint256, uint256, uint256);
}

interface FactoryV2 {
	function createPair(address, address) external returns (address);
}

interface PairV2 {
	function sync() external;
}

interface RouterV3 {
	function factory() external view returns (address);
	function positionManager() external view returns (address);
	function WETH9() external view returns (address);
}

interface FactoryV3 {
	function createPool(address _tokenA, address _tokenB, uint24 _fee) external returns (address);
}

interface PoolV3 {
	function slot0() external view returns (uint160, int24, uint16, uint16, uint16, uint8, bool);
	function initialize(uint160 _sqrtPriceX96) external;
}

interface PositionManager {
	struct MintParams {
		address token0;
		address token1;
		uint24 fee;
		int24 tickLower;
		int24 tickUpper;
		uint256 amount0Desired;
		uint256 amount1Desired;
		uint256 amount0Min;
		uint256 amount1Min;
		address recipient;
		uint256 deadline;
	}
	struct CollectParams {
		uint256 tokenId;
		address recipient;
		uint128 amount0Max;
		uint128 amount1Max;
	}
	function mint(MintParams calldata) external payable returns (uint256 tokenId, uint128 liquidity, uint256 amount0, uint256 amount1);
	function collect(CollectParams calldata) external payable returns (uint256 amount0, uint256 amount1);
}

interface ERC20 {
	function balanceOf(address) external view returns (uint256);
	function transfer(address, uint256) external returns (bool);
}

interface IWETH is ERC20 {
	function withdraw(uint256) external;
}


contract Team {

	RouterV3 constant private ROUTER = RouterV3(0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45);
	ERC20 constant private WCELL = ERC20(0x18E5F92103d1B34623738Ee79214B1659f2eE109);

	struct Share {
		address payable user;
		uint256 shares;
	}
	Share[] public shares;
	uint256 public totalShares;
	ERC20 immutable public token;


	constructor() {
		token = ERC20(msg.sender);
		_addShare(0xFaDED72464D6e76e37300B467673b36ECc4d2ccF, 4);
		_addShare(0xEC513e5959dBB02F314fc2F30041FCA2685119F3, 1);
	}

	receive() external payable {}

	function withdrawETH() public {
		uint256 _balance = address(this).balance;
		if (_balance > 0) {
			for (uint256 i = 0; i < shares.length; i++) {
				Share memory _share = shares[i];
				!_share.user.send(_balance * _share.shares / totalShares);
			}
		}
	}

	function withdrawToken(ERC20 _token) public {
		IWETH _weth = IWETH(ROUTER.WETH9());
		if (address(_token) == address(_weth)) {
			_weth.withdraw(_weth.balanceOf(address(this)));
			withdrawETH();
		} else {
			uint256 _balance = _token.balanceOf(address(this));
			if (_balance > 0) {
				if (_token == token) {
					_token.transfer(shares[0].user, _balance);
				} else {
					for (uint256 i = 0; i < shares.length; i++) {
						Share memory _share = shares[i];
						_token.transfer(_share.user, _balance * _share.shares / totalShares);
					}
				}
			}
		}
	}

	function withdrawWETH() public {
		withdrawToken(ERC20(ROUTER.WETH9()));
	}

	function withdrawFees() external {
		withdrawWETH();
		withdrawToken(WCELL);
		withdrawToken(token);
	}


	function _addShare(address _user, uint256 _shares) internal {
		shares.push(Share(payable(_user), _shares));
		totalShares += _shares;
	}
}


contract Automatons is xNFT {

	uint256 constant private TOTAL_SUPPLY = 4096;
	uint256 constant private V2_LIQUIDITY_TOKENS = 256;
	uint256 constant private V3_WCELL_LIQUIDITY_TOKENS = 256;
	uint256 constant private V3_WETH_LIQUIDITY_TOKENS = 1280;
	RouterV2 constant private ROUTER_V2 = RouterV2(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
	RouterV3 constant private ROUTER_V3 = RouterV3(0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45);
	PoolV3 constant private WCELL_POOL_V3 = PoolV3(0x685c401540C103631A0ba7f14A3d16Ae3cB4E50B);
	address constant private WCELL = 0x18E5F92103d1B34623738Ee79214B1659f2eE109;
	uint256 immutable private ETH_WCELL_RATIO;
	uint256 immutable private LP_INITIAL_ETH;
	uint256 constant private LP_UPPER_ETH = 1e8 ether;
	int24 constant private MIN_TICK = -887272;
	int24 constant private MAX_TICK = -MIN_TICK;
	uint160 constant private MIN_SQRT_RATIO = 4295128739;
	uint160 constant private MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;
	uint128 constant private UINT128_MAX = type(uint128).max;
	bytes32 constant private MERKLE_ROOT = 0x3f856c8d1611023aaa9915c692b07293eea0d4dd7c26df3914d5bfbd430ce84c;

	Metadata public metadata;
	Team immutable public team;
	PoolV3 immutable public wcellPoolV3;
	PoolV3 immutable public wethPoolV3;
	uint256 public wcellPositionId;
	uint256 public wethPositionId;
	PairV2 public pairV2;
	bytes32 public salt;
	mapping(address => bool) public hasClaimedAirdrop;
	uint256 public mintable = 512;
	uint256 constant public mintCost = 0.1 ether;

	event Claim(address indexed account, uint256 tokens);


	constructor() xNFT(address(this), TOTAL_SUPPLY) payable {
		require(msg.value > 0);
		info.owner = 0xFaDED72464D6e76e37300B467673b36ECc4d2ccF;
		team = new Team();
		metadata = new Metadata();
		LP_INITIAL_ETH = totalSupply * msg.value / V2_LIQUIDITY_TOKENS;
		address _this = address(this);
		address _weth = ROUTER_V3.WETH9();
		(uint160 _initialSqrtPrice, ) = _getPriceAndTickFromValues(_weth < _this, TOTAL_SUPPLY, LP_INITIAL_ETH);
		wethPoolV3 = PoolV3(FactoryV3(ROUTER_V3.factory()).createPool(_this, _weth, 10000));
		wethPoolV3.initialize(_initialSqrtPrice);
		(uint256 _wcellSqrtPrice, , , , , , ) = WCELL_POOL_V3.slot0();
		ETH_WCELL_RATIO = (_wcellSqrtPrice * _wcellSqrtPrice * 1e18) >> 192;
		(_initialSqrtPrice, ) = _getPriceAndTickFromValues(WCELL < _this, TOTAL_SUPPLY, 1e18 * LP_INITIAL_ETH / ETH_WCELL_RATIO);
		wcellPoolV3 = PoolV3(FactoryV3(ROUTER_V3.factory()).createPool(_this, WCELL, 10000));
		wcellPoolV3.initialize(_initialSqrtPrice);
		salt = keccak256(abi.encodePacked("Salt:", blockhash(block.number - 1)));
	}

	function setMetadata(Metadata _metadata) external _onlyOwner {
		metadata = _metadata;
	}


	function initialize() external _withoutEventEmits {
		require(address(pairV2) == address(0x0));
		address _this = address(this);
		address _weth = ROUTER_V3.WETH9();
		_approveERC20(_this, address(ROUTER_V2), V2_LIQUIDITY_TOKENS);
		pairV2 = PairV2(FactoryV2(ROUTER_V2.factory()).createPair(_weth, _this));
		ROUTER_V2.addLiquidityETH{value:_this.balance}(_this, V2_LIQUIDITY_TOKENS, 0, 0, owner(), block.timestamp);
		PositionManager _pm = PositionManager(ROUTER_V3.positionManager());
		_approveERC20(_this, address(_pm), V3_WCELL_LIQUIDITY_TOKENS + V3_WETH_LIQUIDITY_TOKENS);
		bool _weth0 = _weth < _this;
		( , int24 _minTick) = _getPriceAndTickFromValues(_weth0, TOTAL_SUPPLY, LP_INITIAL_ETH);
		( , int24 _maxTick) = _getPriceAndTickFromValues(_weth0, TOTAL_SUPPLY, LP_UPPER_ETH);
		(wethPositionId, , , ) = _pm.mint(PositionManager.MintParams({
			token0: _weth0 ? _weth : _this,
			token1: !_weth0 ? _weth : _this,
			fee: 10000,
			tickLower: _weth0 ? _maxTick : _minTick,
			tickUpper: !_weth0 ? _maxTick : _minTick,
			amount0Desired: _weth0 ? 0 : V3_WETH_LIQUIDITY_TOKENS,
			amount1Desired: !_weth0 ? 0 : V3_WETH_LIQUIDITY_TOKENS,
			amount0Min: 0,
			amount1Min: 0,
			recipient: _this,
			deadline: block.timestamp
		}));
		_weth0 = WCELL < _this;
		( , _minTick) = _getPriceAndTickFromValues(_weth0, TOTAL_SUPPLY, 1e18 * LP_INITIAL_ETH / ETH_WCELL_RATIO);
		( , _maxTick) = _getPriceAndTickFromValues(_weth0, TOTAL_SUPPLY, 1e18 * LP_UPPER_ETH / ETH_WCELL_RATIO);
		(wcellPositionId, , , ) = _pm.mint(PositionManager.MintParams({
			token0: _weth0 ? WCELL : _this,
			token1: !_weth0 ? WCELL : _this,
			fee: 10000,
			tickLower: _weth0 ? _maxTick : _minTick,
			tickUpper: !_weth0 ? _maxTick : _minTick,
			amount0Desired: _weth0 ? 0 : V3_WCELL_LIQUIDITY_TOKENS,
			amount1Desired: !_weth0 ? 0 : V3_WCELL_LIQUIDITY_TOKENS,
			amount0Min: 0,
			amount1Min: 0,
			recipient: _this,
			deadline: block.timestamp
		}));
	}

	function collectAllTradingFees() external {
		collectTradingFees(UINT128_MAX, UINT128_MAX, UINT128_MAX, UINT128_MAX);
	}

	function collectTradingFees(uint128 _wethAmount0Max, uint128 _wethAmount1Max, uint128 _wcellAmount0Max, uint128 _wcellAmount1Max) public {
		PositionManager _pm = PositionManager(ROUTER_V3.positionManager());
		_pm.collect(PositionManager.CollectParams({
			tokenId: wethPositionId,
			recipient: address(team),
			amount0Max: _wethAmount0Max,
			amount1Max: _wethAmount1Max
		}));
		_pm.collect(PositionManager.CollectParams({
			tokenId: wcellPositionId,
			recipient: address(team),
			amount0Max: _wcellAmount0Max,
			amount1Max: _wcellAmount1Max
		}));
		team.withdrawFees();
	}

	function claim(address _account, uint256 _tokens, bytes32[] calldata _proof) external {
		require(!hasClaimedAirdrop[_account]);
		require(_verify(_proof, keccak256(abi.encodePacked(_account, _tokens))));
		hasClaimedAirdrop[_account] = true;
		_transferERC20(address(this), _account, _tokens);
		emit Claim(_account, _tokens);
	}

	function mint(uint256 _tokens) external payable {
		require(_tokens <= mintable);
		uint256 _cost = _tokens * mintCost;
		require(msg.value >= _cost);
		mintable -= _tokens;
		_transferERC20(address(this), msg.sender, _tokens);
		payable(team).transfer(_cost);
		if (msg.value > _cost) {
			payable(msg.sender).transfer(msg.value - _cost);
		}
	}


	function name() external override view returns (string memory) {
		return metadata.name();
	}

	function symbol() external override view returns (string memory) {
		return metadata.symbol();
	}

	function tokenURI(uint256 _tokenId) public override view returns (string memory) {
		return metadata.tokenURI(_tokenId);
	}


	function _initialize() internal override _withoutEventEmits {
		super._initialize();
	}


	function _getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {
		unchecked {
			uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));
			require(absTick <= uint256(int256(MAX_TICK)), 'T');

			uint256 ratio = absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000;
			if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;
			if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;
			if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;
			if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;
			if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;
			if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;
			if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;
			if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;
			if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;
			if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;
			if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;
			if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;
			if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;
			if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;
			if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;
			if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;
			if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;
			if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;
			if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;

			if (tick > 0) ratio = type(uint256).max / ratio;

			sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));
		}
	}

	function _getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {
		unchecked {
			require(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO, 'R');
			uint256 ratio = uint256(sqrtPriceX96) << 32;

			uint256 r = ratio;
			uint256 msb = 0;

			assembly {
				let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))
				msb := or(msb, f)
				r := shr(f, r)
			}
			assembly {
				let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))
				msb := or(msb, f)
				r := shr(f, r)
			}
			assembly {
				let f := shl(5, gt(r, 0xFFFFFFFF))
				msb := or(msb, f)
				r := shr(f, r)
			}
			assembly {
				let f := shl(4, gt(r, 0xFFFF))
				msb := or(msb, f)
				r := shr(f, r)
			}
			assembly {
				let f := shl(3, gt(r, 0xFF))
				msb := or(msb, f)
				r := shr(f, r)
			}
			assembly {
				let f := shl(2, gt(r, 0xF))
				msb := or(msb, f)
				r := shr(f, r)
			}
			assembly {
				let f := shl(1, gt(r, 0x3))
				msb := or(msb, f)
				r := shr(f, r)
			}
			assembly {
				let f := gt(r, 0x1)
				msb := or(msb, f)
			}

			if (msb >= 128) r = ratio >> (msb - 127);
			else r = ratio << (127 - msb);

			int256 log_2 = (int256(msb) - 128) << 64;

			assembly {
				r := shr(127, mul(r, r))
				let f := shr(128, r)
				log_2 := or(log_2, shl(63, f))
				r := shr(f, r)
			}
			assembly {
				r := shr(127, mul(r, r))
				let f := shr(128, r)
				log_2 := or(log_2, shl(62, f))
				r := shr(f, r)
			}
			assembly {
				r := shr(127, mul(r, r))
				let f := shr(128, r)
				log_2 := or(log_2, shl(61, f))
				r := shr(f, r)
			}
			assembly {
				r := shr(127, mul(r, r))
				let f := shr(128, r)
				log_2 := or(log_2, shl(60, f))
				r := shr(f, r)
			}
			assembly {
				r := shr(127, mul(r, r))
				let f := shr(128, r)
				log_2 := or(log_2, shl(59, f))
				r := shr(f, r)
			}
			assembly {
				r := shr(127, mul(r, r))
				let f := shr(128, r)
				log_2 := or(log_2, shl(58, f))
				r := shr(f, r)
			}
			assembly {
				r := shr(127, mul(r, r))
				let f := shr(128, r)
				log_2 := or(log_2, shl(57, f))
				r := shr(f, r)
			}
			assembly {
				r := shr(127, mul(r, r))
				let f := shr(128, r)
				log_2 := or(log_2, shl(56, f))
				r := shr(f, r)
			}
			assembly {
				r := shr(127, mul(r, r))
				let f := shr(128, r)
				log_2 := or(log_2, shl(55, f))
				r := shr(f, r)
			}
			assembly {
				r := shr(127, mul(r, r))
				let f := shr(128, r)
				log_2 := or(log_2, shl(54, f))
				r := shr(f, r)
			}
			assembly {
				r := shr(127, mul(r, r))
				let f := shr(128, r)
				log_2 := or(log_2, shl(53, f))
				r := shr(f, r)
			}
			assembly {
				r := shr(127, mul(r, r))
				let f := shr(128, r)
				log_2 := or(log_2, shl(52, f))
				r := shr(f, r)
			}
			assembly {
				r := shr(127, mul(r, r))
				let f := shr(128, r)
				log_2 := or(log_2, shl(51, f))
				r := shr(f, r)
			}
			assembly {
				r := shr(127, mul(r, r))
				let f := shr(128, r)
				log_2 := or(log_2, shl(50, f))
			}

			int256 log_sqrt10001 = log_2 * 255738958999603826347141;

			int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);
			int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);

			tick = tickLow == tickHi ? tickLow : _getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;
		}
	}

	function _sqrt(uint256 _n) internal pure returns (uint256 result) {
		unchecked {
			uint256 _tmp = (_n + 1) / 2;
			result = _n;
			while (_tmp < result) {
				result = _tmp;
				_tmp = (_n / _tmp + _tmp) / 2;
			}
		}
	}

	function _getPriceAndTickFromValues(bool _weth0, uint256 _tokens, uint256 _weth) internal pure returns (uint160 price, int24 tick) {
		uint160 _tmpPrice = uint160(_sqrt(2**192 / (!_weth0 ? _tokens : _weth) * (_weth0 ? _tokens : _weth)));
		tick = _getTickAtSqrtRatio(_tmpPrice);
		tick = tick - (tick % 200);
		price = _getSqrtRatioAtTick(tick);
	}

	function _verify(bytes32[] memory _proof, bytes32 _leaf) internal pure returns (bool) {
		bytes32 _computedHash = _leaf;
		for (uint256 i = 0; i < _proof.length; i++) {
			bytes32 _proofElement = _proof[i];
			if (_computedHash <= _proofElement) {
				_computedHash = keccak256(abi.encodePacked(_computedHash, _proofElement));
			} else {
				_computedHash = keccak256(abi.encodePacked(_proofElement, _computedHash));
			}
		}
		return _computedHash == MERKLE_ROOT;
	}
}


contract Deploy {

	Automatons immutable public automatons;
	address constant private weth = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;

	constructor() payable {
		automatons = new Automatons{ value: msg.value, salt: _findSaltForWETH0() }();
		automatons.initialize();
	}

	function _findSaltForWETH0() internal view returns (bytes32) {
		bytes32 _codehash = keccak256(type(Automatons).creationCode);
		uint256 _salt = 0;
		address _predicted;
		do {
			_salt++;
			_predicted = address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), address(this), bytes32(_salt), _codehash)))));
		} while (_predicted < weth);
		return bytes32(_salt);
	}
}

File 2 of 3 : Metadata.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

interface AUTO {
	function salt() external view returns (bytes32);
}

contract Metadata {
	
	string public name = "Automatons xNFT";
	string public symbol = "AUTO";

	uint256 constant private TARGET_BIT_COUNT = 13;
	string constant private TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

	struct Size {
		uint248 size;
		uint8 chance;
	}
	Size[] private sizes;

	struct Color {
		bytes3 backgroundColor;
		bytes3 foregroundColor;
		uint16 chance;
		string name;
	}
	Color[] private colors;

	struct Reflection {
		uint8 chance;
		string name;
	}
	Reflection[] private reflections;

	AUTO immutable public automatons;


	constructor() {
		automatons = AUTO(msg.sender);

		// sizes
		sizes.push(Size(16, 20));
		sizes.push(Size(32, 200));
		sizes.push(Size(48, 120));
		sizes.push(Size(64, 50));
		sizes.push(Size(96, 10));
		sizes.push(Size(128, 1));
		
		// colors
		colors.push(Color(0xffffff, 0x000000, 3200, "Clean White"));
		colors.push(Color(0x000000, 0xffffff, 800, "Deep Black"));
		colors.push(Color(0x179629, 0x15491f, 100, "Slimy Green"));
		colors.push(Color(0xc9a91c, 0x5f5120, 75, "Pacific Blue"));
		colors.push(Color(0x009fff, 0x144d79, 55, "Orange Peel"));
		colors.push(Color(0x3bb5cf, 0x235763, 35, "Old Gold"));
		colors.push(Color(0x908070, 0x463f38, 25, "Slate Gray"));
		colors.push(Color(0xac8fe6, 0x53466d, 15, "Charm Pink"));
		colors.push(Color(0x2b2ca6, 0x191d52, 10, "Metallic Red"));
		colors.push(Color(0xa95178, 0x522b3d, 5, "Royal Purple"));

		// reflections
		reflections.push(Reflection(40, "None"));
		reflections.push(Reflection(20, "Rotation"));
		reflections.push(Reflection(10, "Single"));
		reflections.push(Reflection(5, "Double"));
	}

	function tokenURI(uint256 _tokenId) external view returns (string memory) {
		unchecked {
			( , , uint256 _size, uint256 _colorIndex, uint256 _reflectionIndex) = getTokenInfo(_tokenId);
			string memory _json = string(abi.encodePacked('{"name":"AUTO #', _uint2str(_tokenId), '","description":"The first collection to use the xNFT hybrid standard. Created by the CellMates team.",'));
			_json = string(abi.encodePacked(_json, '"image":"', svgURI(_tokenId), '","attributes":['));
			_json = string(abi.encodePacked(_json, '{"trait_type":"Size","value":"', _uint2str(_size), '"},'));
			_json = string(abi.encodePacked(_json, '{"trait_type":"Color","value":"', colors[_colorIndex].name, '"},'));
			_json = string(abi.encodePacked(_json, '{"trait_type":"Reflection","value":"', reflections[_reflectionIndex].name, '"}'));
			_json = string(abi.encodePacked(_json, ']}'));
			return string(abi.encodePacked('data:application/json;base64,', _encode(bytes(_json))));
		}
	}

	function svgURI(uint256 _tokenId) public view returns (string memory) {
		return string(abi.encodePacked('data:image/svg+xml;base64,', _encode(bytes(getSVG(_tokenId)))));
	}
	
	function bmpURI(uint256 _tokenId) public view returns (string memory) {
		return string(abi.encodePacked('data:image/bmp;base64,', _encode(getBMP(_tokenId))));
	}

	function getSVG(uint256 _tokenId) public view returns (string memory) {
		( , , , uint256 _colorIndex, ) = getTokenInfo(_tokenId);
		return string(abi.encodePacked('<svg xmlns="http://www.w3.org/2000/svg" version="1.1" preserveAspectRatio="xMidYMid meet" viewBox="0 0 512 512" width="100%" height="100%"><defs><style type="text/css">svg{image-rendering:optimizeSpeed;image-rendering:-moz-crisp-edges;image-rendering:-o-crisp-edges;image-rendering:-webkit-optimize-contrast;image-rendering:pixelated;image-rendering:optimize-contrast;-ms-interpolation-mode:nearest-neighbor;background-color:', _col2str(colors[_colorIndex].backgroundColor), ';background-image:url(', bmpURI(_tokenId), ');background-repeat:no-repeat;background-size:contain;background-position:50% 50%;}</style></defs></svg>'));
	}
	
	function getBMP(uint256 _tokenId) public view returns (bytes memory) {
		(bytes32 _seed, uint32 _rule, uint256 _size, uint256 _colorIndex, uint256 _reflectionIndex) = getTokenInfo(_tokenId);
		return _getBMP(_makePalette(colors[_colorIndex].backgroundColor, colors[_colorIndex].foregroundColor), _convertToColors(_generate(_seed, _rule, _size, _reflectionIndex)), _size + 2 * _getPadding(_size));
	}
	
	function getTokenInfo(uint256 _tokenId) public view returns (bytes32 seed, uint32 rule, uint256 size, uint256 colorIndex, uint256 reflectionIndex) {
		unchecked {
			seed = keccak256(abi.encodePacked("Seed:", _tokenId, automatons.salt()));
			uint256[32] memory _bitIndexes;
			for (uint256 i = 0; i < _bitIndexes.length; i++) {
				_bitIndexes[i] = i;
			}
			for (uint256 i = 0; i < TARGET_BIT_COUNT; i++) {
				uint256 _index = i + uint256(keccak256(abi.encodePacked("Shuffle:", i, seed))) % (_bitIndexes.length - i);
				uint256 tmp = _bitIndexes[_index];
				_bitIndexes[_index] = _bitIndexes[i];
				_bitIndexes[i] = tmp;
			}
			for (uint256 i = 0; i < TARGET_BIT_COUNT; i++) {
				rule |= uint32(1 << _bitIndexes[i]);
			}
			size = _sampleSize(seed);
			colorIndex = _sampleColor(seed);
			reflectionIndex = _sampleReflection(seed);
		}
	}


	function _sampleSize(bytes32 _seed) internal view returns (uint256 size) {
		unchecked {
			uint256 _total = 0;
			for (uint256 i = 0; i < sizes.length; i++) {
				_total += sizes[i].chance;
			}
			uint256 _target = uint256(keccak256(abi.encodePacked("Size:", _seed))) % _total;
			_total = 0;
			for (uint256 i = 0; i < sizes.length; i++) {
				_total += sizes[i].chance;
				if (_target < _total) {
					return sizes[i].size;
				}
			}
		}
	}

	function _sampleColor(bytes32 _seed) internal view returns (uint256 colorIndex) {
		unchecked {
			uint256 _total = 0;
			for (uint256 i = 0; i < colors.length; i++) {
				_total += colors[i].chance;
			}
			uint256 _target = uint256(keccak256(abi.encodePacked("Color:", _seed))) % _total;
			_total = 0;
			for (uint256 i = 0; i < colors.length; i++) {
				_total += colors[i].chance;
				if (_target < _total) {
					return i;
				}
			}
		}
	}

	function _sampleReflection(bytes32 _seed) internal view returns (uint256 reflectionIndex) {
		unchecked {
			uint256 _total = 0;
			for (uint256 i = 0; i < reflections.length; i++) {
				_total += reflections[i].chance;
			}
			uint256 _target = uint256(keccak256(abi.encodePacked("Reflection:", _seed))) % _total;
			_total = 0;
			for (uint256 i = 0; i < reflections.length; i++) {
				_total += reflections[i].chance;
				if (_target < _total) {
					return i;
				}
			}
		}
	}

	function _getPadding(uint256 _size) internal pure returns (uint256) {
		return _size / 8;
	}
	
	function _generate(bytes32 _seed, uint32 _rule, uint256 _size, uint256 _reflectionIndex) internal pure returns (uint8[][] memory state) {
		unchecked {
			uint256 _randomness = uint256(keccak256(abi.encodePacked("State:", _seed)));
			uint256 _xSize = _reflectionIndex == 0 ? _size : _size / 2;
			uint256 _ySize = _reflectionIndex == 3 ? _size / 2 : _size;
			uint256[] memory _rows = new uint256[](_ySize);
			for (uint256 y = 0; y < _ySize; y++) {
				if (y == 0) {
					_rows[y] = _randomness & ((1 << _xSize) - 1);
				} else {
					uint256 _row = 0;
					uint256 _lastRow = _rows[y - 1];
					_lastRow |= _lastRow << _xSize;
					_lastRow <<= 2;
					_lastRow |= (_lastRow >> _xSize) & 3;
					for (uint256 x = 0; x < _xSize; x++) {
						uint8 _config = uint8(_lastRow >> x) & 0x1f;
						_row |= uint256((_rule >> _config) & 1) << x;
					}
					_rows[y] = _row;
				}
			}
			uint256 _padding = _getPadding(_size);
			state = new uint8[][](_size + 2 * _padding);
			for (uint256 y = 0; y < state.length; y++) {
				state[y] = new uint8[](_size + 2 * _padding);
				if (y >= _padding && y < _size + _padding) {
					for (uint256 x = _padding; x < state[y].length - _padding; x++) {
						uint256 _xPos = x - _padding;
						uint256 _yPos = y - _padding;
						if (_reflectionIndex != 0 && x >= _xSize + _padding) {
							_xPos = _size + _padding - x - 1;
							if (_reflectionIndex == 1) {
								_yPos = _size + _padding - y - 1;
							}
						}
						if (_reflectionIndex == 3 && y >= _ySize + _padding) {
							_yPos = _size + _padding - y - 1;
						}
						state[y][x] = uint8(_rows[_yPos] >> (_xPos)) & 1;
					}
				}
			}
		}
	}

	function _convertToColors(uint8[][] memory _state) internal pure returns (bytes memory cols) {
		unchecked {
			uint256 _scanline = _state[0].length;
			if (_scanline % 4 != 0) {
				_scanline += 4 - (_scanline % 4);
			}
			cols = new bytes(_state.length * _scanline);
			for (uint256 y = 0; y < _state.length; y++) {
				for (uint256 x = 0; x < _state[y].length; x++) {
					cols[(_state.length - y - 1) * _scanline + x] = bytes1(_state[y][x]);
				}
			}
		}
	}
	
	function _makePalette(bytes3 _backgroundColor, bytes3 _foregroundColor) internal pure returns (bytes memory) {
		unchecked {
			return abi.encodePacked(_backgroundColor, bytes1(0), _foregroundColor, bytes1(0));
		}
	}

	function _getBMP(bytes memory _palette, bytes memory _colors, uint256 _size) internal pure returns (bytes memory) {
		unchecked {
			uint32 _bufSize = 14 + 40 + uint32(_palette.length);
			bytes memory _buf = new bytes(_bufSize - _palette.length);
			_buf[0] = 0x42;
			_buf[1] = 0x4d;
			uint32 _tmp = _bufSize + uint32(_colors.length);
			uint32 b;
			for (uint i = 2; i < 6; i++) {
				assembly {
					b := and(_tmp, 0xff)
					_tmp := shr(8, _tmp)
				}
				_buf[i] = bytes1(uint8(b));
			}
			_tmp = _bufSize;
			for (uint i = 10; i < 14; i++) {
				assembly {
					b := and(_tmp, 0xff)
					_tmp := shr(8, _tmp)
				}
				_buf[i] = bytes1(uint8(b));
			}
			_buf[14] = 0x28;
			_tmp = uint32(_size);
			for (uint i = 18; i < 22; i++) {
				assembly {
					b := and(_tmp, 0xff)
					_tmp := shr(8, _tmp)
				}
				_buf[i] = bytes1(uint8(b));
				_buf[i + 4] = bytes1(uint8(b));
			}
			_buf[26] = 0x01;
			_buf[28] = 0x08;
			_tmp = uint32(_colors.length);
			for (uint i = 34; i < 38; i++) {
				assembly {
					b := and(_tmp, 0xff)
					_tmp := shr(8, _tmp)
				}
				_buf[i] = bytes1(uint8(b));
			}
			_tmp = uint32(_palette.length / 4);
			for (uint i = 46; i < 50; i++) {
				assembly {
					b := and(_tmp, 0xff)
					_tmp := shr(8, _tmp)
				}
				_buf[i] = bytes1(uint8(b));
				_buf[i + 4] = bytes1(uint8(b));
			}
			return abi.encodePacked(_buf, _palette, _colors);
		}
	}

	function _uint2str(uint256 _value) internal pure returns (string memory) {
		unchecked {
			uint256 _digits = 1;
			uint256 _n = _value;
			while (_n > 9) {
				_n /= 10;
				_digits++;
			}
			bytes memory _out = new bytes(_digits);
			for (uint256 i = 0; i < _out.length; i++) {
				uint256 _dec = (_value / (10**(_out.length - i - 1))) % 10;
				_out[i] = bytes1(uint8(_dec) + 48);
			}
			return string(_out);
		}
	}

	function _col2str(bytes3 _col) internal pure returns (string memory str) {
		unchecked {
			str = "#";
			for (uint256 i = 0; i < 6; i++) {
				uint256 _hex = (uint24(_col) >> (4 * (i + 1 - 2 * (i % 2)))) % 16;
				bytes memory _char = new bytes(1);
				_char[0] = bytes1(uint8(_hex) + (_hex > 9 ? 87 : 48));
				str = string(abi.encodePacked(str, string(_char)));
			}
		}
	}

	function _encode(bytes memory _data) internal pure returns (string memory result) {
		unchecked {
			if (_data.length == 0) return '';
			string memory _table = TABLE;
			uint256 _encodedLen = 4 * ((_data.length + 2) / 3);
			result = new string(_encodedLen + 32);

			assembly {
				mstore(result, _encodedLen)
				let tablePtr := add(_table, 1)
				let dataPtr := _data
				let endPtr := add(dataPtr, mload(_data))
				let resultPtr := add(result, 32)

				for {} lt(dataPtr, endPtr) {}
				{
					dataPtr := add(dataPtr, 3)
					let input := mload(dataPtr)
					mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(18, input), 0x3F)))))
					resultPtr := add(resultPtr, 1)
					mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(12, input), 0x3F)))))
					resultPtr := add(resultPtr, 1)
					mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr( 6, input), 0x3F)))))
					resultPtr := add(resultPtr, 1)
					mstore(resultPtr, shl(248, mload(add(tablePtr, and(        input,  0x3F)))))
					resultPtr := add(resultPtr, 1)
				}
				switch mod(mload(_data), 3)
				case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) }
				case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) }
			}
			return result;
		}
	}
}

File 3 of 3 : xNFT.sol
//
// ██   ██ ███    ██ ███████ ████████ 
//  ██ ██  ████   ██ ██         ██    
//   ███   ██ ██  ██ █████      ██    
//  ██ ██  ██  ██ ██ ██         ██    
// ██   ██ ██   ████ ██         ██    
//
// xNFT - Exchangeable Non-Fungible Tokens
// An experimental hybrid of ERC-20 & ERC-721.
//
// - Easily inheritable
// - Extremely gas efficient
// - Logically coherent single contract hybrid
//
//
// !!! Important Caveats !!!
// - `ownerOf()` is unbounded in gas usage due to loops, as such, all contract
//   calls are blocked to it to prevent high transaction fees.
//   !! This will break external contracts that use `ownerOf()` !!
//   For new implementations, use the `isOwnerOf()` method to check ownership.
//   Queries outside of the blockchain should not be effected.
// - `transferFrom()` can behave unexpectedly due to how the function needs to
//   be overloaded to work for both ERC-20 & ERC-721 applications.
//   !! Any contract that does not wrap `transferFrom()` with a before/after
//   balance check has the potential to be exploited !!
//
// WARNING - Hybrid NFT standards are universally new, and inherently DANGEROUS,
// no systems have been built with these use cases in mind, and there are a number of 
// ways that experimental, complex contracts can lead to unforseen consequences.
// INTERACT WITH EXPERIMENTAL SMART CONTRACTS AT YOUR OWN RISK

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

interface Receiver {
	function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes calldata _data) external returns (bytes4);
}

abstract contract xNFT {

	uint256 constant internal MASK_SIZE = 256;
	uint256 constant internal MAX_ALLOWED_SUPPLY = 57344;
	uint256 constant internal UINT_MAX = type(uint256).max;
	uint256 constant internal M1 = 0x5555555555555555555555555555555555555555555555555555555555555555;
	uint256 constant internal M2 = 0x3333333333333333333333333333333333333333333333333333333333333333;
	uint256 constant internal M4 = 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f;
	uint256 constant internal H01 = 0x0101010101010101010101010101010101010101010101010101010101010101;
	bytes32 constant internal TRANSFER_TOPIC = keccak256(bytes("Transfer(address,address,uint256)"));
	bytes32 constant internal APPROVAL_TOPIC = keccak256(bytes("Approval(address,address,uint256)"));

	uint8 constant public decimals = 0;
	uint256 immutable public totalSupply;
	uint256 immutable internal maskDepth;
	bool internal skipEventEmits = false;

	struct User {
		uint16 balance;
		uint16 approvedCount;
		bytes28 activeMasks;
		mapping(uint256 => bytes32) masks;
		mapping(address => uint256) allowance;
		mapping(address => bool) approved;
	}

	struct Info {
		address owner;
		mapping(address => User) users;
		mapping(uint256 => address) approved;
		address[] holders;
		mapping(address => uint256) indexOf;
	}
	Info internal info;

	mapping(bytes4 => bool) public supportsInterface;


	event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
	event ERC20Transfer(bytes32 indexed topic0, address indexed from, address indexed to, uint256 tokens) anonymous;
	event Approval(address indexed owner, address indexed spender, uint256 indexed tokenId);
	event ERC20Approval(bytes32 indexed topic0, address indexed owner, address indexed spender, uint256 tokens) anonymous;
	event ApprovalForAll(address indexed owner, address indexed operator, bool approved);


	modifier _onlyOwner() {
		require(msg.sender == owner());
		_;
	}

	modifier _withoutEventEmits() {
		skipEventEmits = true;
		_;
		skipEventEmits = false;
	}


	constructor(address _owner, uint256 _totalSupply) {
		require(_totalSupply > 0 && _totalSupply <= MAX_ALLOWED_SUPPLY);
		info.owner = _owner;
		totalSupply = _totalSupply;
		maskDepth = ((totalSupply - 1) / MASK_SIZE) + 1;
		supportsInterface[0x01ffc9a7] = true; // ERC-165
		supportsInterface[0x80ac58cd] = true; // ERC-721
		supportsInterface[0x5b5e139f] = true; // Metadata
		supportsInterface[0x780e9d63] = true; // Enumerable
		_initialize();
	}

	function setOwner(address _owner) external _onlyOwner {
		info.owner = _owner;
	}


	function approve(address _spender, uint256 _tokens) external returns (bool) {
		unchecked {
			if (_tokens > totalSupply && _tokens <= 2 * totalSupply) {
				_approveNFT(_spender, _tokens);
			} else {
				_approveERC20(msg.sender, _spender, _tokens);
			}
			return true;	
		}
	}

	function setApprovalForAll(address _operator, bool _approved) external {
		info.users[msg.sender].approved[_operator] = _approved;
		emit ApprovalForAll(msg.sender, _operator, _approved);
	}

	function transfer(address _to, uint256 _tokens) external returns (bool) {
		_transferERC20(msg.sender, _to, _tokens);
		return true;
	}

	function transferFrom(address _from, address _to, uint256 _tokens) external returns (bool) {
		unchecked {
			if (_tokens > totalSupply && _tokens <= 2 * totalSupply) {
				_transferNFT(_from, _to, _tokens);
			} else {
				uint256 _allowance = allowance(_from, msg.sender);
				require(_allowance >= _tokens);
				if (_allowance != UINT_MAX) {
					info.users[_from].allowance[msg.sender] -= _tokens;
				}
				_transferERC20(_from, _to, _tokens);
			}
			return true;
		}
	}

	function safeTransferFrom(address _from, address _to, uint256 _tokenId) external {
		safeTransferFrom(_from, _to, _tokenId, "");
	}

	function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes memory _data) public {
		_transferNFT(_from, _to, _tokenId);
		uint32 _size;
		assembly {
			_size := extcodesize(_to)
		}
		if (_size > 0) {
			require(Receiver(_to).onERC721Received(msg.sender, _from, _tokenId, _data) == Receiver.onERC721Received.selector);
		}
	}

	function bulkTransfer(address _to, uint256[] memory _tokenIds) external {
		_transferNFTs(_to, _tokenIds);
	}
	

	function owner() public view returns (address) {
		return info.owner;
	}

	function holders() external view returns (address[] memory) {
		return info.holders;
	}

	function name() external virtual view returns (string memory);

	function symbol() external virtual view returns (string memory);

	function tokenURI(uint256 _tokenId) public virtual view returns (string memory);

	function maskAtIndexOf(uint256 _index, address _user) public view returns (bytes32) {
		unchecked {
			require(_index < maskDepth);
			return info.users[_user].masks[_index];
		}
	}

	function masksOf(address _user) external view returns (bytes32[] memory masks) {
		unchecked {
			masks = new bytes32[](maskDepth);
			for (uint256 i = 0; i < masks.length; i++) {
				masks[i] = maskAtIndexOf(i, _user);
			}
		}
	}

	function balanceOf(address _user) public view returns (uint256 balance) {
		return info.users[_user].balance;
	}

	function allowance(address _user, address _spender) public view returns (uint256) {
		return info.users[_user].allowance[_spender];
	}

	// !!! Important !!!
	// To save gas on bulk ERC-20 & ERC-721 transfers, this method has been written in a way
	// that doesn't individually update a storage slot for each token owner but instead loops
	// through an array of holders in order to find a match.
	// As such it costs approximately 5k gas per loop (1 block = 30m gas = 6k loops) so having
	// another contract call this method could result in very large transaction fees. To prevent
	// this from happening, this method will block and revert if the caller is a contract.
	// !! This will break external contracts that use `ownerOf()` but queries outside of the
	// blockchain should not be effected !!
	//
	// If you need to externally check if a token is owned by a certain address, use the
	// new `isOwnerOf(address _user, uint256 _tokenId)` method instead.
	// Most current NFT based contracts don't use `ownerOf()` and assume that if a call
	// to `transferFrom()` was successful then `_from` was in fact the owner.
	function ownerOf(uint256 _tokenId) public view returns (address) {
		unchecked {
			uint32 _size;
			assembly {
				_size := caller()
			}
			require(_size == 0);
			require(_tokenId > totalSupply && _tokenId <= 2 * totalSupply);
			(uint256 _maskIndex, bytes32 _mask) = _tokenIdToMask(_tokenId);
			uint256 _holdersLength = info.holders.length;
			for (uint256 i = 0; i < _holdersLength; i++) {
				address _holder = info.holders[i];
				if (maskAtIndexOf(_maskIndex, _holder) & _mask == _mask) {
					return _holder;
				}
			}
			return address(0x0);
		}
	}

	function getApproved(uint256 _tokenId) public view returns (address) {
		unchecked {
			require(_tokenId > totalSupply && _tokenId <= 2 * totalSupply);
			return info.approved[_tokenId];
		}
	}

	function isApprovedForAll(address _owner, address _operator) public view returns (bool) {
		return info.users[_owner].approved[_operator];
	}

	function isOwnerOf(address _user, uint256 _tokenId) external view returns (bool) {
		unchecked {
			require(_tokenId > totalSupply && _tokenId <= 2 * totalSupply);
			(uint256 _maskIndex, bytes32 _mask) = _tokenIdToMask(_tokenId);
			return maskAtIndexOf(_maskIndex, _user) & _mask == _mask;
		}
	}

	function tokenByIndex(uint256 _index) external view returns (uint256) {
		unchecked {
			require(_index < totalSupply);
			return totalSupply + _index + 1;
		}
	}

	function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256 tokenId) {
		unchecked {
			require(_index < balanceOf(_owner));
			uint256 _count = 0;
			uint256 _activeMasks = uint224(info.users[_owner].activeMasks);
			while (_activeMasks > 0 && _count <= _index) {
				uint256 _activeIndex = _lsb(_activeMasks);
				_activeMasks ^= 1 << _activeIndex;
				bytes32 _mask = maskAtIndexOf(_activeIndex, _owner);
				uint256 _maskCount = _popcount(_mask);
				if (_count + _maskCount <= _index) {
					_count += _maskCount;
				} else {
					uint256 _n = uint256(_mask);
					while (_n > 0 && _count <= _index) {
						uint256 _pos = _lsb(_n);
						_n ^= 1 << _pos;
						_count++;
						if (_count == _index + 1) {
							return (MASK_SIZE * _activeIndex) + totalSupply + _pos + 1;
						}
					}
				}
			}
		}
	}

	function getToken(uint256 _tokenId, bool _getOwner) public view returns (address tokenOwner, address approved, string memory uri) {
		return (_getOwner ? ownerOf(_tokenId) : address(0x0), getApproved(_tokenId), tokenURI(_tokenId));
	}

	function getTokens(uint256[] memory _tokenIds, bool _getOwner) external view returns (address[] memory owners, address[] memory approveds, string[] memory uris) {
		uint256 _length = _tokenIds.length;
		owners = new address[](_length);
		approveds = new address[](_length);
		uris = new string[](_length);
		for (uint256 i = 0; i < _length; i++) {
			(owners[i], approveds[i], uris[i]) = getToken(_tokenIds[i], _getOwner);
		}
	}


	// Can be overridden by a parent contract if needed. Most of the logic inside this function is
	// essential for setting up the initial supply so be careful when altering it.
	// If all you want to do is save gas on deployment by preventing all the NFT `Transfer()` events
	// from emitting, use this in your parent contract:
	// `function _initialize() internal override _withoutEventEmits { super._initialize(); }`
	function _initialize() internal virtual {
		unchecked {
			for (uint256 i = 0; i < maskDepth; i++) {
				if (i == maskDepth - 1 && totalSupply % MASK_SIZE != 0) {
					info.users[owner()].masks[i] = bytes32(UINT_MAX) >> (MASK_SIZE - (totalSupply % MASK_SIZE));
				} else {
					info.users[owner()].masks[i] = bytes32(UINT_MAX);
				}
			}
			info.users[owner()].balance = uint16(totalSupply);
			info.users[owner()].activeMasks = bytes28(uint224(2**maskDepth - 1));
			info.holders.push(owner());
			emit ERC20Transfer(TRANSFER_TOPIC, address(0x0), owner(), totalSupply);
			if (!skipEventEmits) {
				for (uint256 i = 0; i < totalSupply; i++) {
					emit Transfer(address(0x0), owner(), totalSupply + i + 1);
				}
			}
		}
	}
	
	function _approveERC20(address _owner, address _spender, uint256 _tokens) internal {
		info.users[_owner].allowance[_spender] = _tokens;
		emit ERC20Approval(APPROVAL_TOPIC, _owner, _spender, _tokens);
	}

	function _approveNFT(address _spender, uint256 _tokenId) internal {
		unchecked {
			(uint256 _maskIndex, bytes32 _mask) = _tokenIdToMask(_tokenId);
			require(maskAtIndexOf(_maskIndex, msg.sender) & _mask == _mask);
			info.approved[_tokenId] = _spender;
			info.users[msg.sender].approvedCount++;
			emit Approval(msg.sender, _spender, _tokenId);
		}
	}
	
	// Can be overridden by a parent contract to change how token ids are selected when performing
	// an ERC-20 transfer. It is not recommended to do this unless you're sure you know what
	// the outcome will be and test it to make sure your implementation works as expected.
	function _transferERC20(address _from, address _to, uint256 _tokens) internal virtual {
		unchecked {
			uint256 _count = 0;
			uint256[] memory _tokenIds = new uint256[](_tokens);
			bytes32[] memory _masks = new bytes32[](maskDepth);
			uint256 _activeMasks = uint224(info.users[_from].activeMasks);
			while (_activeMasks > 0 && _count < _tokens) {
				uint256 _activeIndex = _lsb(_activeMasks);
				_activeMasks ^= 1 << _activeIndex;
				bytes32 _mask = maskAtIndexOf(_activeIndex, _from);
				uint256 _n = uint256(_mask);
				while (_n > 0 && _count < _tokens) {
					uint256 _pos = _lsb(_n);
					bytes32 _tokenMask = bytes32(1 << _pos);
					_masks[_activeIndex] |= _tokenMask;
					_tokenIds[_count++] = (MASK_SIZE * _activeIndex) + totalSupply + _pos + 1;
					_n ^= uint256(_tokenMask);
				}
				require(_mask & _masks[_activeIndex] == _masks[_activeIndex]);
			}
			require(_count == _tokens);
			_transfer(_from, _to, _masks, _tokenIds);
		}
	}
	
	function _transferNFT(address _from, address _to, uint256 _tokenId) internal {
		unchecked {
			require(_tokenId > totalSupply && _tokenId <= 2 * totalSupply);
			(uint256 _maskIndex, bytes32 _mask) = _tokenIdToMask(_tokenId);
			require(maskAtIndexOf(_maskIndex, _from) & _mask == _mask);
			require(msg.sender == _from || msg.sender == getApproved(_tokenId) || isApprovedForAll(_from, msg.sender));
			bytes32[] memory _masks = new bytes32[](maskDepth);
			_masks[_maskIndex] = _mask;
			uint256[] memory _tokenIds = new uint256[](1);
			_tokenIds[0] = _tokenId;
			_transfer(_from, _to, _masks, _tokenIds);
		}
	}
	
	function _transferNFTs(address _to, uint256[] memory _tokenIds) internal {
		unchecked {
			bytes32[] memory _masks = new bytes32[](maskDepth);
			for (uint256 i = 0; i < _tokenIds.length; i++) {
				(uint256 _maskIndex, bytes32 _mask) = _tokenIdToMask(_tokenIds[i]);
				_masks[_maskIndex] |= _mask;
			}
			uint256 _count = 0;
			for (uint256 i = 0; i < _masks.length; i++) {
				if (_masks[i] != 0x0) {
					require(maskAtIndexOf(i, msg.sender) & _masks[i] == _masks[i]);
					_count += _popcount(_masks[i]);
				}
			}
			require(_count == _tokenIds.length);
			_transfer(msg.sender, _to, _masks, _tokenIds);
		}
	}

	// Can be overridden by a parent contract in order to add some logic before the transfer completes. The
	// code here is important for the ERC-721 side of things so unless you explicitly want to change how this
	// works, you should always use `super._beforeTransfer(...);` in your overridden function.
	function _beforeTransfer(address _from, address _to, bytes32[] memory, uint256[] memory _tokenIds) internal virtual {
		unchecked {
			bool _skip = skipEventEmits;
			bool _skipApproveds = info.users[_from].approvedCount == 0;
			if (!(_skipApproveds && _skip)) {
				for (uint256 i = 0; i < _tokenIds.length; i++) {
					if (!_skipApproveds && getApproved(_tokenIds[i]) != address(0x0)) {
						info.users[_from].approvedCount--;
						info.approved[_tokenIds[i]] = address(0x0);
						emit Approval(address(0x0), address(0x0), _tokenIds[i]);
					}
					if (!_skip) {
						emit Transfer(_from, _to, _tokenIds[i]);
					}
				}
			}
		}
	}

	function _transfer(address _from, address _to, bytes32[] memory _masks, uint256[] memory _tokenIds) internal {
		unchecked {
			require(_to != address(0x0));
			require(_tokenIds.length > 0);
			_beforeTransfer(_from, _to, _masks, _tokenIds);
			uint256 _fromActive = uint224(info.users[_from].activeMasks);
			uint256 _toActive = uint224(info.users[_to].activeMasks);
			for (uint256 i = 0; i < _masks.length; i++) {
				if (_masks[i] != bytes32(0x0)) {
					bytes32 _fromMask = maskAtIndexOf(i, _from);
					_fromMask ^= _masks[i];
					info.users[_from].masks[i] = _fromMask;
					bytes32 _toMask = maskAtIndexOf(i, _to);
					_toMask |= _masks[i];
					info.users[_to].masks[i] = _toMask;
					if (_fromMask == 0x0) {
						_fromActive ^= 1 << i;
					}
					_toActive |= 1 << i;
					require(_fromMask & _toMask == 0x0);
				}
			}
			uint256 _fromBalance = balanceOf(_from);
			_fromBalance -= _tokenIds.length;
			info.users[_from].balance = uint16(_fromBalance);
			info.users[_from].activeMasks = bytes28(uint224(_fromActive));
			uint256 _toBalance = balanceOf(_to);
			info.users[_to].balance = uint16(_toBalance + _tokenIds.length);
			info.users[_to].activeMasks = bytes28(uint224(_toActive));
			if (_fromBalance == 0) {
				uint256 _index = info.indexOf[_from];
				if (_toBalance == 0) {
					info.holders[_index] = _to;
					info.indexOf[_to] = _index;
				} else {
					address _moved = info.holders[info.holders.length - 1];
					info.holders[_index] = _moved;
					info.indexOf[_moved] = _index;
					info.holders.pop();
				}
				delete info.indexOf[_from];
			} else if (_toBalance == 0) {
				info.holders.push(_to);
				info.indexOf[_to] = info.holders.length - 1;
			}
			emit ERC20Transfer(TRANSFER_TOPIC, _from, _to, _tokenIds.length);
			_afterTransfer(_from, _to, _masks, _tokenIds);
		}
	}

	// Can be overridden by a parent contract and used as a way to execute extra code after a transfer has completed.
	function _afterTransfer(address _from, address _to, bytes32[] memory _masks, uint256[] memory _tokenIds) internal virtual {}


	function _tokenIdToMask(uint256 _tokenId) internal view returns (uint256 maskIndex, bytes32 mask) {
		unchecked {
			maskIndex = (_tokenId - totalSupply - 1) / MASK_SIZE;
			mask = bytes32(1 << (_tokenId - (MASK_SIZE * maskIndex) - totalSupply - 1));
		}
	}
	
	function _popcount(bytes32 _b) internal pure returns (uint256) {
		unchecked {
			uint256 _n = uint256(_b);
			if (_n == 0) {
				return 0;
			} else if (_n == UINT_MAX) {
				return MASK_SIZE;
			}
			_n -= (_n >> 1) & M1;
			_n = (_n & M2) + ((_n >> 2) & M2);
			_n = (_n + (_n >> 4)) & M4;
			_n = (_n * H01) >> 248;
			return _n;
		}
	}


	// An extremely gas efficient implementation of the least significant bit algorithm. Due to all of
	// the constants in the if/else binary search tree, this function does add approximately 1.1m gas
	// to the deployment cost (~0.022 ETH @ 20 Gwei) but the end users will save on transaction fees.
	// The 'break even' point is around 3,000 total transfer volume where by you spending the extra to
	// make it more efficient, you have saved your end users more than you initially paid.
	// If you would rather have cheaper deployment costs and slightly less efficient transfers, replace
	// the entire `_lsb()` function with the one commented below:
	// ```function _lsb(uint256 _n) internal pure returns (uint256 i) {
	// 	unchecked { uint256 _b = _n & ~(_n - 1); i = 0;
	// 	for (uint256 _s = 0x80; _s > 0; _s >>= 1) { if (_b >= (1 << _s)) { _b >>= _s; i |= _s; } } }
	// }```
	function _lsb(uint256 _n) internal pure returns (uint256 i) {
		unchecked {
			uint256 _b = _n & ~(_n - 1);
			if (_b < 0x0100000000000000000000000000000000)
				if (_b < 0x010000000000000000)
					if (_b < 0x0100000000)
						if (_b < 0x010000)
							if (_b < 0x0100)
								if (_b < 0x10)
									if (_b < 0x04)
										if (_b < 0x02) return 0; else return 1;
									else
										if (_b < 0x08) return 2; else return 3;
								else
									if (_b < 0x40)
										if (_b < 0x20) return 4; else return 5;
									else
										if (_b < 0x80) return 6; else return 7;
							else
								if (_b < 0x1000)
									if (_b < 0x0400)
										if (_b < 0x0200) return 8; else return 9;
									else
										if (_b < 0x0800) return 10; else return 11;
								else
									if (_b < 0x4000)
										if (_b < 0x2000) return 12; else return 13;
									else
										if (_b < 0x8000) return 14; else return 15;
						else
							if (_b < 0x01000000)
								if (_b < 0x100000)
									if (_b < 0x040000)
										if (_b < 0x020000) return 16; else return 17;
									else
										if (_b < 0x080000) return 18; else return 19;
								else
									if (_b < 0x400000)
										if (_b < 0x200000) return 20; else return 21;
									else
										if (_b < 0x800000) return 22; else return 23;
							else
								if (_b < 0x10000000)
									if (_b < 0x04000000)
										if (_b < 0x02000000) return 24; else return 25;
									else
										if (_b < 0x08000000) return 26; else return 27;
								else
									if (_b < 0x40000000)
										if (_b < 0x20000000) return 28; else return 29;
									else
										if (_b < 0x80000000) return 30; else return 31;
					else
						if (_b < 0x01000000000000)
							if (_b < 0x010000000000)
								if (_b < 0x1000000000)
									if (_b < 0x0400000000)
										if (_b < 0x0200000000) return 32; else return 33;
									else
										if (_b < 0x0800000000) return 34; else return 35;
								else
									if (_b < 0x4000000000)
										if (_b < 0x2000000000) return 36; else return 37;
									else
										if (_b < 0x8000000000) return 38; else return 39;
							else
								if (_b < 0x100000000000)
									if (_b < 0x040000000000)
										if (_b < 0x020000000000) return 40; else return 41;
									else
										if (_b < 0x080000000000) return 42; else return 43;
								else
									if (_b < 0x400000000000)
										if (_b < 0x200000000000) return 44; else return 45;
									else
										if (_b < 0x800000000000) return 46; else return 47;
						else
							if (_b < 0x0100000000000000)
								if (_b < 0x10000000000000)
									if (_b < 0x04000000000000)
										if (_b < 0x02000000000000) return 48; else return 49;
									else
										if (_b < 0x08000000000000) return 50; else return 51;
								else
									if (_b < 0x40000000000000)
										if (_b < 0x20000000000000) return 52; else return 53;
									else
										if (_b < 0x80000000000000) return 54; else return 55;
							else
								if (_b < 0x1000000000000000)
									if (_b < 0x0400000000000000)
										if (_b < 0x0200000000000000) return 56; else return 57;
									else
										if (_b < 0x0800000000000000) return 58; else return 59;
								else
									if (_b < 0x4000000000000000)
										if (_b < 0x2000000000000000) return 60; else return 61;
									else
										if (_b < 0x8000000000000000) return 62; else return 63;
				else
					if (_b < 0x01000000000000000000000000)
						if (_b < 0x0100000000000000000000)
							if (_b < 0x01000000000000000000)
								if (_b < 0x100000000000000000)
									if (_b < 0x040000000000000000)
										if (_b < 0x020000000000000000) return 64; else return 65;
									else
										if (_b < 0x080000000000000000) return 66; else return 67;
								else
									if (_b < 0x400000000000000000)
										if (_b < 0x200000000000000000) return 68; else return 69;
									else
										if (_b < 0x800000000000000000) return 70; else return 71;
							else
								if (_b < 0x10000000000000000000)
									if (_b < 0x04000000000000000000)
										if (_b < 0x02000000000000000000) return 72; else return 73;
									else
										if (_b < 0x08000000000000000000) return 74; else return 75;
								else
									if (_b < 0x40000000000000000000)
										if (_b < 0x20000000000000000000) return 76; else return 77;
									else
										if (_b < 0x80000000000000000000) return 78; else return 79;
						else
							if (_b < 0x010000000000000000000000)
								if (_b < 0x1000000000000000000000)
									if (_b < 0x0400000000000000000000)
										if (_b < 0x0200000000000000000000) return 80; else return 81;
									else
										if (_b < 0x0800000000000000000000) return 82; else return 83;
								else
									if (_b < 0x4000000000000000000000)
										if (_b < 0x2000000000000000000000) return 84; else return 85;
									else
										if (_b < 0x8000000000000000000000) return 86; else return 87;
							else
								if (_b < 0x100000000000000000000000)
									if (_b < 0x040000000000000000000000)
										if (_b < 0x020000000000000000000000) return 88; else return 89;
									else
										if (_b < 0x080000000000000000000000) return 90; else return 91;
								else
									if (_b < 0x400000000000000000000000)
										if (_b < 0x200000000000000000000000) return 92; else return 93;
									else
										if (_b < 0x800000000000000000000000) return 94; else return 95;
					else
						if (_b < 0x010000000000000000000000000000)
							if (_b < 0x0100000000000000000000000000)
								if (_b < 0x10000000000000000000000000)
									if (_b < 0x04000000000000000000000000)
										if (_b < 0x02000000000000000000000000) return 96; else return 97;
									else
										if (_b < 0x08000000000000000000000000) return 98; else return 99;
								else
									if (_b < 0x40000000000000000000000000)
										if (_b < 0x20000000000000000000000000) return 100; else return 101;
									else
										if (_b < 0x80000000000000000000000000) return 102; else return 103;
							else
								if (_b < 0x1000000000000000000000000000)
									if (_b < 0x0400000000000000000000000000)
										if (_b < 0x0200000000000000000000000000) return 104; else return 105;
									else
										if (_b < 0x0800000000000000000000000000) return 106; else return 107;
								else
									if (_b < 0x4000000000000000000000000000)
										if (_b < 0x2000000000000000000000000000) return 108; else return 109;
									else
										if (_b < 0x8000000000000000000000000000) return 110; else return 111;
						else
							if (_b < 0x01000000000000000000000000000000)
								if (_b < 0x100000000000000000000000000000)
									if (_b < 0x040000000000000000000000000000)
										if (_b < 0x020000000000000000000000000000) return 112; else return 113;
									else
										if (_b < 0x080000000000000000000000000000) return 114; else return 115;
								else
									if (_b < 0x400000000000000000000000000000)
										if (_b < 0x200000000000000000000000000000) return 116; else return 117;
									else
										if (_b < 0x800000000000000000000000000000) return 118; else return 119;
							else
								if (_b < 0x10000000000000000000000000000000)
									if (_b < 0x04000000000000000000000000000000)
										if (_b < 0x02000000000000000000000000000000) return 120; else return 121;
									else
										if (_b < 0x08000000000000000000000000000000) return 122; else return 123;
								else
									if (_b < 0x40000000000000000000000000000000)
										if (_b < 0x20000000000000000000000000000000) return 124; else return 125;
									else
										if (_b < 0x80000000000000000000000000000000) return 126; else return 127;
			else
				if (_b < 0x01000000000000000000000000000000000000000000000000)
					if (_b < 0x010000000000000000000000000000000000000000)
						if (_b < 0x01000000000000000000000000000000000000)
							if (_b < 0x010000000000000000000000000000000000)
								if (_b < 0x1000000000000000000000000000000000)
									if (_b < 0x0400000000000000000000000000000000)
										if (_b < 0x0200000000000000000000000000000000) return 128; else return 129;
									else
										if (_b < 0x0800000000000000000000000000000000) return 130; else return 131;
								else
									if (_b < 0x4000000000000000000000000000000000)
										if (_b < 0x2000000000000000000000000000000000) return 132; else return 133;
									else
										if (_b < 0x8000000000000000000000000000000000) return 134; else return 135;
							else
								if (_b < 0x100000000000000000000000000000000000)
									if (_b < 0x040000000000000000000000000000000000)
										if (_b < 0x020000000000000000000000000000000000) return 136; else return 137;
									else
										if (_b < 0x080000000000000000000000000000000000) return 138; else return 139;
								else
									if (_b < 0x400000000000000000000000000000000000)
										if (_b < 0x200000000000000000000000000000000000) return 140; else return 141;
									else
										if (_b < 0x800000000000000000000000000000000000) return 142; else return 143;
						else
							if (_b < uint160(0x0100000000000000000000000000000000000000))
								if (_b < 0x10000000000000000000000000000000000000)
									if (_b < 0x04000000000000000000000000000000000000)
										if (_b < 0x02000000000000000000000000000000000000) return 144; else return 145;
									else
										if (_b < 0x08000000000000000000000000000000000000) return 146; else return 147;
								else
									if (_b < 0x40000000000000000000000000000000000000)
										if (_b < 0x20000000000000000000000000000000000000) return 148; else return 149;
									else
										if (_b < 0x80000000000000000000000000000000000000) return 150; else return 151;
							else
								if (_b < uint160(0x1000000000000000000000000000000000000000))
									if (_b < uint160(0x0400000000000000000000000000000000000000))
										if (_b < uint160(0x0200000000000000000000000000000000000000)) return 152; else return 153;
									else
										if (_b < uint160(0x0800000000000000000000000000000000000000)) return 154; else return 155;
								else
									if (_b < uint160(0x4000000000000000000000000000000000000000))
										if (_b < uint160(0x2000000000000000000000000000000000000000)) return 156; else return 157;
									else
										if (_b < uint160(0x8000000000000000000000000000000000000000)) return 158; else return 159;
					else
						if (_b < 0x0100000000000000000000000000000000000000000000)
							if (_b < 0x01000000000000000000000000000000000000000000)
								if (_b < 0x100000000000000000000000000000000000000000)
									if (_b < 0x040000000000000000000000000000000000000000)
										if (_b < 0x020000000000000000000000000000000000000000) return 160; else return 161;
									else
										if (_b < 0x080000000000000000000000000000000000000000) return 162; else return 163;
								else
									if (_b < 0x400000000000000000000000000000000000000000)
										if (_b < 0x200000000000000000000000000000000000000000) return 164; else return 165;
									else
										if (_b < 0x800000000000000000000000000000000000000000) return 166; else return 167;
							else
								if (_b < 0x10000000000000000000000000000000000000000000)
									if (_b < 0x04000000000000000000000000000000000000000000)
										if (_b < 0x02000000000000000000000000000000000000000000) return 168; else return 169;
									else
										if (_b < 0x08000000000000000000000000000000000000000000) return 170; else return 171;
								else
									if (_b < 0x40000000000000000000000000000000000000000000)
										if (_b < 0x20000000000000000000000000000000000000000000) return 172; else return 173;
									else
										if (_b < 0x80000000000000000000000000000000000000000000) return 174; else return 175;
						else
							if (_b < 0x010000000000000000000000000000000000000000000000)
								if (_b < 0x1000000000000000000000000000000000000000000000)
									if (_b < 0x0400000000000000000000000000000000000000000000)
										if (_b < 0x0200000000000000000000000000000000000000000000) return 176; else return 177;
									else
										if (_b < 0x0800000000000000000000000000000000000000000000) return 178; else return 179;
								else
									if (_b < 0x4000000000000000000000000000000000000000000000)
										if (_b < 0x2000000000000000000000000000000000000000000000) return 180; else return 181;
									else
										if (_b < 0x8000000000000000000000000000000000000000000000) return 182; else return 183;
							else
								if (_b < 0x100000000000000000000000000000000000000000000000)
									if (_b < 0x040000000000000000000000000000000000000000000000)
										if (_b < 0x020000000000000000000000000000000000000000000000) return 184; else return 185;
									else
										if (_b < 0x080000000000000000000000000000000000000000000000) return 186; else return 187;
								else
									if (_b < 0x400000000000000000000000000000000000000000000000)
										if (_b < 0x200000000000000000000000000000000000000000000000) return 188; else return 189;
									else
										if (_b < 0x800000000000000000000000000000000000000000000000) return 190; else return 191;
				else
					if (_b < 0x0100000000000000000000000000000000000000000000000000000000)
						if (_b < 0x010000000000000000000000000000000000000000000000000000)
							if (_b < 0x0100000000000000000000000000000000000000000000000000)
								if (_b < 0x10000000000000000000000000000000000000000000000000)
									if (_b < 0x04000000000000000000000000000000000000000000000000)
										if (_b < 0x02000000000000000000000000000000000000000000000000) return 192; else return 193;
									else
										if (_b < 0x08000000000000000000000000000000000000000000000000) return 194; else return 195;
								else
									if (_b < 0x40000000000000000000000000000000000000000000000000)
										if (_b < 0x20000000000000000000000000000000000000000000000000) return 196; else return 197;
									else
										if (_b < 0x80000000000000000000000000000000000000000000000000) return 198; else return 199;
							else
								if (_b < 0x1000000000000000000000000000000000000000000000000000)
									if (_b < 0x0400000000000000000000000000000000000000000000000000)
										if (_b < 0x0200000000000000000000000000000000000000000000000000) return 200; else return 201;
									else
										if (_b < 0x0800000000000000000000000000000000000000000000000000) return 202; else return 203;
								else
									if (_b < 0x4000000000000000000000000000000000000000000000000000)
										if (_b < 0x2000000000000000000000000000000000000000000000000000) return 204; else return 205;
									else
										if (_b < 0x8000000000000000000000000000000000000000000000000000) return 206; else return 207;
						else
							if (_b < 0x01000000000000000000000000000000000000000000000000000000)
								if (_b < 0x100000000000000000000000000000000000000000000000000000)
									if (_b < 0x040000000000000000000000000000000000000000000000000000)
										if (_b < 0x020000000000000000000000000000000000000000000000000000) return 208; else return 209;
									else
										if (_b < 0x080000000000000000000000000000000000000000000000000000) return 210; else return 211;
								else
									if (_b < 0x400000000000000000000000000000000000000000000000000000)
										if (_b < 0x200000000000000000000000000000000000000000000000000000) return 212; else return 213;
									else
										if (_b < 0x800000000000000000000000000000000000000000000000000000) return 214; else return 215;
							else
								if (_b < 0x10000000000000000000000000000000000000000000000000000000)
									if (_b < 0x04000000000000000000000000000000000000000000000000000000)
										if (_b < 0x02000000000000000000000000000000000000000000000000000000) return 216; else return 217;
									else
										if (_b < 0x08000000000000000000000000000000000000000000000000000000) return 218; else return 219;
								else
									if (_b < 0x40000000000000000000000000000000000000000000000000000000)
										if (_b < 0x20000000000000000000000000000000000000000000000000000000) return 220; else return 221;
									else
										if (_b < 0x80000000000000000000000000000000000000000000000000000000) return 222; else return 223;
					else
						if (_b < 0x01000000000000000000000000000000000000000000000000000000000000)
							if (_b < 0x010000000000000000000000000000000000000000000000000000000000)
								if (_b < 0x1000000000000000000000000000000000000000000000000000000000)
									if (_b < 0x0400000000000000000000000000000000000000000000000000000000)
										if (_b < 0x0200000000000000000000000000000000000000000000000000000000) return 224; else return 225;
									else
										if (_b < 0x0800000000000000000000000000000000000000000000000000000000) return 226; else return 227;
								else
									if (_b < 0x4000000000000000000000000000000000000000000000000000000000)
										if (_b < 0x2000000000000000000000000000000000000000000000000000000000) return 228; else return 229;
									else
										if (_b < 0x8000000000000000000000000000000000000000000000000000000000) return 230; else return 231;
							else
								if (_b < 0x100000000000000000000000000000000000000000000000000000000000)
									if (_b < 0x040000000000000000000000000000000000000000000000000000000000)
										if (_b < 0x020000000000000000000000000000000000000000000000000000000000) return 232; else return 233;
									else
										if (_b < 0x080000000000000000000000000000000000000000000000000000000000) return 234; else return 235;
								else
									if (_b < 0x400000000000000000000000000000000000000000000000000000000000)
										if (_b < 0x200000000000000000000000000000000000000000000000000000000000) return 236; else return 237;
									else
										if (_b < 0x800000000000000000000000000000000000000000000000000000000000) return 238; else return 239;
						else
							if (_b < 0x0100000000000000000000000000000000000000000000000000000000000000)
								if (_b < 0x10000000000000000000000000000000000000000000000000000000000000)
									if (_b < 0x04000000000000000000000000000000000000000000000000000000000000)
										if (_b < 0x02000000000000000000000000000000000000000000000000000000000000) return 240; else return 241;
									else
										if (_b < 0x08000000000000000000000000000000000000000000000000000000000000) return 242; else return 243;
								else
									if (_b < 0x40000000000000000000000000000000000000000000000000000000000000)
										if (_b < 0x20000000000000000000000000000000000000000000000000000000000000) return 244; else return 245;
									else
										if (_b < 0x80000000000000000000000000000000000000000000000000000000000000) return 246; else return 247;
							else
								if (_b < 0x1000000000000000000000000000000000000000000000000000000000000000)
									if (_b < 0x0400000000000000000000000000000000000000000000000000000000000000)
										if (_b < 0x0200000000000000000000000000000000000000000000000000000000000000) return 248; else return 249;
									else
										if (_b < 0x0800000000000000000000000000000000000000000000000000000000000000) return 250; else return 251;
								else
									if (_b < 0x4000000000000000000000000000000000000000000000000000000000000000)
										if (_b < 0x2000000000000000000000000000000000000000000000000000000000000000) return 252; else return 253;
									else
										if (_b < 0x8000000000000000000000000000000000000000000000000000000000000000) return 254; else return 255;
		}
	}
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"payable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","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":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokens","type":"uint256"}],"name":"Claim","type":"event"},{"anonymous":true,"inputs":[{"indexed":true,"internalType":"bytes32","name":"topic0","type":"bytes32"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokens","type":"uint256"}],"name":"ERC20Approval","type":"event"},{"anonymous":true,"inputs":[{"indexed":true,"internalType":"bytes32","name":"topic0","type":"bytes32"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokens","type":"uint256"}],"name":"ERC20Transfer","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":"_user","type":"address"},{"internalType":"address","name":"_spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_tokens","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"bulkTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_tokens","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"collectAllTradingFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"_wethAmount0Max","type":"uint128"},{"internalType":"uint128","name":"_wethAmount1Max","type":"uint128"},{"internalType":"uint128","name":"_wcellAmount0Max","type":"uint128"},{"internalType":"uint128","name":"_wcellAmount1Max","type":"uint128"}],"name":"collectTradingFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bool","name":"_getOwner","type":"bool"}],"name":"getToken","outputs":[{"internalType":"address","name":"tokenOwner","type":"address"},{"internalType":"address","name":"approved","type":"address"},{"internalType":"string","name":"uri","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"bool","name":"_getOwner","type":"bool"}],"name":"getTokens","outputs":[{"internalType":"address[]","name":"owners","type":"address[]"},{"internalType":"address[]","name":"approveds","type":"address[]"},{"internalType":"string[]","name":"uris","type":"string[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"hasClaimedAirdrop","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"holders","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"isOwnerOf","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"maskAtIndexOf","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"masksOf","outputs":[{"internalType":"bytes32[]","name":"masks","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"metadata","outputs":[{"internalType":"contract Metadata","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokens","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"pairV2","outputs":[{"internalType":"contract PairV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"salt","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"},{"internalType":"bool","name":"_approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract Metadata","name":"_metadata","type":"address"}],"name":"setMetadata","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"","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":[],"name":"team","outputs":[{"internalType":"contract Team","name":"","type":"address"}],"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":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokens","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokens","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wcellPoolV3","outputs":[{"internalType":"contract PoolV3","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wcellPositionId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wethPoolV3","outputs":[{"internalType":"contract PoolV3","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wethPositionId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

6101606040525f805460ff19169055610200600d5530611000600180546001600160a01b0319166001600160a01b038416178155608082905261010090620000489083620010ea565b6200005491906200111a565b6200006190600162001130565b60a05260066020527f477a984de5936bcb02475f64e0ea676103106ac0785c67bf7e9e846450b51ef68054600160ff1991821681179092557fd544553a2e70858ffdf1e1169f6f124859d29ddf2686bcabf4e6f71bc630442280548216831790557fcc41b8fe3dd37df8e4a56c49f4e83a8fb6899f1fe8f1ddc40678281e8ec62212805482168317905563780e9d6360e01b5f527fa99870648958e45dc5b37a02b811cf5f899ba384167c205b3dcb1f6df5e47372805490911690911790556200012a620006c1565b50505f341162000138575f80fd5b600180546001600160a01b03191673faded72464d6e76e37300b467673b36ecc4d2ccf1790556040516200016c90620010ba565b604051809103905ff08015801562000186573d5f803e3d5ffd5b506001600160a01b031661010052604051620001a290620010c8565b604051809103905ff080158015620001bc573d5f803e3d5ffd5b50600780546001600160a01b0319166001600160a01b039290921691909117905560805161010090620001f190349062001146565b620001fd91906200111a565b60e052604080516312a9293f60e21b8152905130915f917368b3465833fb72a70ecdf485e0e4c7bd8665fc4591634aa4a4fc9160048083019260209291908290030181865afa15801562000253573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019062000279919062001175565b90505f620002a7836001600160a01b0316836001600160a01b03161061100060e051620006e260201b60201c565b5090507368b3465833fb72a70ecdf485e0e4c7bd8665fc456001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002fb573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019062000321919062001175565b60405163a167129560e01b81526001600160a01b03858116600483015284811660248301526127106044830152919091169063a1671295906064016020604051808303815f875af115801562000379573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906200039f919062001175565b6001600160a01b0390811661014081905260405163f637731d60e01b815291831660048301529063f637731d906024015f604051808303815f87803b158015620003e7575f80fd5b505af1158015620003fa573d5f803e3d5ffd5b505050505f73685c401540c103631a0ba7f14a3d16ae3cb4e50b6001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa15801562000450573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620004769190620011b1565b5050505050506001600160a01b0316905060c0818262000497919062001146565b620004ab90670de0b6b3a764000062001146565b901c60c081905260e05162000506916001600160a01b0387167318e5f92103d1b34623738ee79214b1659f2ee10910916110009190620004f490670de0b6b3a764000062001146565b6200050091906200111a565b620006e2565b50809250507368b3465833fb72a70ecdf485e0e4c7bd8665fc456001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200055c573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019062000582919062001175565b60405163a167129560e01b81526001600160a01b0386811660048301527318e5f92103d1b34623738ee79214b1659f2ee10960248301526127106044830152919091169063a1671295906064016020604051808303815f875af1158015620005ec573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019062000612919062001175565b6001600160a01b0390811661012081905260405163f637731d60e01b815291841660048301529063f637731d906024015f604051808303815f87803b1580156200065a575f80fd5b505af11580156200066d573d5f803e3d5ffd5b50505050600143620006809190620010ea565b6040516429b0b63a1d60d91b60208201529040602582015260450160405160208183030381529060405280519060200120600b8190555050505050620012a5565b5f805460ff19166001179055620006d76200076a565b5f805460ff19169055565b5f805f6200072a86620006f65784620006f8565b855b871562000706578562000708565b865b6200071890600160c01b6200111a565b62000724919062001146565b62000a07565b9050620007378162000a52565b91506200074660c88362001259565b6200075290836200127d565b91506200075f8262000d77565b925050935093915050565b5f5b60a0518110156200085757600160a0510381148015620007a15750610100608051816200079d576200079d62001106565b0615155b156200080c5761010060805181620007bd57620007bd62001106565b5f19919006610100031c60025f620007dd6001546001600160a01b031690565b6001600160a01b0316815260208082019290925260409081015f9081208582526001019092529020556200084e565b5f1960025f620008246001546001600160a01b031690565b6001600160a01b0316815260208082019290925260409081015f9081208582526001019092529020555b6001016200076c565b5060805160025f620008716001546001600160a01b031690565b6001600160a01b031681526020808201929092526040015f908120805461ffff191661ffff949094169390931790925560a051600290810a5f190190911b91620008c36001546001600160a01b031690565b6001600160a01b031681526020808201929092526040015f20805463ffffffff166401000000009390921c9290920217905560046200090a6001546001600160a01b031690565b8154600180820184555f93845260209093200180546001600160a01b0319166001600160a01b039283161790559054166001600160a01b03165f6001600160a01b031660405180606001604052806021815260200162009d7f60219139805190602001206080516040516200098191815260200190565b60405180910390a35f5460ff1662000a05575f5b60805181101562000a03576080518101600101620009bb6001546001600160a01b031690565b6001600160a01b03165f6001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a460010162000995565b505b565b80600260018201045b8181101562000a4c5780915060028182858162000a315762000a3162001106565b04018162000a435762000a4362001106565b04905062000a10565b50919050565b5f6401000276a36001600160a01b0383161080159062000a8e575073fffd8963efd1fc6a506488495d951d5263988d266001600160a01b038316105b62000ac45760405162461bcd60e51b81526020600482015260016024820152602960f91b60448201526064015b60405180910390fd5b600160201b600160c01b03602083901b166001600160801b03811160071b81811c6001600160401b03811160061b90811c63ffffffff811160051b90811c61ffff811160041b90811c60ff8111600390811b91821c600f811160021b90811c918211600190811b92831c9790881196179094179092171790911717176080811062000b5857607f810383901c915062000b62565b80607f0383901b91505b908002607f81811c60ff83811c9190911c800280831c81831c1c800280841c81841c1c800280851c81851c1c800280861c81861c1c800280871c81871c1c800280881c81881c1c800280891c81891c1c8002808a1c818a1c1c8002808b1c818b1c1c8002808c1c818c1c1c8002808d1c818d1c1c8002808e1c9c81901c9c909c1c80029c8d901c9e9d607f198f0160401b60c09190911c678000000000000000161760c19b909b1c674000000000000000169a909a1760c29990991c672000000000000000169890981760c39790971c671000000000000000169690961760c49590951c670800000000000000169490941760c59390931c670400000000000000169290921760c69190911c670200000000000000161760c79190911c670100000000000000161760c89190911c6680000000000000161760c99190911c6640000000000000161760ca9190911c6620000000000000161760cb9190911c6610000000000000161760cc9190911c6608000000000000161760cd9190911c66040000000000001617693627a301d71055774c8581026f028f6481ab7f045a5af012a19d003aa9198101608090811d906fdb2df09e81959a81455e260799a0632f8301901d600281810b9083900b1462000d68576001600160a01b03891662000d4a8262000d77565b6001600160a01b0316111562000d61578162000d6a565b8062000d6a565b815b9998505050505050505050565b5f805f8360020b1262000d8e578260020b62000d95565b8260020b5f035b9050620d89e881111562000dd05760405162461bcd60e51b81526020600482015260016024820152601560fa1b604482015260640162000abb565b5f816001165f0362000de757600160801b62000df9565b6ffffcb933bd6fad37aa2d162d1a5940015b6001600160881b03169050600282161562000e24576ffff97272373d413259a46990580e213a0260801c5b600482161562000e44576ffff2e50f5f656932ef12357cf3c7fdcc0260801c5b600882161562000e64576fffe5caca7e10e4e61c3624eaa0941cd00260801c5b601082161562000e84576fffcb9843d60f6159c9db58835c9266440260801c5b602082161562000ea4576fff973b41fa98c081472e6896dfb254c00260801c5b604082161562000ec4576fff2ea16466c96a3843ec78b326b528610260801c5b608082161562000ee4576ffe5dee046a99a2a811c461f1969c30530260801c5b61010082161562000f05576ffcbe86c7900a88aedcffc83b479aa3a40260801c5b61020082161562000f26576ff987a7253ac413176f2b074cf7815e540260801c5b61040082161562000f47576ff3392b0822b70005940c7a398e4b70f30260801c5b61080082161562000f68576fe7159475a2c29b7443b29c7fa6e889d90260801c5b61100082161562000f89576fd097f3bdfd2022b8845ad8f792aa58250260801c5b61200082161562000faa576fa9f746462d870fdf8a65dc1f90e061e50260801c5b61400082161562000fcb576f70d869a156d2a1b890bb3df62baf32f70260801c5b61800082161562000fec576f31be135f97d08fd981231505542fcfa60260801c5b620100008216156200100e576f09aa508b5b7a84e1c677de54f3e99bc90260801c5b620200008216156200102f576e5d6af8dedb81196699c329225ee6040260801c5b620400008216156200104f576d2216e584f5fa1ea926041bedfe980260801c5b620800008216156200106d576b048a170391f7dc42444e8fa20260801c5b5f8460020b13156200109057805f19816200108c576200108c62001106565b0490505b640100000000810615620010a6576001620010a8565b5f5b60ff16602082901c0192505050919050565b61093980620066f283390190565b612d54806200702b83390190565b634e487b7160e01b5f52601160045260245ffd5b81810381811115620011005762001100620010d6565b92915050565b634e487b7160e01b5f52601260045260245ffd5b5f826200112b576200112b62001106565b500490565b80820180821115620011005762001100620010d6565b8082028115828204841417620011005762001100620010d6565b6001600160a01b038116811462000a03575f80fd5b5f6020828403121562001186575f80fd5b8151620011938162001160565b9392505050565b805161ffff81168114620011ac575f80fd5b919050565b5f805f805f805f60e0888a031215620011c8575f80fd5b8751620011d58162001160565b8097505060208801518060020b8114620011ed575f80fd5b9550620011fd604089016200119a565b94506200120d606089016200119a565b93506200121d608089016200119a565b925060a088015160ff8116811462001233575f80fd5b60c0890151909250801515811462001249575f80fd5b8091505092959891949750929550565b5f8260020b806200126e576200126e62001106565b808360020b0791505092915050565b600282810b9082900b03627fffff198112627fffff82131715620011005762001100620010d6565b60805160a05160c05160e05161010051610120516101405161533e620013b45f395f6104b101525f61042601525f818161064201528181610cd701528181610d9201528181610e330152611be001525f818161172401526118e501525f81816118c1015261192e01525f818161094701528181611353015281816120f2015281816122120152613b6c01525f81816103b5015281816109a1015281816109cb01528181610a1701528181610a4101528181610ea901528181610ed30152818161108501528181611215015281816112410152818161127b015281816112a501528181611d8b01528181611db50152818161200a01528181612034015281816123260152613abd015261533e5ff3fe60806040526004361061026a575f3560e01c806370a082311161014a578063a9059cbb116100be578063d28a476111610078578063d28a4761146107a7578063db737c78146107c6578063dd62ed3e146107f4578063e985e9c514610839578063f3cb838514610884578063f4cdda36146108a3575f80fd5b8063a9059cbb146106fb578063b88d4fde1461071a578063bdb4b84814610739578063bfa0b13314610754578063c5b8f77214610769578063c87b56dd14610788575f80fd5b8063888ce1f31161010f578063888ce1f3146106645780638da5cb5b146106795780638fffabed1461069657806395d89b41146106b5578063a0712d68146106c9578063a22cb465146106dc575f80fd5b806370a08231146105985780637c187f7b146105d05780638129fc1c146105fc5780638188f71c1461061057806385f2aef214610631575f80fd5b806324cea3a6116101e15780633d13f874116101a65780633d13f874146104f257806342842e0e146105115780634bce92f3146105305780634bf365df146105455780634f6ccce71461055a5780636352211e14610579575f80fd5b806324cea3a6146104485780632f745c591461045c578063313ce5671461047b578063348fb288146104a0578063392f37e9146104d3575f80fd5b80631078d1ed116102325780631078d1ed1461035557806313af40351461038357806318160ddd146103a457806319781e3c146103d757806323b872dd146103f657806324bfe56514610415575f80fd5b806301ffc9a71461026e57806306fdde03146102b1578063076f4662146102d2578063081812fc146102ff578063095ea7b314610336575b5f80fd5b348015610279575f80fd5b5061029c61028836600461492a565b60066020525f908152604090205460ff1681565b60405190151581526020015b60405180910390f35b3480156102bc575f80fd5b506102c56108d1565b6040516102a89190614999565b3480156102dd575f80fd5b506102f16102ec3660046149bf565b610944565b6040519081526020016102a8565b34801561030a575f80fd5b5061031e6103193660046149ed565b61099e565b6040516001600160a01b0390911681526020016102a8565b348015610341575f80fd5b5061029c610350366004614a04565b610a14565b348015610360575f80fd5b5061037461036f366004614b02565b610a8f565b6040516102a893929190614b8f565b34801561038e575f80fd5b506103a261039d366004614c14565b610c11565b005b3480156103af575f80fd5b506102f17f000000000000000000000000000000000000000000000000000000000000000081565b3480156103e2575f80fd5b506103a26103f1366004614c43565b610c49565b348015610401575f80fd5b5061029c610410366004614c9c565b610ea6565b348015610420575f80fd5b5061031e7f000000000000000000000000000000000000000000000000000000000000000081565b348015610453575f80fd5b506103a2610f8a565b348015610467575f80fd5b506102f1610476366004614a04565b610fa6565b348015610486575f80fd5b5061048e5f81565b60405160ff90911681526020016102a8565b3480156104ab575f80fd5b5061031e7f000000000000000000000000000000000000000000000000000000000000000081565b3480156104de575f80fd5b5060075461031e906001600160a01b031681565b3480156104fd575f80fd5b506103a261050c366004614cda565b6110d4565b34801561051c575f80fd5b506103a261052b366004614c9c565b6111f3565b34801561053b575f80fd5b506102f160085481565b348015610550575f80fd5b506102f1600d5481565b348015610565575f80fd5b506102f16105743660046149ed565b611212565b348015610584575f80fd5b5061031e6105933660046149ed565b611267565b3480156105a3575f80fd5b506102f16105b2366004614c14565b6001600160a01b03165f9081526002602052604090205461ffff1690565b3480156105db575f80fd5b506105ef6105ea366004614c14565b61134f565b6040516102a89190614d5e565b348015610607575f80fd5b506103a26113f5565b34801561061b575f80fd5b50610624611ad8565b6040516102a89190614da1565b34801561063c575f80fd5b5061031e7f000000000000000000000000000000000000000000000000000000000000000081565b34801561066f575f80fd5b506102f160095481565b348015610684575f80fd5b506001546001600160a01b031661031e565b3480156106a1575f80fd5b50600a5461031e906001600160a01b031681565b3480156106c0575f80fd5b506102c5611b3b565b6103a26106d73660046149ed565b611b82565b3480156106e7575f80fd5b506103a26106f6366004614db3565b611c66565b348015610706575f80fd5b5061029c610715366004614a04565b611cd5565b348015610725575f80fd5b506103a2610734366004614e03565b611ce1565b348015610744575f80fd5b506102f167016345785d8a000081565b34801561075f575f80fd5b506102f1600b5481565b348015610774575f80fd5b5061029c610783366004614a04565b611d88565b348015610793575f80fd5b506102c56107a23660046149ed565b611e09565b3480156107b2575f80fd5b506103a26107c1366004614eaa565b611e77565b3480156107d1575f80fd5b506107e56107e0366004614ef6565b611e81565b6040516102a893929190614f17565b3480156107ff575f80fd5b506102f161080e366004614f4b565b6001600160a01b039182165f9081526002602081815260408084209490951683529201909152205490565b348015610844575f80fd5b5061029c610853366004614f4b565b6001600160a01b039182165f9081526002602090815260408083209390941682526003909201909152205460ff1690565b34801561088f575f80fd5b506103a261089e366004614c14565b611eb8565b3480156108ae575f80fd5b5061029c6108bd366004614c14565b600c6020525f908152604090205460ff1681565b600754604080516306fdde0360e01b815290516060926001600160a01b0316916306fdde03916004808301925f9291908290030181865afa158015610918573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261093f9190810190614f77565b905090565b5f7f00000000000000000000000000000000000000000000000000000000000000008310610970575f80fd5b506001600160a01b0381165f9081526002602090815260408083208584526001019091529020545b92915050565b5f7f0000000000000000000000000000000000000000000000000000000000000000821180156109f157507f00000000000000000000000000000000000000000000000000000000000000006002028211155b6109f9575f80fd5b505f908152600360205260409020546001600160a01b031690565b5f7f000000000000000000000000000000000000000000000000000000000000000082118015610a6757507f00000000000000000000000000000000000000000000000000000000000000006002028211155b15610a7b57610a768383611ef0565b610a86565b610a86338484611f9f565b50600192915050565b60608060605f85519050806001600160401b03811115610ab157610ab1614a2e565b604051908082528060200260200182016040528015610ada578160200160208202803683370190505b509350806001600160401b03811115610af557610af5614a2e565b604051908082528060200260200182016040528015610b1e578160200160208202803683370190505b509250806001600160401b03811115610b3957610b39614a2e565b604051908082528060200260200182016040528015610b6c57816020015b6060815260200190600190039081610b575790505b5091505f5b81811015610c0857610b9c878281518110610b8e57610b8e614fdf565b602002602001015187611e81565b878481518110610bae57610bae614fdf565b60200260200101878581518110610bc757610bc7614fdf565b60200260200101878681518110610be057610be0614fdf565b60209081029190910101929092526001600160a01b0392831690915291169052600101610b71565b50509250925092565b6001546001600160a01b03163314610c27575f80fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b5f7368b3465833fb72a70ecdf485e0e4c7bd8665fc456001600160a01b031663791b98bc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c9a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cbe9190614ff3565b6040805160808101825260095481526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660208301526001600160801b038981168385015288166060830152915163fc6f786560e01b81529293509083169163fc6f786591610d389160040161500e565b60408051808303815f875af1158015610d53573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d779190615051565b50506040805160808101825260085481526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660208301526001600160801b038681168385015285166060830152915163fc6f786560e01b81529183169163fc6f786591610df09160040161500e565b60408051808303815f875af1158015610e0b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e2f9190615051565b50507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663476343ee6040518163ffffffff1660e01b81526004015f604051808303815f87803b158015610e89575f80fd5b505af1158015610e9b573d5f803e3d5ffd5b505050505050505050565b5f7f000000000000000000000000000000000000000000000000000000000000000082118015610ef957507f00000000000000000000000000000000000000000000000000000000000000006002028211155b15610f0e57610f09848484612008565b610f80565b6001600160a01b0384165f908152600260208181526040808420338552909201905290205482811015610f3f575f80fd5b5f198114610f73576001600160a01b0385165f90815260026020818152604080842033855290920190529020805484900390555b610f7e8585856121c9565b505b5060019392505050565b610fa46001600160801b03806001600160801b0380610c49565b565b6001600160a01b0382165f9081526002602052604081205461ffff168210610fcc575f80fd5b6001600160a01b0383165f9081526002602052604081205464010000000090046001600160e01b03165b5f811180156110055750838211155b156110cc575f611014826123db565b9050806001901b821891505f61102a8288610944565b90505f61103682613928565b9050868186011161104a57938401936110c4565b815b5f8111801561105b5750878611155b156110c2575f61106a826123db565b60018881019890821b93909318929091508990036110bc57807f000000000000000000000000000000000000000000000000000000000000000086610100020101600101975050505050505050610998565b5061104c565b505b505050610ff6565b505092915050565b6001600160a01b0384165f908152600c602052604090205460ff16156110f8575f80fd5b6111758282808060200260200160405190810160405280939291908181526020018383602002808284375f92019190915250506040516bffffffffffffffffffffffff1960608a901b16602082015260348101889052605401915061115a9050565b604051602081830303815290604052805190602001206139f4565b61117d575f80fd5b6001600160a01b0384165f908152600c60205260409020805460ff191660011790556111aa3085856121c9565b836001600160a01b03167f47cee97cb7acd717b3c0aa1435d004cd5b3c8c57d70dbceb4e4458bbd60e39d4846040516111e591815260200190565b60405180910390a250505050565b61120d83838360405180602001604052805f815250611ce1565b505050565b5f7f0000000000000000000000000000000000000000000000000000000000000000821061123e575f80fd5b507f00000000000000000000000000000000000000000000000000000000000000000160010190565b5f3363ffffffff811615611279575f80fd5b7f0000000000000000000000000000000000000000000000000000000000000000831180156112cb57507f00000000000000000000000000000000000000000000000000000000000000006002028311155b6112d3575f80fd5b5f806112de85613ab6565b60045491935091505f5b81811015611343575f6001600301828154811061130757611307614fdf565b5f918252602090912001546001600160a01b0316905083806113298784610944565b160361133a57979650505050505050565b506001016112e8565b505f9695505050505050565b60607f00000000000000000000000000000000000000000000000000000000000000006001600160401b0381111561138957611389614a2e565b6040519080825280602002602001820160405280156113b2578160200160208202803683370190505b5090505f5b81518110156113ef576113ca8184610944565b8282815181106113dc576113dc614fdf565b60209081029190910101526001016113b7565b50919050565b5f805460ff19166001179055600a546001600160a01b031615611416575f80fd5b5f3090505f7368b3465833fb72a70ecdf485e0e4c7bd8665fc456001600160a01b0316634aa4a4fc6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561146b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061148f9190614ff3565b90506114b282737a250d5630b4cf539739df2c5dacb4c659f2488d610100611f9f565b737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015611502573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115269190614ff3565b6040516364e329cb60e11b81526001600160a01b0383811660048301528481166024830152919091169063c9c65396906044016020604051808303815f875af1158015611575573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115999190614ff3565b600a80546001600160a01b039283166001600160a01b0319909116179055737a250d5630b4cf539739df2c5dacb4c659f2488d9063f305d71990841631846101005f806115ee6001546001600160a01b031690565b60405160e088901b6001600160e01b03191681526001600160a01b03958616600482015260248101949094526044840192909252606483015290911660848201524260a482015260c40160606040518083038185885af1158015611654573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906116799190615073565b5050505f7368b3465833fb72a70ecdf485e0e4c7bd8665fc456001600160a01b031663791b98bc6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116cd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116f19190614ff3565b905061170b83826117066105006101006150b2565b611f9f565b6001600160a01b03808416908316105f611748826110007f0000000000000000000000000000000000000000000000000000000000000000613af3565b9150505f611764836110006a52b7d2dcc80cd2e4000000613af3565b915050836001600160a01b031663883164566040518061016001604052808661178d578961178f565b885b6001600160a01b0316815260200186156117a957896117ab565b885b6001600160a01b031681526127106020820152604001866117cc57856117ce565b845b60020b815260200186156117e257856117e4565b845b60020b8152602001866117f9576105006117fb565b5f5b8152602001861561180e57610500611810565b5f5b81526020015f81526020015f8152602001896001600160a01b03168152602001428152506040518263ffffffff1660e01b815260040161185091906150c5565b6080604051808303815f875af115801561186c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118909190615189565b5050506009556001600160a01b0386167318e5f92103d1b34623738ee79214b1659f2ee109109250611921836110007f00000000000000000000000000000000000000000000000000000000000000006119127f0000000000000000000000000000000000000000000000000000000000000000670de0b6b3a76400006151c4565b61191c91906151ef565b613af3565b925061196a9050836110007f00000000000000000000000000000000000000000000000000000000000000006119126a52b7d2dcc80cd2e4000000670de0b6b3a76400006151c4565b905080915050836001600160a01b031663883164566040518061016001604052808661199657896119ac565b7318e5f92103d1b34623738ee79214b1659f2ee1095b6001600160a01b0316815260200186156119c657896119dc565b7318e5f92103d1b34623738ee79214b1659f2ee1095b6001600160a01b031681526127106020820152604001866119fd57856119ff565b845b60020b81526020018615611a135785611a15565b845b60020b815260200186611a2a57610100611a2c565b5f5b81526020018615611a3f57610100611a41565b5f5b81526020015f81526020015f8152602001896001600160a01b03168152602001428152506040518263ffffffff1660e01b8152600401611a8191906150c5565b6080604051808303815f875af1158015611a9d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ac19190615189565b50505060085550505f805460ff1916905550505050565b60606001600301805480602002602001604051908101604052809291908181526020018280548015611b3157602002820191905f5260205f20905b81546001600160a01b03168152600190910190602001808311611b13575b5050505050905090565b600754604080516395d89b4160e01b815290516060926001600160a01b0316916395d89b41916004808301925f9291908290030181865afa158015610918573d5f803e3d5ffd5b600d54811115611b90575f80fd5b5f611ba367016345785d8a0000836151c4565b905080341015611bb1575f80fd5b81600d5f828254611bc29190615202565b90915550611bd390503033846121c9565b6040516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169082156108fc029083905f818181858888f19350505050158015611c26573d5f803e3d5ffd5b5080341115611c6257336108fc611c3d8334615202565b6040518115909202915f818181858888f1935050505015801561120d573d5f803e3d5ffd5b5050565b335f8181526002602090815260408083206001600160a01b0387168085526003909101835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b5f610a863384846121c9565b611cec848484612008565b823b63ffffffff811615611d8157604051630a85bd0160e11b808252906001600160a01b0386169063150b7a0290611d2e9033908a9089908990600401615215565b6020604051808303815f875af1158015611d4a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d6e9190615251565b6001600160e01b03191614611d81575f80fd5b5050505050565b5f7f000000000000000000000000000000000000000000000000000000000000000082118015611ddb57507f00000000000000000000000000000000000000000000000000000000000000006002028211155b611de3575f80fd5b5f80611dee84613ab6565b915091508081611dfe8488610944565b161495945050505050565b60075460405163c87b56dd60e01b8152600481018390526060916001600160a01b03169063c87b56dd906024015f60405180830381865afa158015611e50573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526109989190810190614f77565b611c628282613b69565b5f80606083611e90575f611e99565b611e9985611267565b611ea28661099e565b611eab87611e09565b9250925092509250925092565b6001546001600160a01b03163314611ece575f80fd5b600780546001600160a01b0319166001600160a01b0392909216919091179055565b5f80611efb83613ab6565b915091508081611f0b8433610944565b1614611f15575f80fd5b5f83815260036020908152604080832080546001600160a01b0389166001600160a01b03199091168117909155338085526002909352818420805461ffff6201000080830482166001019091160263ffff000019909116179055905186939192917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a450505050565b6001600160a01b038084165f81815260026020818152604080842095881680855295909201815291819020859055805160608101909152602180825290916152c7908301398051906020012083604051611ffb91815260200190565b60405180910390a3505050565b7f00000000000000000000000000000000000000000000000000000000000000008111801561205a57507f00000000000000000000000000000000000000000000000000000000000000006002028111155b612062575f80fd5b5f8061206d83613ab6565b91509150808161207d8488610944565b1614612087575f80fd5b336001600160a01b03861614806120b757506120a28361099e565b6001600160a01b0316336001600160a01b0316145b806120e757506001600160a01b0385165f90815260026020908152604080832033845260030190915290205460ff165b6120ef575f80fd5b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160401b0381111561212857612128614a2e565b604051908082528060200260200182016040528015612151578160200160208202803683370190505b5090508181848151811061216757612167614fdf565b60209081029190910101526040805160018082528183019092525f9181602001602082028036833701905050905084815f815181106121a8576121a8614fdf565b6020026020010181815250506121c087878484613cf4565b50505050505050565b5f80826001600160401b038111156121e3576121e3614a2e565b60405190808252806020026020018201604052801561220c578160200160208202803683370190505b5090505f7f00000000000000000000000000000000000000000000000000000000000000006001600160401b0381111561224857612248614a2e565b604051908082528060200260200182016040528015612271578160200160208202803683370190505b506001600160a01b0387165f9081526002602052604090205490915064010000000090046001600160e01b03165b5f811180156122ad57508484105b156123c4575f6122bc826123db565b9050806001901b821891505f6122d2828a610944565b9050805b5f811180156122e457508787105b1561237d575f6122f3826123db565b86519091506001821b90819088908790811061231157612311614fdf565b602002602001018181511791508181525050817f000000000000000000000000000000000000000000000000000000000000000086610100020101600101888a806001019b508151811061236757612367614fdf565b60209081029190910101529190911890506122d6565b84838151811061238f5761238f614fdf565b60200260200101518584815181106123a9576123a9614fdf565b60200260200101518316146123bc575f80fd5b50505061229f565b8484146123cf575f80fd5b6121c087878486613cf4565b5f5f198201198216600160801b811015612eb4576801000000000000000081101561292d5764010000000081101561266a576201000081101561252d5761010081101561249f576010811015612460576004811015612445576002811015610a8657505f92915050565b60088110156124575750600292915050565b50600392915050565b604081101561248457602081101561247b5750600492915050565b50600592915050565b60808110156124965750600692915050565b50600792915050565b6110008110156124eb576104008110156124cf576102008110156124c65750600892915050565b50600992915050565b6108008110156124e25750600a92915050565b50600b92915050565b614000811015612511576120008110156125085750600c92915050565b50600d92915050565b6180008110156125245750600e92915050565b50600f92915050565b63010000008110156125ce5762100000811015612589576204000081101561256c57620200008110156125635750601092915050565b50601192915050565b620800008110156125805750601292915050565b50601392915050565b624000008110156125b157622000008110156125a85750601492915050565b50601592915050565b628000008110156125c55750601692915050565b50601792915050565b63100000008110156126225763040000008110156126045763020000008110156125fb5750601892915050565b50601992915050565b63080000008110156126195750601a92915050565b50601b92915050565b634000000081101561264c5763200000008110156126435750601c92915050565b50601d92915050565b63800000008110156126615750601e92915050565b50601f92915050565b66010000000000008110156127d4576501000000000081101561272a576410000000008110156126df576404000000008110156126c0576402000000008110156126b75750602092915050565b50602192915050565b6408000000008110156126d65750602292915050565b50602392915050565b64400000000081101561270b576420000000008110156127025750602492915050565b50602592915050565b6480000000008110156127215750602692915050565b50602792915050565b651000000000008110156127865765040000000000811015612766576502000000000081101561275d5750602892915050565b50602992915050565b6508000000000081101561277d5750602a92915050565b50602b92915050565b654000000000008110156127b457652000000000008110156127ab5750602c92915050565b50602d92915050565b658000000000008110156127cb5750602e92915050565b50602f92915050565b600160381b81101561289157661000000000000081101561284057660400000000000081101561281f5766020000000000008110156128165750603092915050565b50603192915050565b66080000000000008110156128375750603292915050565b50603392915050565b66400000000000008110156128705766200000000000008110156128675750603492915050565b50603592915050565b66800000000000008110156128885750603692915050565b50603792915050565b6001603c1b8110156128e5576001603a1b8110156128c757600160391b8110156128be5750603892915050565b50603992915050565b6001603b1b8110156128dc5750603a92915050565b50603b92915050565b6001603e1b81101561290f576001603d1b8110156129065750603c92915050565b50603d92915050565b6001603f1b8110156129245750603e92915050565b50603f92915050565b600160601b811015612c2057600160501b811015612adc576901000000000000000000811015612a1657681000000000000000008110156129bf576804000000000000000081101561299c57680200000000000000008110156129935750604092915050565b50604192915050565b680800000000000000008110156129b65750604292915050565b50604392915050565b684000000000000000008110156129f357682000000000000000008110156129ea5750604492915050565b50604592915050565b68800000000000000000811015612a0d5750604692915050565b50604792915050565b6910000000000000000000811015612a82576904000000000000000000811015612a5e576902000000000000000000811015612a555750604892915050565b50604992915050565b6908000000000000000000811015612a795750604a92915050565b50604b92915050565b6940000000000000000000811015612ab8576920000000000000000000811015612aaf5750604c92915050565b50604d92915050565b6980000000000000000000811015612ad35750604e92915050565b50604f92915050565b600160581b811015612b8457600160541b811015612b3c57600160521b811015612b1e57600160511b811015612b155750605092915050565b50605192915050565b600160531b811015612b335750605292915050565b50605392915050565b600160561b811015612b6657600160551b811015612b5d5750605492915050565b50605592915050565b600160571b811015612b7b5750605692915050565b50605792915050565b6001605c1b811015612bd8576001605a1b811015612bba57600160591b811015612bb15750605892915050565b50605992915050565b6001605b1b811015612bcf5750605a92915050565b50605b92915050565b6001605e1b811015612c02576001605d1b811015612bf95750605c92915050565b50605d92915050565b6001605f1b811015612c175750605e92915050565b50605f92915050565b600160701b811015612d7057600160681b811015612cd457600160641b811015612c8c57600160621b811015612c6e57600160611b811015612c655750606092915050565b50606192915050565b600160631b811015612c835750606292915050565b50606392915050565b600160661b811015612cb657600160651b811015612cad5750606492915050565b50606592915050565b600160671b811015612ccb5750606692915050565b50606792915050565b6001606c1b811015612d28576001606a1b811015612d0a57600160691b811015612d015750606892915050565b50606992915050565b6001606b1b811015612d1f5750606a92915050565b50606b92915050565b6001606e1b811015612d52576001606d1b811015612d495750606c92915050565b50606d92915050565b6001606f1b811015612d675750606e92915050565b50606f92915050565b600160781b811015612e1857600160741b811015612dd057600160721b811015612db257600160711b811015612da95750607092915050565b50607192915050565b600160731b811015612dc75750607292915050565b50607392915050565b600160761b811015612dfa57600160751b811015612df15750607492915050565b50607592915050565b600160771b811015612e0f5750607692915050565b50607792915050565b6001607c1b811015612e6c576001607a1b811015612e4e57600160791b811015612e455750607892915050565b50607992915050565b6001607b1b811015612e635750607a92915050565b50607b92915050565b6001607e1b811015612e96576001607d1b811015612e8d5750607c92915050565b50607d92915050565b6001607f1b811015612eab5750607e92915050565b50607f92915050565b600160c01b8110156133f457600160a01b81101561316057600160901b81101561301c57600160881b811015612f8057600160841b811015612f3857600160821b811015612f1a57600160811b811015612f115750608092915050565b50608192915050565b600160831b811015612f2f5750608292915050565b50608392915050565b600160861b811015612f6257600160851b811015612f595750608492915050565b50608592915050565b600160871b811015612f775750608692915050565b50608792915050565b6001608c1b811015612fd4576001608a1b811015612fb657600160891b811015612fad5750608892915050565b50608992915050565b6001608b1b811015612fcb5750608a92915050565b50608b92915050565b6001608e1b811015612ffe576001608d1b811015612ff55750608c92915050565b50608d92915050565b6001608f1b8110156130135750608e92915050565b50608f92915050565b600160981b8110156130c457600160941b81101561307c57600160921b81101561305e57600160911b8110156130555750609092915050565b50609192915050565b600160931b8110156130735750609292915050565b50609392915050565b600160961b8110156130a657600160951b81101561309d5750609492915050565b50609592915050565b600160971b8110156130bb5750609692915050565b50609792915050565b6001609c1b811015613118576001609a1b8110156130fa57600160991b8110156130f15750609892915050565b50609992915050565b6001609b1b81101561310f5750609a92915050565b50609b92915050565b6001609e1b811015613142576001609d1b8110156131395750609c92915050565b50609d92915050565b6001609f1b8110156131575750609e92915050565b50609f92915050565b600160b01b8110156132b057600160a81b81101561321457600160a41b8110156131cc57600160a21b8110156131ae57600160a11b8110156131a5575060a092915050565b5060a192915050565b600160a31b8110156131c3575060a292915050565b5060a392915050565b600160a61b8110156131f657600160a51b8110156131ed575060a492915050565b5060a592915050565b600160a71b81101561320b575060a692915050565b5060a792915050565b600160ac1b81101561326857600160aa1b81101561324a57600160a91b811015613241575060a892915050565b5060a992915050565b600160ab1b81101561325f575060aa92915050565b5060ab92915050565b600160ae1b81101561329257600160ad1b811015613289575060ac92915050565b5060ad92915050565b600160af1b8110156132a7575060ae92915050565b5060af92915050565b600160b81b81101561335857600160b41b81101561331057600160b21b8110156132f257600160b11b8110156132e9575060b092915050565b5060b192915050565b600160b31b811015613307575060b292915050565b5060b392915050565b600160b61b81101561333a57600160b51b811015613331575060b492915050565b5060b592915050565b600160b71b81101561334f575060b692915050565b5060b792915050565b600160bc1b8110156133ac57600160ba1b81101561338e57600160b91b811015613385575060b892915050565b5060b992915050565b600160bb1b8110156133a3575060ba92915050565b5060bb92915050565b600160be1b8110156133d657600160bd1b8110156133cd575060bc92915050565b5060bd92915050565b600160bf1b8110156133eb575060be92915050565b5060bf92915050565b600160e01b81101561369457600160d01b81101561355057600160c81b8110156134b457600160c41b81101561346c57600160c21b81101561344e57600160c11b811015613445575060c092915050565b5060c192915050565b600160c31b811015613463575060c292915050565b5060c392915050565b600160c61b81101561349657600160c51b81101561348d575060c492915050565b5060c592915050565b600160c71b8110156134ab575060c692915050565b5060c792915050565b600160cc1b81101561350857600160ca1b8110156134ea57600160c91b8110156134e1575060c892915050565b5060c992915050565b600160cb1b8110156134ff575060ca92915050565b5060cb92915050565b600160ce1b81101561353257600160cd1b811015613529575060cc92915050565b5060cd92915050565b600160cf1b811015613547575060ce92915050565b5060cf92915050565b600160d81b8110156135f857600160d41b8110156135b057600160d21b81101561359257600160d11b811015613589575060d092915050565b5060d192915050565b600160d31b8110156135a7575060d292915050565b5060d392915050565b600160d61b8110156135da57600160d51b8110156135d1575060d492915050565b5060d592915050565b600160d71b8110156135ef575060d692915050565b5060d792915050565b600160dc1b81101561364c57600160da1b81101561362e57600160d91b811015613625575060d892915050565b5060d992915050565b600160db1b811015613643575060da92915050565b5060db92915050565b600160de1b81101561367657600160dd1b81101561366d575060dc92915050565b5060dd92915050565b600160df1b81101561368b575060de92915050565b5060df92915050565b600160f01b8110156137e457600160e81b81101561374857600160e41b81101561370057600160e21b8110156136e257600160e11b8110156136d9575060e092915050565b5060e192915050565b600160e31b8110156136f7575060e292915050565b5060e392915050565b600160e61b81101561372a57600160e51b811015613721575060e492915050565b5060e592915050565b600160e71b81101561373f575060e692915050565b5060e792915050565b600160ec1b81101561379c57600160ea1b81101561377e57600160e91b811015613775575060e892915050565b5060e992915050565b600160eb1b811015613793575060ea92915050565b5060eb92915050565b600160ee1b8110156137c657600160ed1b8110156137bd575060ec92915050565b5060ed92915050565b600160ef1b8110156137db575060ee92915050565b5060ef92915050565b600160f81b81101561388c57600160f41b81101561384457600160f21b81101561382657600160f11b81101561381d575060f092915050565b5060f192915050565b600160f31b81101561383b575060f292915050565b5060f392915050565b600160f61b81101561386e57600160f51b811015613865575060f492915050565b5060f592915050565b600160f71b811015613883575060f692915050565b5060f792915050565b600160fc1b8110156138e057600160fa1b8110156138c257600160f91b8110156138b9575060f892915050565b5060f992915050565b600160fb1b8110156138d7575060fa92915050565b5060fb92915050565b600160fe1b81101561390a57600160fd1b811015613901575060fc92915050565b5060fd92915050565b600160ff1b81101561391f575060fe92915050565b5060ff92915050565b5f8180820361393957505f92915050565b5f19810361394b575061010092915050565b7f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f7f5555555555555555555555555555555555555555555555555555555555555555600183901c16909103600281901c7f3333333333333333333333333333333333333333333333333333333333333333908116911601600481901c01167f01010101010101010101010101010101010101010101010101010101010101010260f81c92915050565b5f81815b8451811015613a8c575f858281518110613a1457613a14614fdf565b60200260200101519050808311613a56576040805160208101859052908101829052606001604051602081830303815290604052805190602001209250613a83565b60408051602081018390529081018490526060016040516020818303038152906040528051906020012092505b506001016139f8565b507f3f856c8d1611023aaa9915c692b07293eea0d4dd7c26df3914d5bfbd430ce84c149392505050565b6101005f197f0000000000000000000000000000000000000000000000000000000000000000808403820183900494600193860290940303011b90565b5f805f613b3186613b045784613b06565b855b8715613b125785613b14565b865b613b2290600160c01b6151ef565b613b2c91906151c4565b6140dd565b9050613b3c8161411a565b9150613b4960c88361526c565b613b53908361528d565b9150613b5e82614416565b925050935093915050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160401b03811115613ba257613ba2614a2e565b604051908082528060200260200182016040528015613bcb578160200160208202803683370190505b5090505f5b8251811015613c2f575f80613bfd858481518110613bf057613bf0614fdf565b6020026020010151613ab6565b9150915080848381518110613c1457613c14614fdf565b60209081029190910101805190911790525050600101613bd0565b505f805b8251811015613cd557828181518110613c4e57613c4e614fdf565b60200260200101515f801b14613ccd57828181518110613c7057613c70614fdf565b6020026020010151838281518110613c8a57613c8a614fdf565b6020026020010151613c9c8333610944565b1614613ca6575f80fd5b613cc8838281518110613cbb57613cbb614fdf565b6020026020010151613928565b820191505b600101613c33565b5082518114613ce2575f80fd5b613cee33858486613cf4565b50505050565b6001600160a01b038316613d06575f80fd5b5f815111613d12575f80fd5b613d1e84848484614744565b6001600160a01b038085165f908152600260205260408082205492861682528120546001600160e01b036401000000009384900481169390910416905b8451811015613e5e575f801b858281518110613d7957613d79614fdf565b602002602001015114613e56575f613d918289610944565b9050858281518110613da557613da5614fdf565b6020908102919091018101516001600160a01b038a165f908152600283526040808220868352600101909352918220921891829055613de48389610944565b9050868381518110613df857613df8614fdf565b6020908102919091018101516001600160a01b038a165f908152600283526040808220878352600101909352918220921791829055829003613e3e57826001901b851894505b6001831b939093179281811615613e53575f80fd5b50505b600101613d5b565b506001600160a01b038681165f908152600260205260408082208054875161ffff8083169190910380821663ffff0000938416176401000000006001600160e01b038b8116820292909217909555968c16865293852080548a5197891690940292841693821696870190911692909217179055919082900361401f576001600160a01b0388165f9081526005602052604081205490829003613f4e578760016003018281548110613f1157613f11614fdf565b5f91825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918a168152600590915260409020819055614001565b600480545f91905f198101908110613f6857613f68614fdf565b5f91825260209091200154600480546001600160a01b039092169250829184908110613f9657613f96614fdf565b5f91825260208083209190910180546001600160a01b0319166001600160a01b0394851617905591831681526005909152604090208290556004805480613fdf57613fdf6152b2565b5f8281526020902081015f1990810180546001600160a01b0319169055019055505b506001600160a01b0388165f90815260056020526040812055614086565b805f0361408657600480546001810182557f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0180546001600160a01b0319166001600160a01b038a1690811790915590545f918252600560205260409091205f1990910190555b866001600160a01b0316886001600160a01b03166040518060600160405280602181526020016152e8602191398051906020012087516040516140cb91815260200190565b60405180910390a35050505050505050565b80600260018201045b818110156113ef57809150600281828581614103576141036151db565b040181614112576141126151db565b0490506140e6565b5f6401000276a36001600160a01b03831610801590614155575073fffd8963efd1fc6a506488495d951d5263988d266001600160a01b038316105b61418a5760405162461bcd60e51b81526020600482015260016024820152602960f91b60448201526064015b60405180910390fd5b640100000000600160c01b03602083901b166001600160801b03811160071b81811c6001600160401b03811160061b90811c63ffffffff811160051b90811c61ffff811160041b90811c60ff8111600390811b91821c600f811160021b90811c918211600190811b92831c9790881196179094179092171790911717176080811061421d57607f810383901c9150614227565b80607f0383901b91505b908002607f81811c60ff83811c9190911c800280831c81831c1c800280841c81841c1c800280851c81851c1c800280861c81861c1c800280871c81871c1c800280881c81881c1c800280891c81891c1c8002808a1c818a1c1c8002808b1c818b1c1c8002808c1c818c1c1c8002808d1c818d1c1c8002808e1c9c81901c9c909c1c80029c8d901c9e9d607f198f0160401b60c09190911c6001603f1b161760c19b909b1c6001603e1b169a909a1760c29990991c6001603d1b169890981760c39790971c6001603c1b169690961760c49590951c6001603b1b169490941760c59390931c6001603a1b169290921760c69190911c600160391b161760c79190911c600160381b161760c89190911c6680000000000000161760c99190911c6640000000000000161760ca9190911c6620000000000000161760cb9190911c6610000000000000161760cc9190911c6608000000000000161760cd9190911c66040000000000001617693627a301d71055774c8581026f028f6481ab7f045a5af012a19d003aa9198101608090811d906fdb2df09e81959a81455e260799a0632f8301901d600281810b9083900b1461440757886001600160a01b03166143ec82614416565b6001600160a01b031611156144015781614409565b80614409565b815b9998505050505050505050565b5f805f8360020b1261442b578260020b614432565b8260020b5f035b9050620d89e881111561446b5760405162461bcd60e51b81526020600482015260016024820152601560fa1b6044820152606401614181565b5f816001165f0361448057600160801b614492565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff16905060028216156144c6576ffff97272373d413259a46990580e213a0260801c5b60048216156144e5576ffff2e50f5f656932ef12357cf3c7fdcc0260801c5b6008821615614504576fffe5caca7e10e4e61c3624eaa0941cd00260801c5b6010821615614523576fffcb9843d60f6159c9db58835c9266440260801c5b6020821615614542576fff973b41fa98c081472e6896dfb254c00260801c5b6040821615614561576fff2ea16466c96a3843ec78b326b528610260801c5b6080821615614580576ffe5dee046a99a2a811c461f1969c30530260801c5b6101008216156145a0576ffcbe86c7900a88aedcffc83b479aa3a40260801c5b6102008216156145c0576ff987a7253ac413176f2b074cf7815e540260801c5b6104008216156145e0576ff3392b0822b70005940c7a398e4b70f30260801c5b610800821615614600576fe7159475a2c29b7443b29c7fa6e889d90260801c5b611000821615614620576fd097f3bdfd2022b8845ad8f792aa58250260801c5b612000821615614640576fa9f746462d870fdf8a65dc1f90e061e50260801c5b614000821615614660576f70d869a156d2a1b890bb3df62baf32f70260801c5b618000821615614680576f31be135f97d08fd981231505542fcfa60260801c5b620100008216156146a1576f09aa508b5b7a84e1c677de54f3e99bc90260801c5b620200008216156146c1576e5d6af8dedb81196699c329225ee6040260801c5b620400008216156146e0576d2216e584f5fa1ea926041bedfe980260801c5b620800008216156146fd576b048a170391f7dc42444e8fa20260801c5b5f8460020b131561471c57805f1981614718576147186151db565b0490505b640100000000810615614730576001614732565b5f5b60ff16602082901c0192505050919050565b5f80546001600160a01b0386168252600260205260409091205460ff9091169062010000900461ffff16158080156147795750815b61490a575f5b83518110156121c057811580156147c957505f6001600160a01b03166147bd8583815181106147b0576147b0614fdf565b602002602001015161099e565b6001600160a01b031614155b156148a2576001600160a01b0387165f90815260026020526040812080545f1961ffff62010000808404821692909201160263ffff0000199091161790558451600390829087908590811061482057614820614fdf565b602002602001015181526020019081526020015f205f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555083818151811061486a5761486a614fdf565b60209081029190910101516040515f9081907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925908290a45b82614902578381815181106148b9576148b9614fdf565b6020026020010151866001600160a01b0316886001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b60010161477f565b505050505050565b6001600160e01b031981168114614927575f80fd5b50565b5f6020828403121561493a575f80fd5b813561494581614912565b9392505050565b5f5b8381101561496657818101518382015260200161494e565b50505f910152565b5f815180845261498581602086016020860161494c565b601f01601f19169290920160200192915050565b602081525f614945602083018461496e565b6001600160a01b0381168114614927575f80fd5b5f80604083850312156149d0575f80fd5b8235915060208301356149e2816149ab565b809150509250929050565b5f602082840312156149fd575f80fd5b5035919050565b5f8060408385031215614a15575f80fd5b8235614a20816149ab565b946020939093013593505050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b0381118282101715614a6a57614a6a614a2e565b604052919050565b5f82601f830112614a81575f80fd5b813560206001600160401b03821115614a9c57614a9c614a2e565b8160051b614aab828201614a42565b9283528481018201928281019087851115614ac4575f80fd5b83870192505b84831015614ae357823582529183019190830190614aca565b979650505050505050565b80358015158114614afd575f80fd5b919050565b5f8060408385031215614b13575f80fd5b82356001600160401b03811115614b28575f80fd5b614b3485828601614a72565b925050614b4360208401614aee565b90509250929050565b5f815180845260208085019450602084015f5b83811015614b845781516001600160a01b031687529582019590820190600101614b5f565b509495945050505050565b606081525f614ba16060830186614b4c565b602083820381850152614bb48287614b4c565b915083820360408501528185518084528284019150828160051b8501018388015f5b83811015614c0457601f19878403018552614bf283835161496e565b94860194925090850190600101614bd6565b50909a9950505050505050505050565b5f60208284031215614c24575f80fd5b8135614945816149ab565b6001600160801b0381168114614927575f80fd5b5f805f8060808587031215614c56575f80fd5b8435614c6181614c2f565b93506020850135614c7181614c2f565b92506040850135614c8181614c2f565b91506060850135614c9181614c2f565b939692955090935050565b5f805f60608486031215614cae575f80fd5b8335614cb9816149ab565b92506020840135614cc9816149ab565b929592945050506040919091013590565b5f805f8060608587031215614ced575f80fd5b8435614cf8816149ab565b93506020850135925060408501356001600160401b0380821115614d1a575f80fd5b818701915087601f830112614d2d575f80fd5b813581811115614d3b575f80fd5b8860208260051b8501011115614d4f575f80fd5b95989497505060200194505050565b602080825282518282018190525f9190848201906040850190845b81811015614d9557835183529284019291840191600101614d79565b50909695505050505050565b602081525f6149456020830184614b4c565b5f8060408385031215614dc4575f80fd5b8235614dcf816149ab565b9150614b4360208401614aee565b5f6001600160401b03821115614df557614df5614a2e565b50601f01601f191660200190565b5f805f8060808587031215614e16575f80fd5b8435614e21816149ab565b93506020850135614e31816149ab565b92506040850135915060608501356001600160401b03811115614e52575f80fd5b8501601f81018713614e62575f80fd5b8035614e75614e7082614ddd565b614a42565b818152886020838501011115614e89575f80fd5b816020840160208301375f6020838301015280935050505092959194509250565b5f8060408385031215614ebb575f80fd5b8235614ec6816149ab565b915060208301356001600160401b03811115614ee0575f80fd5b614eec85828601614a72565b9150509250929050565b5f8060408385031215614f07575f80fd5b82359150614b4360208401614aee565b6001600160a01b038481168252831660208201526060604082018190525f90614f429083018461496e565b95945050505050565b5f8060408385031215614f5c575f80fd5b8235614f67816149ab565b915060208301356149e2816149ab565b5f60208284031215614f87575f80fd5b81516001600160401b03811115614f9c575f80fd5b8201601f81018413614fac575f80fd5b8051614fba614e7082614ddd565b818152856020838501011115614fce575f80fd5b614f4282602083016020860161494c565b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215615003575f80fd5b8151614945816149ab565b815181526020808301516001600160a01b0316908201526040808301516001600160801b0390811691830191909152606092830151169181019190915260800190565b5f8060408385031215615062575f80fd5b505080516020909101519092909150565b5f805f60608486031215615085575f80fd5b8351925060208401519150604084015190509250925092565b634e487b7160e01b5f52601160045260245ffd5b808201808211156109985761099861509e565b81516001600160a01b03168152610160810160208301516150f160208401826001600160a01b03169052565b506040830151615108604084018262ffffff169052565b50606083015161511d606084018260020b9052565b506080830151615132608084018260020b9052565b5060a083015160a083015260c083015160c083015260e083015160e083015261010080840151818401525061012080840151615178828501826001600160a01b03169052565b505061014092830151919092015290565b5f805f806080858703121561519c575f80fd5b8451935060208501516151ae81614c2f565b6040860151606090960151949790965092505050565b80820281158282048414176109985761099861509e565b634e487b7160e01b5f52601260045260245ffd5b5f826151fd576151fd6151db565b500490565b818103818111156109985761099861509e565b6001600160a01b03858116825284166020820152604081018390526080606082018190525f906152479083018461496e565b9695505050505050565b5f60208284031215615261575f80fd5b815161494581614912565b5f8260020b8061527e5761527e6151db565b808360020b0791505092915050565b600282810b9082900b03627fffff198112627fffff821317156109985761099861509e565b634e487b7160e01b5f52603160045260245ffdfe417070726f76616c28616464726573732c616464726573732c75696e74323536295472616e7366657228616464726573732c616464726573732c75696e7432353629a264697066735822122069d46335cf5f96540b8e9eb83f90e3f81428e4e7c384d4ff3c208ef923e6acea64736f6c6343000818003360a060405234801561000f575f80fd5b503360805261003373faded72464d6e76e37300b467673b36ecc4d2ccf6004610057565b61005273ec513e5959dbb02f314fc2f30041fca2685119f36001610057565b61012a565b604080518082019091526001600160a01b038381168252602082018381525f80546001808201835582805294517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563600290920291820180546001600160a01b031916919095161790935590517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e564909201919091558154839291906100fc908490610105565b90915550505050565b8082018082111561012457634e487b7160e01b5f52601160045260245ffd5b92915050565b6080516107e96101505f395f8181610150015281816101b4015261044d01526107e95ff3fe608060405260043610610071575f3560e01c806357a858fc1161004c57806357a858fc146100ce578063894760691461010c578063e086e5ec1461012b578063fc0c546a1461013f575f80fd5b80633a98ef391461007c578063476343ee146100a45780634c02f62e146100ba575f80fd5b3661007857005b5f80fd5b348015610087575f80fd5b5061009160015481565b6040519081526020015b60405180910390f35b3480156100af575f80fd5b506100b861018a565b005b3480156100c5575f80fd5b506100b86101da565b3480156100d9575f80fd5b506100ed6100e83660046106b9565b610251565b604080516001600160a01b03909316835260208301919091520161009b565b348015610117575f80fd5b506100b86101263660046106e4565b610286565b348015610136575f80fd5b506100b861061b565b34801561014a575f80fd5b506101727f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161009b565b6101926101da565b6101af7318e5f92103d1b34623738ee79214b1659f2ee109610286565b6101d87f0000000000000000000000000000000000000000000000000000000000000000610286565b565b6101d87368b3465833fb72a70ecdf485e0e4c7bd8665fc456001600160a01b0316634aa4a4fc6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561022d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101269190610706565b5f818154811061025f575f80fd5b5f918252602090912060029091020180546001909101546001600160a01b03909116915082565b5f7368b3465833fb72a70ecdf485e0e4c7bd8665fc456001600160a01b0316634aa4a4fc6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102fb9190610706565b9050806001600160a01b0316826001600160a01b0316036103db576040516370a0823160e01b81523060048201526001600160a01b03821690632e1a7d4d9082906370a0823190602401602060405180830381865afa158015610360573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103849190610721565b6040518263ffffffff1660e01b81526004016103a291815260200190565b5f604051808303815f87803b1580156103b9575f80fd5b505af11580156103cb573d5f803e3d5ffd5b505050506103d761061b565b5050565b6040516370a0823160e01b81523060048201525f906001600160a01b038416906370a0823190602401602060405180830381865afa15801561041f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104439190610721565b90508015610616577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b03160361052957826001600160a01b031663a9059cbb5f80815481106104a5576104a5610738565b5f91825260209091206002909102015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602481018490526044016020604051808303815f875af11580156104ff573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610523919061074c565b50505050565b5f5b5f54811015610523575f80828154811061054757610547610738565b5f9182526020918290206040805180820190915260029092020180546001600160a01b03908116808452600192830154948401859052915492945088169263a9059cbb9290610596908861076b565b6105a09190610794565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303815f875af11580156105e8573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061060c919061074c565b505060010161052b565b505050565b4780156106b6575f5b5f548110156103d7575f80828154811061064057610640610738565b5f9182526020918290206040805180820190915260029092020180546001600160a01b03168083526001918201549383018490529054919350916108fc9190610689908761076b565b6106939190610794565b6040518115909202915f818181858888f150506001909401935061062492505050565b50565b5f602082840312156106c9575f80fd5b5035919050565b6001600160a01b03811681146106b6575f80fd5b5f602082840312156106f4575f80fd5b81356106ff816106d0565b9392505050565b5f60208284031215610716575f80fd5b81516106ff816106d0565b5f60208284031215610731575f80fd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b5f6020828403121561075c575f80fd5b815180151581146106ff575f80fd5b808202811582820484141761078e57634e487b7160e01b5f52601160045260245ffd5b92915050565b5f826107ae57634e487b7160e01b5f52601260045260245ffd5b50049056fea26469706673582212207b700e3a7e46284f5e69ec5d328c765a875a3a15be5550aa30646655cfe2fec664736f6c6343000818003360e0604052600f60a09081526e105d5d1bdb585d1bdb9cc81e139195608a1b60c0525f906200002f908262000d58565b506040805180820190915260048152634155544f60e01b60208201526001906200005a908262000d58565b5034801562000067575f80fd5b50336080908152604080518082018252601081526014602080830191825260028054600181810183555f8381529551945160ff908116600160f81b9081026001600160f81b03978816177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace948501558851808a018a5286815260c881880190815286548086018855878b52915190518416830290891617908501558851808a018a5260308152607881880190815286548086018855878b52915190518416830290891617908501558851808a018a52898152603281880190815286548086018855878b52915190518416830290891617908501558851808a018a526060808252600a82890190815287548087018955888c529251905185168402908a1617918601919091558951808b018b528b815280880185815287548087018955888c52915190519094169092029290971691909117920191909155855196870186526001600160e81b03198752868301858152610c808888019081528751808901909852600b88526a436c65616e20576869746560a81b94880194909452938701958652600380549182018155909452855193025f8051602062002cf4833981519152810180549351925161ffff1666010000000000000261ffff60301b1960e894851c63010000000265ffffffffffff199096169690941c95909517939093179190911692909217815591515f8051602062002cd4833981519152909101906200028f908262000d58565b5050604080516080810182525f8082526001600160e81b031960208084019182526103208486019081528551808701909652600a8652694465657020426c61636b60b01b9186019190915260608401948552600380546001810182559352835160029093025f8051602062002cf4833981519152810180549351925161ffff1666010000000000000261ffff60301b1960e894851c63010000000265ffffffffffff199096169690941c95909517939093179190911692909217815592519193505f8051602062002cd483398151915201906200036d908262000d58565b5050604080516080810182526217962960e81b81526215491f60e81b602080830191825260648385019081528451808601909552600b85526a29b634b6bc9023b932b2b760a91b9185019190915260608301938452600380546001810182555f91909152835160029091025f8051602062002cf4833981519152810180549451935161ffff1666010000000000000261ffff60301b1960e895861c63010000000265ffffffffffff199097169490951c9390931794909417929092161782559251919350915f8051602062002cd483398151915201906200044f908262000d58565b50506040805160808101825262326a4760ea1b81526202fa8960ed1b6020808301918252604b8385019081528451808601909552600c85526b5061636966696320426c756560a01b9185019190915260608301938452600380546001810182555f91909152835160029091025f8051602062002cf4833981519152810180549451935161ffff1666010000000000000261ffff60301b1960e895861c63010000000265ffffffffffff199097169490951c9390931794909417929092161782559251919350915f8051602062002cd4833981519152019062000532908262000d58565b505060408051608081018252619fff60e81b815262144d7960e81b602080830191825260378385019081528451808601909552600b85526a13dc985b99d9481419595b60aa1b9185019190915260608301938452600380546001810182555f91909152835160029091025f8051602062002cf4833981519152810180549451935161ffff1666010000000000000261ffff60301b1960e895861c63010000000265ffffffffffff199097169490951c9390931794909417929092161782559251919350915f8051602062002cd4833981519152019062000613908262000d58565b505060408051608081018252623bb5cf60e81b81526223576360e81b602080830191825260238385019081528451808601909552600885526713db190811dbdb1960c21b9185019190915260608301938452600380546001810182555f91909152835160029091025f8051602062002cf4833981519152810180549451935161ffff1666010000000000000261ffff60301b1960e895861c63010000000265ffffffffffff199097169490951c9390931794909417929092161782559251919350915f8051602062002cd48339815191520190620006f2908262000d58565b5050604080516080810182526209080760ec1b81526208c7e760eb1b602080830191825260198385019081528451808601909552600a855269536c617465204772617960b01b9185019190915260608301938452600380546001810182555f91909152835160029091025f8051602062002cf4833981519152810180549451935161ffff1666010000000000000261ffff60301b1960e895861c63010000000265ffffffffffff199097169490951c9390931794909417929092161782559251919350915f8051602062002cd48339815191520190620007d3908262000d58565b505060408051608081018252625647f360e91b81526253466d60e81b6020808301918252600f8385019081528451808601909552600a855269436861726d2050696e6b60b01b9185019190915260608301938452600380546001810182555f91909152835160029091025f8051602062002cf4833981519152810180549451935161ffff1666010000000000000261ffff60301b1960e895861c63010000000265ffffffffffff199097169490951c9390931794909417929092161782559251919350915f8051602062002cd48339815191520190620008b4908262000d58565b5050604080516080810182526215965360e91b8152620c8ea960e91b6020808301918252600a8385019081528451808601909552600c85526b13595d185b1b1a58c814995960a21b9185019190915260608301938452600380546001810182555f91909152835160029091025f8051602062002cf4833981519152810180549451935161ffff1666010000000000000261ffff60301b1960e895861c63010000000265ffffffffffff199097169490951c9390931794909417929092161782559251919350915f8051602062002cd4833981519152019062000997908262000d58565b50506040805160808101825262152a2f60eb1b815262522b3d60e81b602080830191825260058385019081528451808601909552600c85526b526f79616c20507572706c6560a01b9185019190915260608301938452600380546001810182555f91909152835160029091025f8051602062002cf4833981519152810180549451935161ffff1666010000000000000261ffff60301b1960e895861c63010000000265ffffffffffff199097169490951c9390931794909417929092161782559251919350915f8051602062002cd4833981519152019062000a7a908262000d58565b50506040805180820182526028815281518083019092526004808352634e6f6e6560e01b602080850191909152820192835280546001810182555f9190915281515f8051602062002d348339815191526002909202918201805460ff191660ff90921691909117815592519193505f8051602062002d14833981519152019062000b05908262000d58565b505060408051808201825260148152815180830190925260088252672937ba30ba34b7b760c11b6020808401919091528101918252600480546001810182555f9190915281515f8051602062002d348339815191526002909202918201805460ff191660ff90921691909117815592519193505f8051602062002d14833981519152019062000b95908262000d58565b5050604080518082018252600a81528151808301909252600682526553696e676c6560d01b6020808401919091528101918252600480546001810182555f9190915281515f8051602062002d348339815191526002909202918201805460ff191660ff90921691909117815592519193505f8051602062002d14833981519152019062000c23908262000d58565b50506040805180820182526005815281518083019092526006825265446f75626c6560d01b6020808401919091528101918252600480546001810182555f9190915281515f8051602062002d348339815191526002909202918201805460ff191660ff90921691909117815592519193505f8051602062002d14833981519152019062000cb1908262000d58565b50505062000e24565b634e487b7160e01b5f52604160045260245ffd5b600181811c9082168062000ce357607f821691505b60208210810362000d0257634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111562000d5357805f5260205f20601f840160051c8101602085101562000d2f5750805b601f840160051c820191505b8181101562000d50575f815560010162000d3b565b50505b505050565b81516001600160401b0381111562000d745762000d7462000cba565b62000d8c8162000d85845462000cce565b8462000d08565b602080601f83116001811462000dc2575f841562000daa5750858301515b5f19600386901b1c1916600185901b17855562000e1c565b5f85815260208120601f198616915b8281101562000df25788860151825594840194600190910190840162000dd1565b508582101562000e1057878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b608051611e9162000e435f395f818160c101526103220152611e915ff3fe608060405234801561000f575f80fd5b506004361061008f575f3560e01c80638c7a63ae116100635780638c7a63ae1461011657806395d89b4114610156578063be985ac91461015e578063c87b56dd14610171578063ca54cc3f14610184575f80fd5b8062b958f31461009357806305c5652b146100bc57806306fdde03146100fb57806348b62fe414610103575b5f80fd5b6100a66100a136600461159d565b610197565b6040516100b39190611601565b60405180910390f35b6100e37f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016100b3565b6100a66101d0565b6100a661011136600461159d565b61025b565b61012961012436600461159d565b61031a565b6040805195865263ffffffff9094166020860152928401919091526060830152608082015260a0016100b3565b6100a6610544565b6100a661016c36600461159d565b610551565b6100a661017f36600461159d565b6105c2565b6100a661019236600461159d565b61073a565b60606101aa6101a58361025b565b610758565b6040516020016101ba9190611635565b6040516020818303038152906040529050919050565b5f80546101dc90611672565b80601f016020809104026020016040519081016040528092919081815260200182805461020890611672565b80156102535780601f1061022a57610100808354040283529160200191610253565b820191905f5260205f20905b81548152906001019060200180831161023657829003601f168201915b505050505081565b60605f805f805f61026b8761031a565b9450945094509450945061030f6102d86003848154811061028e5761028e6116a4565b5f9182526020909120600290910201546003805460e89290921b91869081106102b9576102b96116a4565b5f9182526020909120600290910201546301000000900460e81b6108a2565b6102ec6102e7888888876108e5565b610c3b565b6102f586610d72565b6103009060026116cc565b61030a90876116e3565b610d7e565b979650505050505050565b5f805f805f857f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663bfa0b1336040518163ffffffff1660e01b8152600401602060405180830381865afa15801561037c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103a091906116f6565b6040516429b2b2b21d60d91b6020820152602581019290925260458201526065016040516020818303038152906040528051906020012094506103e161157e565b5f5b602081101561040c57808282602081106103ff576103ff6116a4565b60200201526001016103e3565b505f5b600d8110156104e4575f81602003828960405160200161044c9291906729b43ab33336329d60c11b81526008810192909252602882015260480190565b604051602081830303815290604052805190602001205f1c816104715761047161170d565b06820190505f838260208110610489576104896116a4565b602002015190508383602081106104a2576104a26116a4565b60200201518483602081106104b9576104b96116a4565b602002018181525050808484602081106104d5576104d56116a4565b6020020152505060010161040f565b505f5b600d81101561051857818160208110610502576105026116a4565b602002015160019081901b9690961795016104e7565b50610522866110ef565b935061052d866111fe565b9250610538866112f0565b91505091939590929450565b600180546101dc90611672565b60605f61055d8361031a565b50935050505061059160038281548110610579576105796116a4565b5f91825260209091206002909102015460e81b6113d1565b61059a84610197565b6040516020016105ab929190611721565b604051602081830303815290604052915050919050565b60605f805f6105d08561031a565b94509450945050505f6105e2866114a0565b6040516020016105f291906119f2565b60405160208183030381529060405290508061060d8761073a565b60405160200161061e929190611aac565b604051602081830303815290604052905080610639856114a0565b60405160200161064a929190611b0c565b6040516020818303038152906040529050806003848154811061066f5761066f6116a4565b905f5260205f20906002020160010160405160200161068f929190611c0b565b604051602081830303815290604052905080600483815481106106b4576106b46116a4565b905f5260205f2090600202016001016040516020016106d4929190611c65565b6040516020818303038152906040529050806040516020016106f69190611ccb565b604051602081830303815290604052905061071081610758565b6040516020016107209190611cf0565b604051602081830303815290604052945050505050919050565b60606107486101a583610551565b6040516020016101ba9190611d34565b606081515f0361077557505060408051602081019091525f815290565b5f604051806060016040528060408152602001611e1c6040913990505f60038451600201816107a6576107a661170d565b0460040290508060200167ffffffffffffffff8111156107c8576107c8611d78565b6040519080825280601f01601f1916602001820160405280156107f2576020820181803683370190505b509250808352600182018485518101602086015b818310156108605760039283018051603f601282901c811687015160f890811b8552600c83901c8216880151811b6001860152600683901c8216880151811b60028601529116860151901b93820193909352600401610806565b60038851066001811461087a576002811461088b57610896565b613d3d60f01b600119830152610896565b603d60f81b5f198301525b50505050505050919050565b604080516001600160e81b031984811660208301525f60238301819052908416602483015260278201528151600881830301815260289091019091525b92915050565b6040516529ba30ba329d60d11b6020820152602681018590526060905f9060460160408051601f19818403018152919052805160209091012090505f83156109305760028504610932565b845b90505f846003146109435785610948565b600286045b90505f8167ffffffffffffffff81111561096457610964611d78565b60405190808252806020026020018201604052801561098d578160200160208202803683370190505b5090505f5b82811015610a5457805f036109ce576001846001901b0385168282815181106109bd576109bd6116a4565b602002602001018181525050610a4c565b5f808360018403815181106109e5576109e56116a4565b602090810291909101015180871b1760021b80871c6003161790505f5b86811015610a2957600163ffffffff8d16601f84841c161c8116821b939093179201610a02565b5081848481518110610a3d57610a3d6116a4565b60200260200101818152505050505b600101610992565b505f610a5f88610d72565b905080600202880167ffffffffffffffff811115610a7f57610a7f611d78565b604051908082528060200260200182016040528015610ab257816020015b6060815260200190600190039081610a9d5790505b5095505f5b8651811015610c2d5781600202890167ffffffffffffffff811115610ade57610ade611d78565b604051908082528060200260200182016040528015610b07578160200160208202803683370190505b50878281518110610b1a57610b1a6116a4565b6020026020010181905250818110158015610b36575081890181105b15610c2557815b82888381518110610b5057610b506116a4565b60200260200101515103811015610c23578281038383038a15801590610b7857508488018310155b15610b9a57600183868e01030391508a600103610b9a57600184868e01030390505b8a6003148015610bac57508487018410155b15610bbc57600184868e01030390505b81868281518110610bcf57610bcf6116a4565b6020026020010151901c6001168a8581518110610bee57610bee6116a4565b60200260200101518481518110610c0757610c076116a4565b60ff909216602092830291909101909101525050600101610b3d565b505b600101610ab7565b505050505050949350505050565b60605f825f81518110610c5057610c506116a4565b602002602001015151905060048181610c6b57610c6b61170d565b0615610c7a5760048106600403015b8083510267ffffffffffffffff811115610c9657610c96611d78565b6040519080825280601f01601f191660200182016040528015610cc0576020820181803683370190505b5091505f5b8351811015610d6b575f5b848281518110610ce257610ce26116a4565b602002602001015151811015610d6257848281518110610d0457610d046116a4565b60200260200101518181518110610d1d57610d1d6116a4565b602002602001015160f81b8482856001868a510303020181518110610d4457610d446116a4565b60200101906001600160f81b03191690815f1a905350600101610cd0565b50600101610cc5565b5050919050565b5f6108df600883611d8c565b825160609060368101905f9063ffffffff83160367ffffffffffffffff811115610daa57610daa611d78565b6040519080825280601f01601f191660200182016040528015610dd4576020820181803683370190505b509050604260f81b815f81518110610dee57610dee6116a4565b60200101906001600160f81b03191690815f1a905350604d60f81b81600181518110610e1c57610e1c6116a4565b60200101906001600160f81b03191690815f1a905350845182015f60025b6006811015610e835760ff831691508260081c92508160f81b848281518110610e6557610e656116a4565b60200101906001600160f81b03191690815f1a905350600101610e3a565b50839150600a5b600e811015610ed35760ff831691508260081c92508160f81b848281518110610eb557610eb56116a4565b60200101906001600160f81b03191690815f1a905350600101610e8a565b50602860f81b83600e81518110610eec57610eec6116a4565b60200101906001600160f81b03191690815f1a90535085915060125b6016811015610f805760ff831691508260081c92508160f81b848281518110610f3357610f336116a4565b60200101906001600160f81b03191690815f1a9053508160f81b848260040181518110610f6257610f626116a4565b60200101906001600160f81b03191690815f1a905350600101610f08565b50600160f81b83601a81518110610f9957610f996116a4565b60200101906001600160f81b03191690815f1a905350600860f81b83601c81518110610fc757610fc76116a4565b60200101906001600160f81b03191690815f1a9053508651915060225b602681101561102d5760ff831691508260081c92508160f81b84828151811061100f5761100f6116a4565b60200101906001600160f81b03191690815f1a905350600101610fe4565b50600488518161103f5761103f61170d565b049150602e5b60328110156110bd5760ff831691508260081c92508160f81b848281518110611070576110706116a4565b60200101906001600160f81b03191690815f1a9053508160f81b84826004018151811061109f5761109f6116a4565b60200101906001600160f81b03191690815f1a905350600101611045565b508288886040516020016110d393929190611dab565b6040516020818303038152906040529450505050509392505050565b5f80805b6002548110156111325760028181548110611110576111106116a4565b5f91825260209091200154600160f81b900460ff1691909101906001016110f3565b506040516429b4bd329d60d91b6020820152602581018490525f908290604501604051602081830303815290604052805190602001205f1c816111775761117761170d565b0690505f91505f5b6002548110156111f6576002818154811061119c5761119c6116a4565b5f91825260209091200154600160f81b900460ff169290920191828210156111ee57600281815481106111d1576111d16116a4565b5f918252602090912001546001600160f81b031695945050505050565b60010161117f565b505050919050565b5f80805b60035481101561124a576003818154811061121f5761121f6116a4565b5f9182526020909120600290910201546601000000000000900461ffff169190910190600101611202565b506040516521b7b637b91d60d11b6020820152602681018490525f908290604601604051602081830303815290604052805190602001205f1c816112905761129061170d565b0690505f91505f5b6003548110156111f657600381815481106112b5576112b56116a4565b5f9182526020909120600290910201546601000000000000900461ffff169290920191828210156112e857949350505050565b600101611298565b5f80805b6004548110156113315760048181548110611311576113116116a4565b5f91825260209091206002909102015460ff1691909101906001016112f4565b506040516a2932b33632b1ba34b7b71d60a91b6020820152602b81018490525f908290604b01604051602081830303815290604052805190602001205f1c8161137c5761137c61170d565b0690505f91505f5b6004548110156111f657600481815481106113a1576113a16116a4565b5f91825260209091206002909102015460ff169290920191828210156113c957949350505050565b600101611384565b6040805180820190915260018152602360f81b60208201525f5b600681101561149a57604080516001808252818301909252600f60e886901c600285851602850384016004021c16915f91906020820181803683370190505090506009821161143b57603061143e565b60575b820160f81b815f81518110611455576114556116a4565b60200101906001600160f81b03191690815f1a905350838160405160200161147e929190611ded565b60408051808303601f19018152919052935050506001016113eb565b50919050565b60606001825b60098111156114bf5760019190910190600a90046114a6565b5f8267ffffffffffffffff8111156114d9576114d9611d78565b6040519080825280601f01601f191660200182016040528015611503576020820181803683370190505b5090505f5b8151811015611575575f600a60018385510303600a0a888161152c5761152c61170d565b048161153a5761153a61170d565b0690508060300160f81b838381518110611556576115566116a4565b60200101906001600160f81b03191690815f1a90535050600101611508565b50949350505050565b6040518061040001604052806020906020820280368337509192915050565b5f602082840312156115ad575f80fd5b5035919050565b5f5b838110156115ce5781810151838201526020016115b6565b50505f910152565b5f81518084526115ed8160208601602086016115b4565b601f01601f19169290920160200192915050565b602081525f61161360208301846115d6565b9392505050565b5f815161162b8185602086016115b4565b9290920192915050565b7519185d184e9a5b5859d94bd89b5c0ed8985cd94d8d0b60521b81525f82516116658160168501602087016115b4565b9190910160160192915050565b600181811c9082168061168657607f821691505b60208210810361149a57634e487b7160e01b5f52602260045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b80820281158282048414176108df576108df6116b8565b808201808211156108df576108df6116b8565b5f60208284031215611706575f80fd5b5051919050565b634e487b7160e01b5f52601260045260245ffd5b7f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323081527f30302f737667222076657273696f6e3d22312e3122207072657365727665417360208201527f70656374526174696f3d22784d6964594d6964206d656574222076696577426f60408201527f783d223020302035313220353132222077696474683d2231303025222068656960608201527f6768743d2231303025223e3c646566733e3c7374796c6520747970653d22746560808201527f78742f637373223e7376677b696d6167652d72656e646572696e673a6f70746960a08201527f6d697a6553706565643b696d6167652d72656e646572696e673a2d6d6f7a2d6360c08201527f726973702d65646765733b696d6167652d72656e646572696e673a2d6f2d637260e08201527f6973702d65646765733b696d6167652d72656e646572696e673a2d7765626b696101008201527f742d6f7074696d697a652d636f6e74726173743b696d6167652d72656e6465726101208201527f696e673a706978656c617465643b696d6167652d72656e646572696e673a6f706101408201527f74696d697a652d636f6e74726173743b2d6d732d696e746572706f6c6174696f6101608201527f6e2d6d6f64653a6e6561726573742d6e65696768626f723b6261636b67726f7561018082015268373216b1b7b637b91d60b91b6101a08201525f6119ea61196461195e61193c6101a986018861161a565b75076c4c2c6d6cee4deeadcc85ad2dac2ceca74eae4d8560531b815260160190565b8561161a565b7f293b6261636b67726f756e642d7265706561743a6e6f2d7265706561743b626181527f636b67726f756e642d73697a653a636f6e7461696e3b6261636b67726f756e6460208201527f2d706f736974696f6e3a353025203530253b7d3c2f7374796c653e3c2f646566604082015267399f1e17b9bb339f60c11b606082015260680190565b949350505050565b6e7b226e616d65223a224155544f202360881b815281515f90611a1c81600f8501602087016115b4565b7f222c226465736372697074696f6e223a2254686520666972737420636f6c6c65600f9390910192830152507f6374696f6e20746f207573652074686520784e46542068796272696420737461602f8201527f6e646172642e2043726561746564206279207468652043656c6c4d6174657320604f820152661d19585b4b888b60ca1b606f820152607601919050565b5f8351611abd8184602088016115b4565b681134b6b0b3b2911d1160b91b9083019081528351611ae38160098401602088016115b4565b6f222c2261747472696275746573223a5b60801b60099290910191820152601901949350505050565b5f8351611b1d8184602088016115b4565b7f7b2274726169745f74797065223a2253697a65222c2276616c7565223a2200009083019081528351611b5781601e8401602088016115b4565b62089f4b60ea1b601e9290910191820152602101949350505050565b80545f90600181811c9080831680611b8c57607f831692505b60208084108203611bab57634e487b7160e01b5f52602260045260245ffd5b818015611bbf5760018114611bd457611bff565b60ff1986168952841515850289019650611bff565b5f888152602090205f5b86811015611bf75781548b820152908501908301611bde565b505084890196505b50505050505092915050565b5f8351611c1c8184602088016115b4565b7f7b2274726169745f74797065223a22436f6c6f72222c2276616c7565223a2200908301908152611c50601f820185611b73565b62089f4b60ea1b815260030195945050505050565b5f8351611c768184602088016115b4565b7f7b2274726169745f74797065223a225265666c656374696f6e222c2276616c759083019081526332911d1160e11b6020820152611cb76024820185611b73565b61227d60f01b815260020195945050505050565b5f8251611cdc8184602087016115b4565b615d7d60f01b920191825250600201919050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081525f8251611d2781601d8501602087016115b4565b91909101601d0192915050565b7f646174613a696d6167652f7376672b786d6c3b6261736536342c00000000000081525f8251611d6b81601a8501602087016115b4565b91909101601a0192915050565b634e487b7160e01b5f52604160045260245ffd5b5f82611da657634e487b7160e01b5f52601260045260245ffd5b500490565b5f8451611dbc8184602089016115b4565b845190830190611dd08183602089016115b4565b8451910190611de38183602088016115b4565b0195945050505050565b5f8351611dfe8184602088016115b4565b835190830190611e128183602088016115b4565b0194935050505056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa26469706673582212209b902f1bbbe22c2f94ffb97e27c2b2f56513b713e4875b1f60343db9810741ec64736f6c63430008180033c2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85cc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19c8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5472616e7366657228616464726573732c616464726573732c75696e7432353629

Deployed Bytecode

0x60806040526004361061026a575f3560e01c806370a082311161014a578063a9059cbb116100be578063d28a476111610078578063d28a4761146107a7578063db737c78146107c6578063dd62ed3e146107f4578063e985e9c514610839578063f3cb838514610884578063f4cdda36146108a3575f80fd5b8063a9059cbb146106fb578063b88d4fde1461071a578063bdb4b84814610739578063bfa0b13314610754578063c5b8f77214610769578063c87b56dd14610788575f80fd5b8063888ce1f31161010f578063888ce1f3146106645780638da5cb5b146106795780638fffabed1461069657806395d89b41146106b5578063a0712d68146106c9578063a22cb465146106dc575f80fd5b806370a08231146105985780637c187f7b146105d05780638129fc1c146105fc5780638188f71c1461061057806385f2aef214610631575f80fd5b806324cea3a6116101e15780633d13f874116101a65780633d13f874146104f257806342842e0e146105115780634bce92f3146105305780634bf365df146105455780634f6ccce71461055a5780636352211e14610579575f80fd5b806324cea3a6146104485780632f745c591461045c578063313ce5671461047b578063348fb288146104a0578063392f37e9146104d3575f80fd5b80631078d1ed116102325780631078d1ed1461035557806313af40351461038357806318160ddd146103a457806319781e3c146103d757806323b872dd146103f657806324bfe56514610415575f80fd5b806301ffc9a71461026e57806306fdde03146102b1578063076f4662146102d2578063081812fc146102ff578063095ea7b314610336575b5f80fd5b348015610279575f80fd5b5061029c61028836600461492a565b60066020525f908152604090205460ff1681565b60405190151581526020015b60405180910390f35b3480156102bc575f80fd5b506102c56108d1565b6040516102a89190614999565b3480156102dd575f80fd5b506102f16102ec3660046149bf565b610944565b6040519081526020016102a8565b34801561030a575f80fd5b5061031e6103193660046149ed565b61099e565b6040516001600160a01b0390911681526020016102a8565b348015610341575f80fd5b5061029c610350366004614a04565b610a14565b348015610360575f80fd5b5061037461036f366004614b02565b610a8f565b6040516102a893929190614b8f565b34801561038e575f80fd5b506103a261039d366004614c14565b610c11565b005b3480156103af575f80fd5b506102f17f000000000000000000000000000000000000000000000000000000000000100081565b3480156103e2575f80fd5b506103a26103f1366004614c43565b610c49565b348015610401575f80fd5b5061029c610410366004614c9c565b610ea6565b348015610420575f80fd5b5061031e7f00000000000000000000000097cc21a332c96ee626548051b62d28828a7a295e81565b348015610453575f80fd5b506103a2610f8a565b348015610467575f80fd5b506102f1610476366004614a04565b610fa6565b348015610486575f80fd5b5061048e5f81565b60405160ff90911681526020016102a8565b3480156104ab575f80fd5b5061031e7f0000000000000000000000007c72445127e3b1dfd7ecfbf7988c8e9e82718b6581565b3480156104de575f80fd5b5060075461031e906001600160a01b031681565b3480156104fd575f80fd5b506103a261050c366004614cda565b6110d4565b34801561051c575f80fd5b506103a261052b366004614c9c565b6111f3565b34801561053b575f80fd5b506102f160085481565b348015610550575f80fd5b506102f1600d5481565b348015610565575f80fd5b506102f16105743660046149ed565b611212565b348015610584575f80fd5b5061031e6105933660046149ed565b611267565b3480156105a3575f80fd5b506102f16105b2366004614c14565b6001600160a01b03165f9081526002602052604090205461ffff1690565b3480156105db575f80fd5b506105ef6105ea366004614c14565b61134f565b6040516102a89190614d5e565b348015610607575f80fd5b506103a26113f5565b34801561061b575f80fd5b50610624611ad8565b6040516102a89190614da1565b34801561063c575f80fd5b5061031e7f000000000000000000000000eefe1c0bc74f0114722641656e6072002eaac8cd81565b34801561066f575f80fd5b506102f160095481565b348015610684575f80fd5b506001546001600160a01b031661031e565b3480156106a1575f80fd5b50600a5461031e906001600160a01b031681565b3480156106c0575f80fd5b506102c5611b3b565b6103a26106d73660046149ed565b611b82565b3480156106e7575f80fd5b506103a26106f6366004614db3565b611c66565b348015610706575f80fd5b5061029c610715366004614a04565b611cd5565b348015610725575f80fd5b506103a2610734366004614e03565b611ce1565b348015610744575f80fd5b506102f167016345785d8a000081565b34801561075f575f80fd5b506102f1600b5481565b348015610774575f80fd5b5061029c610783366004614a04565b611d88565b348015610793575f80fd5b506102c56107a23660046149ed565b611e09565b3480156107b2575f80fd5b506103a26107c1366004614eaa565b611e77565b3480156107d1575f80fd5b506107e56107e0366004614ef6565b611e81565b6040516102a893929190614f17565b3480156107ff575f80fd5b506102f161080e366004614f4b565b6001600160a01b039182165f9081526002602081815260408084209490951683529201909152205490565b348015610844575f80fd5b5061029c610853366004614f4b565b6001600160a01b039182165f9081526002602090815260408083209390941682526003909201909152205460ff1690565b34801561088f575f80fd5b506103a261089e366004614c14565b611eb8565b3480156108ae575f80fd5b5061029c6108bd366004614c14565b600c6020525f908152604090205460ff1681565b600754604080516306fdde0360e01b815290516060926001600160a01b0316916306fdde03916004808301925f9291908290030181865afa158015610918573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261093f9190810190614f77565b905090565b5f7f00000000000000000000000000000000000000000000000000000000000000108310610970575f80fd5b506001600160a01b0381165f9081526002602090815260408083208584526001019091529020545b92915050565b5f7f0000000000000000000000000000000000000000000000000000000000001000821180156109f157507f00000000000000000000000000000000000000000000000000000000000010006002028211155b6109f9575f80fd5b505f908152600360205260409020546001600160a01b031690565b5f7f000000000000000000000000000000000000000000000000000000000000100082118015610a6757507f00000000000000000000000000000000000000000000000000000000000010006002028211155b15610a7b57610a768383611ef0565b610a86565b610a86338484611f9f565b50600192915050565b60608060605f85519050806001600160401b03811115610ab157610ab1614a2e565b604051908082528060200260200182016040528015610ada578160200160208202803683370190505b509350806001600160401b03811115610af557610af5614a2e565b604051908082528060200260200182016040528015610b1e578160200160208202803683370190505b509250806001600160401b03811115610b3957610b39614a2e565b604051908082528060200260200182016040528015610b6c57816020015b6060815260200190600190039081610b575790505b5091505f5b81811015610c0857610b9c878281518110610b8e57610b8e614fdf565b602002602001015187611e81565b878481518110610bae57610bae614fdf565b60200260200101878581518110610bc757610bc7614fdf565b60200260200101878681518110610be057610be0614fdf565b60209081029190910101929092526001600160a01b0392831690915291169052600101610b71565b50509250925092565b6001546001600160a01b03163314610c27575f80fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b5f7368b3465833fb72a70ecdf485e0e4c7bd8665fc456001600160a01b031663791b98bc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c9a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cbe9190614ff3565b6040805160808101825260095481526001600160a01b037f000000000000000000000000eefe1c0bc74f0114722641656e6072002eaac8cd811660208301526001600160801b038981168385015288166060830152915163fc6f786560e01b81529293509083169163fc6f786591610d389160040161500e565b60408051808303815f875af1158015610d53573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d779190615051565b50506040805160808101825260085481526001600160a01b037f000000000000000000000000eefe1c0bc74f0114722641656e6072002eaac8cd811660208301526001600160801b038681168385015285166060830152915163fc6f786560e01b81529183169163fc6f786591610df09160040161500e565b60408051808303815f875af1158015610e0b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e2f9190615051565b50507f000000000000000000000000eefe1c0bc74f0114722641656e6072002eaac8cd6001600160a01b031663476343ee6040518163ffffffff1660e01b81526004015f604051808303815f87803b158015610e89575f80fd5b505af1158015610e9b573d5f803e3d5ffd5b505050505050505050565b5f7f000000000000000000000000000000000000000000000000000000000000100082118015610ef957507f00000000000000000000000000000000000000000000000000000000000010006002028211155b15610f0e57610f09848484612008565b610f80565b6001600160a01b0384165f908152600260208181526040808420338552909201905290205482811015610f3f575f80fd5b5f198114610f73576001600160a01b0385165f90815260026020818152604080842033855290920190529020805484900390555b610f7e8585856121c9565b505b5060019392505050565b610fa46001600160801b03806001600160801b0380610c49565b565b6001600160a01b0382165f9081526002602052604081205461ffff168210610fcc575f80fd5b6001600160a01b0383165f9081526002602052604081205464010000000090046001600160e01b03165b5f811180156110055750838211155b156110cc575f611014826123db565b9050806001901b821891505f61102a8288610944565b90505f61103682613928565b9050868186011161104a57938401936110c4565b815b5f8111801561105b5750878611155b156110c2575f61106a826123db565b60018881019890821b93909318929091508990036110bc57807f000000000000000000000000000000000000000000000000000000000000100086610100020101600101975050505050505050610998565b5061104c565b505b505050610ff6565b505092915050565b6001600160a01b0384165f908152600c602052604090205460ff16156110f8575f80fd5b6111758282808060200260200160405190810160405280939291908181526020018383602002808284375f92019190915250506040516bffffffffffffffffffffffff1960608a901b16602082015260348101889052605401915061115a9050565b604051602081830303815290604052805190602001206139f4565b61117d575f80fd5b6001600160a01b0384165f908152600c60205260409020805460ff191660011790556111aa3085856121c9565b836001600160a01b03167f47cee97cb7acd717b3c0aa1435d004cd5b3c8c57d70dbceb4e4458bbd60e39d4846040516111e591815260200190565b60405180910390a250505050565b61120d83838360405180602001604052805f815250611ce1565b505050565b5f7f0000000000000000000000000000000000000000000000000000000000001000821061123e575f80fd5b507f00000000000000000000000000000000000000000000000000000000000010000160010190565b5f3363ffffffff811615611279575f80fd5b7f0000000000000000000000000000000000000000000000000000000000001000831180156112cb57507f00000000000000000000000000000000000000000000000000000000000010006002028311155b6112d3575f80fd5b5f806112de85613ab6565b60045491935091505f5b81811015611343575f6001600301828154811061130757611307614fdf565b5f918252602090912001546001600160a01b0316905083806113298784610944565b160361133a57979650505050505050565b506001016112e8565b505f9695505050505050565b60607f00000000000000000000000000000000000000000000000000000000000000106001600160401b0381111561138957611389614a2e565b6040519080825280602002602001820160405280156113b2578160200160208202803683370190505b5090505f5b81518110156113ef576113ca8184610944565b8282815181106113dc576113dc614fdf565b60209081029190910101526001016113b7565b50919050565b5f805460ff19166001179055600a546001600160a01b031615611416575f80fd5b5f3090505f7368b3465833fb72a70ecdf485e0e4c7bd8665fc456001600160a01b0316634aa4a4fc6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561146b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061148f9190614ff3565b90506114b282737a250d5630b4cf539739df2c5dacb4c659f2488d610100611f9f565b737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015611502573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115269190614ff3565b6040516364e329cb60e11b81526001600160a01b0383811660048301528481166024830152919091169063c9c65396906044016020604051808303815f875af1158015611575573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115999190614ff3565b600a80546001600160a01b039283166001600160a01b0319909116179055737a250d5630b4cf539739df2c5dacb4c659f2488d9063f305d71990841631846101005f806115ee6001546001600160a01b031690565b60405160e088901b6001600160e01b03191681526001600160a01b03958616600482015260248101949094526044840192909252606483015290911660848201524260a482015260c40160606040518083038185885af1158015611654573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906116799190615073565b5050505f7368b3465833fb72a70ecdf485e0e4c7bd8665fc456001600160a01b031663791b98bc6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116cd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116f19190614ff3565b905061170b83826117066105006101006150b2565b611f9f565b6001600160a01b03808416908316105f611748826110007f000000000000000000000000000000000000000000000003782dace9d9000000613af3565b9150505f611764836110006a52b7d2dcc80cd2e4000000613af3565b915050836001600160a01b031663883164566040518061016001604052808661178d578961178f565b885b6001600160a01b0316815260200186156117a957896117ab565b885b6001600160a01b031681526127106020820152604001866117cc57856117ce565b845b60020b815260200186156117e257856117e4565b845b60020b8152602001866117f9576105006117fb565b5f5b8152602001861561180e57610500611810565b5f5b81526020015f81526020015f8152602001896001600160a01b03168152602001428152506040518263ffffffff1660e01b815260040161185091906150c5565b6080604051808303815f875af115801561186c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118909190615189565b5050506009556001600160a01b0386167318e5f92103d1b34623738ee79214b1659f2ee109109250611921836110007f00000000000000000000000000000000000000000000000055dd981adc3dbdbf6119127f000000000000000000000000000000000000000000000003782dace9d9000000670de0b6b3a76400006151c4565b61191c91906151ef565b613af3565b925061196a9050836110007f00000000000000000000000000000000000000000000000055dd981adc3dbdbf6119126a52b7d2dcc80cd2e4000000670de0b6b3a76400006151c4565b905080915050836001600160a01b031663883164566040518061016001604052808661199657896119ac565b7318e5f92103d1b34623738ee79214b1659f2ee1095b6001600160a01b0316815260200186156119c657896119dc565b7318e5f92103d1b34623738ee79214b1659f2ee1095b6001600160a01b031681526127106020820152604001866119fd57856119ff565b845b60020b81526020018615611a135785611a15565b845b60020b815260200186611a2a57610100611a2c565b5f5b81526020018615611a3f57610100611a41565b5f5b81526020015f81526020015f8152602001896001600160a01b03168152602001428152506040518263ffffffff1660e01b8152600401611a8191906150c5565b6080604051808303815f875af1158015611a9d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ac19190615189565b50505060085550505f805460ff1916905550505050565b60606001600301805480602002602001604051908101604052809291908181526020018280548015611b3157602002820191905f5260205f20905b81546001600160a01b03168152600190910190602001808311611b13575b5050505050905090565b600754604080516395d89b4160e01b815290516060926001600160a01b0316916395d89b41916004808301925f9291908290030181865afa158015610918573d5f803e3d5ffd5b600d54811115611b90575f80fd5b5f611ba367016345785d8a0000836151c4565b905080341015611bb1575f80fd5b81600d5f828254611bc29190615202565b90915550611bd390503033846121c9565b6040516001600160a01b037f000000000000000000000000eefe1c0bc74f0114722641656e6072002eaac8cd169082156108fc029083905f818181858888f19350505050158015611c26573d5f803e3d5ffd5b5080341115611c6257336108fc611c3d8334615202565b6040518115909202915f818181858888f1935050505015801561120d573d5f803e3d5ffd5b5050565b335f8181526002602090815260408083206001600160a01b0387168085526003909101835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b5f610a863384846121c9565b611cec848484612008565b823b63ffffffff811615611d8157604051630a85bd0160e11b808252906001600160a01b0386169063150b7a0290611d2e9033908a9089908990600401615215565b6020604051808303815f875af1158015611d4a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d6e9190615251565b6001600160e01b03191614611d81575f80fd5b5050505050565b5f7f000000000000000000000000000000000000000000000000000000000000100082118015611ddb57507f00000000000000000000000000000000000000000000000000000000000010006002028211155b611de3575f80fd5b5f80611dee84613ab6565b915091508081611dfe8488610944565b161495945050505050565b60075460405163c87b56dd60e01b8152600481018390526060916001600160a01b03169063c87b56dd906024015f60405180830381865afa158015611e50573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526109989190810190614f77565b611c628282613b69565b5f80606083611e90575f611e99565b611e9985611267565b611ea28661099e565b611eab87611e09565b9250925092509250925092565b6001546001600160a01b03163314611ece575f80fd5b600780546001600160a01b0319166001600160a01b0392909216919091179055565b5f80611efb83613ab6565b915091508081611f0b8433610944565b1614611f15575f80fd5b5f83815260036020908152604080832080546001600160a01b0389166001600160a01b03199091168117909155338085526002909352818420805461ffff6201000080830482166001019091160263ffff000019909116179055905186939192917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a450505050565b6001600160a01b038084165f81815260026020818152604080842095881680855295909201815291819020859055805160608101909152602180825290916152c7908301398051906020012083604051611ffb91815260200190565b60405180910390a3505050565b7f00000000000000000000000000000000000000000000000000000000000010008111801561205a57507f00000000000000000000000000000000000000000000000000000000000010006002028111155b612062575f80fd5b5f8061206d83613ab6565b91509150808161207d8488610944565b1614612087575f80fd5b336001600160a01b03861614806120b757506120a28361099e565b6001600160a01b0316336001600160a01b0316145b806120e757506001600160a01b0385165f90815260026020908152604080832033845260030190915290205460ff165b6120ef575f80fd5b5f7f00000000000000000000000000000000000000000000000000000000000000106001600160401b0381111561212857612128614a2e565b604051908082528060200260200182016040528015612151578160200160208202803683370190505b5090508181848151811061216757612167614fdf565b60209081029190910101526040805160018082528183019092525f9181602001602082028036833701905050905084815f815181106121a8576121a8614fdf565b6020026020010181815250506121c087878484613cf4565b50505050505050565b5f80826001600160401b038111156121e3576121e3614a2e565b60405190808252806020026020018201604052801561220c578160200160208202803683370190505b5090505f7f00000000000000000000000000000000000000000000000000000000000000106001600160401b0381111561224857612248614a2e565b604051908082528060200260200182016040528015612271578160200160208202803683370190505b506001600160a01b0387165f9081526002602052604090205490915064010000000090046001600160e01b03165b5f811180156122ad57508484105b156123c4575f6122bc826123db565b9050806001901b821891505f6122d2828a610944565b9050805b5f811180156122e457508787105b1561237d575f6122f3826123db565b86519091506001821b90819088908790811061231157612311614fdf565b602002602001018181511791508181525050817f000000000000000000000000000000000000000000000000000000000000100086610100020101600101888a806001019b508151811061236757612367614fdf565b60209081029190910101529190911890506122d6565b84838151811061238f5761238f614fdf565b60200260200101518584815181106123a9576123a9614fdf565b60200260200101518316146123bc575f80fd5b50505061229f565b8484146123cf575f80fd5b6121c087878486613cf4565b5f5f198201198216600160801b811015612eb4576801000000000000000081101561292d5764010000000081101561266a576201000081101561252d5761010081101561249f576010811015612460576004811015612445576002811015610a8657505f92915050565b60088110156124575750600292915050565b50600392915050565b604081101561248457602081101561247b5750600492915050565b50600592915050565b60808110156124965750600692915050565b50600792915050565b6110008110156124eb576104008110156124cf576102008110156124c65750600892915050565b50600992915050565b6108008110156124e25750600a92915050565b50600b92915050565b614000811015612511576120008110156125085750600c92915050565b50600d92915050565b6180008110156125245750600e92915050565b50600f92915050565b63010000008110156125ce5762100000811015612589576204000081101561256c57620200008110156125635750601092915050565b50601192915050565b620800008110156125805750601292915050565b50601392915050565b624000008110156125b157622000008110156125a85750601492915050565b50601592915050565b628000008110156125c55750601692915050565b50601792915050565b63100000008110156126225763040000008110156126045763020000008110156125fb5750601892915050565b50601992915050565b63080000008110156126195750601a92915050565b50601b92915050565b634000000081101561264c5763200000008110156126435750601c92915050565b50601d92915050565b63800000008110156126615750601e92915050565b50601f92915050565b66010000000000008110156127d4576501000000000081101561272a576410000000008110156126df576404000000008110156126c0576402000000008110156126b75750602092915050565b50602192915050565b6408000000008110156126d65750602292915050565b50602392915050565b64400000000081101561270b576420000000008110156127025750602492915050565b50602592915050565b6480000000008110156127215750602692915050565b50602792915050565b651000000000008110156127865765040000000000811015612766576502000000000081101561275d5750602892915050565b50602992915050565b6508000000000081101561277d5750602a92915050565b50602b92915050565b654000000000008110156127b457652000000000008110156127ab5750602c92915050565b50602d92915050565b658000000000008110156127cb5750602e92915050565b50602f92915050565b600160381b81101561289157661000000000000081101561284057660400000000000081101561281f5766020000000000008110156128165750603092915050565b50603192915050565b66080000000000008110156128375750603292915050565b50603392915050565b66400000000000008110156128705766200000000000008110156128675750603492915050565b50603592915050565b66800000000000008110156128885750603692915050565b50603792915050565b6001603c1b8110156128e5576001603a1b8110156128c757600160391b8110156128be5750603892915050565b50603992915050565b6001603b1b8110156128dc5750603a92915050565b50603b92915050565b6001603e1b81101561290f576001603d1b8110156129065750603c92915050565b50603d92915050565b6001603f1b8110156129245750603e92915050565b50603f92915050565b600160601b811015612c2057600160501b811015612adc576901000000000000000000811015612a1657681000000000000000008110156129bf576804000000000000000081101561299c57680200000000000000008110156129935750604092915050565b50604192915050565b680800000000000000008110156129b65750604292915050565b50604392915050565b684000000000000000008110156129f357682000000000000000008110156129ea5750604492915050565b50604592915050565b68800000000000000000811015612a0d5750604692915050565b50604792915050565b6910000000000000000000811015612a82576904000000000000000000811015612a5e576902000000000000000000811015612a555750604892915050565b50604992915050565b6908000000000000000000811015612a795750604a92915050565b50604b92915050565b6940000000000000000000811015612ab8576920000000000000000000811015612aaf5750604c92915050565b50604d92915050565b6980000000000000000000811015612ad35750604e92915050565b50604f92915050565b600160581b811015612b8457600160541b811015612b3c57600160521b811015612b1e57600160511b811015612b155750605092915050565b50605192915050565b600160531b811015612b335750605292915050565b50605392915050565b600160561b811015612b6657600160551b811015612b5d5750605492915050565b50605592915050565b600160571b811015612b7b5750605692915050565b50605792915050565b6001605c1b811015612bd8576001605a1b811015612bba57600160591b811015612bb15750605892915050565b50605992915050565b6001605b1b811015612bcf5750605a92915050565b50605b92915050565b6001605e1b811015612c02576001605d1b811015612bf95750605c92915050565b50605d92915050565b6001605f1b811015612c175750605e92915050565b50605f92915050565b600160701b811015612d7057600160681b811015612cd457600160641b811015612c8c57600160621b811015612c6e57600160611b811015612c655750606092915050565b50606192915050565b600160631b811015612c835750606292915050565b50606392915050565b600160661b811015612cb657600160651b811015612cad5750606492915050565b50606592915050565b600160671b811015612ccb5750606692915050565b50606792915050565b6001606c1b811015612d28576001606a1b811015612d0a57600160691b811015612d015750606892915050565b50606992915050565b6001606b1b811015612d1f5750606a92915050565b50606b92915050565b6001606e1b811015612d52576001606d1b811015612d495750606c92915050565b50606d92915050565b6001606f1b811015612d675750606e92915050565b50606f92915050565b600160781b811015612e1857600160741b811015612dd057600160721b811015612db257600160711b811015612da95750607092915050565b50607192915050565b600160731b811015612dc75750607292915050565b50607392915050565b600160761b811015612dfa57600160751b811015612df15750607492915050565b50607592915050565b600160771b811015612e0f5750607692915050565b50607792915050565b6001607c1b811015612e6c576001607a1b811015612e4e57600160791b811015612e455750607892915050565b50607992915050565b6001607b1b811015612e635750607a92915050565b50607b92915050565b6001607e1b811015612e96576001607d1b811015612e8d5750607c92915050565b50607d92915050565b6001607f1b811015612eab5750607e92915050565b50607f92915050565b600160c01b8110156133f457600160a01b81101561316057600160901b81101561301c57600160881b811015612f8057600160841b811015612f3857600160821b811015612f1a57600160811b811015612f115750608092915050565b50608192915050565b600160831b811015612f2f5750608292915050565b50608392915050565b600160861b811015612f6257600160851b811015612f595750608492915050565b50608592915050565b600160871b811015612f775750608692915050565b50608792915050565b6001608c1b811015612fd4576001608a1b811015612fb657600160891b811015612fad5750608892915050565b50608992915050565b6001608b1b811015612fcb5750608a92915050565b50608b92915050565b6001608e1b811015612ffe576001608d1b811015612ff55750608c92915050565b50608d92915050565b6001608f1b8110156130135750608e92915050565b50608f92915050565b600160981b8110156130c457600160941b81101561307c57600160921b81101561305e57600160911b8110156130555750609092915050565b50609192915050565b600160931b8110156130735750609292915050565b50609392915050565b600160961b8110156130a657600160951b81101561309d5750609492915050565b50609592915050565b600160971b8110156130bb5750609692915050565b50609792915050565b6001609c1b811015613118576001609a1b8110156130fa57600160991b8110156130f15750609892915050565b50609992915050565b6001609b1b81101561310f5750609a92915050565b50609b92915050565b6001609e1b811015613142576001609d1b8110156131395750609c92915050565b50609d92915050565b6001609f1b8110156131575750609e92915050565b50609f92915050565b600160b01b8110156132b057600160a81b81101561321457600160a41b8110156131cc57600160a21b8110156131ae57600160a11b8110156131a5575060a092915050565b5060a192915050565b600160a31b8110156131c3575060a292915050565b5060a392915050565b600160a61b8110156131f657600160a51b8110156131ed575060a492915050565b5060a592915050565b600160a71b81101561320b575060a692915050565b5060a792915050565b600160ac1b81101561326857600160aa1b81101561324a57600160a91b811015613241575060a892915050565b5060a992915050565b600160ab1b81101561325f575060aa92915050565b5060ab92915050565b600160ae1b81101561329257600160ad1b811015613289575060ac92915050565b5060ad92915050565b600160af1b8110156132a7575060ae92915050565b5060af92915050565b600160b81b81101561335857600160b41b81101561331057600160b21b8110156132f257600160b11b8110156132e9575060b092915050565b5060b192915050565b600160b31b811015613307575060b292915050565b5060b392915050565b600160b61b81101561333a57600160b51b811015613331575060b492915050565b5060b592915050565b600160b71b81101561334f575060b692915050565b5060b792915050565b600160bc1b8110156133ac57600160ba1b81101561338e57600160b91b811015613385575060b892915050565b5060b992915050565b600160bb1b8110156133a3575060ba92915050565b5060bb92915050565b600160be1b8110156133d657600160bd1b8110156133cd575060bc92915050565b5060bd92915050565b600160bf1b8110156133eb575060be92915050565b5060bf92915050565b600160e01b81101561369457600160d01b81101561355057600160c81b8110156134b457600160c41b81101561346c57600160c21b81101561344e57600160c11b811015613445575060c092915050565b5060c192915050565b600160c31b811015613463575060c292915050565b5060c392915050565b600160c61b81101561349657600160c51b81101561348d575060c492915050565b5060c592915050565b600160c71b8110156134ab575060c692915050565b5060c792915050565b600160cc1b81101561350857600160ca1b8110156134ea57600160c91b8110156134e1575060c892915050565b5060c992915050565b600160cb1b8110156134ff575060ca92915050565b5060cb92915050565b600160ce1b81101561353257600160cd1b811015613529575060cc92915050565b5060cd92915050565b600160cf1b811015613547575060ce92915050565b5060cf92915050565b600160d81b8110156135f857600160d41b8110156135b057600160d21b81101561359257600160d11b811015613589575060d092915050565b5060d192915050565b600160d31b8110156135a7575060d292915050565b5060d392915050565b600160d61b8110156135da57600160d51b8110156135d1575060d492915050565b5060d592915050565b600160d71b8110156135ef575060d692915050565b5060d792915050565b600160dc1b81101561364c57600160da1b81101561362e57600160d91b811015613625575060d892915050565b5060d992915050565b600160db1b811015613643575060da92915050565b5060db92915050565b600160de1b81101561367657600160dd1b81101561366d575060dc92915050565b5060dd92915050565b600160df1b81101561368b575060de92915050565b5060df92915050565b600160f01b8110156137e457600160e81b81101561374857600160e41b81101561370057600160e21b8110156136e257600160e11b8110156136d9575060e092915050565b5060e192915050565b600160e31b8110156136f7575060e292915050565b5060e392915050565b600160e61b81101561372a57600160e51b811015613721575060e492915050565b5060e592915050565b600160e71b81101561373f575060e692915050565b5060e792915050565b600160ec1b81101561379c57600160ea1b81101561377e57600160e91b811015613775575060e892915050565b5060e992915050565b600160eb1b811015613793575060ea92915050565b5060eb92915050565b600160ee1b8110156137c657600160ed1b8110156137bd575060ec92915050565b5060ed92915050565b600160ef1b8110156137db575060ee92915050565b5060ef92915050565b600160f81b81101561388c57600160f41b81101561384457600160f21b81101561382657600160f11b81101561381d575060f092915050565b5060f192915050565b600160f31b81101561383b575060f292915050565b5060f392915050565b600160f61b81101561386e57600160f51b811015613865575060f492915050565b5060f592915050565b600160f71b811015613883575060f692915050565b5060f792915050565b600160fc1b8110156138e057600160fa1b8110156138c257600160f91b8110156138b9575060f892915050565b5060f992915050565b600160fb1b8110156138d7575060fa92915050565b5060fb92915050565b600160fe1b81101561390a57600160fd1b811015613901575060fc92915050565b5060fd92915050565b600160ff1b81101561391f575060fe92915050565b5060ff92915050565b5f8180820361393957505f92915050565b5f19810361394b575061010092915050565b7f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f7f5555555555555555555555555555555555555555555555555555555555555555600183901c16909103600281901c7f3333333333333333333333333333333333333333333333333333333333333333908116911601600481901c01167f01010101010101010101010101010101010101010101010101010101010101010260f81c92915050565b5f81815b8451811015613a8c575f858281518110613a1457613a14614fdf565b60200260200101519050808311613a56576040805160208101859052908101829052606001604051602081830303815290604052805190602001209250613a83565b60408051602081018390529081018490526060016040516020818303038152906040528051906020012092505b506001016139f8565b507f3f856c8d1611023aaa9915c692b07293eea0d4dd7c26df3914d5bfbd430ce84c149392505050565b6101005f197f0000000000000000000000000000000000000000000000000000000000001000808403820183900494600193860290940303011b90565b5f805f613b3186613b045784613b06565b855b8715613b125785613b14565b865b613b2290600160c01b6151ef565b613b2c91906151c4565b6140dd565b9050613b3c8161411a565b9150613b4960c88361526c565b613b53908361528d565b9150613b5e82614416565b925050935093915050565b5f7f00000000000000000000000000000000000000000000000000000000000000106001600160401b03811115613ba257613ba2614a2e565b604051908082528060200260200182016040528015613bcb578160200160208202803683370190505b5090505f5b8251811015613c2f575f80613bfd858481518110613bf057613bf0614fdf565b6020026020010151613ab6565b9150915080848381518110613c1457613c14614fdf565b60209081029190910101805190911790525050600101613bd0565b505f805b8251811015613cd557828181518110613c4e57613c4e614fdf565b60200260200101515f801b14613ccd57828181518110613c7057613c70614fdf565b6020026020010151838281518110613c8a57613c8a614fdf565b6020026020010151613c9c8333610944565b1614613ca6575f80fd5b613cc8838281518110613cbb57613cbb614fdf565b6020026020010151613928565b820191505b600101613c33565b5082518114613ce2575f80fd5b613cee33858486613cf4565b50505050565b6001600160a01b038316613d06575f80fd5b5f815111613d12575f80fd5b613d1e84848484614744565b6001600160a01b038085165f908152600260205260408082205492861682528120546001600160e01b036401000000009384900481169390910416905b8451811015613e5e575f801b858281518110613d7957613d79614fdf565b602002602001015114613e56575f613d918289610944565b9050858281518110613da557613da5614fdf565b6020908102919091018101516001600160a01b038a165f908152600283526040808220868352600101909352918220921891829055613de48389610944565b9050868381518110613df857613df8614fdf565b6020908102919091018101516001600160a01b038a165f908152600283526040808220878352600101909352918220921791829055829003613e3e57826001901b851894505b6001831b939093179281811615613e53575f80fd5b50505b600101613d5b565b506001600160a01b038681165f908152600260205260408082208054875161ffff8083169190910380821663ffff0000938416176401000000006001600160e01b038b8116820292909217909555968c16865293852080548a5197891690940292841693821696870190911692909217179055919082900361401f576001600160a01b0388165f9081526005602052604081205490829003613f4e578760016003018281548110613f1157613f11614fdf565b5f91825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918a168152600590915260409020819055614001565b600480545f91905f198101908110613f6857613f68614fdf565b5f91825260209091200154600480546001600160a01b039092169250829184908110613f9657613f96614fdf565b5f91825260208083209190910180546001600160a01b0319166001600160a01b0394851617905591831681526005909152604090208290556004805480613fdf57613fdf6152b2565b5f8281526020902081015f1990810180546001600160a01b0319169055019055505b506001600160a01b0388165f90815260056020526040812055614086565b805f0361408657600480546001810182557f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0180546001600160a01b0319166001600160a01b038a1690811790915590545f918252600560205260409091205f1990910190555b866001600160a01b0316886001600160a01b03166040518060600160405280602181526020016152e8602191398051906020012087516040516140cb91815260200190565b60405180910390a35050505050505050565b80600260018201045b818110156113ef57809150600281828581614103576141036151db565b040181614112576141126151db565b0490506140e6565b5f6401000276a36001600160a01b03831610801590614155575073fffd8963efd1fc6a506488495d951d5263988d266001600160a01b038316105b61418a5760405162461bcd60e51b81526020600482015260016024820152602960f91b60448201526064015b60405180910390fd5b640100000000600160c01b03602083901b166001600160801b03811160071b81811c6001600160401b03811160061b90811c63ffffffff811160051b90811c61ffff811160041b90811c60ff8111600390811b91821c600f811160021b90811c918211600190811b92831c9790881196179094179092171790911717176080811061421d57607f810383901c9150614227565b80607f0383901b91505b908002607f81811c60ff83811c9190911c800280831c81831c1c800280841c81841c1c800280851c81851c1c800280861c81861c1c800280871c81871c1c800280881c81881c1c800280891c81891c1c8002808a1c818a1c1c8002808b1c818b1c1c8002808c1c818c1c1c8002808d1c818d1c1c8002808e1c9c81901c9c909c1c80029c8d901c9e9d607f198f0160401b60c09190911c6001603f1b161760c19b909b1c6001603e1b169a909a1760c29990991c6001603d1b169890981760c39790971c6001603c1b169690961760c49590951c6001603b1b169490941760c59390931c6001603a1b169290921760c69190911c600160391b161760c79190911c600160381b161760c89190911c6680000000000000161760c99190911c6640000000000000161760ca9190911c6620000000000000161760cb9190911c6610000000000000161760cc9190911c6608000000000000161760cd9190911c66040000000000001617693627a301d71055774c8581026f028f6481ab7f045a5af012a19d003aa9198101608090811d906fdb2df09e81959a81455e260799a0632f8301901d600281810b9083900b1461440757886001600160a01b03166143ec82614416565b6001600160a01b031611156144015781614409565b80614409565b815b9998505050505050505050565b5f805f8360020b1261442b578260020b614432565b8260020b5f035b9050620d89e881111561446b5760405162461bcd60e51b81526020600482015260016024820152601560fa1b6044820152606401614181565b5f816001165f0361448057600160801b614492565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff16905060028216156144c6576ffff97272373d413259a46990580e213a0260801c5b60048216156144e5576ffff2e50f5f656932ef12357cf3c7fdcc0260801c5b6008821615614504576fffe5caca7e10e4e61c3624eaa0941cd00260801c5b6010821615614523576fffcb9843d60f6159c9db58835c9266440260801c5b6020821615614542576fff973b41fa98c081472e6896dfb254c00260801c5b6040821615614561576fff2ea16466c96a3843ec78b326b528610260801c5b6080821615614580576ffe5dee046a99a2a811c461f1969c30530260801c5b6101008216156145a0576ffcbe86c7900a88aedcffc83b479aa3a40260801c5b6102008216156145c0576ff987a7253ac413176f2b074cf7815e540260801c5b6104008216156145e0576ff3392b0822b70005940c7a398e4b70f30260801c5b610800821615614600576fe7159475a2c29b7443b29c7fa6e889d90260801c5b611000821615614620576fd097f3bdfd2022b8845ad8f792aa58250260801c5b612000821615614640576fa9f746462d870fdf8a65dc1f90e061e50260801c5b614000821615614660576f70d869a156d2a1b890bb3df62baf32f70260801c5b618000821615614680576f31be135f97d08fd981231505542fcfa60260801c5b620100008216156146a1576f09aa508b5b7a84e1c677de54f3e99bc90260801c5b620200008216156146c1576e5d6af8dedb81196699c329225ee6040260801c5b620400008216156146e0576d2216e584f5fa1ea926041bedfe980260801c5b620800008216156146fd576b048a170391f7dc42444e8fa20260801c5b5f8460020b131561471c57805f1981614718576147186151db565b0490505b640100000000810615614730576001614732565b5f5b60ff16602082901c0192505050919050565b5f80546001600160a01b0386168252600260205260409091205460ff9091169062010000900461ffff16158080156147795750815b61490a575f5b83518110156121c057811580156147c957505f6001600160a01b03166147bd8583815181106147b0576147b0614fdf565b602002602001015161099e565b6001600160a01b031614155b156148a2576001600160a01b0387165f90815260026020526040812080545f1961ffff62010000808404821692909201160263ffff0000199091161790558451600390829087908590811061482057614820614fdf565b602002602001015181526020019081526020015f205f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555083818151811061486a5761486a614fdf565b60209081029190910101516040515f9081907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925908290a45b82614902578381815181106148b9576148b9614fdf565b6020026020010151866001600160a01b0316886001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b60010161477f565b505050505050565b6001600160e01b031981168114614927575f80fd5b50565b5f6020828403121561493a575f80fd5b813561494581614912565b9392505050565b5f5b8381101561496657818101518382015260200161494e565b50505f910152565b5f815180845261498581602086016020860161494c565b601f01601f19169290920160200192915050565b602081525f614945602083018461496e565b6001600160a01b0381168114614927575f80fd5b5f80604083850312156149d0575f80fd5b8235915060208301356149e2816149ab565b809150509250929050565b5f602082840312156149fd575f80fd5b5035919050565b5f8060408385031215614a15575f80fd5b8235614a20816149ab565b946020939093013593505050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b0381118282101715614a6a57614a6a614a2e565b604052919050565b5f82601f830112614a81575f80fd5b813560206001600160401b03821115614a9c57614a9c614a2e565b8160051b614aab828201614a42565b9283528481018201928281019087851115614ac4575f80fd5b83870192505b84831015614ae357823582529183019190830190614aca565b979650505050505050565b80358015158114614afd575f80fd5b919050565b5f8060408385031215614b13575f80fd5b82356001600160401b03811115614b28575f80fd5b614b3485828601614a72565b925050614b4360208401614aee565b90509250929050565b5f815180845260208085019450602084015f5b83811015614b845781516001600160a01b031687529582019590820190600101614b5f565b509495945050505050565b606081525f614ba16060830186614b4c565b602083820381850152614bb48287614b4c565b915083820360408501528185518084528284019150828160051b8501018388015f5b83811015614c0457601f19878403018552614bf283835161496e565b94860194925090850190600101614bd6565b50909a9950505050505050505050565b5f60208284031215614c24575f80fd5b8135614945816149ab565b6001600160801b0381168114614927575f80fd5b5f805f8060808587031215614c56575f80fd5b8435614c6181614c2f565b93506020850135614c7181614c2f565b92506040850135614c8181614c2f565b91506060850135614c9181614c2f565b939692955090935050565b5f805f60608486031215614cae575f80fd5b8335614cb9816149ab565b92506020840135614cc9816149ab565b929592945050506040919091013590565b5f805f8060608587031215614ced575f80fd5b8435614cf8816149ab565b93506020850135925060408501356001600160401b0380821115614d1a575f80fd5b818701915087601f830112614d2d575f80fd5b813581811115614d3b575f80fd5b8860208260051b8501011115614d4f575f80fd5b95989497505060200194505050565b602080825282518282018190525f9190848201906040850190845b81811015614d9557835183529284019291840191600101614d79565b50909695505050505050565b602081525f6149456020830184614b4c565b5f8060408385031215614dc4575f80fd5b8235614dcf816149ab565b9150614b4360208401614aee565b5f6001600160401b03821115614df557614df5614a2e565b50601f01601f191660200190565b5f805f8060808587031215614e16575f80fd5b8435614e21816149ab565b93506020850135614e31816149ab565b92506040850135915060608501356001600160401b03811115614e52575f80fd5b8501601f81018713614e62575f80fd5b8035614e75614e7082614ddd565b614a42565b818152886020838501011115614e89575f80fd5b816020840160208301375f6020838301015280935050505092959194509250565b5f8060408385031215614ebb575f80fd5b8235614ec6816149ab565b915060208301356001600160401b03811115614ee0575f80fd5b614eec85828601614a72565b9150509250929050565b5f8060408385031215614f07575f80fd5b82359150614b4360208401614aee565b6001600160a01b038481168252831660208201526060604082018190525f90614f429083018461496e565b95945050505050565b5f8060408385031215614f5c575f80fd5b8235614f67816149ab565b915060208301356149e2816149ab565b5f60208284031215614f87575f80fd5b81516001600160401b03811115614f9c575f80fd5b8201601f81018413614fac575f80fd5b8051614fba614e7082614ddd565b818152856020838501011115614fce575f80fd5b614f4282602083016020860161494c565b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215615003575f80fd5b8151614945816149ab565b815181526020808301516001600160a01b0316908201526040808301516001600160801b0390811691830191909152606092830151169181019190915260800190565b5f8060408385031215615062575f80fd5b505080516020909101519092909150565b5f805f60608486031215615085575f80fd5b8351925060208401519150604084015190509250925092565b634e487b7160e01b5f52601160045260245ffd5b808201808211156109985761099861509e565b81516001600160a01b03168152610160810160208301516150f160208401826001600160a01b03169052565b506040830151615108604084018262ffffff169052565b50606083015161511d606084018260020b9052565b506080830151615132608084018260020b9052565b5060a083015160a083015260c083015160c083015260e083015160e083015261010080840151818401525061012080840151615178828501826001600160a01b03169052565b505061014092830151919092015290565b5f805f806080858703121561519c575f80fd5b8451935060208501516151ae81614c2f565b6040860151606090960151949790965092505050565b80820281158282048414176109985761099861509e565b634e487b7160e01b5f52601260045260245ffd5b5f826151fd576151fd6151db565b500490565b818103818111156109985761099861509e565b6001600160a01b03858116825284166020820152604081018390526080606082018190525f906152479083018461496e565b9695505050505050565b5f60208284031215615261575f80fd5b815161494581614912565b5f8260020b8061527e5761527e6151db565b808360020b0791505092915050565b600282810b9082900b03627fffff198112627fffff821317156109985761099861509e565b634e487b7160e01b5f52603160045260245ffdfe417070726f76616c28616464726573732c616464726573732c75696e74323536295472616e7366657228616464726573732c616464726573732c75696e7432353629a264697066735822122069d46335cf5f96540b8e9eb83f90e3f81428e4e7c384d4ff3c208ef923e6acea64736f6c63430008180033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.