| Token | Symbol | Balance | Price | Value |
|---|---|---|---|---|
| no token holdings | ||||
| Type | Age | Block | Details |
|---|---|---|---|
| no cross-chain L1↔L2 transactions for this address | |||
| Transaction Hash | Method | Block | Age | From | To | Amount | Token | ||
|---|---|---|---|---|---|---|---|---|---|
| no token transfers for this address yet | |||||||||
| Block | Age | Parent Transaction Hash | Type | Method | From | To | Value | |
|---|---|---|---|---|---|---|---|---|
| no internal transactions found for this address yet (traced blocks + on-demand) | ||||||||
| Txn Hash | Age | Event | Topics / Data |
|---|---|---|---|
| 0x5e5ab0…824399 | 4 days agoThu, 13 Aug 2026 20:43:07 UTC | 0x2a271e…1fca | [0] 0x000000000000…00000008 [1] 0x000000000000…55d24f89 |
| 0x58c579…f0a074 | 4 days agoThu, 13 Aug 2026 20:30:35 UTC | 0x2a271e…1fca | [0] 0x000000000000…0000013b [1] 0x000000000000…a841211e |
| 0xa46dca…5a3e27 | 4 days agoThu, 13 Aug 2026 20:28:09 UTC | 0x3af54b…86ea | [0] 0x000000000000…00000004 [1] 0x000000000000…0000013b data: 0x000000000000000000…ee8fa1ff |
| 0xa46dca…5a3e27 | 4 days agoThu, 13 Aug 2026 20:28:09 UTC | 0x006ae8…be0c | [0] 0x000000000000…0000013b [1] 0x000000000000…8ee37105 data: 0x000000000000000000…ee8fa1ff |
| 0xa46dca…5a3e27 | 4 days agoThu, 13 Aug 2026 20:28:09 UTC | Transfer | [0] 0x000000000000…00000000 [1] 0x000000000000…8ee37105 [2] 0x000000000000…0000013b |
| 0x40ea52…060d19 | 4 days agoThu, 13 Aug 2026 20:27:55 UTC | 0x63dae6…f9be | [0] 0x000000000000…00000004 |
| 0x0d5518…8aa125 | 4 days agoThu, 13 Aug 2026 20:27:16 UTC | 0xbdbb36…51bf | [0] 0x000000000000…0000013a [1] 0x000000000000…7f5ad350 data: 0x000000000000000000…00000000 |
| 0x0d5518…8aa125 | 4 days agoThu, 13 Aug 2026 20:27:16 UTC | 0x006ae8…be0c | [0] 0x000000000000…0000013a [1] 0x000000000000…7f5ad350 data: 0x000000000000000000…00000001 |
| 0x0d5518…8aa125 | 4 days agoThu, 13 Aug 2026 20:27:16 UTC | Transfer | [0] 0x000000000000…00000000 [1] 0x000000000000…7f5ad350 [2] 0x000000000000…0000013a |
| 0x0d5518…8aa125 | 4 days agoThu, 13 Aug 2026 20:27:16 UTC | 0xbdbb36…51bf | [0] 0x000000000000…00000139 [1] 0x000000000000…aff2adfd data: 0x000000000000000000…00000000 |
| 0x0d5518…8aa125 | 4 days agoThu, 13 Aug 2026 20:27:16 UTC | 0x006ae8…be0c | [0] 0x000000000000…00000139 [1] 0x000000000000…aff2adfd data: 0x000000000000000000…00000001 |
| 0x0d5518…8aa125 | 4 days agoThu, 13 Aug 2026 20:27:16 UTC | Transfer | [0] 0x000000000000…00000000 [1] 0x000000000000…aff2adfd [2] 0x000000000000…00000139 |
| 0x0d5518…8aa125 | 4 days agoThu, 13 Aug 2026 20:27:16 UTC | 0xbdbb36…51bf | [0] 0x000000000000…00000138 [1] 0x000000000000…a7a94a28 data: 0x000000000000000000…00000000 |
| 0x0d5518…8aa125 | 4 days agoThu, 13 Aug 2026 20:27:16 UTC | 0x006ae8…be0c | [0] 0x000000000000…00000138 [1] 0x000000000000…a7a94a28 data: 0x000000000000000000…00000001 |
| 0x0d5518…8aa125 | 4 days agoThu, 13 Aug 2026 20:27:16 UTC | Transfer | [0] 0x000000000000…00000000 [1] 0x000000000000…a7a94a28 [2] 0x000000000000…00000138 |
| 0x0d5518…8aa125 | 4 days agoThu, 13 Aug 2026 20:27:16 UTC | 0xbdbb36…51bf | [0] 0x000000000000…00000137 [1] 0x000000000000…ae1ad5f1 data: 0x000000000000000000…00000000 |
| 0x0d5518…8aa125 | 4 days agoThu, 13 Aug 2026 20:27:16 UTC | 0x006ae8…be0c | [0] 0x000000000000…00000137 [1] 0x000000000000…ae1ad5f1 data: 0x000000000000000000…00000001 |
| 0x0d5518…8aa125 | 4 days agoThu, 13 Aug 2026 20:27:16 UTC | Transfer | [0] 0x000000000000…00000000 [1] 0x000000000000…ae1ad5f1 [2] 0x000000000000…00000137 |
| 0x0d5518…8aa125 | 4 days agoThu, 13 Aug 2026 20:27:16 UTC | 0xbdbb36…51bf | [0] 0x000000000000…00000136 [1] 0x000000000000…c0acdc33 data: 0x000000000000000000…00000000 |
| 0x0d5518…8aa125 | 4 days agoThu, 13 Aug 2026 20:27:16 UTC | 0x006ae8…be0c | [0] 0x000000000000…00000136 [1] 0x000000000000…c0acdc33 data: 0x000000000000000000…00000001 |
| 0x0d5518…8aa125 | 4 days agoThu, 13 Aug 2026 20:27:16 UTC | Transfer | [0] 0x000000000000…00000000 [1] 0x000000000000…c0acdc33 [2] 0x000000000000…00000136 |
| 0x4e59a0…289153 | 4 days agoThu, 13 Aug 2026 20:27:15 UTC | 0xe5512d…a93a | [0] 0x000000000000…00000004 [1] 0x000000000000…8ee37105 [2] 0x000000000000…00000008 data: 0x000000000000000000…00000135 |
| 0x1acba5…8effa9 | 4 days agoThu, 13 Aug 2026 20:26:31 UTC | 0xbdbb36…51bf | [0] 0x000000000000…00000135 [1] 0x000000000000…8ee37105 data: 0x000000000000000000…00000000 |
| 0x1acba5…8effa9 | 4 days agoThu, 13 Aug 2026 20:26:31 UTC | 0x006ae8…be0c | [0] 0x000000000000…00000135 [1] 0x000000000000…8ee37105 data: 0x000000000000000000…02410041 |
| 0x1acba5…8effa9 | 4 days agoThu, 13 Aug 2026 20:26:31 UTC | Transfer | [0] 0x000000000000…00000000 [1] 0x000000000000…8ee37105 [2] 0x000000000000…00000135 |
| Transaction Hash | Method | Block | Age | From | To | Type | Item | ||
|---|---|---|---|---|---|---|---|---|---|
| no NFT transfers for this address yet | |||||||||
| Transaction Hash | Method ? | Block | Age | From | To | Amount | Txn Fee ? | ||
|---|---|---|---|---|---|---|---|---|---|
| 0xa46dca…5a3e27 | claimChild | 35,677,649 | 4 days agoThu, 13 Aug 2026 20:28:09 UTC | 0xa5ba…7105 | IN | Mendel Breeder | $0.000 ETH | 0.00000594 | |
| 0x4e59a0…289153 | breed | 35,677,109 | 4 days agoThu, 13 Aug 2026 20:27:15 UTC | 0xa5ba…7105 | IN | Mendel Breeder | $0.000 ETH | 0.00000875 | |
| 0x1acba5…8effa9 | mintGenesis | 35,676,676 | 4 days agoThu, 13 Aug 2026 20:26:31 UTC | 0xa5ba…7105 | IN | Mendel Breeder | $0.000 ETH | 0.00000435 | |
| 0x26c1fe…78fd98 | mintGenesis | 35,676,623 | 4 days agoThu, 13 Aug 2026 20:26:26 UTC | 0x6017…b6f4 | IN | Mendel Breeder | $0.000 ETH | 0.00000506 | |
| 0xcf4577…b19192 | mintGenesis | 35,676,437 | 4 days agoThu, 13 Aug 2026 20:26:09 UTC | 0xe3fa…1897 | IN | Mendel Breeder | $0.000 ETH | 0.00000444 | |
| 0x77b511…54ccad | mintGenesis | 35,676,414 | 4 days agoThu, 13 Aug 2026 20:26:06 UTC | 0xe3fa…1897 | IN | Mendel Breeder | $0.000 ETH | 0.00000514 | |
| 0xb53dfb…e49855 | mintGenesis | 35,676,254 | 4 days agoThu, 13 Aug 2026 20:25:50 UTC | 0x87b9…a90a | IN | Mendel Breeder | $0.000 ETH | 0.00000437 | |
| 0x014132…3b4be9 | mintGenesis | 35,674,815 | 4 days agoThu, 13 Aug 2026 20:23:26 UTC | 0x1809…317f | IN | Mendel Breeder | $0.000 ETH | 0.00000443 | |
| 0x4174c0…3fa259 | mintGenesis | 35,674,815 | 4 days agoThu, 13 Aug 2026 20:23:26 UTC | 0x3644…2656 | IN | Mendel Breeder | $0.000 ETH | 0.00000443 | |
| 0x28ea8f…12a540 | mintGenesis | 35,674,815 | 4 days agoThu, 13 Aug 2026 20:23:26 UTC | 0xb637…5b9c | IN | Mendel Breeder | $0.000 ETH | 0.00000443 | |
| 0xc98df1…880412 | mintGenesis | 35,674,815 | 4 days agoThu, 13 Aug 2026 20:23:26 UTC | 0x9be4…0190 | IN | Mendel Breeder | $0.000 ETH | 0.00000443 | |
| 0x7da728…315504 | mintGenesis | 35,674,815 | 4 days agoThu, 13 Aug 2026 20:23:26 UTC | 0xb919…b487 | IN | Mendel Breeder | $0.000 ETH | 0.00000443 | |
| 0x5796cb…5c06a1 | mintGenesis | 35,674,815 | 4 days agoThu, 13 Aug 2026 20:23:26 UTC | 0x8604…318a | IN | Mendel Breeder | $0.000 ETH | 0.00000443 | |
| 0x953a5a…20da5f | mintGenesis | 35,674,815 | 4 days agoThu, 13 Aug 2026 20:23:26 UTC | 0x33dc…a423 | IN | Mendel Breeder | $0.000 ETH | 0.00000443 | |
| 0x08cb99…04057b | mintGenesis | 35,674,815 | 4 days agoThu, 13 Aug 2026 20:23:26 UTC | 0x2af1…e5d3 | IN | Mendel Breeder | $0.000 ETH | 0.00000443 | |
| 0x14ff88…35f9d2 | mintGenesis | 35,674,815 | 4 days agoThu, 13 Aug 2026 20:23:26 UTC | 0xccdd…84dc | IN | Mendel Breeder | $0.000 ETH | 0.00000443 | |
| 0x5c6a4c…4b9ba9 | mintGenesis | 35,674,814 | 4 days agoThu, 13 Aug 2026 20:23:25 UTC | 0x5fd7…891f | IN | Mendel Breeder | $0.000 ETH | 0.00000441 | |
| 0xf478f1…176e43 | mintGenesis | 35,674,814 | 4 days agoThu, 13 Aug 2026 20:23:25 UTC | 0xee82…213e | IN | Mendel Breeder | $0.000 ETH | 0.00000441 | |
| 0xdf0efe…1fe379 | mintGenesis | 35,674,814 | 4 days agoThu, 13 Aug 2026 20:23:25 UTC | 0xa0c3…16ba | IN | Mendel Breeder | $0.000 ETH | 0.00000441 | |
| 0x5b47eb…323aa2 | mintGenesis | 35,674,814 | 4 days agoThu, 13 Aug 2026 20:23:25 UTC | 0x5a91…6328 | IN | Mendel Breeder | $0.000 ETH | 0.00000441 | |
| 0xd790db…0a7b92 | mintGenesis | 35,674,814 | 4 days agoThu, 13 Aug 2026 20:23:25 UTC | 0xea33…f7c9 | IN | Mendel Breeder | $0.000 ETH | 0.00000441 | |
| 0x8fe027…d8ec06 | mintGenesis | 35,674,814 | 4 days agoThu, 13 Aug 2026 20:23:25 UTC | 0xf693…5d11 | IN | Mendel Breeder | $0.000 ETH | 0.00000441 | |
| 0x9c6a95…69b5c3 | mintGenesis | 35,674,814 | 4 days agoThu, 13 Aug 2026 20:23:25 UTC | 0x7430…89eb | IN | Mendel Breeder | $0.000 ETH | 0.00000441 | |
| 0xf4377d…152010 | mintGenesis | 35,674,814 | 4 days agoThu, 13 Aug 2026 20:23:25 UTC | 0xd74a…48a1 | IN | Mendel Breeder | $0.000 ETH | 0.00000441 | |
| 0x70c214…6e8121 | mintGenesis | 35,674,814 | 4 days agoThu, 13 Aug 2026 20:23:25 UTC | 0x92cf…2a56 | IN | Mendel Breeder | $0.000 ETH | 0.00000441 |
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {VRFConsumerBaseV2Plus} from "@chainlink/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol";
import {VRFV2PlusClient} from "@chainlink/contracts/src/v0.8/vrf/dev/libraries/VRFV2PlusClient.sol";
import {Pausable} from "@openzeppelin/contracts/utils/Pausable.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import {BreederGenome} from "./BreederGenome.sol";
import {GenomeLib} from "./GenomeLib.sol";
/// @title BreedingEngine
/// @notice Chainlink VRF-driven Mendelian breeding. Two distinct parents each
/// contribute one allele per gene to a child; a Mutation-gene-driven
/// roll can splice in brand-new alleles. Because VRF is async, breeding
/// is two-phase and the callback is kept deliberately light:
///
/// 1. `breed(a, b)` — checks + locks a fertility charge on each
/// parent, then requests randomness.
/// 2. VRF callback — only records the random word (cannot strand a
/// breed by reverting on heavy work).
/// 3. `claimChild(id)` — anyone-safe, breeder-gated: assembles the
/// child genome and mints the child NFT.
///
/// @dev The child coin *launch* (Launchpad / ReactiveCoin) and the coin<->NFT
/// back-link (`bindBreeder`) are a later milestone; this contract stops at
/// minting the child breeder NFT and emitting {ChildBorn}.
///
/// Invariants honoured: randomness is VRF-only (mutation/selection never
/// read block values, #5); dominance stays read-time via GenomeLib (#1);
/// the callback stays light with a two-step claim (#3).
contract BreedingEngine is BreederGenome, VRFConsumerBaseV2Plus, Pausable, ReentrancyGuard {
using GenomeLib for uint256;
// ---- VRF config ---------------------------------------------------------
bytes32 public keyHash;
uint256 public subscriptionId;
uint32 public callbackGasLimit;
uint16 public requestConfirmations;
uint32 internal constant NUM_WORDS = 1;
// ---- breeding state -----------------------------------------------------
struct Breed {
address breeder; // who initiated (and who the child mints to)
uint256 parentA;
uint256 parentB;
uint256 randomWord; // filled by the VRF callback
bool fulfilled;
bool claimed;
}
/// @notice Breed request by VRF requestId.
mapping(uint256 requestId => Breed) public breeds;
/// @notice Fertility charges already spent by a token (as a parent).
mapping(uint256 tokenId => uint32 spent) public chargesSpent;
/// @notice The primary (parentA) parent of a bred token; 0 for genesis tokens.
/// @dev Defines the lineage the Launchpad walks for bloodline royalties.
mapping(uint256 tokenId => uint256 parent) public primaryParentOf;
/// @notice Launchpad authorised to bind a coin to a breeder NFT (invariant #4).
address public launchpad;
// ---- platform fees (revenue) -------------------------------------------
/// @notice ETH price to mint a genesis (founding) breeder.
uint256 public genesisFee;
/// @notice ETH price to breed (also raises the cost of Sybil bloodlines).
uint256 public breedFee;
/// @notice Where collected genesis/breed fees are withdrawn.
address public feeRecipient;
/// @notice Genesis/breed fees accrued and awaiting withdrawal.
uint256 public feesAccrued;
// ---- genesis balancing --------------------------------------------------
/// @notice Max dominance tier a public genesis allele may start at. Higher
/// tiers must be earned through breeding + mutation, so founders
/// can't mint an all-dominant "god" genome.
uint8 public genesisMaxTier = 1;
/// @notice Max Fertility trait (breed charges) a genesis coin may start with.
uint8 public genesisMaxFertility = 3;
event BreedRequested(uint256 indexed requestId, address indexed breeder, uint256 indexed parentA, uint256 parentB);
event BreedFulfilled(uint256 indexed requestId);
event ChildBorn(uint256 indexed requestId, uint256 indexed childId, uint256 parentA, uint256 parentB, uint256 genome);
event CoinBound(uint256 indexed tokenId, address indexed coin);
event GenesisMinted(uint256 indexed tokenId, address indexed to, uint256 feePaid);
event FeesWithdrawn(address indexed to, uint256 amount);
constructor(address vrfCoordinator, uint256 subId, bytes32 keyHash_, uint32 callbackGasLimit_, uint16 confirmations_)
BreederGenome()
VRFConsumerBaseV2Plus(vrfCoordinator)
{
subscriptionId = subId;
keyHash = keyHash_;
callbackGasLimit = callbackGasLimit_;
requestConfirmations = confirmations_;
feeRecipient = msg.sender;
}
// ---- platform fee admin -------------------------------------------------
function setFees(uint256 genesisFee_, uint256 breedFee_) external onlyOwner {
genesisFee = genesisFee_;
breedFee = breedFee_;
}
function setFeeRecipient(address recipient) external onlyOwner {
feeRecipient = recipient;
}
/// @notice Tune the genesis genome caps (dominance tier and starting fertility).
function setGenesisLimits(uint8 maxTier, uint8 maxFertility) external onlyOwner {
require(maxTier <= GenomeLib.MAX_TIER && maxFertility <= GenomeLib.MAX_TRAIT, "BreedingEngine: bad limit");
genesisMaxTier = maxTier;
genesisMaxFertility = maxFertility;
}
function pause() external onlyOwner {
_pause();
}
function unpause() external onlyOwner {
_unpause();
}
/// @notice Withdraw accrued genesis/breed fees to the fee recipient.
function withdrawFees() external nonReentrant {
uint256 amount = feesAccrued;
feesAccrued = 0;
address to = feeRecipient;
(bool ok,) = to.call{value: amount}("");
require(ok, "BreedingEngine: withdraw failed");
emit FeesWithdrawn(to, amount);
}
/// @dev Take `fee` from msg.value, refund the excess, and accrue the fee.
function _takeFee(uint256 fee) internal {
require(msg.value >= fee, "BreedingEngine: fee");
feesAccrued += fee;
uint256 refund = msg.value - fee;
if (refund > 0) {
(bool ok,) = msg.sender.call{value: refund}("");
require(ok, "BreedingEngine: refund failed");
}
}
// ---- genesis minting ----------------------------------------------------
/// @notice Admin/prototype mint: the owner can mint a genesis breeder free.
/// @dev Overrides the open base mint to gate it behind ownership.
function mintGenome(address to, uint256 genome)
external
override
onlyOwner
whenNotPaused
returns (uint256 tokenId)
{
return _mintGenome(to, genome);
}
/// @notice Public paid path: pay {genesisFee} to mint a founding breeder.
/// @dev The requested genome is balanced before minting — dominance tiers are
/// clamped and starting fertility is capped — so founders start on an
/// even footing and rare dominant bloodlines are bred, not bought.
function mintGenesis(uint256 genome)
external
payable
whenNotPaused
nonReentrant
returns (uint256 tokenId)
{
_takeFee(genesisFee);
uint256 balanced = genome.clampTiers(genesisMaxTier).capGeneTrait(GenomeLib.GENE_FERTILITY, genesisMaxFertility);
tokenId = _mintGenome(msg.sender, balanced);
emit GenesisMinted(tokenId, msg.sender, genesisFee);
}
/// @notice Owner can retune VRF request parameters (not the coordinator).
function setVrfConfig(bytes32 keyHash_, uint256 subId, uint32 callbackGasLimit_, uint16 confirmations_)
external
onlyOwner
{
keyHash = keyHash_;
subscriptionId = subId;
callbackGasLimit = callbackGasLimit_;
requestConfirmations = confirmations_;
}
// ---- fertility accounting ----------------------------------------------
/// @inheritdoc BreederGenome
/// @dev Available = genetic max (expressed Fertility) minus charges spent.
function availableCharges(uint256 tokenId) public view override returns (uint8) {
uint8 maxCharges = genomeOf[tokenId].expressed(GenomeLib.GENE_FERTILITY);
uint32 spent = chargesSpent[tokenId];
if (spent >= maxCharges) return 0;
return uint8(maxCharges - uint8(spent));
}
// ---- phase 1: request ---------------------------------------------------
/// @notice Lock a charge on each parent and request VRF randomness.
/// @dev The caller must own both parents, which must be distinct and each
/// still have a breed charge. The charge is spent up front so it cannot
/// be double-committed across concurrent requests.
function breed(uint256 parentA, uint256 parentB)
external
payable
whenNotPaused
nonReentrant
returns (uint256 requestId)
{
require(parentA != parentB, "BreedingEngine: same parent");
require(ownerOf(parentA) == msg.sender, "BreedingEngine: not owner A");
require(ownerOf(parentB) == msg.sender, "BreedingEngine: not owner B");
require(availableCharges(parentA) > 0, "BreedingEngine: A infertile");
require(availableCharges(parentB) > 0, "BreedingEngine: B infertile");
_takeFee(breedFee); // platform revenue + raises the cost of Sybil bloodlines
// Spend a charge on each parent (locks them against re-use in flight).
chargesSpent[parentA] += 1;
chargesSpent[parentB] += 1;
VRFV2PlusClient.RandomWordsRequest memory req = VRFV2PlusClient.RandomWordsRequest({
keyHash: keyHash,
subId: subscriptionId,
requestConfirmations: requestConfirmations,
callbackGasLimit: callbackGasLimit,
numWords: NUM_WORDS,
extraArgs: VRFV2PlusClient._argsToBytes(VRFV2PlusClient.ExtraArgsV1({nativePayment: false}))
});
requestId = s_vrfCoordinator.requestRandomWords(req);
breeds[requestId] = Breed({
breeder: msg.sender,
parentA: parentA,
parentB: parentB,
randomWord: 0,
fulfilled: false,
claimed: false
});
emit BreedRequested(requestId, msg.sender, parentA, parentB);
}
// ---- phase 2: VRF callback (KEEP LIGHT) ---------------------------------
/// @dev Records the random word only. All heavy work is deferred to
/// {claimChild} so a reverting/overweight callback can never strand a
/// breed (and burn the fertility charge) — invariant #3.
function fulfillRandomWords(uint256 requestId, uint256[] calldata randomWords) internal override {
Breed storage b = breeds[requestId];
if (b.breeder == address(0) || b.fulfilled) return; // unknown or replayed
b.randomWord = randomWords[0];
b.fulfilled = true;
emit BreedFulfilled(requestId);
}
// ---- phase 3: claim -----------------------------------------------------
/// @notice Assemble and mint the child once randomness has arrived.
/// @dev Breeder-gated and single-shot; deterministic in the stored word, so
/// it can be safely retried if it ever runs out of gas.
function claimChild(uint256 requestId) external nonReentrant returns (uint256 childId) {
Breed storage b = breeds[requestId];
require(b.fulfilled, "BreedingEngine: not fulfilled");
require(!b.claimed, "BreedingEngine: already claimed");
require(msg.sender == b.breeder, "BreedingEngine: not breeder");
b.claimed = true; // effects before interaction (child mint)
uint256 childGenome = _mix(genomeOf[b.parentA], genomeOf[b.parentB], b.randomWord);
childId = _mintGenome(b.breeder, childGenome);
primaryParentOf[childId] = b.parentA; // lineage for bloodline royalties
emit ChildBorn(requestId, childId, b.parentA, b.parentB, childGenome);
}
// ---- launchpad binding (invariant #4: coin <-> NFT link) ---------------
/// @notice Set the Launchpad allowed to bind coins to breeder NFTs.
function setLaunchpad(address launchpad_) external onlyOwner {
launchpad = launchpad_;
}
/// @notice Store the coin address for a breeder NFT (the NFT->coin half of
/// the bidirectional link). Called by the Launchpad at launch, before
/// the coin records its NFT id.
function bindCoin(uint256 tokenId, address coin) external {
require(msg.sender == launchpad, "BreedingEngine: not launchpad");
require(coinOf[tokenId] == address(0), "BreedingEngine: already bound");
_requireOwned(tokenId);
coinOf[tokenId] = coin;
emit CoinBound(tokenId, coin);
}
// ---- Mendelian genome assembly -----------------------------------------
/// @notice Deterministically build a child genome from two parents + a VRF
/// word. Each gene: one allele from each parent (VRF-selected), with
/// an independent per-allele mutation roll.
/// @dev Entropy is expanded from the single VRF word via keccak (a PRF seeded
/// by VRF) — still VRF-only, no block values.
function _mix(uint256 genomeA, uint256 genomeB, uint256 seed) internal pure returns (uint256 child) {
// Mutation rate (0..63): the more mutation-prone parent sets the pace.
uint8 mutRate = _max(genomeA.expressed(GenomeLib.GENE_MUTATION), genomeB.expressed(GenomeLib.GENE_MUTATION));
for (uint8 i = 0; i < uint8(GenomeLib.GENE_COUNT); i++) {
uint16 geneA = genomeA.geneAt(i);
uint16 geneB = genomeB.geneAt(i);
uint256 e = uint256(keccak256(abi.encode(seed, i)));
// Pick one allele from each parent (bit 0 for A, bit 1 for B).
uint8 fromA = (e & 1 == 0) ? GenomeLib.alleleA(geneA) : GenomeLib.alleleB(geneA);
uint8 fromB = ((e >> 1) & 1 == 0) ? GenomeLib.alleleA(geneB) : GenomeLib.alleleB(geneB);
// Independent mutation rolls: a fresh random allele replaces the
// inherited one when the roll lands under the rate.
if (uint8((e >> 8) & GenomeLib.TRAIT_MASK) < mutRate) {
fromA = _randomAllele(e >> 16);
}
if (uint8((e >> 40) & GenomeLib.TRAIT_MASK) < mutRate) {
fromB = _randomAllele(e >> 48);
}
child = child.setGene(i, GenomeLib.makeGene(fromA, fromB));
}
child = child.clean();
}
/// @dev A brand-new allele: random tier (2 bits) + random trait (6 bits).
function _randomAllele(uint256 x) internal pure returns (uint8) {
return GenomeLib.makeAllele(uint8(x & 0x3), uint8((x >> 2) & GenomeLib.TRAIT_MASK));
}
function _max(uint8 a, uint8 b) internal pure returns (uint8) {
return a >= b ? a : b;
}
}[
{
"type": "constructor",
"inputs": [
{
"name": "vrfCoordinator",
"type": "address",
"internalType": "address"
},
{
"name": "subId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "keyHash_",
"type": "bytes32",
"internalType": "bytes32"
},
{
"name": "callbackGasLimit_",
"type": "uint32",
"internalType": "uint32"
},
{
"name": "confirmations_",
"type": "uint16",
"internalType": "uint16"
}
],
"stateMutability": "nonpayable"
},
{
"name": "ERC721IncorrectOwner",
"type": "error",
"inputs": [
{
"name": "sender",
"type": "address",
"internalType": "address"
},
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "owner",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "ERC721InsufficientApproval",
"type": "error",
"inputs": [
{
"name": "operator",
"type": "address",
"internalType": "address"
},
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "ERC721InvalidApprover",
"type": "error",
"inputs": [
{
"name": "approver",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "ERC721InvalidOperator",
"type": "error",
"inputs": [
{
"name": "operator",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "ERC721InvalidOwner",
"type": "error",
"inputs": [
{
"name": "owner",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "ERC721InvalidReceiver",
"type": "error",
"inputs": [
{
"name": "receiver",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "ERC721InvalidSender",
"type": "error",
"inputs": [
{
"name": "sender",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "ERC721NonexistentToken",
"type": "error",
"inputs": [
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "EnforcedPause",
"type": "error",
"inputs": []
},
{
"name": "ExpectedPause",
"type": "error",
"inputs": []
},
{
"name": "OnlyCoordinatorCanFulfill",
"type": "error",
"inputs": [
{
"name": "have",
"type": "address",
"internalType": "address"
},
{
"name": "want",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "OnlyOwnerOrCoordinator",
"type": "error",
"inputs": [
{
"name": "have",
"type": "address",
"internalType": "address"
},
{
"name": "owner",
"type": "address",
"internalType": "address"
},
{
"name": "coordinator",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "ReentrancyGuardReentrantCall",
"type": "error",
"inputs": []
},
{
"name": "ZeroAddress",
"type": "error",
"inputs": []
},
{
"name": "Approval",
"type": "event",
"inputs": [
{
"name": "owner",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "approved",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "tokenId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "ApprovalForAll",
"type": "event",
"inputs": [
{
"name": "owner",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "operator",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "approved",
"type": "bool",
"indexed": false,
"internalType": "bool"
}
],
"anonymous": false
},
{
"name": "BreedFulfilled",
"type": "event",
"inputs": [
{
"name": "requestId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "BreedRequested",
"type": "event",
"inputs": [
{
"name": "requestId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "breeder",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "parentA",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "parentB",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "ChildBorn",
"type": "event",
"inputs": [
{
"name": "requestId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "childId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "parentA",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "parentB",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "genome",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "CoinBound",
"type": "event",
"inputs": [
{
"name": "tokenId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "coin",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "CoordinatorSet",
"type": "event",
"inputs": [
{
"name": "vrfCoordinator",
"type": "address",
"indexed": false,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "FeesWithdrawn",
"type": "event",
"inputs": [
{
"name": "to",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "amount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "GenesisMinted",
"type": "event",
"inputs": [
{
"name": "tokenId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "to",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "feePaid",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "GenomeMinted",
"type": "event",
"inputs": [
{
"name": "tokenId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "to",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "genome",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "OwnershipTransferRequested",
"type": "event",
"inputs": [
{
"name": "from",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "to",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "OwnershipTransferred",
"type": "event",
"inputs": [
{
"name": "from",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "to",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "Paused",
"type": "event",
"inputs": [
{
"name": "account",
"type": "address",
"indexed": false,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "Transfer",
"type": "event",
"inputs": [
{
"name": "from",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "to",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "tokenId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "Unpaused",
"type": "event",
"inputs": [
{
"name": "account",
"type": "address",
"indexed": false,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "acceptOwnership",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "approve",
"type": "function",
"inputs": [
{
"name": "to",
"type": "address",
"internalType": "address"
},
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "availableCharges",
"type": "function",
"inputs": [
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "uint8",
"internalType": "uint8"
}
],
"stateMutability": "view"
},
{
"name": "balanceOf",
"type": "function",
"inputs": [
{
"name": "owner",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "bindCoin",
"type": "function",
"inputs": [
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "coin",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "breed",
"type": "function",
"inputs": [
{
"name": "parentA",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "parentB",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "requestId",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "payable"
},
{
"name": "breedFee",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "breeds",
"type": "function",
"inputs": [
{
"name": "requestId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "breeder",
"type": "address",
"internalType": "address"
},
{
"name": "parentA",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "parentB",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "randomWord",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "fulfilled",
"type": "bool",
"internalType": "bool"
},
{
"name": "claimed",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "callbackGasLimit",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint32",
"internalType": "uint32"
}
],
"stateMutability": "view"
},
{
"name": "chargesSpent",
"type": "function",
"inputs": [
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "spent",
"type": "uint32",
"internalType": "uint32"
}
],
"stateMutability": "view"
},
{
"name": "claimChild",
"type": "function",
"inputs": [
{
"name": "requestId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "childId",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "nonpayable"
},
{
"name": "coinOf",
"type": "function",
"inputs": [
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "coin",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "eggCount",
"type": "function",
"inputs": [
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "uint8",
"internalType": "uint8"
}
],
"stateMutability": "view"
},
{
"name": "expressedTrait",
"type": "function",
"inputs": [
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "gene",
"type": "uint8",
"internalType": "uint8"
}
],
"outputs": [
{
"name": "",
"type": "uint8",
"internalType": "uint8"
}
],
"stateMutability": "view"
},
{
"name": "feeRecipient",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "feesAccrued",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "genesisFee",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "genesisMaxFertility",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint8",
"internalType": "uint8"
}
],
"stateMutability": "view"
},
{
"name": "genesisMaxTier",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint8",
"internalType": "uint8"
}
],
"stateMutability": "view"
},
{
"name": "genomeOf",
"type": "function",
"inputs": [
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "genome",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "getApproved",
"type": "function",
"inputs": [
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "isApprovedForAll",
"type": "function",
"inputs": [
{
"name": "owner",
"type": "address",
"internalType": "address"
},
{
"name": "operator",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "keyHash",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bytes32",
"internalType": "bytes32"
}
],
"stateMutability": "view"
},
{
"name": "launchpad",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "mintGenesis",
"type": "function",
"inputs": [
{
"name": "genome",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "payable"
},
{
"name": "mintGenome",
"type": "function",
"inputs": [
{
"name": "to",
"type": "address",
"internalType": "address"
},
{
"name": "genome",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "nonpayable"
},
{
"name": "name",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "string",
"internalType": "string"
}
],
"stateMutability": "view"
},
{
"name": "owner",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "ownerOf",
"type": "function",
"inputs": [
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "pause",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "paused",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "primaryParentOf",
"type": "function",
"inputs": [
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "parent",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "rawFulfillRandomWords",
"type": "function",
"inputs": [
{
"name": "requestId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "randomWords",
"type": "uint256[]",
"internalType": "uint256[]"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "requestConfirmations",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint16",
"internalType": "uint16"
}
],
"stateMutability": "view"
},
{
"name": "s_vrfCoordinator",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "contract IVRFCoordinatorV2Plus"
}
],
"stateMutability": "view"
},
{
"name": "safeTransferFrom",
"type": "function",
"inputs": [
{
"name": "from",
"type": "address",
"internalType": "address"
},
{
"name": "to",
"type": "address",
"internalType": "address"
},
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "safeTransferFrom",
"type": "function",
"inputs": [
{
"name": "from",
"type": "address",
"internalType": "address"
},
{
"name": "to",
"type": "address",
"internalType": "address"
},
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "data",
"type": "bytes",
"internalType": "bytes"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setApprovalForAll",
"type": "function",
"inputs": [
{
"name": "operator",
"type": "address",
"internalType": "address"
},
{
"name": "approved",
"type": "bool",
"internalType": "bool"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setCoordinator",
"type": "function",
"inputs": [
{
"name": "_vrfCoordinator",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setFeeRecipient",
"type": "function",
"inputs": [
{
"name": "recipient",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setFees",
"type": "function",
"inputs": [
{
"name": "genesisFee_",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "breedFee_",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setGenesisLimits",
"type": "function",
"inputs": [
{
"name": "maxTier",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "maxFertility",
"type": "uint8",
"internalType": "uint8"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setLaunchpad",
"type": "function",
"inputs": [
{
"name": "launchpad_",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setVrfConfig",
"type": "function",
"inputs": [
{
"name": "keyHash_",
"type": "bytes32",
"internalType": "bytes32"
},
{
"name": "subId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "callbackGasLimit_",
"type": "uint32",
"internalType": "uint32"
},
{
"name": "confirmations_",
"type": "uint16",
"internalType": "uint16"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "subscriptionId",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "supportsInterface",
"type": "function",
"inputs": [
{
"name": "interfaceId",
"type": "bytes4",
"internalType": "bytes4"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "symbol",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "string",
"internalType": "string"
}
],
"stateMutability": "view"
},
{
"name": "tokenURI",
"type": "function",
"inputs": [
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "string",
"internalType": "string"
}
],
"stateMutability": "view"
},
{
"name": "transferFrom",
"type": "function",
"inputs": [
{
"name": "from",
"type": "address",
"internalType": "address"
},
{
"name": "to",
"type": "address",
"internalType": "address"
},
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "transferOwnership",
"type": "function",
"inputs": [
{
"name": "to",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "unpause",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "withdrawFees",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
}
]0x608034620004ad57601f6200448238819003918201601f19168301916001600160401b03831184841017620003aa5780849260a094604052833981010312620004ad578051906001600160a01b0382168203620004ad576020810151604082015160608301519263ffffffff84168403620004ad57608001519161ffff83168303620004ad576200008f620004b1565b600e81526d26b2b73232b610213932b2b232b960911b6020820152620000b4620004b1565b6005815264109491515160da1b6020820152815190916001600160401b038211620003aa575f5490600182811c92168015620004a2575b60208310146200038b5781601f84931162000442575b50602090601f8311600114620003ca575f92620003be575b50508160011b915f199060031b1c1916175f555b8051906001600160401b038211620003aa5760015490600182811c921680156200039f575b60208310146200038b5781601f8493116200032a575b50602090601f8311600114620002b3575f92620002a7575b50508160011b915f199060031b1c1916176001555b600160085533156200026257600980546001600160a01b03199081163317909155946001600160a01b03811615620002505760018060a01b031685600b541617600b5560017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005561030161ffff196017541617601755600d55600c5563ffffffff65ffff00000000600e549260201b1692169065ffffffffffff19161717600e5533906015541617601555604051613f709081620004d28239f35b60405163d92e233d60e01b8152600490fd5b60405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f00000000000000006044820152606490fd5b015190505f8062000180565b60015f9081525f80516020620044628339815191529350601f198516905b818110620003115750908460019594939210620002f8575b505050811b0160015562000195565b01515f1960f88460031b161c191690555f8080620002e9565b92936020600181928786015181550195019301620002d1565b60015f529091505f8051602062004462833981519152601f840160051c8101916020851062000380575b90601f859493920160051c01905b81811062000371575062000168565b5f815584935060010162000362565b909150819062000354565b634e487b7160e01b5f52602260045260245ffd5b91607f169162000152565b634e487b7160e01b5f52604160045260245ffd5b015190505f8062000119565b5f80805293505f805160206200444283398151915291905b601f198416851062000426576001945083601f198116106200040d575b505050811b015f556200012d565b01515f1960f88460031b161c191690555f8080620003ff565b81810151835560209485019460019093019290910190620003e2565b5f80529091505f8051602062004442833981519152601f840160051c8101916020851062000497575b90601f859493920160051c01905b81811062000488575062000101565b5f815584935060010162000479565b90915081906200046b565b91607f1691620000eb565b5f80fd5b60408051919082016001600160401b03811183821017620003aa5760405256fe6080806040526004361015610012575f80fd5b5f3560e01c90816301ffc9a714612f795750806302669b5214612f5157806306fdde0314612e94578063081812fc14612e58578063095ea7b314612d7757806309c1ba2e14612d5a5780630b78f9c014612d3b5780631817d87e14612d1e5780631fe543e314612c925780632103ee8914612c2957806323b872dd14612c1257806324f7469714612bef5780632c0209f514612b7f57806336f4c0eb14612b3c5780633f4ba83a14612acb57806342842e0e14612a9e5780634690484014612a76578063476343ee146129b057806348b57bfc146129805780635c975abb1461295b57806361728f391461293e5780636352211e1461290e57806365782959146128f0578063662d9656146128c657806370584c47146128a3578063706a8f83146127f657806370a08231146127a057806373b8751a1461249c57806379ba5097146123f55780637d3450431461238e5780638456cb591461232d57806384c82640146122fb57806388e75473146122db5780638da5cb5b146122b35780638ea98117146121ec57806394db0595146121cf57806395d89b41146120c55780639eccacf61461209d578063a22cb46514611fd5578063b0fb162f14611fb2578063b6e8284414611f73578063b88d4fde14611edd578063bab4253114611ea7578063c759c8f714611d86578063c87b56dd146109a9578063d7992dab1461097f578063d9ecad7b14610500578063dff63243146103c3578063e0df99e8146103a6578063e74b981b14610363578063e985e9c5146103115763f2fde38b14610258575f80fd5b3461030d57602036600319011261030d5761027161302a565b6102796133b8565b6001600160a01b03908116903382146102c857600a80546001600160a01b03191683179055600954167fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12785f80a3005b60405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606490fd5b5f80fd5b3461030d57604036600319011261030d5761032a61302a565b610332613040565b9060018060a01b038091165f52600560205260405f2091165f52602052602060ff60405f2054166040519015158152f35b3461030d57602036600319011261030d5761037c61302a565b6103846133b8565b601580546001600160a01b0319166001600160a01b0392909216919091179055005b3461030d575f36600319011261030d576020601354604051908152f35b602036600319011261030d576004356103da613731565b6103e261349a565b6103ed6013546139e8565b6017549060ff905f828416815b600880868516101561046857859184610442928461ff0061041b848b613b61565b92610436898461042d82828916613e48565b96841c16613e48565b901b1691161791613b91565b921684811461045457600101916103fa565b634e487b7160e01b5f52601160045260245ffd5b60206104b88361ffff60401b89808c60081c169061ff0061049d61049184848860401c16613e6c565b93838760481c16613e6c565b60081b1691161760401b169061ffff60401b191617336134c9565b601354604051908152817fbdbb3678ff29a0befcc1ce3c9336057a0a776e7d442359dd836076e312ab51bf843393a360015f80516020613f1b83398151915255604051908152f35b61050936613056565b610511613731565b61051961349a565b80821461093a576105298261337e565b336001600160a01b03909116036108f557336001600160a01b0361054c8361337e565b16036108b05760ff61055d83613324565b161561086b5760ff61056e82613324565b16156108265761057f6014546139e8565b815f52601060205260405f2080549063ffffffff61059e818416613369565b1663ffffffff19809316179055815f52601060205260405f209081549063ffffffff6105cb818416613369565b169116179055600c5491600d54600e549060405194602086019580871067ffffffffffffffff8811176108125763ffffffff60209460a0946106d8996040525f84526040519363125fa26760e31b88860152511515602485015260248452610632846130e9565b6040519461063f866130b1565b85528685015261ffff81871c1660408501521660608301526001608083015282820152600180831b03600b5416905f604051809881958294634d8e1c2f60e11b84528860048501528051602485015288810151604485015261ffff604082015116606485015263ffffffff606082015116608485015263ffffffff60808201511660a4850152015160c060c484015260e4830190613005565b03925af1918215610807575f926107d2575b602093506040516106fa816130b1565b33815284810183815261077760046040840193858552606081015f815260808201955f875260a08301955f87528a5f52600f8c5260405f209360018060a01b039051166001600160601b0360a01b8554161784555160018401555160028301555160038201550192511515839060ff801983541691151516179055565b51151561ff0082549160081b169061ff001916179055604051908152827fe5512d7763f01631a3b5ec33fc32e1aa6ae349baeb9d0db5f256d1937882a93a853393a460015f80516020613f1b83398151915255604051908152f35b91506020833d6020116107ff575b816107ed60209383613121565b8101031261030d5760209251916106ea565b3d91506107e0565b6040513d5f823e3d90fd5b634e487b7160e01b5f52604160045260245ffd5b60405162461bcd60e51b815260206004820152601b60248201527f4272656564696e67456e67696e653a204220696e66657274696c6500000000006044820152606490fd5b60405162461bcd60e51b815260206004820152601b60248201527f4272656564696e67456e67696e653a204120696e66657274696c6500000000006044820152606490fd5b60405162461bcd60e51b815260206004820152601b60248201527f4272656564696e67456e67696e653a206e6f74206f776e6572204200000000006044820152606490fd5b60405162461bcd60e51b815260206004820152601b60248201527f4272656564696e67456e67696e653a206e6f74206f776e6572204100000000006044820152606490fd5b60405162461bcd60e51b815260206004820152601b60248201527f4272656564696e67456e67696e653a2073616d6520706172656e7400000000006044820152606490fd5b3461030d57602036600319011261030d576004355f526011602052602060405f2054604051908152f35b3461030d57602036600319011261030d576109c560043561337e565b506004355f52600660205260405f20546109e86109e3600435613324565b61386c565b60ff8260601c16917f2c3730252c35352529223e3c636972636c652063783d22313630222063793d2260ff8260681c1660038360661c16600384606e1c16115f14611d7a57610a52603f825b610a3f828516613bca565b9760ff85168103611d7357505b16613bca565b92610a5c81613c33565b9461115061042b87604051977f3c7265637420783d223130342220793d223936222077696474683d223936222060208a0152610c116101268a8d7f6865696768743d22313730222072783d223230222066696c6c3d2268736c28008060408401528551966020870197610ad381605f87018b612fe4565b84017f2c3830252c3535252922206f7061636974793d22302e32222f3e000000000000605f8201527f3c6c696e652078313d22313630222079313d223732222078323d2231363022206079820152703c991e91191c99111039ba3937b5b29e9160791b6099820152610b4f82518093602060aa85019101612fe4565b019073111039ba3937b5b296bbb4b23a341e911991179f60611b60aa8301527f3c7265637420783d223131322220793d223930222077696474683d223936222060be83015260de820152610bad82518093602060fd85019101612fe4565b0172161b18129618991294911039ba3937b5b29e9160691b60fd8201528d61011091610be28251809360208685019101612fe4565b019075111039ba3937b5b296bbb4b23a341e9119171a91179f60511b908201520361010681018c52018a613121565b6040519788927f3c706f6c796c696e6520706f696e74733d223136302c313130203138312c313360208501527f30203133392c313531203136302c313731203138312c313931203133392c323160408501527f32203136302c323332222066696c6c3d226e6f6e6522207374726f6b653d2268806060860152620e6d8560eb1b60808601528d610cab81518092602060838a019101612fe4565b8501907f2c3835252c3538252922207374726f6b652d77696474683d22322e35222f3e0060838301527f3c706f6c796c696e6520706f696e74733d223136302c313130203133392c313360a28301527f30203138312c313531203136302c313731203133392c313931203138312c323160c283015260e2820152620e6d8560eb1b6101028201527f2c3735252c3535252922207374726f6b652d77696474683d223222206f70616361010591855190610d678285830187612fe4565b01918201526b34ba3c9e9118171a9a91179f60a11b6101258201527f3c67207374726f6b653d2272676261283233372c3234332c3232362c302e31386101318201527f2922207374726f6b652d77696474683d22312e35223e3c6c696e652078313d226101518201527f313831222079313d22313330222078323d22313339222079323d22313330222f6101718201527f3e3c6c696e652078313d22313339222079313d22313531222078323d223138316101918201527f222079323d22313531222f3e3c6c696e652078313d22313831222079313d22316101b18201527f3931222078323d22313339222079323d22313931222f3e3c6c696e652078313d6101d18201527f22313339222079313d22323132222078323d22313831222079323d22323132226101f182015265179f1e17b39f60d11b6102118201528d7f2c3835252c36302529223e3c636972636c652063783d22313630222063793d226c078ce40ccd2d8d87a44d0e6d85609b1b918261021785015261022493610ef58251809360208885019101612fe4565b01928301527f3131302220723d2235222f3e3c636972636c652063783d22313831222063793d6102448301527f223133302220723d2235222f3e3c636972636c652063783d22313339222063796102648301527f3d223135312220723d2235222f3e3c636972636c652063783d223136302220636102848301527f793d223137312220723d2235222f3e3c636972636c652063783d2231383122206102a48301527f63793d223139312220723d2235222f3e3c636972636c652063783d22313339226102c48301527f2063793d223231322220723d2235222f3e3c636972636c652063783d223136306102e483015275111031bc9e911919991110391e911a91179f1e17b39f60511b61030483015261031a82015261101d6103279451809386840190612fe4565b01918201527f3131302220723d22332e35222f3e3c636972636c652063783d223133392220636103478201527f793d223133302220723d22332e35222f3e3c636972636c652063783d223138316103678201527f222063793d223135312220723d22332e35222f3e3c636972636c652063783d226103878201527f313630222063793d223137312220723d22332e35222f3e3c636972636c6520636103a78201527f783d22313339222063793d223139312220723d22332e35222f3e3c636972636c6103c78201527f652063783d22313831222063793d223231322220723d22332e35222f3e3c63696103e78201527f72636c652063783d22313630222063793d223233322220723d22332e35222f3e610407820152631e17b39f60e11b6104278201520361040b810187520185613121565b60038260061c16600383600e1c16115f14611d695760ff8260081c16925b603f8416600103611cef5760405161118581613105565b600381526242544360e81b6020820152915b611417610112603f87161515998a5f14611cce576040516111b781613105565b60028152611b1960f11b6020820152905b8b15611ca8576111d6613bed565b9b5b15611c9a576040516111e981613105565b60078152662330613065303560c81b6020820152905b603f61120a8a613ad1565b169760018903611c485760405161122081613105565b6004815263213ab93760e11b6020820152925b6040519e8f957f3c7265637420783d2231362220793d223136222077696474683d2200000000006020880152611273815180926020603b8b019101612fe4565b86017f22206865696768743d223236222072783d2237222066696c6c3d220000000000603b8201526112af825180936020605685019101612fe4565b017f222f3e3c7465787420783d2232372220793d2233342220666f6e742d66616d6960568201527f6c793d226d6f6e6f73706163652220666f6e742d73697a653d2231342220666f607682015275373a16bbb2b4b3b43a1e911b981811103334b6361e9160511b609682015261132f82518093602060ac85019101612fe4565b019061111f60f11b918260ac82015261135282518093602060ae85019101612fe4565b01917f3c2f746578743e3c7465787420783d223330342220793d22333422207465787460ae8401527f2d616e63686f723d22656e642220666f6e742d66616d696c793d226d6f6e6f7360ce8401527f706163652220666f6e742d73697a653d223132222066696c6c3d22000000000060ee840152610109926113dd8251809360208785019101612fe4565b01918201526113f782518093602061010b85019101612fe4565b01661e17ba32bc3a1f60c91b61010b8201520360f281018b520189613121565b604051611423816130cd565b5f8152955f965b60ff88169060ff8416821015611554576012918281029281840414901517156104545781607601607611610454577f222063793d22333132222072783d2237222072793d2237222066696c6c3d226861154b607e6001938f7f2c3630252c3632252922207374726f6b653d222330623062306222207374726f6114b160ff98607601613881565b9160405196846114cb89965180926020808a019101612fe4565b8501936c1e32b63634b839b29031bc1e9160991b6020860152602d946114fa8251809360208985019101612fe4565b0193840152620e6d8560eb1b604d8401526050926115218251809360208785019101612fe4565b01918201526d35b296bbb4b23a341e911891179f60911b607082015203605e810184520182613121565b9801169661142a565b6117c49150878787611c26978f8f8f996117c9611b5d9a6117c4610179611a9096611bbf9f651e17b9bb339f60d11b60c59e6047996040519788957f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323060208801527f30302f737667222077696474683d2233323022206865696768743d223334302260408801527f2076696577426f783d223020302033323020333430223e00000000000000000060608801527f3c726563742077696474683d2233323022206865696768743d223334302220666077880152680d2d8d87a44d0e6d8560bb1b609788015261164d81518092602060a08b019101612fe4565b8601946a161a9a92961c929491179f60a91b60a08701527f3c67207374726f6b653d2272676261283230302c3235302c36302c302e30352960ab8701527f223e3c6c696e652078313d2230222079313d223830222078323d22333230222060cb8701527f79323d223830222f3e3c6c696e652078313d2230222079313d2231343022207860eb8701527f323d22333230222079323d22313430222f3e3c6c696e652078313d223022207961010b8701527f313d22323030222078323d22333230222079323d22323030222f3e3c6c696e6561012b8701527f2078313d2230222079313d22323630222078323d22333230222079323d22323661014b870152671811179f1e17b39f60c11b61016b870152610173956117748251809360208a85019101612fe4565b016117888251809360208985019101612fe4565b0161179c8251809360208885019101612fe4565b016117b08251809360208785019101612fe4565b019182015203610159810184520182613121565b613c82565b9561182b6118046117db600435613881565b99603f604051916117eb83613105565b600583526414995858dd60da1b60208401521690613dc1565b9660405161181181613105565b60088152672932b0b1ba34b7b760c11b6020820152613dc1565b60038260261c16600383602e1c16115f14611c395761187360ff8360281c165b603f6040519161185a83613105565b6005835264437572766560d81b60208401521690613dc1565b9260038360361c16600384603e1c16115f14611c2a576118ba60ff8460381c165b603f604051916118a383613105565b600383526246656560e81b60208401521690613dc1565b9661195b60ff61195461192d603f611906611900826118d88c613af7565b166040516118e581613105565b600981526846657274696c69747960b81b6020820152613dc1565b99613aab565b1660405161191381613105565b600881526726baba30ba34b7b760c11b6020820152613dc1565b93603f6040519161193d83613105565b600383526248756560e81b60208401521690613dc1565b9316613881565b93604051988996602088019b605b60f81b8d5261198281518092602060218d019101612fe4565b880195600b60fa1b968760218201526119a5825180936020602285019101612fe4565b018660228201526119c0825180936020602385019101612fe4565b018560238201526119db825180936020602485019101612fe4565b018460248201526119f6825180936020602585019101612fe4565b01836025820152611a11825180936020602685019101612fe4565b01826026820152611a2c825180936020602785019101612fe4565b019060278201527f7b2274726169745f74797065223a2245676773222c2276616c7565223a0000006028820152611a6d825180936020604585019101612fe4565b01607d60f81b6045820152605d60f81b6046820152036027810184520182613121565b604051968794717b226e616d65223a2242726565646572202360701b6020870152611ac581518092602060328a019101612fe4565b8501917f222c226465736372697074696f6e223a2241204d656e64656c2062726565646560328401527f722e2047656e6f6d652c2066657274696c69747920616e64207265616374697660528401527f6520776972696e672061726520656e636f646564206f6e2d636861696e2e222c60728401526c1130ba3a3934b13aba32b9911d60991b6092840152518093609f840190612fe4565b017f2c22696d616765223a22646174613a696d6167652f7376672b786d6c3b626173609f82015263194d8d0b60e21b60bf820152611ba582518093602060c385019101612fe4565b0161227d60f01b60c38201520360a5810184520182613121565b611c12603d60405180937f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c0000006020830152611c028151809260208686019101612fe4565b810103601d810184520182613121565b604051918291602083526020830190613005565b0390f35b6118ba60ff8460301c16611894565b61187360ff8360201c1661184b565b60028903611c7757604051611c5c81613105565b600781526652656c6561736560c81b60208201525b92611233565b604051611c8381613105565b6005815264125b995c9d60da1b6020820152611c71565b611ca2613c10565b906111ff565b604051611cb481613105565b60078152661199309933191960c91b60208201529b6111d8565b604051611cda81613105565b6002815261033360f41b6020820152906111c8565b603f8416600203611d1d57604051611d0681613105565b600381526208aa8960eb1b60208201525b91611197565b603f8416600303611d4a57604051611d3481613105565b60048152634c494e4b60e01b6020820152611d17565b604051611d5681613105565b60018152602d60f81b6020820152611d17565b60ff82169261116e565b9050610a4c565b610a52603f8692610a34565b3461030d57604036600319011261030d57600435611da2613040565b6012549091906001600160a01b039081163303611e6257815f5260076020528060405f205416611e1d57611dd58261337e565b50815f52600760205260405f20921691826001600160601b0360a01b8254161790557f2a271ecaeada73483ceb34d77843b075105f79886da2a902cc281afa85101fca5f80a3005b60405162461bcd60e51b815260206004820152601d60248201527f4272656564696e67456e67696e653a20616c726561647920626f756e640000006044820152606490fd5b60405162461bcd60e51b815260206004820152601d60248201527f4272656564696e67456e67696e653a206e6f74206c61756e63687061640000006044820152606490fd5b3461030d57602036600319011261030d576020611ed26109e3600435611ecc8161337e565b50613324565b60ff60405191168152f35b3461030d57608036600319011261030d57611ef661302a565b611efe613040565b906044356064359267ffffffffffffffff841161030d573660238501121561030d57836004013592611f2f84613143565b93611f3d6040519586613121565b808552366024828801011161030d576020815f926024611f7199018389013786010152611f6b83838361315f565b33613752565b005b3461030d57604036600319011261030d576020611faa611f9161302a565b611f996133b8565b611fa1613731565b602435906134c9565b604051908152f35b3461030d575f36600319011261030d576020600e5461ffff60405191831c168152f35b3461030d57604036600319011261030d57611fee61302a565b602435908115159081830361030d573315612085576001600160a01b031691821561206c5761203e90335f52600560205260405f20845f5260205260405f209060ff801983541691151516179055565b6040519081527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160203392a3005b604051630b61174360e31b815260048101849052602490fd5b60405163a9fbf51f60e01b81525f6004820152602490fd5b3461030d575f36600319011261030d57600b546040516001600160a01b039091168152602090f35b3461030d575f36600319011261030d576040515f600190600154918260011c91600184169182156121c5575b60209485851084146121b15785879486865291825f14612191575050600114612136575b5061212292500383613121565b611c26604051928284938452830190613005565b84915060015f527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6905f915b858310612179575050612122935082010185612115565b80548389018501528794508693909201918101612162565b60ff19168582015261212295151560051b85010192508791506121159050565b634e487b7160e01b5f52602260045260245ffd5b92607f16926120f1565b3461030d575f36600319011261030d576020601654604051908152f35b3461030d57602036600319011261030d5761220561302a565b6009546001600160a01b039190821633811415806122a5575b61227d575016801561226b576020817fd1a6a14209a385a964d036e404cb5cfb71f4000cdb03c9366292430787261be6926001600160601b0360a01b600b541617600b55604051908152a1005b60405163d92e233d60e01b8152600490fd5b60649083600b54166040519163061db9c160e01b835233600484015260248301526044820152fd5b5082600b541633141561221e565b3461030d575f36600319011261030d576009546040516001600160a01b039091168152602090f35b3461030d575f36600319011261030d57602060ff60175416604051908152f35b3461030d57602036600319011261030d576004355f526007602052602060018060a01b0360405f205416604051908152f35b3461030d575f36600319011261030d576123456133b8565b61234d613731565b600b805460ff60a01b1916600160a01b1790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602090a1005b3461030d57608036600319011261030d5760443563ffffffff811680910361030d576064359061ffff8216820361030d576123c76133b8565b600435600c55602435600d5565ffff00000000600e549260201b169165ffffffffffff19161717600e555f80f35b3461030d575f36600319011261030d57600a546001600160a01b03808216330361245e57600954916001600160601b0360a01b90338285161760095516600a553391167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3005b60405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b6044820152606490fd5b3461030d57602036600319011261030d576124b561349a565b6004355f52600f60205260405f206004810180549060ff82161561275b5760ff8260081c166127165782546001600160a01b031691338390036126d15761ff00191661010017905560018201545f908152600660205260408082205460028501548352908220546003850154929491603f61252f82613aab565b16603f61253b84613aab565b168082106126c95750925b5f965b600860ff891610156126485760016125e460ff928a6125688188613b61565b612572828a613b61565b9086808d60405160208101918252828716604082015260408152612595816130e9565b5190209288841661263f57165b9282881c881661263657165b908b888116603f8360081c161061260b575b9161ff009189809416603f8260281c16106125ed575b5060081b1691161791613b91565b98011696612549565b61260591506003603f8260321c169160301c16613e86565b5f6125d6565b92508791818361262a603f61ff009560121c1660038460101c16613e86565b959294505091506125c0565b60081c166125ae565b60081c166125a2565b602091906001600160801b031661265f81896134c9565b9182916002600183015492845f52601187528360405f205501546040519283528583015260408201527f3af54b3fa3cce2d97cde8d400c1c217a156edb12a3152f61bbbde7e7d63b86ea606060043592a360015f80516020613f1b83398151915255604051908152f35b905092612546565b60405162461bcd60e51b815260206004820152601b60248201527f4272656564696e67456e67696e653a206e6f74206272656564657200000000006044820152606490fd5b60405162461bcd60e51b815260206004820152601f60248201527f4272656564696e67456e67696e653a20616c726561647920636c61696d6564006044820152606490fd5b60405162461bcd60e51b815260206004820152601d60248201527f4272656564696e67456e67696e653a206e6f742066756c66696c6c65640000006044820152606490fd5b3461030d57602036600319011261030d576001600160a01b036127c161302a565b1680156127de575f526003602052602060405f2054604051908152f35b6040516322718ad960e21b81525f6004820152602490fd5b3461030d57604036600319011261030d5760043560ff811680910361030d5761281d61306c565b906128266133b8565b600381111580612895575b156128505761ff006017549260081b169161ffff191617176017555f80f35b60405162461bcd60e51b815260206004820152601960248201527f4272656564696e67456e67696e653a20626164206c696d6974000000000000006044820152606490fd5b50603f60ff83161115612831565b3461030d575f36600319011261030d57602060ff60175460081c16604051908152f35b3461030d57602036600319011261030d576004355f526006602052602060405f2054604051908152f35b3461030d57602036600319011261030d576020611ed2600435613324565b3461030d57602036600319011261030d57602061292c60043561337e565b6040516001600160a01b039091168152f35b3461030d575f36600319011261030d576020600c54604051908152f35b3461030d575f36600319011261030d57602060ff600b5460a01c166040519015158152f35b3461030d57602036600319011261030d576004355f526010602052602063ffffffff60405f205416604051908152f35b3461030d575f36600319011261030d576129c861349a565b601680545f918290556015546001600160a01b03169180808084865af16129ed6132f5565b5015612a315760207fc0819c13be868895eb93e40eaceb96de976442fa1d404e5c55f14bb65a8c489a91604051908152a260015f80516020613f1b83398151915255005b60405162461bcd60e51b815260206004820152601f60248201527f4272656564696e67456e67696e653a207769746864726177206661696c6564006044820152606490fd5b3461030d575f36600319011261030d576015546040516001600160a01b039091168152602090f35b3461030d57611f71612aaf3661307c565b9060405192612abd846130cd565b5f8452611f6b83838361315f565b3461030d575f36600319011261030d57612ae36133b8565b600b5460ff8160a01c1615612b2a5760ff60a01b1916600b556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa90602090a1005b604051638dfc202b60e01b8152600490fd5b3461030d57602036600319011261030d57612b5561302a565b612b5d6133b8565b601280546001600160a01b0319166001600160a01b0392909216919091179055005b3461030d57602036600319011261030d576004355f52600f60205260c060405f2060ff60018060a01b0382541691600181015490600281015460046003830154920154926040519586526020860152604085015260608401528181161515608084015260081c16151560a0820152f35b3461030d575f36600319011261030d57602063ffffffff600e5416604051908152f35b3461030d57611f71612c233661307c565b9161315f565b3461030d57604036600319011261030d57602060ff612c67600435612c4c61306c565b90612c568161337e565b505f526006845260405f2054613b61565b60038160061c16600382600e1c16115f14612c8c5760081c165b603f60405191168152f35b16612c81565b3461030d57604036600319011261030d5760243567ffffffffffffffff80821161030d573660238301121561030d57816004013590811161030d573660248260051b8401011161030d57600b546001600160a01b031633819003612d0057506024611f71920160043561340a565b6044906040519063073e64fd60e21b82523360048301526024820152fd5b3461030d575f36600319011261030d576020601454604051908152f35b3461030d57612d4936613056565b90612d526133b8565b601355601455005b3461030d575f36600319011261030d576020600d54604051908152f35b3461030d57604036600319011261030d57612d9061302a565b602435612d9c8161337e565b33151580612e45575b80612e1c575b612e04576001600160a01b039283169282918491167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9255f80a45f90815260046020526040902080546001600160a01b0319169091179055005b60405163a9fbf51f60e01b8152336004820152602490fd5b5060018060a01b0381165f52600560205260405f20335f5260205260ff60405f20541615612dab565b506001600160a01b038116331415612da5565b3461030d57602036600319011261030d57600435612e758161337e565b505f526004602052602060018060a01b0360405f205416604051908152f35b3461030d575f36600319011261030d576040515f80549060018260011c9160018416918215612f47575b60209485851084146121b15785879486865291825f14612191575050600114612eee575061212292500383613121565b5f808052859250907f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5635b858310612f2f575050612122935082010185612115565b80548389018501528794508693909201918101612f18565b92607f1692612ebe565b3461030d575f36600319011261030d576012546040516001600160a01b039091168152602090f35b3461030d57602036600319011261030d576004359063ffffffff60e01b821680920361030d576020916380ac58cd60e01b8114908115612fd3575b8115612fc2575b5015158152f35b6301ffc9a760e01b14905083612fbb565b635b5e139f60e01b81149150612fb4565b5f5b838110612ff55750505f910152565b8181015183820152602001612fe6565b9060209161301e81518092818552858086019101612fe4565b601f01601f1916010190565b600435906001600160a01b038216820361030d57565b602435906001600160a01b038216820361030d57565b604090600319011261030d576004359060243590565b6024359060ff8216820361030d57565b606090600319011261030d576001600160a01b0390600435828116810361030d5791602435908116810361030d579060443590565b60c0810190811067ffffffffffffffff82111761081257604052565b6020810190811067ffffffffffffffff82111761081257604052565b6060810190811067ffffffffffffffff82111761081257604052565b6040810190811067ffffffffffffffff82111761081257604052565b90601f8019910116810190811067ffffffffffffffff82111761081257604052565b67ffffffffffffffff811161081257601f01601f191660200190565b6001600160a01b0391821692909183156132dd57815f52602092600284528260409583875f205416953315158061324b575b506002908761321a575b825f5260038152885f2060018154019055835f5252865f20816001600160601b0360a01b825416179055857fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a416928383036131f95750505050565b6064945051926364283d7b60e01b8452600484015260248301526044820152fd5b5f84815260046020526040812080546001600160a01b03191690558881526003825289902080545f1901905561319b565b919250908061329c575b15613263579084915f613191565b868587613280576024915190637e27328960e01b82526004820152fd5b604491519063177e802f60e01b82523360048301526024820152fd5b5033861480156132c1575b806132555750845f52600481523384885f20541614613255565b50855f5260058152865f20335f52815260ff875f2054166132a7565b604051633250574960e11b81525f6004820152602490fd5b3d1561331f573d9061330682613143565b916133146040519384613121565b82523d5f602084013e565b606090565b5f526006602052603f61333a60405f2054613af7565b16601060205260405f20548163ffffffff821610156133635760ff16900360ff81116104545790565b50505f90565b90600163ffffffff8093160191821161045457565b5f818152600260205260409020546001600160a01b03169081156133a0575090565b60249060405190637e27328960e01b82526004820152fd5b6009546001600160a01b031633036133cc57565b60405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b6044820152606490fd5b5f818152600f602052604090208054919390916001600160a01b031615801561348c575b61348657156134725790356003820155600401805460ff191660011790557f63dae61891760763c3808f2a7ce299886a802c880a30aca6a8aee448bc76f9be5f80a2565b634e487b7160e01b5f52603260045260245ffd5b50505050565b5060ff60048301541661342e565b5f80516020613f1b83398151915260028154146134b75760029055565b604051633ee5aeb560e01b8152600490fd5b6008549192915f199182821461045457600182016008556001600160801b03829516825f526020916006835260409082825f2055815190613509826130cd565b5f82526001600160a01b038181169790881561371a57888891825f5260028952865f20541680151593846136e9575b505f82815260038a528781208054600101905583815260028a5287812080546001600160a01b031916841790557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9080a46136d2573b6135bd575b50519081527e6ae82e27a11feb3e16adba8bf0b23025bc8719a5d3d64f4d9a4e884e3dbe0c9190a3565b8195969397949291518881806135fb630a85bd0160e11b958683523360048401525f6024840152886044840152608060648401526084830190613005565b03815f8c5af15f9181613692575b50613640578888886136196132f5565b805193908461363a578251633250574960e11b815260048101859052602490fd5b84925001fd5b63ffffffff60e099959897939496991b160361367b577e6ae82e27a11feb3e16adba8bf0b23025bc8719a5d3d64f4d9a4e884e3dbe0c613593565b51633250574960e11b815260048101859052602490fd5b9091508981813d83116136cb575b6136aa8183613121565b8101031261030d57516001600160e01b03198116810361030d57905f613609565b503d6136a0565b82516339e3563760e11b81525f6004820152602490fd5b5f84815260046020526040902080546001600160a01b0319169055815f5260038a52875f209081540190555f613538565b8451633250574960e11b81525f6004820152602490fd5b60ff600b5460a01c1661374057565b60405163d93c066560e01b8152600490fd5b9291803b613762575b5050505050565b604051630a85bd0160e11b8082526001600160a01b039586166004830152928516602482015260448101939093526080606484015290921692602090829081906137b0906084830190613005565b03815f875af15f9181613827575b506137f557826137cc6132f5565b80519190826137ee57604051633250574960e11b815260048101839052602490fd5b6020915001fd5b6001600160e01b0319160361380f57505f8080808061375b565b60249060405190633250574960e11b82526004820152fd5b9091506020813d602011613864575b8161384360209383613121565b8101031261030d57516001600160e01b03198116810361030d57905f6137be565b3d9150613836565b600660ff8216111561387e5750600690565b90565b805f917a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000808210156139da575b506d04ee2d6d415b85acef8100000000808310156139cb575b50662386f26fc10000808310156139bc575b506305f5e100808310156139ad575b506127108083101561399e575b50606482101561398e575b600a80921015613984575b600190816021600186019561391a87613143565b966139286040519889613121565b808852613937601f1991613143565b01366020890137860101905b61394f575b5050505090565b5f19019083906f181899199a1a9b1b9c1cb0b131b232b360811b8282061a83530491821561397f57919082613943565b613948565b9160010191613906565b91906064600291049101916138fb565b6004919392049101915f6138f0565b6008919392049101915f6138e3565b6010919392049101915f6138d4565b6020919392049101915f6138c2565b60409350810491505f6138a9565b803410613a70576016548181018091116104545760165580340390348211610454573403613a135750565b5f80808093335af1613a236132f5565b5015613a2b57565b60405162461bcd60e51b815260206004820152601d60248201527f4272656564696e67456e67696e653a20726566756e64206661696c65640000006044820152606490fd5b60405162461bcd60e51b81526020600482015260136024820152724272656564696e67456e67696e653a2066656560681b6044820152606490fd5b60ff9060038160561c16600382605e1c16115f14613aca5760581c1690565b60501c1690565b60ff9060038160161c16600382601e1c16115f14613af05760181c1690565b60101c1690565b60ff9060038160461c16600382604e1c16115f14613b165760481c1690565b60401c1690565b15613b2457565b60405162461bcd60e51b815260206004820152601560248201527408ecadcdedaca98d2c47440cecadcca40d2dcc8caf605b1b6044820152606490fd5b610ff060ff831692613b7560088510613b1d565b60041b1691808304601014901517156104545761ffff911c1690565b9091610ff060ff841693613ba760088610613b1d565b60041b1692808404601014901517156104545761ffff809116831b921b19161790565b60ff16610168908181029181830414901517156104545761387e9060061c613881565b60405190613bfa82613105565b60078252662363386661336360c81b6020830152565b60405190613c1d82613105565b60078252660233861393538360cc1b6020830152565b613c3e603f91613ad1565b1660018114613c7957600214613c565761387e613c10565b604051613c6281613105565b6007815266119a9a329b333360c91b602082015290565b5061387e613bed565b805115613dae57805191600280840180941161045457600393849004600281901b91906001600160fe1b038116036104545793604051937f4142434445464748494a4b4c4d4e4f505152535455565758595a616263646566601f52603f917f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f603f5260208601928291835184019160208301998a51945f8c525b848110613d7257505050505090600391602095969752510680600114613d5d57600214613d50575b50808452830101604052565b603d905f1901535f613d44565b50603d90815f1982015360011901535f613d44565b836004919c95989c019b838d51818160121c165183538181600c1c16516001840153818160061c1651858401531651858201530196939a613d1c565b50604051613dbb816130cd565b5f815290565b90603a613dd360ff61387e9316613881565b926040519384916e3d913a3930b4ba2fba3cb832911d1160891b6020840152613e06815180926020602f87019101612fe4565b8201691116113b30b63ab2911d60b11b602f820152613e2f825180936020603985019101612fe4565b01607d60f81b603982015203601a810184520182613121565b9060ff811660038360061c16115f14613e6857603f61387e921690613e86565b5090565b9060ff8116603f83161115613e6857600361387e9260061c165b600360ff821611613ee157603f60ff831611613ea65760061b60c0161790565b60405162461bcd60e51b815260206004820152601360248201527247656e6f6d654c69623a2074726169743e363360681b6044820152606490fd5b60405162461bcd60e51b815260206004820152601160248201527047656e6f6d654c69623a20746965723e3360781b6044820152606490fdfe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a2646970667358221220e0e20a8c7c93e733eb677b64bdab5ab0b24409220d350874fad59907572c9ea064736f6c63430008180033290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6000000000000000000000000bb572f865e85e3fb7acf1a0ae4215623a1bac93c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030d400000000000000000000000000000000000000000000000000000000000000003
0x6080806040526004361015610012575f80fd5b5f3560e01c90816301ffc9a714612f795750806302669b5214612f5157806306fdde0314612e94578063081812fc14612e58578063095ea7b314612d7757806309c1ba2e14612d5a5780630b78f9c014612d3b5780631817d87e14612d1e5780631fe543e314612c925780632103ee8914612c2957806323b872dd14612c1257806324f7469714612bef5780632c0209f514612b7f57806336f4c0eb14612b3c5780633f4ba83a14612acb57806342842e0e14612a9e5780634690484014612a76578063476343ee146129b057806348b57bfc146129805780635c975abb1461295b57806361728f391461293e5780636352211e1461290e57806365782959146128f0578063662d9656146128c657806370584c47146128a3578063706a8f83146127f657806370a08231146127a057806373b8751a1461249c57806379ba5097146123f55780637d3450431461238e5780638456cb591461232d57806384c82640146122fb57806388e75473146122db5780638da5cb5b146122b35780638ea98117146121ec57806394db0595146121cf57806395d89b41146120c55780639eccacf61461209d578063a22cb46514611fd5578063b0fb162f14611fb2578063b6e8284414611f73578063b88d4fde14611edd578063bab4253114611ea7578063c759c8f714611d86578063c87b56dd146109a9578063d7992dab1461097f578063d9ecad7b14610500578063dff63243146103c3578063e0df99e8146103a6578063e74b981b14610363578063e985e9c5146103115763f2fde38b14610258575f80fd5b3461030d57602036600319011261030d5761027161302a565b6102796133b8565b6001600160a01b03908116903382146102c857600a80546001600160a01b03191683179055600954167fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12785f80a3005b60405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606490fd5b5f80fd5b3461030d57604036600319011261030d5761032a61302a565b610332613040565b9060018060a01b038091165f52600560205260405f2091165f52602052602060ff60405f2054166040519015158152f35b3461030d57602036600319011261030d5761037c61302a565b6103846133b8565b601580546001600160a01b0319166001600160a01b0392909216919091179055005b3461030d575f36600319011261030d576020601354604051908152f35b602036600319011261030d576004356103da613731565b6103e261349a565b6103ed6013546139e8565b6017549060ff905f828416815b600880868516101561046857859184610442928461ff0061041b848b613b61565b92610436898461042d82828916613e48565b96841c16613e48565b901b1691161791613b91565b921684811461045457600101916103fa565b634e487b7160e01b5f52601160045260245ffd5b60206104b88361ffff60401b89808c60081c169061ff0061049d61049184848860401c16613e6c565b93838760481c16613e6c565b60081b1691161760401b169061ffff60401b191617336134c9565b601354604051908152817fbdbb3678ff29a0befcc1ce3c9336057a0a776e7d442359dd836076e312ab51bf843393a360015f80516020613f1b83398151915255604051908152f35b61050936613056565b610511613731565b61051961349a565b80821461093a576105298261337e565b336001600160a01b03909116036108f557336001600160a01b0361054c8361337e565b16036108b05760ff61055d83613324565b161561086b5760ff61056e82613324565b16156108265761057f6014546139e8565b815f52601060205260405f2080549063ffffffff61059e818416613369565b1663ffffffff19809316179055815f52601060205260405f209081549063ffffffff6105cb818416613369565b169116179055600c5491600d54600e549060405194602086019580871067ffffffffffffffff8811176108125763ffffffff60209460a0946106d8996040525f84526040519363125fa26760e31b88860152511515602485015260248452610632846130e9565b6040519461063f866130b1565b85528685015261ffff81871c1660408501521660608301526001608083015282820152600180831b03600b5416905f604051809881958294634d8e1c2f60e11b84528860048501528051602485015288810151604485015261ffff604082015116606485015263ffffffff606082015116608485015263ffffffff60808201511660a4850152015160c060c484015260e4830190613005565b03925af1918215610807575f926107d2575b602093506040516106fa816130b1565b33815284810183815261077760046040840193858552606081015f815260808201955f875260a08301955f87528a5f52600f8c5260405f209360018060a01b039051166001600160601b0360a01b8554161784555160018401555160028301555160038201550192511515839060ff801983541691151516179055565b51151561ff0082549160081b169061ff001916179055604051908152827fe5512d7763f01631a3b5ec33fc32e1aa6ae349baeb9d0db5f256d1937882a93a853393a460015f80516020613f1b83398151915255604051908152f35b91506020833d6020116107ff575b816107ed60209383613121565b8101031261030d5760209251916106ea565b3d91506107e0565b6040513d5f823e3d90fd5b634e487b7160e01b5f52604160045260245ffd5b60405162461bcd60e51b815260206004820152601b60248201527f4272656564696e67456e67696e653a204220696e66657274696c6500000000006044820152606490fd5b60405162461bcd60e51b815260206004820152601b60248201527f4272656564696e67456e67696e653a204120696e66657274696c6500000000006044820152606490fd5b60405162461bcd60e51b815260206004820152601b60248201527f4272656564696e67456e67696e653a206e6f74206f776e6572204200000000006044820152606490fd5b60405162461bcd60e51b815260206004820152601b60248201527f4272656564696e67456e67696e653a206e6f74206f776e6572204100000000006044820152606490fd5b60405162461bcd60e51b815260206004820152601b60248201527f4272656564696e67456e67696e653a2073616d6520706172656e7400000000006044820152606490fd5b3461030d57602036600319011261030d576004355f526011602052602060405f2054604051908152f35b3461030d57602036600319011261030d576109c560043561337e565b506004355f52600660205260405f20546109e86109e3600435613324565b61386c565b60ff8260601c16917f2c3730252c35352529223e3c636972636c652063783d22313630222063793d2260ff8260681c1660038360661c16600384606e1c16115f14611d7a57610a52603f825b610a3f828516613bca565b9760ff85168103611d7357505b16613bca565b92610a5c81613c33565b9461115061042b87604051977f3c7265637420783d223130342220793d223936222077696474683d223936222060208a0152610c116101268a8d7f6865696768743d22313730222072783d223230222066696c6c3d2268736c28008060408401528551966020870197610ad381605f87018b612fe4565b84017f2c3830252c3535252922206f7061636974793d22302e32222f3e000000000000605f8201527f3c6c696e652078313d22313630222079313d223732222078323d2231363022206079820152703c991e91191c99111039ba3937b5b29e9160791b6099820152610b4f82518093602060aa85019101612fe4565b019073111039ba3937b5b296bbb4b23a341e911991179f60611b60aa8301527f3c7265637420783d223131322220793d223930222077696474683d223936222060be83015260de820152610bad82518093602060fd85019101612fe4565b0172161b18129618991294911039ba3937b5b29e9160691b60fd8201528d61011091610be28251809360208685019101612fe4565b019075111039ba3937b5b296bbb4b23a341e9119171a91179f60511b908201520361010681018c52018a613121565b6040519788927f3c706f6c796c696e6520706f696e74733d223136302c313130203138312c313360208501527f30203133392c313531203136302c313731203138312c313931203133392c323160408501527f32203136302c323332222066696c6c3d226e6f6e6522207374726f6b653d2268806060860152620e6d8560eb1b60808601528d610cab81518092602060838a019101612fe4565b8501907f2c3835252c3538252922207374726f6b652d77696474683d22322e35222f3e0060838301527f3c706f6c796c696e6520706f696e74733d223136302c313130203133392c313360a28301527f30203138312c313531203136302c313731203133392c313931203138312c323160c283015260e2820152620e6d8560eb1b6101028201527f2c3735252c3535252922207374726f6b652d77696474683d223222206f70616361010591855190610d678285830187612fe4565b01918201526b34ba3c9e9118171a9a91179f60a11b6101258201527f3c67207374726f6b653d2272676261283233372c3234332c3232362c302e31386101318201527f2922207374726f6b652d77696474683d22312e35223e3c6c696e652078313d226101518201527f313831222079313d22313330222078323d22313339222079323d22313330222f6101718201527f3e3c6c696e652078313d22313339222079313d22313531222078323d223138316101918201527f222079323d22313531222f3e3c6c696e652078313d22313831222079313d22316101b18201527f3931222078323d22313339222079323d22313931222f3e3c6c696e652078313d6101d18201527f22313339222079313d22323132222078323d22313831222079323d22323132226101f182015265179f1e17b39f60d11b6102118201528d7f2c3835252c36302529223e3c636972636c652063783d22313630222063793d226c078ce40ccd2d8d87a44d0e6d85609b1b918261021785015261022493610ef58251809360208885019101612fe4565b01928301527f3131302220723d2235222f3e3c636972636c652063783d22313831222063793d6102448301527f223133302220723d2235222f3e3c636972636c652063783d22313339222063796102648301527f3d223135312220723d2235222f3e3c636972636c652063783d223136302220636102848301527f793d223137312220723d2235222f3e3c636972636c652063783d2231383122206102a48301527f63793d223139312220723d2235222f3e3c636972636c652063783d22313339226102c48301527f2063793d223231322220723d2235222f3e3c636972636c652063783d223136306102e483015275111031bc9e911919991110391e911a91179f1e17b39f60511b61030483015261031a82015261101d6103279451809386840190612fe4565b01918201527f3131302220723d22332e35222f3e3c636972636c652063783d223133392220636103478201527f793d223133302220723d22332e35222f3e3c636972636c652063783d223138316103678201527f222063793d223135312220723d22332e35222f3e3c636972636c652063783d226103878201527f313630222063793d223137312220723d22332e35222f3e3c636972636c6520636103a78201527f783d22313339222063793d223139312220723d22332e35222f3e3c636972636c6103c78201527f652063783d22313831222063793d223231322220723d22332e35222f3e3c63696103e78201527f72636c652063783d22313630222063793d223233322220723d22332e35222f3e610407820152631e17b39f60e11b6104278201520361040b810187520185613121565b60038260061c16600383600e1c16115f14611d695760ff8260081c16925b603f8416600103611cef5760405161118581613105565b600381526242544360e81b6020820152915b611417610112603f87161515998a5f14611cce576040516111b781613105565b60028152611b1960f11b6020820152905b8b15611ca8576111d6613bed565b9b5b15611c9a576040516111e981613105565b60078152662330613065303560c81b6020820152905b603f61120a8a613ad1565b169760018903611c485760405161122081613105565b6004815263213ab93760e11b6020820152925b6040519e8f957f3c7265637420783d2231362220793d223136222077696474683d2200000000006020880152611273815180926020603b8b019101612fe4565b86017f22206865696768743d223236222072783d2237222066696c6c3d220000000000603b8201526112af825180936020605685019101612fe4565b017f222f3e3c7465787420783d2232372220793d2233342220666f6e742d66616d6960568201527f6c793d226d6f6e6f73706163652220666f6e742d73697a653d2231342220666f607682015275373a16bbb2b4b3b43a1e911b981811103334b6361e9160511b609682015261132f82518093602060ac85019101612fe4565b019061111f60f11b918260ac82015261135282518093602060ae85019101612fe4565b01917f3c2f746578743e3c7465787420783d223330342220793d22333422207465787460ae8401527f2d616e63686f723d22656e642220666f6e742d66616d696c793d226d6f6e6f7360ce8401527f706163652220666f6e742d73697a653d223132222066696c6c3d22000000000060ee840152610109926113dd8251809360208785019101612fe4565b01918201526113f782518093602061010b85019101612fe4565b01661e17ba32bc3a1f60c91b61010b8201520360f281018b520189613121565b604051611423816130cd565b5f8152955f965b60ff88169060ff8416821015611554576012918281029281840414901517156104545781607601607611610454577f222063793d22333132222072783d2237222072793d2237222066696c6c3d226861154b607e6001938f7f2c3630252c3632252922207374726f6b653d222330623062306222207374726f6114b160ff98607601613881565b9160405196846114cb89965180926020808a019101612fe4565b8501936c1e32b63634b839b29031bc1e9160991b6020860152602d946114fa8251809360208985019101612fe4565b0193840152620e6d8560eb1b604d8401526050926115218251809360208785019101612fe4565b01918201526d35b296bbb4b23a341e911891179f60911b607082015203605e810184520182613121565b9801169661142a565b6117c49150878787611c26978f8f8f996117c9611b5d9a6117c4610179611a9096611bbf9f651e17b9bb339f60d11b60c59e6047996040519788957f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323060208801527f30302f737667222077696474683d2233323022206865696768743d223334302260408801527f2076696577426f783d223020302033323020333430223e00000000000000000060608801527f3c726563742077696474683d2233323022206865696768743d223334302220666077880152680d2d8d87a44d0e6d8560bb1b609788015261164d81518092602060a08b019101612fe4565b8601946a161a9a92961c929491179f60a91b60a08701527f3c67207374726f6b653d2272676261283230302c3235302c36302c302e30352960ab8701527f223e3c6c696e652078313d2230222079313d223830222078323d22333230222060cb8701527f79323d223830222f3e3c6c696e652078313d2230222079313d2231343022207860eb8701527f323d22333230222079323d22313430222f3e3c6c696e652078313d223022207961010b8701527f313d22323030222078323d22333230222079323d22323030222f3e3c6c696e6561012b8701527f2078313d2230222079313d22323630222078323d22333230222079323d22323661014b870152671811179f1e17b39f60c11b61016b870152610173956117748251809360208a85019101612fe4565b016117888251809360208985019101612fe4565b0161179c8251809360208885019101612fe4565b016117b08251809360208785019101612fe4565b019182015203610159810184520182613121565b613c82565b9561182b6118046117db600435613881565b99603f604051916117eb83613105565b600583526414995858dd60da1b60208401521690613dc1565b9660405161181181613105565b60088152672932b0b1ba34b7b760c11b6020820152613dc1565b60038260261c16600383602e1c16115f14611c395761187360ff8360281c165b603f6040519161185a83613105565b6005835264437572766560d81b60208401521690613dc1565b9260038360361c16600384603e1c16115f14611c2a576118ba60ff8460381c165b603f604051916118a383613105565b600383526246656560e81b60208401521690613dc1565b9661195b60ff61195461192d603f611906611900826118d88c613af7565b166040516118e581613105565b600981526846657274696c69747960b81b6020820152613dc1565b99613aab565b1660405161191381613105565b600881526726baba30ba34b7b760c11b6020820152613dc1565b93603f6040519161193d83613105565b600383526248756560e81b60208401521690613dc1565b9316613881565b93604051988996602088019b605b60f81b8d5261198281518092602060218d019101612fe4565b880195600b60fa1b968760218201526119a5825180936020602285019101612fe4565b018660228201526119c0825180936020602385019101612fe4565b018560238201526119db825180936020602485019101612fe4565b018460248201526119f6825180936020602585019101612fe4565b01836025820152611a11825180936020602685019101612fe4565b01826026820152611a2c825180936020602785019101612fe4565b019060278201527f7b2274726169745f74797065223a2245676773222c2276616c7565223a0000006028820152611a6d825180936020604585019101612fe4565b01607d60f81b6045820152605d60f81b6046820152036027810184520182613121565b604051968794717b226e616d65223a2242726565646572202360701b6020870152611ac581518092602060328a019101612fe4565b8501917f222c226465736372697074696f6e223a2241204d656e64656c2062726565646560328401527f722e2047656e6f6d652c2066657274696c69747920616e64207265616374697660528401527f6520776972696e672061726520656e636f646564206f6e2d636861696e2e222c60728401526c1130ba3a3934b13aba32b9911d60991b6092840152518093609f840190612fe4565b017f2c22696d616765223a22646174613a696d6167652f7376672b786d6c3b626173609f82015263194d8d0b60e21b60bf820152611ba582518093602060c385019101612fe4565b0161227d60f01b60c38201520360a5810184520182613121565b611c12603d60405180937f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c0000006020830152611c028151809260208686019101612fe4565b810103601d810184520182613121565b604051918291602083526020830190613005565b0390f35b6118ba60ff8460301c16611894565b61187360ff8360201c1661184b565b60028903611c7757604051611c5c81613105565b600781526652656c6561736560c81b60208201525b92611233565b604051611c8381613105565b6005815264125b995c9d60da1b6020820152611c71565b611ca2613c10565b906111ff565b604051611cb481613105565b60078152661199309933191960c91b60208201529b6111d8565b604051611cda81613105565b6002815261033360f41b6020820152906111c8565b603f8416600203611d1d57604051611d0681613105565b600381526208aa8960eb1b60208201525b91611197565b603f8416600303611d4a57604051611d3481613105565b60048152634c494e4b60e01b6020820152611d17565b604051611d5681613105565b60018152602d60f81b6020820152611d17565b60ff82169261116e565b9050610a4c565b610a52603f8692610a34565b3461030d57604036600319011261030d57600435611da2613040565b6012549091906001600160a01b039081163303611e6257815f5260076020528060405f205416611e1d57611dd58261337e565b50815f52600760205260405f20921691826001600160601b0360a01b8254161790557f2a271ecaeada73483ceb34d77843b075105f79886da2a902cc281afa85101fca5f80a3005b60405162461bcd60e51b815260206004820152601d60248201527f4272656564696e67456e67696e653a20616c726561647920626f756e640000006044820152606490fd5b60405162461bcd60e51b815260206004820152601d60248201527f4272656564696e67456e67696e653a206e6f74206c61756e63687061640000006044820152606490fd5b3461030d57602036600319011261030d576020611ed26109e3600435611ecc8161337e565b50613324565b60ff60405191168152f35b3461030d57608036600319011261030d57611ef661302a565b611efe613040565b906044356064359267ffffffffffffffff841161030d573660238501121561030d57836004013592611f2f84613143565b93611f3d6040519586613121565b808552366024828801011161030d576020815f926024611f7199018389013786010152611f6b83838361315f565b33613752565b005b3461030d57604036600319011261030d576020611faa611f9161302a565b611f996133b8565b611fa1613731565b602435906134c9565b604051908152f35b3461030d575f36600319011261030d576020600e5461ffff60405191831c168152f35b3461030d57604036600319011261030d57611fee61302a565b602435908115159081830361030d573315612085576001600160a01b031691821561206c5761203e90335f52600560205260405f20845f5260205260405f209060ff801983541691151516179055565b6040519081527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160203392a3005b604051630b61174360e31b815260048101849052602490fd5b60405163a9fbf51f60e01b81525f6004820152602490fd5b3461030d575f36600319011261030d57600b546040516001600160a01b039091168152602090f35b3461030d575f36600319011261030d576040515f600190600154918260011c91600184169182156121c5575b60209485851084146121b15785879486865291825f14612191575050600114612136575b5061212292500383613121565b611c26604051928284938452830190613005565b84915060015f527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6905f915b858310612179575050612122935082010185612115565b80548389018501528794508693909201918101612162565b60ff19168582015261212295151560051b85010192508791506121159050565b634e487b7160e01b5f52602260045260245ffd5b92607f16926120f1565b3461030d575f36600319011261030d576020601654604051908152f35b3461030d57602036600319011261030d5761220561302a565b6009546001600160a01b039190821633811415806122a5575b61227d575016801561226b576020817fd1a6a14209a385a964d036e404cb5cfb71f4000cdb03c9366292430787261be6926001600160601b0360a01b600b541617600b55604051908152a1005b60405163d92e233d60e01b8152600490fd5b60649083600b54166040519163061db9c160e01b835233600484015260248301526044820152fd5b5082600b541633141561221e565b3461030d575f36600319011261030d576009546040516001600160a01b039091168152602090f35b3461030d575f36600319011261030d57602060ff60175416604051908152f35b3461030d57602036600319011261030d576004355f526007602052602060018060a01b0360405f205416604051908152f35b3461030d575f36600319011261030d576123456133b8565b61234d613731565b600b805460ff60a01b1916600160a01b1790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602090a1005b3461030d57608036600319011261030d5760443563ffffffff811680910361030d576064359061ffff8216820361030d576123c76133b8565b600435600c55602435600d5565ffff00000000600e549260201b169165ffffffffffff19161717600e555f80f35b3461030d575f36600319011261030d57600a546001600160a01b03808216330361245e57600954916001600160601b0360a01b90338285161760095516600a553391167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3005b60405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b6044820152606490fd5b3461030d57602036600319011261030d576124b561349a565b6004355f52600f60205260405f206004810180549060ff82161561275b5760ff8260081c166127165782546001600160a01b031691338390036126d15761ff00191661010017905560018201545f908152600660205260408082205460028501548352908220546003850154929491603f61252f82613aab565b16603f61253b84613aab565b168082106126c95750925b5f965b600860ff891610156126485760016125e460ff928a6125688188613b61565b612572828a613b61565b9086808d60405160208101918252828716604082015260408152612595816130e9565b5190209288841661263f57165b9282881c881661263657165b908b888116603f8360081c161061260b575b9161ff009189809416603f8260281c16106125ed575b5060081b1691161791613b91565b98011696612549565b61260591506003603f8260321c169160301c16613e86565b5f6125d6565b92508791818361262a603f61ff009560121c1660038460101c16613e86565b959294505091506125c0565b60081c166125ae565b60081c166125a2565b602091906001600160801b031661265f81896134c9565b9182916002600183015492845f52601187528360405f205501546040519283528583015260408201527f3af54b3fa3cce2d97cde8d400c1c217a156edb12a3152f61bbbde7e7d63b86ea606060043592a360015f80516020613f1b83398151915255604051908152f35b905092612546565b60405162461bcd60e51b815260206004820152601b60248201527f4272656564696e67456e67696e653a206e6f74206272656564657200000000006044820152606490fd5b60405162461bcd60e51b815260206004820152601f60248201527f4272656564696e67456e67696e653a20616c726561647920636c61696d6564006044820152606490fd5b60405162461bcd60e51b815260206004820152601d60248201527f4272656564696e67456e67696e653a206e6f742066756c66696c6c65640000006044820152606490fd5b3461030d57602036600319011261030d576001600160a01b036127c161302a565b1680156127de575f526003602052602060405f2054604051908152f35b6040516322718ad960e21b81525f6004820152602490fd5b3461030d57604036600319011261030d5760043560ff811680910361030d5761281d61306c565b906128266133b8565b600381111580612895575b156128505761ff006017549260081b169161ffff191617176017555f80f35b60405162461bcd60e51b815260206004820152601960248201527f4272656564696e67456e67696e653a20626164206c696d6974000000000000006044820152606490fd5b50603f60ff83161115612831565b3461030d575f36600319011261030d57602060ff60175460081c16604051908152f35b3461030d57602036600319011261030d576004355f526006602052602060405f2054604051908152f35b3461030d57602036600319011261030d576020611ed2600435613324565b3461030d57602036600319011261030d57602061292c60043561337e565b6040516001600160a01b039091168152f35b3461030d575f36600319011261030d576020600c54604051908152f35b3461030d575f36600319011261030d57602060ff600b5460a01c166040519015158152f35b3461030d57602036600319011261030d576004355f526010602052602063ffffffff60405f205416604051908152f35b3461030d575f36600319011261030d576129c861349a565b601680545f918290556015546001600160a01b03169180808084865af16129ed6132f5565b5015612a315760207fc0819c13be868895eb93e40eaceb96de976442fa1d404e5c55f14bb65a8c489a91604051908152a260015f80516020613f1b83398151915255005b60405162461bcd60e51b815260206004820152601f60248201527f4272656564696e67456e67696e653a207769746864726177206661696c6564006044820152606490fd5b3461030d575f36600319011261030d576015546040516001600160a01b039091168152602090f35b3461030d57611f71612aaf3661307c565b9060405192612abd846130cd565b5f8452611f6b83838361315f565b3461030d575f36600319011261030d57612ae36133b8565b600b5460ff8160a01c1615612b2a5760ff60a01b1916600b556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa90602090a1005b604051638dfc202b60e01b8152600490fd5b3461030d57602036600319011261030d57612b5561302a565b612b5d6133b8565b601280546001600160a01b0319166001600160a01b0392909216919091179055005b3461030d57602036600319011261030d576004355f52600f60205260c060405f2060ff60018060a01b0382541691600181015490600281015460046003830154920154926040519586526020860152604085015260608401528181161515608084015260081c16151560a0820152f35b3461030d575f36600319011261030d57602063ffffffff600e5416604051908152f35b3461030d57611f71612c233661307c565b9161315f565b3461030d57604036600319011261030d57602060ff612c67600435612c4c61306c565b90612c568161337e565b505f526006845260405f2054613b61565b60038160061c16600382600e1c16115f14612c8c5760081c165b603f60405191168152f35b16612c81565b3461030d57604036600319011261030d5760243567ffffffffffffffff80821161030d573660238301121561030d57816004013590811161030d573660248260051b8401011161030d57600b546001600160a01b031633819003612d0057506024611f71920160043561340a565b6044906040519063073e64fd60e21b82523360048301526024820152fd5b3461030d575f36600319011261030d576020601454604051908152f35b3461030d57612d4936613056565b90612d526133b8565b601355601455005b3461030d575f36600319011261030d576020600d54604051908152f35b3461030d57604036600319011261030d57612d9061302a565b602435612d9c8161337e565b33151580612e45575b80612e1c575b612e04576001600160a01b039283169282918491167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9255f80a45f90815260046020526040902080546001600160a01b0319169091179055005b60405163a9fbf51f60e01b8152336004820152602490fd5b5060018060a01b0381165f52600560205260405f20335f5260205260ff60405f20541615612dab565b506001600160a01b038116331415612da5565b3461030d57602036600319011261030d57600435612e758161337e565b505f526004602052602060018060a01b0360405f205416604051908152f35b3461030d575f36600319011261030d576040515f80549060018260011c9160018416918215612f47575b60209485851084146121b15785879486865291825f14612191575050600114612eee575061212292500383613121565b5f808052859250907f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5635b858310612f2f575050612122935082010185612115565b80548389018501528794508693909201918101612f18565b92607f1692612ebe565b3461030d575f36600319011261030d576012546040516001600160a01b039091168152602090f35b3461030d57602036600319011261030d576004359063ffffffff60e01b821680920361030d576020916380ac58cd60e01b8114908115612fd3575b8115612fc2575b5015158152f35b6301ffc9a760e01b14905083612fbb565b635b5e139f60e01b81149150612fb4565b5f5b838110612ff55750505f910152565b8181015183820152602001612fe6565b9060209161301e81518092818552858086019101612fe4565b601f01601f1916010190565b600435906001600160a01b038216820361030d57565b602435906001600160a01b038216820361030d57565b604090600319011261030d576004359060243590565b6024359060ff8216820361030d57565b606090600319011261030d576001600160a01b0390600435828116810361030d5791602435908116810361030d579060443590565b60c0810190811067ffffffffffffffff82111761081257604052565b6020810190811067ffffffffffffffff82111761081257604052565b6060810190811067ffffffffffffffff82111761081257604052565b6040810190811067ffffffffffffffff82111761081257604052565b90601f8019910116810190811067ffffffffffffffff82111761081257604052565b67ffffffffffffffff811161081257601f01601f191660200190565b6001600160a01b0391821692909183156132dd57815f52602092600284528260409583875f205416953315158061324b575b506002908761321a575b825f5260038152885f2060018154019055835f5252865f20816001600160601b0360a01b825416179055857fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a416928383036131f95750505050565b6064945051926364283d7b60e01b8452600484015260248301526044820152fd5b5f84815260046020526040812080546001600160a01b03191690558881526003825289902080545f1901905561319b565b919250908061329c575b15613263579084915f613191565b868587613280576024915190637e27328960e01b82526004820152fd5b604491519063177e802f60e01b82523360048301526024820152fd5b5033861480156132c1575b806132555750845f52600481523384885f20541614613255565b50855f5260058152865f20335f52815260ff875f2054166132a7565b604051633250574960e11b81525f6004820152602490fd5b3d1561331f573d9061330682613143565b916133146040519384613121565b82523d5f602084013e565b606090565b5f526006602052603f61333a60405f2054613af7565b16601060205260405f20548163ffffffff821610156133635760ff16900360ff81116104545790565b50505f90565b90600163ffffffff8093160191821161045457565b5f818152600260205260409020546001600160a01b03169081156133a0575090565b60249060405190637e27328960e01b82526004820152fd5b6009546001600160a01b031633036133cc57565b60405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b6044820152606490fd5b5f818152600f602052604090208054919390916001600160a01b031615801561348c575b61348657156134725790356003820155600401805460ff191660011790557f63dae61891760763c3808f2a7ce299886a802c880a30aca6a8aee448bc76f9be5f80a2565b634e487b7160e01b5f52603260045260245ffd5b50505050565b5060ff60048301541661342e565b5f80516020613f1b83398151915260028154146134b75760029055565b604051633ee5aeb560e01b8152600490fd5b6008549192915f199182821461045457600182016008556001600160801b03829516825f526020916006835260409082825f2055815190613509826130cd565b5f82526001600160a01b038181169790881561371a57888891825f5260028952865f20541680151593846136e9575b505f82815260038a528781208054600101905583815260028a5287812080546001600160a01b031916841790557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9080a46136d2573b6135bd575b50519081527e6ae82e27a11feb3e16adba8bf0b23025bc8719a5d3d64f4d9a4e884e3dbe0c9190a3565b8195969397949291518881806135fb630a85bd0160e11b958683523360048401525f6024840152886044840152608060648401526084830190613005565b03815f8c5af15f9181613692575b50613640578888886136196132f5565b805193908461363a578251633250574960e11b815260048101859052602490fd5b84925001fd5b63ffffffff60e099959897939496991b160361367b577e6ae82e27a11feb3e16adba8bf0b23025bc8719a5d3d64f4d9a4e884e3dbe0c613593565b51633250574960e11b815260048101859052602490fd5b9091508981813d83116136cb575b6136aa8183613121565b8101031261030d57516001600160e01b03198116810361030d57905f613609565b503d6136a0565b82516339e3563760e11b81525f6004820152602490fd5b5f84815260046020526040902080546001600160a01b0319169055815f5260038a52875f209081540190555f613538565b8451633250574960e11b81525f6004820152602490fd5b60ff600b5460a01c1661374057565b60405163d93c066560e01b8152600490fd5b9291803b613762575b5050505050565b604051630a85bd0160e11b8082526001600160a01b039586166004830152928516602482015260448101939093526080606484015290921692602090829081906137b0906084830190613005565b03815f875af15f9181613827575b506137f557826137cc6132f5565b80519190826137ee57604051633250574960e11b815260048101839052602490fd5b6020915001fd5b6001600160e01b0319160361380f57505f8080808061375b565b60249060405190633250574960e11b82526004820152fd5b9091506020813d602011613864575b8161384360209383613121565b8101031261030d57516001600160e01b03198116810361030d57905f6137be565b3d9150613836565b600660ff8216111561387e5750600690565b90565b805f917a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000808210156139da575b506d04ee2d6d415b85acef8100000000808310156139cb575b50662386f26fc10000808310156139bc575b506305f5e100808310156139ad575b506127108083101561399e575b50606482101561398e575b600a80921015613984575b600190816021600186019561391a87613143565b966139286040519889613121565b808852613937601f1991613143565b01366020890137860101905b61394f575b5050505090565b5f19019083906f181899199a1a9b1b9c1cb0b131b232b360811b8282061a83530491821561397f57919082613943565b613948565b9160010191613906565b91906064600291049101916138fb565b6004919392049101915f6138f0565b6008919392049101915f6138e3565b6010919392049101915f6138d4565b6020919392049101915f6138c2565b60409350810491505f6138a9565b803410613a70576016548181018091116104545760165580340390348211610454573403613a135750565b5f80808093335af1613a236132f5565b5015613a2b57565b60405162461bcd60e51b815260206004820152601d60248201527f4272656564696e67456e67696e653a20726566756e64206661696c65640000006044820152606490fd5b60405162461bcd60e51b81526020600482015260136024820152724272656564696e67456e67696e653a2066656560681b6044820152606490fd5b60ff9060038160561c16600382605e1c16115f14613aca5760581c1690565b60501c1690565b60ff9060038160161c16600382601e1c16115f14613af05760181c1690565b60101c1690565b60ff9060038160461c16600382604e1c16115f14613b165760481c1690565b60401c1690565b15613b2457565b60405162461bcd60e51b815260206004820152601560248201527408ecadcdedaca98d2c47440cecadcca40d2dcc8caf605b1b6044820152606490fd5b610ff060ff831692613b7560088510613b1d565b60041b1691808304601014901517156104545761ffff911c1690565b9091610ff060ff841693613ba760088610613b1d565b60041b1692808404601014901517156104545761ffff809116831b921b19161790565b60ff16610168908181029181830414901517156104545761387e9060061c613881565b60405190613bfa82613105565b60078252662363386661336360c81b6020830152565b60405190613c1d82613105565b60078252660233861393538360cc1b6020830152565b613c3e603f91613ad1565b1660018114613c7957600214613c565761387e613c10565b604051613c6281613105565b6007815266119a9a329b333360c91b602082015290565b5061387e613bed565b805115613dae57805191600280840180941161045457600393849004600281901b91906001600160fe1b038116036104545793604051937f4142434445464748494a4b4c4d4e4f505152535455565758595a616263646566601f52603f917f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f603f5260208601928291835184019160208301998a51945f8c525b848110613d7257505050505090600391602095969752510680600114613d5d57600214613d50575b50808452830101604052565b603d905f1901535f613d44565b50603d90815f1982015360011901535f613d44565b836004919c95989c019b838d51818160121c165183538181600c1c16516001840153818160061c1651858401531651858201530196939a613d1c565b50604051613dbb816130cd565b5f815290565b90603a613dd360ff61387e9316613881565b926040519384916e3d913a3930b4ba2fba3cb832911d1160891b6020840152613e06815180926020602f87019101612fe4565b8201691116113b30b63ab2911d60b11b602f820152613e2f825180936020603985019101612fe4565b01607d60f81b603982015203601a810184520182613121565b9060ff811660038360061c16115f14613e6857603f61387e921690613e86565b5090565b9060ff8116603f83161115613e6857600361387e9260061c165b600360ff821611613ee157603f60ff831611613ea65760061b60c0161790565b60405162461bcd60e51b815260206004820152601360248201527247656e6f6d654c69623a2074726169743e363360681b6044820152606490fd5b60405162461bcd60e51b815260206004820152601160248201527047656e6f6d654c69623a20746965723e3360781b6044820152606490fdfe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a2646970667358221220e0e20a8c7c93e733eb677b64bdab5ab0b24409220d350874fad59907572c9ea064736f6c63430008180033