ETH Price: $3,308.70 (-3.24%)
Gas: 13 Gwei

Contract

0x0000000000CF4558c36229ac0026ee16D3aE35Cd
 

Overview

ETH Balance

0.5700865 ETH

Eth Value

$1,886.24 (@ $3,308.70/ETH)

More Info

Private Name Tags

TokenTracker

Transaction Hash
Method
Block
From
To
Value
Mint To197291952024-04-25 1:46:3569 days ago1714009595IN
0x00000000...6D3aE35Cd
0.003777 ETH0.001510099.01747133
Mint To197235412024-04-24 6:46:1170 days ago1713941171IN
0x00000000...6D3aE35Cd
0.010777 ETH0.0017287810
Mint To191567902024-02-04 18:41:11149 days ago1707072071IN
0x00000000...6D3aE35Cd
0.005777 ETH0.0025650715.31052807
Mint To191525172024-02-04 4:15:23150 days ago1707020123IN
0x00000000...6D3aE35Cd
0.000777 ETH0.0020277212.5718311
Mint To191335292024-02-01 12:17:11153 days ago1706789831IN
0x00000000...6D3aE35Cd
0.030777 ETH0.005707630.91456965
Mint To191307952024-02-01 3:03:11153 days ago1706756591IN
0x00000000...6D3aE35Cd
0.001777 ETH0.0038745423.12815007
Mint To191173492024-01-30 5:51:23155 days ago1706593883IN
0x00000000...6D3aE35Cd
0.000777 ETH0.0016779210.40306869
Mint To191168012024-01-30 4:01:23155 days ago1706587283IN
0x00000000...6D3aE35Cd
0.000777 ETH0.0022608912.67379983
Mint To191073702024-01-28 20:19:11156 days ago1706473151IN
0x00000000...6D3aE35Cd
0.004662 ETH0.0019309312.32447574
Mint To190986332024-01-27 14:52:35158 days ago1706367155IN
0x00000000...6D3aE35Cd
0.000777 ETH0.0025620215.88451059
Mint To190747322024-01-24 6:32:23161 days ago1706077943IN
0x00000000...6D3aE35Cd
0.001554 ETH0.00150249.17986278
Mint To190738422024-01-24 3:32:23161 days ago1706067143IN
0x00000000...6D3aE35Cd
0.001777 ETH0.0024339213.18220664
Mint To190584172024-01-21 23:24:59163 days ago1705879499IN
0x00000000...6D3aE35Cd
0.000777 ETH0.0021934512.29574923
Mint To190581672024-01-21 22:33:35163 days ago1705876415IN
0x00000000...6D3aE35Cd
0.000777 ETH0.0019499512.0896616
Mint To190401662024-01-19 9:59:59166 days ago1705658399IN
0x00000000...6D3aE35Cd
0.001777 ETH0.0034914120.83963717
Mint To190230252024-01-17 0:27:23168 days ago1705451243IN
0x00000000...6D3aE35Cd
0.001554 ETH0.0051938831.7375515
Mint To190108182024-01-15 7:32:47170 days ago1705303967IN
0x00000000...6D3aE35Cd
0.000777 ETH0.002861317.74130917
Mint To189968682024-01-13 8:46:11172 days ago1705135571IN
0x00000000...6D3aE35Cd
0.000777 ETH0.0025440615.77314685
Mint To189754152024-01-10 8:40:23175 days ago1704876023IN
0x00000000...6D3aE35Cd
0.000777 ETH0.0037190523.05803318
Mint To189753832024-01-10 8:33:47175 days ago1704875627IN
0x00000000...6D3aE35Cd
0.000777 ETH0.003605822.35590355
Mint To189718582024-01-09 20:43:35175 days ago1704833015IN
0x00000000...6D3aE35Cd
0.000777 ETH0.0023601514.63291822
Mint To189677422024-01-09 6:51:59176 days ago1704783119IN
0x00000000...6D3aE35Cd
0.000777 ETH0.0024818313.91235472
Mint To189674852024-01-09 5:59:59176 days ago1704779999IN
0x00000000...6D3aE35Cd
0.005777 ETH0.0028512514.0980359
Mint To189647562024-01-08 20:46:47176 days ago1704746807IN
0x00000000...6D3aE35Cd
0.030777 ETH0.0034425220.54783512
Mint To189157152024-01-01 23:01:59183 days ago1704150119IN
0x00000000...6D3aE35Cd
0.000777 ETH0.0020258412.56019821
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To Value
198135212024-05-06 20:47:3557 days ago1715028455
0x00000000...6D3aE35Cd
0.00025 ETH
197291952024-04-25 1:46:3569 days ago1714009595
0x00000000...6D3aE35Cd
0.003 ETH
197235412024-04-24 6:46:1170 days ago1713941171
0x00000000...6D3aE35Cd
0.0095 ETH
191567902024-02-04 18:41:11149 days ago1707072071
0x00000000...6D3aE35Cd
0.005 ETH
191525172024-02-04 4:15:23150 days ago1707020123
0x00000000...6D3aE35Cd
0.000555 ETH
191335292024-02-01 12:17:11153 days ago1706789831
0x00000000...6D3aE35Cd
0.03 ETH
191307952024-02-01 3:03:11153 days ago1706756591
0x00000000...6D3aE35Cd
0.001 ETH
191173492024-01-30 5:51:23155 days ago1706593883
0x00000000...6D3aE35Cd
0.000555 ETH
191168012024-01-30 4:01:23155 days ago1706587283
0x00000000...6D3aE35Cd
0.000555 ETH
191073702024-01-28 20:19:11156 days ago1706473151
0x00000000...6D3aE35Cd
0.00333 ETH
190986332024-01-27 14:52:35158 days ago1706367155
0x00000000...6D3aE35Cd
0.000555 ETH
190747322024-01-24 6:32:23161 days ago1706077943
0x00000000...6D3aE35Cd
0.00111 ETH
190738422024-01-24 3:32:23161 days ago1706067143
0x00000000...6D3aE35Cd
0.001 ETH
190584172024-01-21 23:24:59163 days ago1705879499
0x00000000...6D3aE35Cd
0.000555 ETH
190581672024-01-21 22:33:35163 days ago1705876415
0x00000000...6D3aE35Cd
0.000555 ETH
190401662024-01-19 9:59:59166 days ago1705658399
0x00000000...6D3aE35Cd
0.001 ETH
190230252024-01-17 0:27:23168 days ago1705451243
0x00000000...6D3aE35Cd
0.00111 ETH
190108182024-01-15 7:32:47170 days ago1705303967
0x00000000...6D3aE35Cd
0.000555 ETH
189968682024-01-13 8:46:11172 days ago1705135571
0x00000000...6D3aE35Cd
0.000555 ETH
189754152024-01-10 8:40:23175 days ago1704876023
0x00000000...6D3aE35Cd
0.000555 ETH
189753832024-01-10 8:33:47175 days ago1704875627
0x00000000...6D3aE35Cd
0.000555 ETH
189718582024-01-09 20:43:35175 days ago1704833015
0x00000000...6D3aE35Cd
0.000555 ETH
189677422024-01-09 6:51:59176 days ago1704783119
0x00000000...6D3aE35Cd
0.000555 ETH
189674852024-01-09 5:59:59176 days ago1704779999
0x00000000...6D3aE35Cd
0.005 ETH
189647562024-01-08 20:46:47176 days ago1704746807
0x00000000...6D3aE35Cd
0.03 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
SuperMinter

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion, MIT license
File 1 of 21 : SuperMinter.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;

import { Ownable, OwnableRoles } from "solady/auth/OwnableRoles.sol";
import { ISoundEditionV2 } from "@core/interfaces/ISoundEditionV2.sol";
import { ISuperMinter } from "@modules/interfaces/ISuperMinter.sol";
import { IERC165 } from "openzeppelin/utils/introspection/IERC165.sol";
import { SafeTransferLib } from "solady/utils/SafeTransferLib.sol";
import { EIP712 } from "solady/utils/EIP712.sol";
import { MerkleProofLib } from "solady/utils/MerkleProofLib.sol";
import { LibBitmap } from "solady/utils/LibBitmap.sol";
import { SignatureCheckerLib } from "solady/utils/SignatureCheckerLib.sol";
import { LibZip } from "solady/utils/LibZip.sol";
import { LibMap } from "solady/utils/LibMap.sol";
import { DelegateCashLib } from "@modules/utils/DelegateCashLib.sol";
import { LibOps } from "@core/utils/LibOps.sol";
import { LibMulticaller } from "multicaller/LibMulticaller.sol";

/**
 * @title SuperMinter
 * @dev The `SuperMinter` class is a generalized minter.
 */
contract SuperMinter is ISuperMinter, EIP712 {
    using LibBitmap for *;
    using MerkleProofLib for *;
    using LibMap for *;

    // =============================================================
    //                            STRUCTS
    // =============================================================

    /**
     * @dev A struct to hold the mint data in storage.
     */
    struct MintData {
        // The platform address.
        address platform;
        // The price per token.
        uint96 price;
        // The start time of the mint.
        uint32 startTime;
        // The end time of the mint.
        uint32 endTime;
        // The maximum number of tokens an account can mint in this mint.
        uint32 maxMintablePerAccount;
        // The maximum tokens mintable.
        uint32 maxMintable;
        // The total number of tokens minted.
        uint32 minted;
        // The affiliate fee BPS.
        uint16 affiliateFeeBPS;
        // The offset to the next mint data in the linked list.
        uint16 next;
        // The head of the mint data linked list.
        // Only stored in the 0-th mint data per edition.
        uint16 head;
        // The total number of mint data.
        // Only stored in the 0-th mint data per edition.
        uint16 numMintData;
        // The total number of mints for the edition-tier.
        // Only stored in the 0-th mint data per edition-tier.
        uint8 nextScheduleNum;
        // The mode of the mint.
        uint8 mode;
        // The packed boolean flags.
        uint8 flags;
        // The affiliate Merkle root, if any.
        bytes32 affiliateMerkleRoot;
        // The Merkle root hash, required if `mode` is `VERIFY_MERKLE`.
        bytes32 merkleRoot;
        // The signer address, required if `mode` is `VERIFY_SIGNATURE`.
        address signer;
    }

    // =============================================================
    //                           CONSTANTS
    // =============================================================

    /**
     * @dev The GA tier. Which is 0.
     */
    uint8 public constant GA_TIER = 0;

    /**
     * @dev For EIP-712 signature digest calculation.
     */
    bytes32 public constant MINT_TO_TYPEHASH =
        // prettier-ignore
        keccak256(
            "MintTo("
                "address edition,"
                "uint8 tier,"
                "uint8 scheduleNum,"
                "address to,"
                "uint32 signedQuantity,"
                "uint32 signedClaimTicket,"
                "uint96 signedPrice,"
                "uint32 signedDeadline,"
                "address affiliate"
            ")"
        );

    /**
     * @dev For EIP-712 signature digest calculation.
     */
    bytes32 public constant DOMAIN_TYPEHASH = _DOMAIN_TYPEHASH;

    /**
     * @dev The default value for options.
     */
    uint8 public constant DEFAULT = 0;

    /**
     * @dev The Merkle drop mint mode.
     */
    uint8 public constant VERIFY_MERKLE = 1;

    /**
     * @dev The Signature mint mint mode.
     */
    uint8 public constant VERIFY_SIGNATURE = 2;

    /**
     * @dev The denominator of all BPS calculations.
     */
    uint16 public constant BPS_DENOMINATOR = LibOps.BPS_DENOMINATOR;

    /**
     * @dev The maximum affiliate fee BPS.
     */
    uint16 public constant MAX_AFFILIATE_FEE_BPS = 1000;

    /**
     * @dev The maximum platform per-mint fee BPS.
     */
    uint16 public constant MAX_PLATFORM_PER_MINT_FEE_BPS = 1000;

    /**
     * @dev The maximum platform per-mint flat fee.
     */
    uint96 public constant MAX_PLATFORM_PER_MINT_FLAT_FEE = 0.1 ether;

    /**
     * @dev The maximum platform per-transaction flat fee.
     */
    uint96 public constant MAX_PLATFORM_PER_TX_FLAT_FEE = 0.1 ether;

    /**
     * @dev The boolean flag on whether the mint has been created.
     */
    uint8 internal constant _MINT_CREATED_FLAG = 1 << 0;

    /**
     * @dev The boolean flag on whether the mint is paused.
     */
    uint8 internal constant _MINT_PAUSED_FLAG = 1 << 1;

    /**
     * @dev The boolean flag on whether the signer is the platform's signer.
     */
    uint8 internal constant _USE_PLATFORM_SIGNER_FLAG = 1 << 2;

    /**
     * @dev The index for the per-platform default fee config.
     *      We use 256, as the tier is uint8, which ranges from 0 to 255.
     */
    uint16 internal constant _DEFAULT_FEE_CONFIG_INDEX = 256;

    // =============================================================
    //                            STORAGE
    // =============================================================

    /**
     * @dev A mapping of `platform` => `feesAccrued`.
     */
    mapping(address => uint256) public platformFeesAccrued;

    /**
     * @dev A mapping of `platform` => `feeRecipient`.
     */
    mapping(address => address) public platformFeeAddress;

    /**
     * @dev A mapping of `affiliate` => `feesAccrued`.
     */
    mapping(address => uint256) public affiliateFeesAccrued;

    /**
     * @dev A mapping of `platform` => `price`.
     */
    mapping(address => uint96) public gaPrice;

    /**
     * @dev A mapping of `platform` => `platformSigner`.
     */
    mapping(address => address) public platformSigner;

    /**
     * @dev A mapping of `mintId` => `mintData`.
     */
    mapping(uint256 => MintData) internal _mintData;

    /**
     * @dev A mapping of `platformTierId` => `platformFeeConfig`.
     */
    mapping(uint256 => PlatformFeeConfig) internal _platformFeeConfigs;

    /**
     * @dev A mapping of `to` => `mintId` => `numberMinted`.
     */
    mapping(address => LibMap.Uint32Map) internal _numberMinted;

    /**
     * @dev A mapping of `mintId` => `signedClaimedTicket` => `claimed`.
     */
    mapping(uint256 => LibBitmap.Bitmap) internal _claimsBitmaps;

    // =============================================================
    //               PUBLIC / EXTERNAL WRITE FUNCTIONS
    // =============================================================

    /**
     * @inheritdoc ISuperMinter
     */
    function createEditionMint(MintCreation memory c) public returns (uint8 scheduleNum) {
        _requireOnlyEditionOwnerOrAdmin(c.edition);

        _validateAffiliateFeeBPS(c.affiliateFeeBPS);

        uint8 mode = c.mode;

        if (mode == DEFAULT) {
            c.signer = address(0);
            c.merkleRoot = bytes32(0);
        } else if (mode == VERIFY_MERKLE) {
            _validateMerkleRoot(c.merkleRoot);
            c.signer = address(0);
        } else if (mode == VERIFY_SIGNATURE) {
            _validateSigner(c.signer);
            c.merkleRoot = bytes32(0);
            c.maxMintablePerAccount = type(uint32).max;
        } else {
            revert InvalidMode();
        }

        // If GA, overwrite any immutable variables as required.
        if (c.tier == GA_TIER) {
            c.endTime = type(uint32).max;
            c.maxMintablePerAccount = type(uint32).max;
            // We allow the `price` to be the minimum price if the `mode` is `VERIFY_SIGNATURE`.
            // Otherwise, the actual default price is the live value of `gaPrice[platform]`,
            // and we'll simply set it to zero to avoid a SLOAD.
            if (mode != VERIFY_SIGNATURE) c.price = 0;
            // Set `maxMintable` to the maximum only if `mode` is `DEFAULT`.
            if (mode == DEFAULT) c.maxMintable = type(uint32).max;
        }

        _validateTimeRange(c.startTime, c.endTime);
        _validateMaxMintablePerAccount(c.maxMintablePerAccount);
        _validateMaxMintable(c.maxMintable);

        unchecked {
            MintData storage tierHead = _mintData[LibOps.packId(c.edition, c.tier, 0)];
            MintData storage editionHead = _mintData[LibOps.packId(c.edition, 0)];

            scheduleNum = tierHead.nextScheduleNum;
            uint256 n = scheduleNum;
            if (++n >= 1 << 8) LibOps.revertOverflow();
            tierHead.nextScheduleNum = uint8(n);

            n = editionHead.numMintData;
            if (++n >= 1 << 16) LibOps.revertOverflow();
            editionHead.numMintData = uint16(n);

            uint256 mintId = LibOps.packId(c.edition, c.tier, scheduleNum);
            bool usePlatformSigner = c.signer == address(1);

            MintData storage d = _mintData[mintId];
            d.platform = c.platform;
            d.price = c.price;
            d.startTime = c.startTime;
            d.endTime = c.endTime;
            d.maxMintablePerAccount = c.maxMintablePerAccount;
            d.maxMintable = c.maxMintable;
            d.affiliateFeeBPS = c.affiliateFeeBPS;
            d.mode = c.mode;
            d.flags = _MINT_CREATED_FLAG | LibOps.toFlag(usePlatformSigner, _USE_PLATFORM_SIGNER_FLAG);
            d.next = editionHead.head;
            editionHead.head = uint16((uint256(c.tier) << 8) | uint256(scheduleNum));

            // Skip writing zeros, to avoid cold SSTOREs.
            if (c.affiliateMerkleRoot != bytes32(0)) d.affiliateMerkleRoot = c.affiliateMerkleRoot;
            if (c.merkleRoot != bytes32(0)) d.merkleRoot = c.merkleRoot;
            if (c.signer != address(0)) {
                if (!usePlatformSigner) d.signer = c.signer; // Only write if it is not the platform signer.
            }

            emit MintCreated(c.edition, c.tier, scheduleNum, c);
        }
    }

    /**
     * @inheritdoc ISuperMinter
     */
    function mintTo(MintTo calldata p) public payable {
        MintData storage d = _getMintData(LibOps.packId(p.edition, p.tier, p.scheduleNum));

        /* ------------------- CHECKS AND UPDATES ------------------- */

        // Check if the mint is open.
        if (LibOps.or(block.timestamp < d.startTime, block.timestamp > d.endTime))
            revert MintNotOpen(block.timestamp, d.startTime, d.endTime);
        if (_isPaused(d)) revert MintPaused(); // Check if the mint is not paused.

        // Perform the sub workflows depending on the mint mode.
        uint8 mode = d.mode;
        if (mode == VERIFY_MERKLE) _verifyMerkle(d, p);
        else if (mode == VERIFY_SIGNATURE) _verifyAndClaimSignature(d, p);

        _incrementMinted(mode, d, p);

        /* ----------- AFFILIATE AND PLATFORM FEES LOGIC ------------ */

        TotalPriceAndFees memory f = _totalPriceAndFees(p.tier, d, p.quantity, p.signedPrice);

        uint256 remaining; // The fee sent to the Sound Edition (i.e. artist fee).
        bool affiliated;

        unchecked {
            if (msg.value != f.total) revert WrongPayment(msg.value, f.total); // Require exact payment.

            remaining = f.total - f.platformFee; // `platformFee <= total`;
            platformFeesAccrued[d.platform] += f.platformFee; // Accrue the platform fee.

            if (affiliated = _isAffiliatedWithProof(d, p.affiliate, p.affiliateProof)) {
                remaining -= f.affiliateFee; // `affiliateFee <= remaining`.
                affiliateFeesAccrued[p.affiliate] += f.affiliateFee; // Accrue the affiliate fee.
            } else {
                // Proof may be invalid, revert to prevent unintended skipping of affiliate fee.
                if (p.affiliate != address(0)) revert InvalidAffiliate();
                f.affiliateFee = 0; // Set the affiliate fee to zero if not affiliated.
            }
        }

        /* ------------------------- MINT --------------------------- */

        ISoundEditionV2 edition = ISoundEditionV2(p.edition);
        MintedLogData memory l;
        l.quantity = p.quantity;
        l.fromTokenId = edition.mint{ value: remaining }(p.tier, p.to, p.quantity);
        l.allowlisted = p.allowlisted;
        l.allowlistedQuantity = p.allowlistedQuantity;
        l.signedClaimTicket = p.signedClaimTicket;
        l.affiliate = p.affiliate;
        l.affiliated = affiliated;
        l.requiredEtherValue = f.total;
        l.unitPrice = f.unitPrice;
        l.platformFee = f.platformFee;
        l.platformFlatFee = f.platformFlatFee;
        l.affiliateFee = f.affiliateFee;

        emit Minted(p.edition, p.tier, p.scheduleNum, p.to, l, p.attributionId);
    }

    // Per edition mint parameter setters:
    // -----------------------------------
    // These functions can only be called by the owner or admin of the edition.

    /**
     * @inheritdoc ISuperMinter
     */
    function setPrice(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        uint96 price
    ) public onlyEditionOwnerOrAdmin(edition) {
        uint256 mintId = LibOps.packId(edition, tier, scheduleNum);
        MintData storage d = _getMintData(mintId);
        // If the tier is GA and the `mode` is `VERIFY_SIGNATURE`, we'll use `gaPrice[platform]`.
        if (tier == GA_TIER && d.mode != VERIFY_SIGNATURE) revert NotConfigurable();
        d.price = price;
        emit PriceSet(edition, tier, scheduleNum, price);
    }

    /**
     * @inheritdoc ISuperMinter
     */
    function setPaused(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        bool paused
    ) public onlyEditionOwnerOrAdmin(edition) {
        uint256 mintId = LibOps.packId(edition, tier, scheduleNum);
        MintData storage d = _getMintData(mintId);
        d.flags = LibOps.setFlagTo(d.flags, _MINT_PAUSED_FLAG, paused);
        emit PausedSet(edition, tier, scheduleNum, paused);
    }

    /**
     * @inheritdoc ISuperMinter
     */
    function setTimeRange(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        uint32 startTime,
        uint32 endTime
    ) public onlyEditionOwnerOrAdmin(edition) {
        uint256 mintId = LibOps.packId(edition, tier, scheduleNum);
        MintData storage d = _getMintData(mintId);
        // For GA tier, `endTime` will always be `type(uint32).max`.
        if (tier == GA_TIER && endTime != type(uint32).max) revert NotConfigurable();
        _validateTimeRange(startTime, endTime);
        d.startTime = startTime;
        d.endTime = endTime;
        emit TimeRangeSet(edition, tier, scheduleNum, startTime, endTime);
    }

    /**
     * @inheritdoc ISuperMinter
     */
    function setStartTime(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        uint32 startTime
    ) public {
        uint256 mintId = LibOps.packId(edition, tier, scheduleNum);
        setTimeRange(edition, tier, scheduleNum, startTime, _mintData[mintId].endTime);
    }

    /**
     * @inheritdoc ISuperMinter
     */
    function setAffiliateFee(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        uint16 bps
    ) public onlyEditionOwnerOrAdmin(edition) {
        uint256 mintId = LibOps.packId(edition, tier, scheduleNum);
        MintData storage d = _getMintData(mintId);
        _validateAffiliateFeeBPS(bps);
        d.affiliateFeeBPS = bps;
        emit AffiliateFeeSet(edition, tier, scheduleNum, bps);
    }

    /**
     * @inheritdoc ISuperMinter
     */
    function setAffiliateMerkleRoot(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        bytes32 root
    ) public onlyEditionOwnerOrAdmin(edition) {
        uint256 mintId = LibOps.packId(edition, tier, scheduleNum);
        MintData storage d = _getMintData(mintId);
        d.affiliateMerkleRoot = root;
        emit AffiliateMerkleRootSet(edition, tier, scheduleNum, root);
    }

    /**
     * @inheritdoc ISuperMinter
     */
    function setMaxMintablePerAccount(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        uint32 value
    ) public onlyEditionOwnerOrAdmin(edition) {
        uint256 mintId = LibOps.packId(edition, tier, scheduleNum);
        MintData storage d = _getMintData(mintId);
        // GA tier will have `type(uint32).max`.
        if (tier == GA_TIER) revert NotConfigurable();
        // Signature mints will have `type(uint32).max`.
        if (d.mode == VERIFY_SIGNATURE) revert NotConfigurable();
        _validateMaxMintablePerAccount(value);
        d.maxMintablePerAccount = value;
        emit MaxMintablePerAccountSet(edition, tier, scheduleNum, value);
    }

    /**
     * @inheritdoc ISuperMinter
     */
    function setMaxMintable(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        uint32 value
    ) public onlyEditionOwnerOrAdmin(edition) {
        uint256 mintId = LibOps.packId(edition, tier, scheduleNum);
        MintData storage d = _getMintData(mintId);
        // We allow edits for GA tier, if the `mode` is not `DEFAULT`.
        if (tier == GA_TIER && d.mode == DEFAULT) revert NotConfigurable();
        _validateMaxMintable(value);
        d.maxMintable = value;
        emit MaxMintableSet(edition, tier, scheduleNum, value);
    }

    /**
     * @inheritdoc ISuperMinter
     */
    function setMerkleRoot(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        bytes32 merkleRoot
    ) public onlyEditionOwnerOrAdmin(edition) {
        uint256 mintId = LibOps.packId(edition, tier, scheduleNum);
        MintData storage d = _getMintData(mintId);
        if (d.mode != VERIFY_MERKLE) revert NotConfigurable();
        _validateMerkleRoot(merkleRoot);
        d.merkleRoot = merkleRoot;
        emit MerkleRootSet(edition, tier, scheduleNum, merkleRoot);
    }

    /**
     * @inheritdoc ISuperMinter
     */
    function setSigner(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        address signer
    ) public onlyEditionOwnerOrAdmin(edition) {
        uint256 mintId = LibOps.packId(edition, tier, scheduleNum);
        MintData storage d = _getMintData(mintId);
        if (d.mode != VERIFY_SIGNATURE) revert NotConfigurable();
        _validateSigner(signer);
        bool usePlatformSigner = signer == address(1);
        d.flags = LibOps.setFlagTo(d.flags, _USE_PLATFORM_SIGNER_FLAG, usePlatformSigner);
        if (!usePlatformSigner) d.signer = signer;
        emit SignerSet(edition, tier, scheduleNum, signer);
    }

    // Withdrawal functions:
    // ---------------------
    // These functions can be called by anyone.

    /**
     * @inheritdoc ISuperMinter
     */
    function withdrawForAffiliate(address affiliate) public {
        uint256 accrued = affiliateFeesAccrued[affiliate];
        if (accrued != 0) {
            affiliateFeesAccrued[affiliate] = 0;
            SafeTransferLib.forceSafeTransferETH(affiliate, accrued);
            emit AffiliateFeesWithdrawn(affiliate, accrued);
        }
    }

    /**
     * @inheritdoc ISuperMinter
     */
    function withdrawForPlatform(address platform) public {
        address recipient = platformFeeAddress[platform];
        _validatePlatformFeeAddress(recipient);
        uint256 accrued = platformFeesAccrued[platform];
        if (accrued != 0) {
            platformFeesAccrued[platform] = 0;
            SafeTransferLib.forceSafeTransferETH(recipient, accrued);
            emit PlatformFeesWithdrawn(platform, accrued);
        }
    }

    // Platform fee functions:
    // -----------------------
    // These functions enable any caller to set their own platform fees.

    /**
     * @inheritdoc ISuperMinter
     */
    function setPlatformFeeAddress(address recipient) public {
        address sender = LibMulticaller.sender();
        _validatePlatformFeeAddress(recipient);
        platformFeeAddress[sender] = recipient;
        emit PlatformFeeAddressSet(sender, recipient);
    }

    /**
     * @inheritdoc ISuperMinter
     */
    function setPlatformFeeConfig(uint8 tier, PlatformFeeConfig memory c) public {
        address sender = LibMulticaller.sender();
        _validatePlatformFeeConfig(c);
        _platformFeeConfigs[LibOps.packId(sender, tier)] = c;
        emit PlatformFeeConfigSet(sender, tier, c);
    }

    /**
     * @inheritdoc ISuperMinter
     */
    function setDefaultPlatformFeeConfig(PlatformFeeConfig memory c) public {
        address sender = LibMulticaller.sender();
        _validatePlatformFeeConfig(c);
        _platformFeeConfigs[LibOps.packId(sender, _DEFAULT_FEE_CONFIG_INDEX)] = c;
        emit DefaultPlatformFeeConfigSet(sender, c);
    }

    /**
     * @inheritdoc ISuperMinter
     */
    function setGAPrice(uint96 price) public {
        address sender = LibMulticaller.sender();
        gaPrice[sender] = price;
        emit GAPriceSet(sender, price);
    }

    /**
     * @inheritdoc ISuperMinter
     */
    function setPlatformSigner(address signer) public {
        address sender = LibMulticaller.sender();
        platformSigner[sender] = signer;
        emit PlatformSignerSet(sender, signer);
    }

    // Misc functions:
    // ---------------

    /**
     * @dev For calldata compression.
     */
    fallback() external payable {
        LibZip.cdFallback();
    }

    /**
     * @dev For calldata compression.
     */
    receive() external payable {
        LibZip.cdFallback();
    }

    // =============================================================
    //               PUBLIC / EXTERNAL VIEW FUNCTIONS
    // =============================================================

    /**
     * @inheritdoc ISuperMinter
     */
    function computeMintToDigest(MintTo calldata p) public view returns (bytes32) {
        // prettier-ignore
        return
            _hashTypedData(keccak256(abi.encode(
                MINT_TO_TYPEHASH,
                p.edition,
                p.tier, 
                p.scheduleNum,
                p.to,
                p.signedQuantity,
                p.signedClaimTicket,
                p.signedPrice,
                p.signedDeadline,
                p.affiliate
            )));
    }

    /**
     * @inheritdoc ISuperMinter
     */
    function totalPriceAndFees(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        uint32 quantity
    ) public view returns (TotalPriceAndFees memory) {
        return totalPriceAndFeesWithSignedPrice(edition, tier, scheduleNum, quantity, 0);
    }

    /**
     * @inheritdoc ISuperMinter
     */
    function totalPriceAndFeesWithSignedPrice(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        uint32 quantity,
        uint96 signedPrice
    ) public view returns (TotalPriceAndFees memory) {
        uint256 mintId = LibOps.packId(edition, tier, scheduleNum);
        return _totalPriceAndFees(tier, _getMintData(mintId), quantity, signedPrice);
    }

    /**
     * @inheritdoc ISuperMinter
     */
    function nextScheduleNum(address edition, uint8 tier) public view returns (uint8) {
        return _mintData[LibOps.packId(edition, tier, 0)].nextScheduleNum;
    }

    /**
     * @inheritdoc ISuperMinter
     */
    function numberMinted(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        address collector
    ) external view returns (uint32) {
        uint256 mintId = LibOps.packId(edition, tier, scheduleNum);
        return _numberMinted[collector].get(mintId);
    }

    /**
     * @inheritdoc ISuperMinter
     */
    function isAffiliatedWithProof(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        address affiliate,
        bytes32[] calldata affiliateProof
    ) public view virtual returns (bool) {
        uint256 mintId = LibOps.packId(edition, tier, scheduleNum);
        return _isAffiliatedWithProof(_getMintData(mintId), affiliate, affiliateProof);
    }

    /**
     * @inheritdoc ISuperMinter
     */
    function isAffiliated(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        address affiliate
    ) public view virtual returns (bool) {
        return isAffiliatedWithProof(edition, tier, scheduleNum, affiliate, MerkleProofLib.emptyProof());
    }

    /**
     * @inheritdoc ISuperMinter
     */
    function checkClaimTickets(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        uint32[] calldata claimTickets
    ) public view returns (bool[] memory claimed) {
        uint256 mintId = LibOps.packId(edition, tier, scheduleNum);
        LibBitmap.Bitmap storage bitmap = _claimsBitmaps[mintId];
        claimed = new bool[](claimTickets.length);
        unchecked {
            for (uint256 i; i != claimTickets.length; i++) {
                claimed[i] = bitmap.get(claimTickets[i]);
            }
        }
    }

    /**
     * @inheritdoc ISuperMinter
     */
    function platformFeeConfig(address platform, uint8 tier) public view returns (PlatformFeeConfig memory) {
        return _platformFeeConfigs[LibOps.packId(platform, tier)];
    }

    /**
     * @inheritdoc ISuperMinter
     */
    function defaultPlatformFeeConfig(address platform) public view returns (PlatformFeeConfig memory) {
        return _platformFeeConfigs[LibOps.packId(platform, _DEFAULT_FEE_CONFIG_INDEX)];
    }

    /**
     * @inheritdoc ISuperMinter
     */
    function effectivePlatformFeeConfig(address platform, uint8 tier) public view returns (PlatformFeeConfig memory) {
        PlatformFeeConfig memory c = _platformFeeConfigs[LibOps.packId(platform, tier)];
        if (!c.active) c = _platformFeeConfigs[LibOps.packId(platform, _DEFAULT_FEE_CONFIG_INDEX)];
        if (!c.active) delete c; // Set all values to zero.
        return c;
    }

    /**
     * @inheritdoc ISuperMinter
     */
    function mintInfoList(address edition) public view returns (MintInfo[] memory a) {
        unchecked {
            MintData storage editionHead = _mintData[LibOps.packId(edition, 0)];
            uint256 n = editionHead.numMintData; // Linked-list length.
            uint16 p = editionHead.head; // Current linked-list pointer.
            a = new MintInfo[](n);
            // Traverse the linked-list and fill the array in reverse.
            // Front: earliest added mint schedule. Back: latest added mint schedule.
            while (n != 0) {
                MintData storage d = _mintData[LibOps.packId(edition, p)];
                a[--n] = mintInfo(edition, uint8(p >> 8), uint8(p));
                p = d.next;
            }
        }
    }

    /**
     * @inheritdoc ISuperMinter
     */
    function mintInfo(
        address edition,
        uint8 tier,
        uint8 scheduleNum
    ) public view returns (MintInfo memory info) {
        uint256 mintId = LibOps.packId(edition, tier, scheduleNum);
        MintData storage d = _getMintData(mintId);
        info.edition = edition;
        info.tier = tier;
        info.scheduleNum = scheduleNum;
        info.platform = d.platform;
        info.price = tier == GA_TIER && d.mode != VERIFY_SIGNATURE ? gaPrice[d.platform] : d.price;
        info.startTime = d.startTime;
        info.endTime = d.endTime;
        info.maxMintablePerAccount = d.maxMintablePerAccount;
        info.maxMintable = d.maxMintable;
        info.minted = d.minted;
        info.affiliateFeeBPS = d.affiliateFeeBPS;
        info.mode = d.mode;
        info.paused = _isPaused(d);
        info.affiliateMerkleRoot = d.affiliateMerkleRoot;
        info.merkleRoot = d.merkleRoot;
        info.signer = _effectiveSigner(d);
        info.usePlatformSigner = _usePlatformSigner(d);
    }

    /**
     * @inheritdoc ISuperMinter
     */
    function name() external pure returns (string memory name_) {
        (name_, ) = _domainNameAndVersion();
    }

    /**
     * @inheritdoc ISuperMinter
     */
    function version() external pure returns (string memory version_) {
        (, version_) = _domainNameAndVersion();
    }

    /**
     * @inheritdoc IERC165
     */
    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
        return LibOps.or(interfaceId == type(ISuperMinter).interfaceId, interfaceId == this.supportsInterface.selector);
    }

    // =============================================================
    //                  INTERNAL / PRIVATE HELPERS
    // =============================================================

    // Validations:
    // ------------

    /**
     * @dev Guards a function to make it callable only by the edition's owner or admin.
     * @param edition The edition address.
     */
    modifier onlyEditionOwnerOrAdmin(address edition) {
        _requireOnlyEditionOwnerOrAdmin(edition);
        _;
    }

    /**
     * @dev Requires that the caller is the owner or admin of `edition`.
     * @param edition The edition address.
     */
    function _requireOnlyEditionOwnerOrAdmin(address edition) internal view {
        address sender = LibMulticaller.sender();
        if (sender != OwnableRoles(edition).owner())
            if (!OwnableRoles(edition).hasAnyRole(sender, LibOps.ADMIN_ROLE)) LibOps.revertUnauthorized();
    }

    /**
     * @dev Validates that `startTime <= endTime`.
     * @param startTime  The start time of the mint.
     * @param endTime    The end time of the mint.
     */
    function _validateTimeRange(uint32 startTime, uint32 endTime) internal pure {
        if (startTime > endTime) revert InvalidTimeRange();
    }

    /**
     * @dev Validates that the max mintable amount per account is not zero.
     * @param value The max mintable amount.
     */
    function _validateMaxMintablePerAccount(uint32 value) internal pure {
        if (value == 0) revert MaxMintablePerAccountIsZero();
    }

    /**
     * @dev Validates that the max mintable per schedule.
     * @param value The max mintable amount.
     */
    function _validateMaxMintable(uint32 value) internal pure {
        if (value == 0) revert MaxMintableIsZero();
    }

    /**
     * @dev Validates that the Merkle root is not empty.
     * @param merkleRoot The Merkle root.
     */
    function _validateMerkleRoot(bytes32 merkleRoot) internal pure {
        if (merkleRoot == bytes32(0)) revert MerkleRootIsEmpty();
    }

    /**
     * @dev Validates that the signer is not the zero address.
     * @param signer The signer.
     */
    function _validateSigner(address signer) internal pure {
        if (signer == address(0)) revert SignerIsZeroAddress();
    }

    /**
     * @dev Validates that the affiliate fee BPS does not exceed the max threshold.
     * @param bps The affiliate fee BPS.
     */
    function _validateAffiliateFeeBPS(uint16 bps) internal pure {
        if (bps > MAX_AFFILIATE_FEE_BPS) revert InvalidAffiliateFeeBPS();
    }

    /**
     * @dev Validates the platform fee configuration.
     * @param c The platform fee configuration.
     */
    function _validatePlatformFeeConfig(PlatformFeeConfig memory c) internal pure {
        if (
            LibOps.or(
                c.perTxFlat > MAX_PLATFORM_PER_TX_FLAT_FEE,
                c.perMintFlat > MAX_PLATFORM_PER_MINT_FLAT_FEE,
                c.perMintBPS > MAX_PLATFORM_PER_MINT_FEE_BPS
            )
        ) revert InvalidPlatformFeeConfig();
    }

    /**
     * @dev Validates that the platform fee address is not the zero address.
     * @param a The platform fee address.
     */
    function _validatePlatformFeeAddress(address a) internal pure {
        if (a == address(0)) revert PlatformFeeAddressIsZero();
    }

    // EIP-712:
    // --------

    /**
     * @dev Override for EIP-712.
     * @return name_    The EIP-712 name.
     * @return version_ The EIP-712 version.
     */
    function _domainNameAndVersion()
        internal
        pure
        virtual
        override
        returns (string memory name_, string memory version_)
    {
        name_ = "SuperMinter";
        version_ = "1";
    }

    // Minting:
    // --------

    /**
     * @dev Increments the number minted in the mint and the number minted by the collector.
     * @param mode The mint mode.
     * @param d    The mint data storage pointer.
     * @param p    The mint-to parameters.
     */
    function _incrementMinted(
        uint8 mode,
        MintData storage d,
        MintTo calldata p
    ) internal {
        unchecked {
            // Increment the number minted in the mint.
            uint256 n = uint256(d.minted) + uint256(p.quantity); // The next `minted`.
            if (n > d.maxMintable) revert ExceedsMintSupply();
            d.minted = uint32(n);

            // Increment the number minted by the collector.
            uint256 mintId = LibOps.packId(p.edition, p.tier, p.scheduleNum);
            if (mode == VERIFY_MERKLE) {
                LibMap.Uint32Map storage m = _numberMinted[p.allowlisted];
                n = uint256(m.get(mintId)) + uint256(p.quantity);
                // Check that `n` does not exceed either the default limit,
                // or the limit in the Merkle leaf if a non-zero value is provided.
                if (LibOps.or(n > d.maxMintablePerAccount, n > p.allowlistedQuantity)) revert ExceedsMaxPerAccount();
                m.set(mintId, uint32(n));
            } else {
                LibMap.Uint32Map storage m = _numberMinted[p.to];
                n = uint256(m.get(mintId)) + uint256(p.quantity);
                if (n > d.maxMintablePerAccount) revert ExceedsMaxPerAccount();
                m.set(mintId, uint32(n));
            }
        }
    }

    /**
     * @dev Verify the signature, and mark the signed claim ticket as claimed.
     * @param d The mint data storage pointer.
     * @param p The mint-to parameters.
     */
    function _verifyAndClaimSignature(MintData storage d, MintTo calldata p) internal {
        if (p.quantity > p.signedQuantity) revert ExceedsSignedQuantity();
        address signer = _effectiveSigner(d);
        if (!SignatureCheckerLib.isValidSignatureNowCalldata(signer, computeMintToDigest(p), p.signature))
            revert InvalidSignature();
        if (block.timestamp > p.signedDeadline) revert SignatureExpired();
        uint256 mintId = LibOps.packId(p.edition, p.tier, p.scheduleNum);
        if (!_claimsBitmaps[mintId].toggle(p.signedClaimTicket)) revert SignatureAlreadyUsed();
    }

    /**
     * @dev Verify the Merkle proof.
     * @param d The mint data storage pointer.
     * @param p The mint-to parameters.
     */
    function _verifyMerkle(MintData storage d, MintTo calldata p) internal view {
        uint32 allowlistedQuantity = p.allowlistedQuantity;
        address allowlisted = p.allowlisted;
        // Revert if `allowlisted` is the zero address to prevent libraries
        // that fill up partial Merkle trees with empty leafs from screwing things up.
        if (allowlisted == address(0)) revert InvalidMerkleProof();
        // If `allowlistedQuantity` is the max limit, we've got to check two cases for backwards compatibility.
        if (allowlistedQuantity == type(uint32).max) {
            // Revert if neither `keccak256(abi.encodePacked(allowlisted))` nor
            // `keccak256(abi.encodePacked(allowlisted, uint32(0)))` are in the Merkle tree.
            if (
                !p.allowlistProof.verifyCalldata(d.merkleRoot, _leaf(allowlisted)) &&
                !p.allowlistProof.verifyCalldata(d.merkleRoot, _leaf(allowlisted, type(uint32).max))
            ) revert InvalidMerkleProof();
        } else {
            // Revert if `keccak256(abi.encodePacked(allowlisted, uint32(allowlistedQuantity)))`
            // is not in the Merkle tree.
            if (!p.allowlistProof.verifyCalldata(d.merkleRoot, _leaf(allowlisted, allowlistedQuantity)))
                revert InvalidMerkleProof();
        }
        // To mint, either the sender or `to` must be equal to `allowlisted`,
        address sender = LibMulticaller.sender();
        if (!LibOps.or(sender == allowlisted, p.to == allowlisted)) {
            // or the sender must be a delegate of `allowlisted`.
            if (!DelegateCashLib.checkDelegateForAll(sender, allowlisted)) revert CallerNotDelegated();
        }
    }

    /**
     * @dev Returns the total price and fees for the mint.
     * @param tier        The tier.
     * @param d           The mint data storage pointer.
     * @param quantity    How many tokens to mint.
     * @param signedPrice The signed price. Only for `VERIFY_SIGNATURE`.
     * @return f A struct containing the total price and fees.
     */
    function _totalPriceAndFees(
        uint8 tier,
        MintData storage d,
        uint32 quantity,
        uint96 signedPrice
    ) internal view returns (TotalPriceAndFees memory f) {
        unchecked {
            PlatformFeeConfig memory c = effectivePlatformFeeConfig(d.platform, tier);
            // The actual unit price per token.
            uint256 unitPrice;
            // For signature mints, even if it is GA tier, we will use the signed price.
            if (d.mode == VERIFY_SIGNATURE) {
                if (signedPrice < d.price) revert SignedPriceTooLow(); // Enforce the price floor.
                unitPrice = signedPrice;
            } else if (tier == GA_TIER) {
                unitPrice = gaPrice[d.platform]; // Else if GA tier, use `gaPrice[platform]`.
            } else {
                unitPrice = d.price; // Else, use the `price`.
            }
            f.unitPrice = unitPrice;
            // The artist will receive the remaining after all BPS fees are deducted from sub total.
            // The minter will have to pay the sub total plus any flat fees.
            f.subTotal = unitPrice * uint256(quantity);
            // Sum the total flat fees for mints, and the transaction flat fee.
            f.platformTxFlatFee = c.perTxFlat;
            f.platformMintFlatFee = c.perMintFlat * uint256(quantity);
            f.platformFlatFee = f.platformMintFlatFee + f.platformTxFlatFee;
            // BPS fees are to be deducted from the sub total.
            f.platformMintBPSFee = LibOps.rawMulDiv(f.subTotal, c.perMintBPS, BPS_DENOMINATOR);
            // The platform fee includes BPS fees deducted from sub total,
            // and flat fees added to sub total.
            f.platformFee = f.platformMintBPSFee + f.platformFlatFee;
            // Affiliate fee is to be deducted from the sub total.
            // Will be conditionally set to zero during mint if not affiliated.
            f.affiliateFee = LibOps.rawMulDiv(f.subTotal, d.affiliateFeeBPS, BPS_DENOMINATOR);
            // The total is the final value which the minter has to pay. It includes all fees.
            f.total = f.subTotal + f.platformFlatFee;
        }
    }

    /**
     * @dev Returns whether the affiliate is affiliated for the mint
     * @param d              The mint data storage pointer.
     * @param affiliate      The affiliate address.
     * @param affiliateProof The Merkle proof for the affiliate.
     * @return The result.
     */
    function _isAffiliatedWithProof(
        MintData storage d,
        address affiliate,
        bytes32[] calldata affiliateProof
    ) internal view virtual returns (bool) {
        bytes32 root = d.affiliateMerkleRoot;
        // If the root is empty, then use the default logic.
        if (root == bytes32(0)) return affiliate != address(0);
        // Otherwise, check if the affiliate is in the Merkle tree.
        // The check that that affiliate is not a zero address is to prevent libraries
        // that fill up partial Merkle trees with empty leafs from screwing things up.
        return LibOps.and(affiliate != address(0), affiliateProof.verifyCalldata(root, _leaf(affiliate)));
    }

    // Utilities:
    // ----------

    /**
     * @dev Equivalent to `keccak256(abi.encodePacked(allowlisted))`.
     * @param allowlisted The allowlisted address.
     * @return result The leaf in the Merkle tree.
     */
    function _leaf(address allowlisted) internal pure returns (bytes32 result) {
        assembly {
            mstore(0x00, allowlisted)
            result := keccak256(0x0c, 0x14)
        }
    }

    /**
     * @dev Equivalent to `keccak256(abi.encodePacked(allowlisted, allowlistedQuantity))`.
     * @param allowlisted         The allowlisted address.
     * @param allowlistedQuantity Number of mints allowlisted.
     * @return result The leaf in the Merkle tree.
     */
    function _leaf(address allowlisted, uint32 allowlistedQuantity) internal pure returns (bytes32 result) {
        assembly {
            mstore(0x04, allowlistedQuantity)
            mstore(0x00, allowlisted)
            result := keccak256(0x0c, 0x18)
        }
    }

    /**
     * @dev Retrieves the mint data from storage, reverting if the mint does not exist.
     * @param mintId The mint ID.
     * @return d The storage pointer to the mint data.
     */
    function _getMintData(uint256 mintId) internal view returns (MintData storage d) {
        d = _mintData[mintId];
        if (d.flags & _MINT_CREATED_FLAG == 0) revert MintDoesNotExist();
    }

    /**
     * @dev Returns whether the mint is paused.
     * @param d The storage pointer to the mint data.
     * @return Whether the mint is paused.
     */
    function _isPaused(MintData storage d) internal view returns (bool) {
        return d.flags & _MINT_PAUSED_FLAG != 0;
    }

    /**
     * @dev Returns the effective signer.
     * @param d The storage pointer to the mint data.
     * @return The effective signer.
     */
    function _effectiveSigner(MintData storage d) internal view returns (address) {
        return _usePlatformSigner(d) ? platformSigner[d.platform] : d.signer;
    }

    /**
     * @dev Returns whether the platform signer is to be used instead.
     * @param d The storage pointer to the mint data.
     * @return Whether the platform signer is to be used instead.
     */
    function _usePlatformSigner(MintData storage d) internal view returns (bool) {
        return d.flags & _USE_PLATFORM_SIGNER_FLAG != 0;
    }
}

File 2 of 21 : OwnableRoles.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import {Ownable} from "./Ownable.sol";

/// @notice Simple single owner and multiroles authorization mixin.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol)
/// @dev While the ownable portion follows [EIP-173](https://eips.ethereum.org/EIPS/eip-173)
/// for compatibility, the nomenclature for the 2-step ownership handover and roles
/// may be unique to this codebase.
abstract contract OwnableRoles is Ownable {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                           EVENTS                           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The `user`'s roles is updated to `roles`.
    /// Each bit of `roles` represents whether the role is set.
    event RolesUpdated(address indexed user, uint256 indexed roles);

    /// @dev `keccak256(bytes("RolesUpdated(address,uint256)"))`.
    uint256 private constant _ROLES_UPDATED_EVENT_SIGNATURE =
        0x715ad5ce61fc9595c7b415289d59cf203f23a94fa06f04af7e489a0a76e1fe26;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                          STORAGE                           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The role slot of `user` is given by:
    /// ```
    ///     mstore(0x00, or(shl(96, user), _ROLE_SLOT_SEED))
    ///     let roleSlot := keccak256(0x00, 0x20)
    /// ```
    /// This automatically ignores the upper bits of the `user` in case
    /// they are not clean, as well as keep the `keccak256` under 32-bytes.
    ///
    /// Note: This is equal to `_OWNER_SLOT_NOT` in for gas efficiency.
    uint256 private constant _ROLE_SLOT_SEED = 0x8b78c6d8;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                     INTERNAL FUNCTIONS                     */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Overwrite the roles directly without authorization guard.
    function _setRoles(address user, uint256 roles) internal virtual {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x0c, _ROLE_SLOT_SEED)
            mstore(0x00, user)
            // Store the new value.
            sstore(keccak256(0x0c, 0x20), roles)
            // Emit the {RolesUpdated} event.
            log3(0, 0, _ROLES_UPDATED_EVENT_SIGNATURE, shr(96, mload(0x0c)), roles)
        }
    }

    /// @dev Updates the roles directly without authorization guard.
    /// If `on` is true, each set bit of `roles` will be turned on,
    /// otherwise, each set bit of `roles` will be turned off.
    function _updateRoles(address user, uint256 roles, bool on) internal virtual {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x0c, _ROLE_SLOT_SEED)
            mstore(0x00, user)
            let roleSlot := keccak256(0x0c, 0x20)
            // Load the current value.
            let current := sload(roleSlot)
            // Compute the updated roles if `on` is true.
            let updated := or(current, roles)
            // Compute the updated roles if `on` is false.
            // Use `and` to compute the intersection of `current` and `roles`,
            // `xor` it with `current` to flip the bits in the intersection.
            if iszero(on) { updated := xor(current, and(current, roles)) }
            // Then, store the new value.
            sstore(roleSlot, updated)
            // Emit the {RolesUpdated} event.
            log3(0, 0, _ROLES_UPDATED_EVENT_SIGNATURE, shr(96, mload(0x0c)), updated)
        }
    }

    /// @dev Grants the roles directly without authorization guard.
    /// Each bit of `roles` represents the role to turn on.
    function _grantRoles(address user, uint256 roles) internal virtual {
        _updateRoles(user, roles, true);
    }

    /// @dev Removes the roles directly without authorization guard.
    /// Each bit of `roles` represents the role to turn off.
    function _removeRoles(address user, uint256 roles) internal virtual {
        _updateRoles(user, roles, false);
    }

    /// @dev Throws if the sender does not have any of the `roles`.
    function _checkRoles(uint256 roles) internal view virtual {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute the role slot.
            mstore(0x0c, _ROLE_SLOT_SEED)
            mstore(0x00, caller())
            // Load the stored value, and if the `and` intersection
            // of the value and `roles` is zero, revert.
            if iszero(and(sload(keccak256(0x0c, 0x20)), roles)) {
                mstore(0x00, 0x82b42900) // `Unauthorized()`.
                revert(0x1c, 0x04)
            }
        }
    }

    /// @dev Throws if the sender is not the owner,
    /// and does not have any of the `roles`.
    /// Checks for ownership first, then lazily checks for roles.
    function _checkOwnerOrRoles(uint256 roles) internal view virtual {
        /// @solidity memory-safe-assembly
        assembly {
            // If the caller is not the stored owner.
            // Note: `_ROLE_SLOT_SEED` is equal to `_OWNER_SLOT_NOT`.
            if iszero(eq(caller(), sload(not(_ROLE_SLOT_SEED)))) {
                // Compute the role slot.
                mstore(0x0c, _ROLE_SLOT_SEED)
                mstore(0x00, caller())
                // Load the stored value, and if the `and` intersection
                // of the value and `roles` is zero, revert.
                if iszero(and(sload(keccak256(0x0c, 0x20)), roles)) {
                    mstore(0x00, 0x82b42900) // `Unauthorized()`.
                    revert(0x1c, 0x04)
                }
            }
        }
    }

    /// @dev Throws if the sender does not have any of the `roles`,
    /// and is not the owner.
    /// Checks for roles first, then lazily checks for ownership.
    function _checkRolesOrOwner(uint256 roles) internal view virtual {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute the role slot.
            mstore(0x0c, _ROLE_SLOT_SEED)
            mstore(0x00, caller())
            // Load the stored value, and if the `and` intersection
            // of the value and `roles` is zero, revert.
            if iszero(and(sload(keccak256(0x0c, 0x20)), roles)) {
                // If the caller is not the stored owner.
                // Note: `_ROLE_SLOT_SEED` is equal to `_OWNER_SLOT_NOT`.
                if iszero(eq(caller(), sload(not(_ROLE_SLOT_SEED)))) {
                    mstore(0x00, 0x82b42900) // `Unauthorized()`.
                    revert(0x1c, 0x04)
                }
            }
        }
    }

    /// @dev Convenience function to return a `roles` bitmap from an array of `ordinals`.
    /// This is meant for frontends like Etherscan, and is therefore not fully optimized.
    /// Not recommended to be called on-chain.
    /// Made internal to conserve bytecode. Wrap it in a public function if needed.
    function _rolesFromOrdinals(uint8[] memory ordinals) internal pure returns (uint256 roles) {
        /// @solidity memory-safe-assembly
        assembly {
            for { let i := shl(5, mload(ordinals)) } i { i := sub(i, 0x20) } {
                // We don't need to mask the values of `ordinals`, as Solidity
                // cleans dirty upper bits when storing variables into memory.
                roles := or(shl(mload(add(ordinals, i)), 1), roles)
            }
        }
    }

    /// @dev Convenience function to return an array of `ordinals` from the `roles` bitmap.
    /// This is meant for frontends like Etherscan, and is therefore not fully optimized.
    /// Not recommended to be called on-chain.
    /// Made internal to conserve bytecode. Wrap it in a public function if needed.
    function _ordinalsFromRoles(uint256 roles) internal pure returns (uint8[] memory ordinals) {
        /// @solidity memory-safe-assembly
        assembly {
            // Grab the pointer to the free memory.
            ordinals := mload(0x40)
            let ptr := add(ordinals, 0x20)
            let o := 0
            // The absence of lookup tables, De Bruijn, etc., here is intentional for
            // smaller bytecode, as this function is not meant to be called on-chain.
            for { let t := roles } 1 {} {
                mstore(ptr, o)
                // `shr` 5 is equivalent to multiplying by 0x20.
                // Push back into the ordinals array if the bit is set.
                ptr := add(ptr, shl(5, and(t, 1)))
                o := add(o, 1)
                t := shr(o, roles)
                if iszero(t) { break }
            }
            // Store the length of `ordinals`.
            mstore(ordinals, shr(5, sub(ptr, add(ordinals, 0x20))))
            // Allocate the memory.
            mstore(0x40, ptr)
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                  PUBLIC UPDATE FUNCTIONS                   */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Allows the owner to grant `user` `roles`.
    /// If the `user` already has a role, then it will be an no-op for the role.
    function grantRoles(address user, uint256 roles) public payable virtual onlyOwner {
        _grantRoles(user, roles);
    }

    /// @dev Allows the owner to remove `user` `roles`.
    /// If the `user` does not have a role, then it will be an no-op for the role.
    function revokeRoles(address user, uint256 roles) public payable virtual onlyOwner {
        _removeRoles(user, roles);
    }

    /// @dev Allow the caller to remove their own roles.
    /// If the caller does not have a role, then it will be an no-op for the role.
    function renounceRoles(uint256 roles) public payable virtual {
        _removeRoles(msg.sender, roles);
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                   PUBLIC READ FUNCTIONS                    */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns the roles of `user`.
    function rolesOf(address user) public view virtual returns (uint256 roles) {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute the role slot.
            mstore(0x0c, _ROLE_SLOT_SEED)
            mstore(0x00, user)
            // Load the stored value.
            roles := sload(keccak256(0x0c, 0x20))
        }
    }

    /// @dev Returns whether `user` has any of `roles`.
    function hasAnyRole(address user, uint256 roles) public view virtual returns (bool) {
        return rolesOf(user) & roles != 0;
    }

    /// @dev Returns whether `user` has all of `roles`.
    function hasAllRoles(address user, uint256 roles) public view virtual returns (bool) {
        return rolesOf(user) & roles == roles;
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         MODIFIERS                          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Marks a function as only callable by an account with `roles`.
    modifier onlyRoles(uint256 roles) virtual {
        _checkRoles(roles);
        _;
    }

    /// @dev Marks a function as only callable by the owner or by an account
    /// with `roles`. Checks for ownership first, then lazily checks for roles.
    modifier onlyOwnerOrRoles(uint256 roles) virtual {
        _checkOwnerOrRoles(roles);
        _;
    }

    /// @dev Marks a function as only callable by an account with `roles`
    /// or the owner. Checks for roles first, then lazily checks for ownership.
    modifier onlyRolesOrOwner(uint256 roles) virtual {
        _checkRolesOrOwner(roles);
        _;
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       ROLE CONSTANTS                       */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    // IYKYK

    uint256 internal constant _ROLE_0 = 1 << 0;
    uint256 internal constant _ROLE_1 = 1 << 1;
    uint256 internal constant _ROLE_2 = 1 << 2;
    uint256 internal constant _ROLE_3 = 1 << 3;
    uint256 internal constant _ROLE_4 = 1 << 4;
    uint256 internal constant _ROLE_5 = 1 << 5;
    uint256 internal constant _ROLE_6 = 1 << 6;
    uint256 internal constant _ROLE_7 = 1 << 7;
    uint256 internal constant _ROLE_8 = 1 << 8;
    uint256 internal constant _ROLE_9 = 1 << 9;
    uint256 internal constant _ROLE_10 = 1 << 10;
    uint256 internal constant _ROLE_11 = 1 << 11;
    uint256 internal constant _ROLE_12 = 1 << 12;
    uint256 internal constant _ROLE_13 = 1 << 13;
    uint256 internal constant _ROLE_14 = 1 << 14;
    uint256 internal constant _ROLE_15 = 1 << 15;
    uint256 internal constant _ROLE_16 = 1 << 16;
    uint256 internal constant _ROLE_17 = 1 << 17;
    uint256 internal constant _ROLE_18 = 1 << 18;
    uint256 internal constant _ROLE_19 = 1 << 19;
    uint256 internal constant _ROLE_20 = 1 << 20;
    uint256 internal constant _ROLE_21 = 1 << 21;
    uint256 internal constant _ROLE_22 = 1 << 22;
    uint256 internal constant _ROLE_23 = 1 << 23;
    uint256 internal constant _ROLE_24 = 1 << 24;
    uint256 internal constant _ROLE_25 = 1 << 25;
    uint256 internal constant _ROLE_26 = 1 << 26;
    uint256 internal constant _ROLE_27 = 1 << 27;
    uint256 internal constant _ROLE_28 = 1 << 28;
    uint256 internal constant _ROLE_29 = 1 << 29;
    uint256 internal constant _ROLE_30 = 1 << 30;
    uint256 internal constant _ROLE_31 = 1 << 31;
    uint256 internal constant _ROLE_32 = 1 << 32;
    uint256 internal constant _ROLE_33 = 1 << 33;
    uint256 internal constant _ROLE_34 = 1 << 34;
    uint256 internal constant _ROLE_35 = 1 << 35;
    uint256 internal constant _ROLE_36 = 1 << 36;
    uint256 internal constant _ROLE_37 = 1 << 37;
    uint256 internal constant _ROLE_38 = 1 << 38;
    uint256 internal constant _ROLE_39 = 1 << 39;
    uint256 internal constant _ROLE_40 = 1 << 40;
    uint256 internal constant _ROLE_41 = 1 << 41;
    uint256 internal constant _ROLE_42 = 1 << 42;
    uint256 internal constant _ROLE_43 = 1 << 43;
    uint256 internal constant _ROLE_44 = 1 << 44;
    uint256 internal constant _ROLE_45 = 1 << 45;
    uint256 internal constant _ROLE_46 = 1 << 46;
    uint256 internal constant _ROLE_47 = 1 << 47;
    uint256 internal constant _ROLE_48 = 1 << 48;
    uint256 internal constant _ROLE_49 = 1 << 49;
    uint256 internal constant _ROLE_50 = 1 << 50;
    uint256 internal constant _ROLE_51 = 1 << 51;
    uint256 internal constant _ROLE_52 = 1 << 52;
    uint256 internal constant _ROLE_53 = 1 << 53;
    uint256 internal constant _ROLE_54 = 1 << 54;
    uint256 internal constant _ROLE_55 = 1 << 55;
    uint256 internal constant _ROLE_56 = 1 << 56;
    uint256 internal constant _ROLE_57 = 1 << 57;
    uint256 internal constant _ROLE_58 = 1 << 58;
    uint256 internal constant _ROLE_59 = 1 << 59;
    uint256 internal constant _ROLE_60 = 1 << 60;
    uint256 internal constant _ROLE_61 = 1 << 61;
    uint256 internal constant _ROLE_62 = 1 << 62;
    uint256 internal constant _ROLE_63 = 1 << 63;
    uint256 internal constant _ROLE_64 = 1 << 64;
    uint256 internal constant _ROLE_65 = 1 << 65;
    uint256 internal constant _ROLE_66 = 1 << 66;
    uint256 internal constant _ROLE_67 = 1 << 67;
    uint256 internal constant _ROLE_68 = 1 << 68;
    uint256 internal constant _ROLE_69 = 1 << 69;
    uint256 internal constant _ROLE_70 = 1 << 70;
    uint256 internal constant _ROLE_71 = 1 << 71;
    uint256 internal constant _ROLE_72 = 1 << 72;
    uint256 internal constant _ROLE_73 = 1 << 73;
    uint256 internal constant _ROLE_74 = 1 << 74;
    uint256 internal constant _ROLE_75 = 1 << 75;
    uint256 internal constant _ROLE_76 = 1 << 76;
    uint256 internal constant _ROLE_77 = 1 << 77;
    uint256 internal constant _ROLE_78 = 1 << 78;
    uint256 internal constant _ROLE_79 = 1 << 79;
    uint256 internal constant _ROLE_80 = 1 << 80;
    uint256 internal constant _ROLE_81 = 1 << 81;
    uint256 internal constant _ROLE_82 = 1 << 82;
    uint256 internal constant _ROLE_83 = 1 << 83;
    uint256 internal constant _ROLE_84 = 1 << 84;
    uint256 internal constant _ROLE_85 = 1 << 85;
    uint256 internal constant _ROLE_86 = 1 << 86;
    uint256 internal constant _ROLE_87 = 1 << 87;
    uint256 internal constant _ROLE_88 = 1 << 88;
    uint256 internal constant _ROLE_89 = 1 << 89;
    uint256 internal constant _ROLE_90 = 1 << 90;
    uint256 internal constant _ROLE_91 = 1 << 91;
    uint256 internal constant _ROLE_92 = 1 << 92;
    uint256 internal constant _ROLE_93 = 1 << 93;
    uint256 internal constant _ROLE_94 = 1 << 94;
    uint256 internal constant _ROLE_95 = 1 << 95;
    uint256 internal constant _ROLE_96 = 1 << 96;
    uint256 internal constant _ROLE_97 = 1 << 97;
    uint256 internal constant _ROLE_98 = 1 << 98;
    uint256 internal constant _ROLE_99 = 1 << 99;
    uint256 internal constant _ROLE_100 = 1 << 100;
    uint256 internal constant _ROLE_101 = 1 << 101;
    uint256 internal constant _ROLE_102 = 1 << 102;
    uint256 internal constant _ROLE_103 = 1 << 103;
    uint256 internal constant _ROLE_104 = 1 << 104;
    uint256 internal constant _ROLE_105 = 1 << 105;
    uint256 internal constant _ROLE_106 = 1 << 106;
    uint256 internal constant _ROLE_107 = 1 << 107;
    uint256 internal constant _ROLE_108 = 1 << 108;
    uint256 internal constant _ROLE_109 = 1 << 109;
    uint256 internal constant _ROLE_110 = 1 << 110;
    uint256 internal constant _ROLE_111 = 1 << 111;
    uint256 internal constant _ROLE_112 = 1 << 112;
    uint256 internal constant _ROLE_113 = 1 << 113;
    uint256 internal constant _ROLE_114 = 1 << 114;
    uint256 internal constant _ROLE_115 = 1 << 115;
    uint256 internal constant _ROLE_116 = 1 << 116;
    uint256 internal constant _ROLE_117 = 1 << 117;
    uint256 internal constant _ROLE_118 = 1 << 118;
    uint256 internal constant _ROLE_119 = 1 << 119;
    uint256 internal constant _ROLE_120 = 1 << 120;
    uint256 internal constant _ROLE_121 = 1 << 121;
    uint256 internal constant _ROLE_122 = 1 << 122;
    uint256 internal constant _ROLE_123 = 1 << 123;
    uint256 internal constant _ROLE_124 = 1 << 124;
    uint256 internal constant _ROLE_125 = 1 << 125;
    uint256 internal constant _ROLE_126 = 1 << 126;
    uint256 internal constant _ROLE_127 = 1 << 127;
    uint256 internal constant _ROLE_128 = 1 << 128;
    uint256 internal constant _ROLE_129 = 1 << 129;
    uint256 internal constant _ROLE_130 = 1 << 130;
    uint256 internal constant _ROLE_131 = 1 << 131;
    uint256 internal constant _ROLE_132 = 1 << 132;
    uint256 internal constant _ROLE_133 = 1 << 133;
    uint256 internal constant _ROLE_134 = 1 << 134;
    uint256 internal constant _ROLE_135 = 1 << 135;
    uint256 internal constant _ROLE_136 = 1 << 136;
    uint256 internal constant _ROLE_137 = 1 << 137;
    uint256 internal constant _ROLE_138 = 1 << 138;
    uint256 internal constant _ROLE_139 = 1 << 139;
    uint256 internal constant _ROLE_140 = 1 << 140;
    uint256 internal constant _ROLE_141 = 1 << 141;
    uint256 internal constant _ROLE_142 = 1 << 142;
    uint256 internal constant _ROLE_143 = 1 << 143;
    uint256 internal constant _ROLE_144 = 1 << 144;
    uint256 internal constant _ROLE_145 = 1 << 145;
    uint256 internal constant _ROLE_146 = 1 << 146;
    uint256 internal constant _ROLE_147 = 1 << 147;
    uint256 internal constant _ROLE_148 = 1 << 148;
    uint256 internal constant _ROLE_149 = 1 << 149;
    uint256 internal constant _ROLE_150 = 1 << 150;
    uint256 internal constant _ROLE_151 = 1 << 151;
    uint256 internal constant _ROLE_152 = 1 << 152;
    uint256 internal constant _ROLE_153 = 1 << 153;
    uint256 internal constant _ROLE_154 = 1 << 154;
    uint256 internal constant _ROLE_155 = 1 << 155;
    uint256 internal constant _ROLE_156 = 1 << 156;
    uint256 internal constant _ROLE_157 = 1 << 157;
    uint256 internal constant _ROLE_158 = 1 << 158;
    uint256 internal constant _ROLE_159 = 1 << 159;
    uint256 internal constant _ROLE_160 = 1 << 160;
    uint256 internal constant _ROLE_161 = 1 << 161;
    uint256 internal constant _ROLE_162 = 1 << 162;
    uint256 internal constant _ROLE_163 = 1 << 163;
    uint256 internal constant _ROLE_164 = 1 << 164;
    uint256 internal constant _ROLE_165 = 1 << 165;
    uint256 internal constant _ROLE_166 = 1 << 166;
    uint256 internal constant _ROLE_167 = 1 << 167;
    uint256 internal constant _ROLE_168 = 1 << 168;
    uint256 internal constant _ROLE_169 = 1 << 169;
    uint256 internal constant _ROLE_170 = 1 << 170;
    uint256 internal constant _ROLE_171 = 1 << 171;
    uint256 internal constant _ROLE_172 = 1 << 172;
    uint256 internal constant _ROLE_173 = 1 << 173;
    uint256 internal constant _ROLE_174 = 1 << 174;
    uint256 internal constant _ROLE_175 = 1 << 175;
    uint256 internal constant _ROLE_176 = 1 << 176;
    uint256 internal constant _ROLE_177 = 1 << 177;
    uint256 internal constant _ROLE_178 = 1 << 178;
    uint256 internal constant _ROLE_179 = 1 << 179;
    uint256 internal constant _ROLE_180 = 1 << 180;
    uint256 internal constant _ROLE_181 = 1 << 181;
    uint256 internal constant _ROLE_182 = 1 << 182;
    uint256 internal constant _ROLE_183 = 1 << 183;
    uint256 internal constant _ROLE_184 = 1 << 184;
    uint256 internal constant _ROLE_185 = 1 << 185;
    uint256 internal constant _ROLE_186 = 1 << 186;
    uint256 internal constant _ROLE_187 = 1 << 187;
    uint256 internal constant _ROLE_188 = 1 << 188;
    uint256 internal constant _ROLE_189 = 1 << 189;
    uint256 internal constant _ROLE_190 = 1 << 190;
    uint256 internal constant _ROLE_191 = 1 << 191;
    uint256 internal constant _ROLE_192 = 1 << 192;
    uint256 internal constant _ROLE_193 = 1 << 193;
    uint256 internal constant _ROLE_194 = 1 << 194;
    uint256 internal constant _ROLE_195 = 1 << 195;
    uint256 internal constant _ROLE_196 = 1 << 196;
    uint256 internal constant _ROLE_197 = 1 << 197;
    uint256 internal constant _ROLE_198 = 1 << 198;
    uint256 internal constant _ROLE_199 = 1 << 199;
    uint256 internal constant _ROLE_200 = 1 << 200;
    uint256 internal constant _ROLE_201 = 1 << 201;
    uint256 internal constant _ROLE_202 = 1 << 202;
    uint256 internal constant _ROLE_203 = 1 << 203;
    uint256 internal constant _ROLE_204 = 1 << 204;
    uint256 internal constant _ROLE_205 = 1 << 205;
    uint256 internal constant _ROLE_206 = 1 << 206;
    uint256 internal constant _ROLE_207 = 1 << 207;
    uint256 internal constant _ROLE_208 = 1 << 208;
    uint256 internal constant _ROLE_209 = 1 << 209;
    uint256 internal constant _ROLE_210 = 1 << 210;
    uint256 internal constant _ROLE_211 = 1 << 211;
    uint256 internal constant _ROLE_212 = 1 << 212;
    uint256 internal constant _ROLE_213 = 1 << 213;
    uint256 internal constant _ROLE_214 = 1 << 214;
    uint256 internal constant _ROLE_215 = 1 << 215;
    uint256 internal constant _ROLE_216 = 1 << 216;
    uint256 internal constant _ROLE_217 = 1 << 217;
    uint256 internal constant _ROLE_218 = 1 << 218;
    uint256 internal constant _ROLE_219 = 1 << 219;
    uint256 internal constant _ROLE_220 = 1 << 220;
    uint256 internal constant _ROLE_221 = 1 << 221;
    uint256 internal constant _ROLE_222 = 1 << 222;
    uint256 internal constant _ROLE_223 = 1 << 223;
    uint256 internal constant _ROLE_224 = 1 << 224;
    uint256 internal constant _ROLE_225 = 1 << 225;
    uint256 internal constant _ROLE_226 = 1 << 226;
    uint256 internal constant _ROLE_227 = 1 << 227;
    uint256 internal constant _ROLE_228 = 1 << 228;
    uint256 internal constant _ROLE_229 = 1 << 229;
    uint256 internal constant _ROLE_230 = 1 << 230;
    uint256 internal constant _ROLE_231 = 1 << 231;
    uint256 internal constant _ROLE_232 = 1 << 232;
    uint256 internal constant _ROLE_233 = 1 << 233;
    uint256 internal constant _ROLE_234 = 1 << 234;
    uint256 internal constant _ROLE_235 = 1 << 235;
    uint256 internal constant _ROLE_236 = 1 << 236;
    uint256 internal constant _ROLE_237 = 1 << 237;
    uint256 internal constant _ROLE_238 = 1 << 238;
    uint256 internal constant _ROLE_239 = 1 << 239;
    uint256 internal constant _ROLE_240 = 1 << 240;
    uint256 internal constant _ROLE_241 = 1 << 241;
    uint256 internal constant _ROLE_242 = 1 << 242;
    uint256 internal constant _ROLE_243 = 1 << 243;
    uint256 internal constant _ROLE_244 = 1 << 244;
    uint256 internal constant _ROLE_245 = 1 << 245;
    uint256 internal constant _ROLE_246 = 1 << 246;
    uint256 internal constant _ROLE_247 = 1 << 247;
    uint256 internal constant _ROLE_248 = 1 << 248;
    uint256 internal constant _ROLE_249 = 1 << 249;
    uint256 internal constant _ROLE_250 = 1 << 250;
    uint256 internal constant _ROLE_251 = 1 << 251;
    uint256 internal constant _ROLE_252 = 1 << 252;
    uint256 internal constant _ROLE_253 = 1 << 253;
    uint256 internal constant _ROLE_254 = 1 << 254;
    uint256 internal constant _ROLE_255 = 1 << 255;
}

File 3 of 21 : ISoundEditionV2.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;

import { IERC721AUpgradeable } from "chiru-labs/ERC721A-Upgradeable/IERC721AUpgradeable.sol";
import { IERC2981Upgradeable } from "openzeppelin-upgradeable/interfaces/IERC2981Upgradeable.sol";
import { IERC165Upgradeable } from "openzeppelin-upgradeable/utils/introspection/IERC165Upgradeable.sol";

import { IMetadataModule } from "./IMetadataModule.sol";

/**
 * @title ISoundEditionV2
 * @notice The interface for Sound edition contracts.
 */
interface ISoundEditionV2 is IERC721AUpgradeable, IERC2981Upgradeable {
    // =============================================================
    //                            STRUCTS
    // =============================================================

    /**
     * @dev The information pertaining to a tier.
     */
    struct TierInfo {
        // The tier.
        uint8 tier;
        // The current max mintable amount.
        uint32 maxMintable;
        // The lower bound of the maximum number of tokens that can be minted for the tier.
        uint32 maxMintableLower;
        // The upper bound of the maximum number of tokens that can be minted for the tier.
        uint32 maxMintableUpper;
        // The timestamp (in seconds since unix epoch) after which the
        // max amount of tokens mintable for the tier will drop from
        // `maxMintableUpper` to `maxMintableLower`.
        uint32 cutoffTime;
        // The total number of tokens minted for the tier.
        uint32 minted;
        // The mint randomness for the tier.
        uint256 mintRandomness;
        // Whether the tier mints have concluded.
        bool mintConcluded;
        // Whether the tier has mint randomness enabled.
        bool mintRandomnessEnabled;
        // Whether the tier is frozen.
        bool isFrozen;
    }

    /**
     * @dev A struct containing the arguments for creating a tier.
     */
    struct TierCreation {
        // The tier.
        uint8 tier;
        // The lower bound of the maximum number of tokens that can be minted for the tier.
        uint32 maxMintableLower;
        // The upper bound of the maximum number of tokens that can be minted for the tier.
        uint32 maxMintableUpper;
        // The timestamp (in seconds since unix epoch) after which the
        // max amount of tokens mintable for the tier will drop from
        // `maxMintableUpper` to `maxMintableLower`.
        uint32 cutoffTime;
        // Whether the tier has mint randomness enabled.
        bool mintRandomnessEnabled;
        // Whether the tier is frozen.
        bool isFrozen;
    }

    /**
     * @dev The information pertaining to this edition.
     */
    struct EditionInfo {
        // Base URI for the metadata.
        string baseURI;
        // Contract URI for OpenSea storefront.
        string contractURI;
        // Name of the collection.
        string name;
        // Symbol of the collection.
        string symbol;
        // Address that receives primary and secondary royalties.
        address fundingRecipient;
        // Address of the metadata module. Optional.
        address metadataModule;
        // Whether the metadata is frozen.
        bool isMetadataFrozen;
        // Whether the ability to create tiers is frozen.
        bool isCreateTierFrozen;
        // The royalty BPS (basis points).
        uint16 royaltyBPS;
        // Next token ID to be minted.
        uint256 nextTokenId;
        // Total number of tokens burned.
        uint256 totalBurned;
        // Total number of tokens minted.
        uint256 totalMinted;
        // Total number of tokens currently in existence.
        uint256 totalSupply;
        // An array of tier info. From lowest (0-indexed) to highest.
        TierInfo[] tierInfo;
    }

    /**
     * @dev A struct containing the arguments for initialization.
     */
    struct EditionInitialization {
        // Name of the collection.
        string name;
        // Symbol of the collection.
        string symbol;
        // Address of the metadata module. Optional.
        address metadataModule;
        // Base URI for the metadata.
        string baseURI;
        // Contract URI for OpenSea storefront.
        string contractURI;
        // Address that receives primary and secondary royalties.
        address fundingRecipient;
        // The royalty BPS (basis points).
        uint16 royaltyBPS;
        // Whether the metadata is frozen.
        bool isMetadataFrozen;
        // Whether the ability to create tiers is frozen.
        bool isCreateTierFrozen;
        // An array of tier creation structs. From lowest (0-indexed) to highest.
        TierCreation[] tierCreations;
    }

    // =============================================================
    //                            EVENTS
    // =============================================================

    /**
     * @dev Emitted when the metadata module is set.
     * @param metadataModule the address of the metadata module.
     */
    event MetadataModuleSet(address metadataModule);

    /**
     * @dev Emitted when the `baseURI` is set.
     * @param baseURI the base URI of the edition.
     */
    event BaseURISet(string baseURI);

    /**
     * @dev Emitted when the `contractURI` is set.
     * @param contractURI The contract URI of the edition.
     */
    event ContractURISet(string contractURI);

    /**
     * @dev Emitted when the metadata is frozen (e.g.: `baseURI` can no longer be changed).
     * @param metadataModule The address of the metadata module.
     * @param baseURI        The base URI of the edition.
     * @param contractURI    The contract URI of the edition.
     */
    event MetadataFrozen(address metadataModule, string baseURI, string contractURI);

    /**
     * @dev Emitted when the ability to create tier is removed.
     */
    event CreateTierFrozen();

    /**
     * @dev Emitted when the `fundingRecipient` is set.
     * @param recipient The address of the funding recipient.
     */
    event FundingRecipientSet(address recipient);

    /**
     * @dev Emitted when the `royaltyBPS` is set.
     * @param bps The new royalty, measured in basis points.
     */
    event RoyaltySet(uint16 bps);

    /**
     * @dev Emitted when the tier's maximum mintable token quantity range is set.
     * @param tier  The tier.
     * @param lower The lower limit of the maximum number of tokens that can be minted.
     * @param upper The upper limit of the maximum number of tokens that can be minted.
     */
    event MaxMintableRangeSet(uint8 tier, uint32 lower, uint32 upper);

    /**
     * @dev Emitted when the tier's cutoff time set.
     * @param tier    The tier.
     * @param cutoff The timestamp.
     */
    event CutoffTimeSet(uint8 tier, uint32 cutoff);

    /**
     * @dev Emitted when the `mintRandomnessEnabled` for the tier is set.
     * @param tier    The tier.
     * @param enabled The boolean value.
     */
    event MintRandomnessEnabledSet(uint8 tier, bool enabled);

    /**
     * @dev Emitted upon initialization.
     * @param init The initialization data.
     */
    event SoundEditionInitialized(EditionInitialization init);

    /**
     * @dev Emitted when a tier is created.
     * @param creation The tier creation data.
     */
    event TierCreated(TierCreation creation);

    /**
     * @dev Emitted when a tier is frozen.
     * @param tier The tier.
     */
    event TierFrozen(uint8 tier);

    /**
     * @dev Emitted upon ETH withdrawal.
     * @param recipient The recipient of the withdrawal.
     * @param amount    The amount withdrawn.
     * @param caller    The account that initiated the withdrawal.
     */
    event ETHWithdrawn(address recipient, uint256 amount, address caller);

    /**
     * @dev Emitted upon ERC20 withdrawal.
     * @param recipient The recipient of the withdrawal.
     * @param tokens    The addresses of the ERC20 tokens.
     * @param amounts   The amount of each token withdrawn.
     * @param caller    The account that initiated the withdrawal.
     */
    event ERC20Withdrawn(address recipient, address[] tokens, uint256[] amounts, address caller);

    /**
     * @dev Emitted upon a mint.
     * @param tier        The tier.
     * @param to          The address to mint to.
     * @param quantity    The number of minted.
     * @param fromTokenId The first token ID minted.
     */
    event Minted(uint8 tier, address to, uint256 quantity, uint256 fromTokenId);

    /**
     * @dev Emitted upon an airdrop.
     * @param tier        The tier.
     * @param to          The recipients of the airdrop.
     * @param quantity    The number of tokens airdropped to each address in `to`.
     * @param fromTokenId The first token ID minted to the first address in `to`.
     */
    event Airdropped(uint8 tier, address[] to, uint256 quantity, uint256 fromTokenId);

    /**
     * @dev EIP-4906 event to signal marketplaces to refresh the metadata.
     * @param fromTokenId The starting token ID.
     * @param toTokenId   The ending token ID.
     */
    event BatchMetadataUpdate(uint256 fromTokenId, uint256 toTokenId);

    // =============================================================
    //                            ERRORS
    // =============================================================

    /**
     * @dev The edition's metadata is frozen (e.g.: `baseURI` can no longer be changed).
     */
    error MetadataIsFrozen();

    /**
     * @dev The ability to create tiers is frozen.
     */
    error CreateTierIsFrozen();

    /**
     * @dev The given `royaltyBPS` is invalid.
     */
    error InvalidRoyaltyBPS();

    /**
     * @dev A minimum of one tier must be provided to initialize a Sound Edition.
     */
    error ZeroTiersProvided();

    /**
     * @dev The requested quantity exceeds the edition's remaining mintable token quantity.
     */
    error ExceedsAvailableSupply();

    /**
     * @dev The given `fundingRecipient` address is invalid.
     */
    error InvalidFundingRecipient();

    /**
     * @dev The `maxMintableLower` must not be greater than `maxMintableUpper`.
     */
    error InvalidMaxMintableRange();

    /**
     * @dev The mint has already concluded.
     */
    error MintHasConcluded();

    /**
     * @dev The mint has not concluded.
     */
    error MintNotConcluded();

    /**
     * @dev Cannot perform the operation after a token has been minted.
     */
    error MintsAlreadyExist();

    /**
     * @dev Cannot perform the operation after a token has been minted in the tier.
     */
    error TierMintsAlreadyExist();

    /**
     * @dev The token IDs must be in strictly ascending order.
     */
    error TokenIdsNotStrictlyAscending();

    /**
     * @dev The tier does not exist.
     */
    error TierDoesNotExist();

    /**
     * @dev The tier already exists.
     */
    error TierAlreadyExists();

    /**
     * @dev The tier is frozen.
     */
    error TierIsFrozen();

    /**
     * @dev One of more of the tokens do not have the correct token tier.
     */
    error InvalidTokenTier();

    /**
     * @dev Please wait for a while before you burn.
     */
    error CannotBurnImmediately();

    /**
     * @dev The token for the tier query doesn't exist.
     */
    error TierQueryForNonexistentToken();

    // =============================================================
    //               PUBLIC / EXTERNAL WRITE FUNCTIONS
    // =============================================================

    /**
     * @dev Initializes the contract.
     * @param init The initialization struct.
     */
    function initialize(EditionInitialization calldata init) external;

    /**
     * @dev Mints `quantity` tokens to addrress `to`
     *      Each token will be assigned a token ID that is consecutively increasing.
     *
     * Calling conditions:
     * - The caller must be the owner of the contract, or have either the
     *   `ADMIN_ROLE`, `MINTER_ROLE`, which can be granted via {grantRole}.
     *   Multiple minters, such as different minter contracts,
     *   can be authorized simultaneously.
     *
     * @param tier     The tier.
     * @param to       Address to mint to.
     * @param quantity Number of tokens to mint.
     * @return fromTokenId The first token ID minted.
     */
    function mint(
        uint8 tier,
        address to,
        uint256 quantity
    ) external payable returns (uint256 fromTokenId);

    /**
     * @dev Mints `quantity` tokens to each of the addresses in `to`.
     *
     * Calling conditions:
     * - The caller must be the owner of the contract, or have the
     *   `ADMIN_ROLE`, which can be granted via {grantRole}.
     *
     * @param tier         The tier.
     * @param to           Address to mint to.
     * @param quantity     Number of tokens to mint.
     * @return fromTokenId The first token ID minted.
     */
    function airdrop(
        uint8 tier,
        address[] calldata to,
        uint256 quantity
    ) external payable returns (uint256 fromTokenId);

    /**
     * @dev Withdraws collected ETH royalties to the fundingRecipient.
     */
    function withdrawETH() external;

    /**
     * @dev Withdraws collected ERC20 royalties to the fundingRecipient.
     * @param tokens array of ERC20 tokens to withdraw
     */
    function withdrawERC20(address[] calldata tokens) external;

    /**
     * @dev Sets metadata module.
     *
     * Calling conditions:
     * - The caller must be the owner of the contract, or have the `ADMIN_ROLE`.
     *
     * @param metadataModule Address of metadata module.
     */
    function setMetadataModule(address metadataModule) external;

    /**
     * @dev Sets global base URI.
     *
     * Calling conditions:
     * - The caller must be the owner of the contract, or have the `ADMIN_ROLE`.
     *
     * @param baseURI The base URI to be set.
     */
    function setBaseURI(string memory baseURI) external;

    /**
     * @dev Sets contract URI.
     *
     * Calling conditions:
     * - The caller must be the owner of the contract, or have the `ADMIN_ROLE`.
     *
     * @param contractURI The contract URI to be set.
     */
    function setContractURI(string memory contractURI) external;

    /**
     * @dev Freezes metadata by preventing any more changes to base URI.
     *
     * Calling conditions:
     * - The caller must be the owner of the contract, or have the `ADMIN_ROLE`.
     */
    function freezeMetadata() external;

    /**
     * @dev Freezes the max tier by preventing any more tiers from being added,
     *
     * Calling conditions:
     * - The caller must be the owner of the contract, or have the `ADMIN_ROLE`.
     */
    function freezeCreateTier() external;

    /**
     * @dev Sets funding recipient address.
     *
     * Calling conditions:
     * - The caller must be the owner of the contract, or have the `ADMIN_ROLE`.
     *
     * @param fundingRecipient Address to be set as the new funding recipient.
     */
    function setFundingRecipient(address fundingRecipient) external;

    /**
     * @dev Creates a new split wallet via the SplitMain contract, then sets it as the `fundingRecipient`.
     *
     * Calling conditions:
     * - The caller must be the owner of the contract, or have the `ADMIN_ROLE`.
     *
     * @param splitMain The address of the SplitMain contract.
     * @param splitData The calldata to forward to the SplitMain contract to create a split.
     * @return split The address of the new split contract.
     */
    function createSplit(address splitMain, bytes calldata splitData) external returns (address split);

    /**
     * @dev Sets royalty amount in bps (basis points).
     *
     * Calling conditions:
     * - The caller must be the owner of the contract, or have the `ADMIN_ROLE`.
     *
     * @param bps The new royalty basis points to be set.
     */
    function setRoyalty(uint16 bps) external;

    /**
     * @dev Freezes the tier.
     *
     * Calling conditions:
     * - The caller must be the owner of the contract, or have the `ADMIN_ROLE`.
     *
     * @param tier  The tier.
     */
    function freezeTier(uint8 tier) external;

    /**
     * @dev Sets the edition max mintable range.
     *
     * Calling conditions:
     * - The caller must be the owner of the contract, or have the `ADMIN_ROLE`.
     *
     * @param tier  The tier.
     * @param lower The lower limit of the maximum number of tokens that can be minted.
     * @param upper The upper limit of the maximum number of tokens that can be minted.
     */
    function setMaxMintableRange(
        uint8 tier,
        uint32 lower,
        uint32 upper
    ) external;

    /**
     * @dev Sets the timestamp after which, the `editionMaxMintable` drops
     *      from `editionMaxMintableUpper` to `editionMaxMintableLower.
     *
     * Calling conditions:
     * - The caller must be the owner of the contract, or have the `ADMIN_ROLE`.
     *
     * @param tier       The tier.
     * @param cutoffTime The timestamp.
     */
    function setCutoffTime(uint8 tier, uint32 cutoffTime) external;

    /**
     * @dev Sets whether the `mintRandomness` is enabled.
     *
     * Calling conditions:
     * - The caller must be the owner of the contract, or have the `ADMIN_ROLE`.
     *
     * @param tier    The tier.
     * @param enabled The boolean value.
     */
    function setMintRandomnessEnabled(uint8 tier, bool enabled) external;

    /**
     * @dev Adds a new tier.
     *
     * Calling conditions:
     * - The caller must be the owner of the contract, or have the `ADMIN_ROLE`.
     *
     * @param creation The tier creation data.
     */
    function createTier(TierCreation calldata creation) external;

    /**
     * @dev Emits an event to signal to marketplaces to refresh all the metadata.
     */
    function emitAllMetadataUpdate() external;

    // =============================================================
    //               PUBLIC / EXTERNAL VIEW FUNCTIONS
    // =============================================================

    /**
     * @dev Returns the edition info.
     * @return info The latest value.
     */
    function editionInfo() external view returns (EditionInfo memory info);

    /**
     * @dev Returns the tier info.
     * @param tier The tier.
     * @return info The latest value.
     */
    function tierInfo(uint8 tier) external view returns (TierInfo memory info);

    /**
     * @dev Returns the GA tier, which is 0.
     * @return The constant value.
     */
    function GA_TIER() external pure returns (uint8);

    /**
     * @dev Basis points denominator used in fee calculations.
     * @return The constant value.
     */
    function BPS_DENOMINATOR() external pure returns (uint16);

    /**
     * @dev Returns the minter role flag.
     *      Note: This constant will always be 2 for past and future sound protocol contracts.
     * @return The constant value.
     */
    function MINTER_ROLE() external view returns (uint256);

    /**
     * @dev Returns the admin role flag.
     *      Note: This constant will always be 1 for past and future sound protocol contracts.
     * @return The constant value.
     */
    function ADMIN_ROLE() external view returns (uint256);

    /**
     * @dev Returns the tier of the `tokenId`.
     * @param tokenId The token ID.
     * @return The latest value.
     */
    function tokenTier(uint256 tokenId) external view returns (uint8);

    /**
     * @dev Returns the tier of the `tokenId`.
     *      Note: Will NOT revert if any `tokenId` does not exist.
     *      If the token has not been minted, the tier will be zero.
     *      If the token is burned, the tier will be the tier before it was burned.
     * @param tokenId The token ID.
     * @return The latest value.
     */
    function explicitTokenTier(uint256 tokenId) external view returns (uint8);

    /**
     * @dev Returns the tiers of the `tokenIds`.
     *      Note: Will NOT revert if any `tokenId` does not exist.
     *      If the token has not been minted, the tier will be zero.
     *      If the token is burned, the tier will be the tier before it was burned.
     * @param tokenIds The token IDs.
     * @return The latest values.
     */
    function tokenTiers(uint256[] calldata tokenIds) external view returns (uint8[] memory);

    /**
     * @dev Returns an array of all the token IDs in the tier.
     * @param tier The tier.
     * @return tokenIds The array of token IDs in the tier.
     */
    function tierTokenIds(uint8 tier) external view returns (uint256[] memory tokenIds);

    /**
     * @dev Returns an array of all the token IDs in the tier, within the range [start, stop).
     * @param tier  The tier.
     * @param start The start of the range. Inclusive.
     * @param stop  The end of the range. Exclusive.
     * @return tokenIds The array of token IDs in the tier.
     */
    function tierTokenIdsIn(
        uint8 tier,
        uint256 start,
        uint256 stop
    ) external view returns (uint256[] memory tokenIds);

    /**
     * @dev Returns the index of `tokenId` in it's tier token ID array.
     * @param tokenId The token ID to find.
     * @return The index of `tokenId`. If not found, returns `type(uint256).max`.
     */
    function tierTokenIdIndex(uint256 tokenId) external view returns (uint256);

    /**
     * @dev Returns the maximum amount of tokens mintable for the tier.
     * @param tier The tier.
     * @return The configured value.
     */
    function maxMintable(uint8 tier) external view returns (uint32);

    /**
     * @dev Returns the upper bound for the maximum tokens that can be minted for the tier.
     * @param tier The tier.
     * @return The configured value.
     */
    function maxMintableUpper(uint8 tier) external view returns (uint32);

    /**
     * @dev Returns the lower bound for the maximum tokens that can be minted for the tier.
     * @param tier The tier.
     * @return The configured value.
     */
    function maxMintableLower(uint8 tier) external view returns (uint32);

    /**
     * @dev Returns the timestamp after which `maxMintable` drops from
     *      `maxMintableUpper` to `maxMintableLower`.
     * @param tier The tier.
     * @return The configured value.
     */
    function cutoffTime(uint8 tier) external view returns (uint32);

    /**
     * @dev Returns the number of tokens minted for the tier.
     * @param tier The tier.
     * @return The latest value.
     */
    function tierMinted(uint8 tier) external view returns (uint32);

    /**
     * @dev Returns the mint randomness for the tier.
     * @param tier The tier.
     * @return The latest value.
     */
    function mintRandomness(uint8 tier) external view returns (uint256);

    /**
     * @dev Returns the one-of-one token ID for the tier.
     * @param tier The tier.
     * @return The latest value.
     */
    function mintRandomnessOneOfOne(uint8 tier) external view returns (uint32);

    /**
     * @dev Returns whether the `mintRandomness` has been enabled.
     * @return The configured value.
     */
    function mintRandomnessEnabled(uint8 tier) external view returns (bool);

    /**
     * @dev Returns whether the mint has been concluded for the tier.
     * @param tier The tier.
     * @return The latest value.
     */
    function mintConcluded(uint8 tier) external view returns (bool);

    /**
     * @dev Returns the base token URI for the collection.
     * @return The configured value.
     */
    function baseURI() external view returns (string memory);

    /**
     * @dev Returns the contract URI to be used by Opensea.
     *      See: https://docs.opensea.io/docs/contract-level-metadata
     * @return The configured value.
     */
    function contractURI() external view returns (string memory);

    /**
     * @dev Returns the address of the funding recipient.
     * @return The configured value.
     */
    function fundingRecipient() external view returns (address);

    /**
     * @dev Returns the address of the metadata module.
     * @return The configured value.
     */
    function metadataModule() external view returns (address);

    /**
     * @dev Returns the royalty basis points.
     * @return The configured value.
     */
    function royaltyBPS() external view returns (uint16);

    /**
     * @dev Returns whether the tier is frozen.
     * @return The configured value.
     */
    function isFrozen(uint8 tier) external view returns (bool);

    /**
     * @dev Returns whether the metadata module is frozen.
     * @return The configured value.
     */
    function isMetadataFrozen() external view returns (bool);

    /**
     * @dev Returns whether the ability to create tiers is frozen.
     * @return The configured value.
     */
    function isCreateTierFrozen() external view returns (bool);

    /**
     * @dev Returns the next token ID to be minted.
     * @return The latest value.
     */
    function nextTokenId() external view returns (uint256);

    /**
     * @dev Returns the number of tokens minted by `owner`.
     * @param owner Address to query for number minted.
     * @return The latest value.
     */
    function numberMinted(address owner) external view returns (uint256);

    /**
     * @dev Returns the number of tokens burned by `owner`.
     * @param owner Address to query for number burned.
     * @return The latest value.
     */
    function numberBurned(address owner) external view returns (uint256);

    /**
     * @dev Returns the total amount of tokens minted.
     * @return The latest value.
     */
    function totalMinted() external view returns (uint256);

    /**
     * @dev Returns the total amount of tokens burned.
     * @return The latest value.
     */
    function totalBurned() external view returns (uint256);

    /**
     * @dev Returns the token URI of `tokenId`, but without reverting if
     *      the token does not exist.
     * @return The latest value.
     */
    function explicitTokenURI(uint256 tokenId) external view returns (string memory);

    /**
     * @dev Informs other contracts which interfaces this contract supports.
     *      Required by https://eips.ethereum.org/EIPS/eip-165
     * @param interfaceId The interface id to check.
     * @return Whether the `interfaceId` is supported.
     */
    function supportsInterface(bytes4 interfaceId)
        external
        view
        override(IERC721AUpgradeable, IERC165Upgradeable)
        returns (bool);
}

File 4 of 21 : ISuperMinter.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;

import { IERC165 } from "openzeppelin/utils/introspection/IERC165.sol";

/**
 * @title ISuperMinter
 * @notice The interface for the generalized minter.
 */
interface ISuperMinter is IERC165 {
    // =============================================================
    //                            STRUCTS
    // =============================================================

    /**
     * @dev A struct containing the arguments to create a mint.
     */
    struct MintCreation {
        // The edition address.
        address edition;
        // The base price per token.
        // For `VERIFY_SIGNATURE`, this will be the minimum limit of the signed price.
        // Will be 0 if the `tier` is `GA_TIER`.
        uint96 price;
        // The start time of the mint.
        uint32 startTime;
        // The end time of the mint.
        uint32 endTime;
        // The maximum number of tokens an account can mint in this mint.
        uint32 maxMintablePerAccount;
        // The maximum number of tokens mintable.
        uint32 maxMintable;
        // The affiliate fee BPS.
        uint16 affiliateFeeBPS;
        // The affiliate Merkle root, if any.
        bytes32 affiliateMerkleRoot;
        // The tier of the mint.
        uint8 tier;
        // The address of the platform.
        address platform;
        // The mode of the mint. Options: `DEFAULT`, `VERIFY_MERKLE`, `VERIFY_SIGNATURE`.
        uint8 mode;
        // The signer address, required if `mode` is `VERIFY_SIGNATURE`.
        // If set to `address(1)`, the platform signer will be used instead.
        address signer;
        // The Merkle root hash, required if `mode` is `VERIFY_MERKLE`.
        bytes32 merkleRoot;
    }

    /**
     * @dev A struct containing the arguments for mint-to.
     */
    struct MintTo {
        // The mint ID.
        address edition;
        // The tier of the mint.
        uint8 tier;
        // The edition-tier schedule number.
        uint8 scheduleNum;
        // The address to mint to.
        address to;
        // The number of tokens to mint.
        uint32 quantity;
        // The allowlisted address. Used if `mode` is `VERIFY_MERKLE`.
        address allowlisted;
        // The allowlisted quantity. Used if `mode` is `VERIFY_MERKLE`.
        // A default zero value means no limit.
        uint32 allowlistedQuantity;
        // The allowlist Merkle proof.
        bytes32[] allowlistProof;
        // The signed price. Used if `mode` is `VERIFY_SIGNATURE`.
        uint96 signedPrice;
        // The signed quantity. Used if `mode` is `VERIFY_SIGNATURE`.
        uint32 signedQuantity;
        // The signed claimed ticket. Used if `mode` is `VERIFY_SIGNATURE`.
        uint32 signedClaimTicket;
        // The expiry timestamp for the signature. Used if `mode` is `VERIFY_SIGNATURE`.
        uint32 signedDeadline;
        // The signature by the signer. Used if `mode` is `VERIFY_SIGNATURE`.
        bytes signature;
        // The affiliate address. Optional.
        address affiliate;
        // The Merkle proof for the affiliate.
        bytes32[] affiliateProof;
        // The attribution ID, optional.
        uint256 attributionId;
    }

    /**
     * @dev A struct containing the total prices and fees.
     */
    struct TotalPriceAndFees {
        // The required Ether value.
        // `subTotal + platformFlatFee`.
        uint256 total;
        // The total price before any additive fees.
        uint256 subTotal;
        // The price per token.
        uint256 unitPrice;
        // The total platform fees.
        // `platformFlatFee + platformMintBPSFee`.
        uint256 platformFee;
        // The total platform flat fees.
        // `platformTxFlatFee + platformMintFlatFee`.
        uint256 platformFlatFee;
        // The platform per-transaction flat fees.
        uint256 platformTxFlatFee;
        // The total platform per-token flat fees.
        uint256 platformMintFlatFee;
        // The total platform per-token BPS fees.
        uint256 platformMintBPSFee;
        // The total affiliate fees.
        uint256 affiliateFee;
    }

    /**
     * @dev A struct containing the log data for the `Minted` event.
     */
    struct MintedLogData {
        // The number of tokens minted.
        uint32 quantity;
        // The starting token ID minted.
        uint256 fromTokenId;
        // The allowlisted address.
        address allowlisted;
        // The allowlisted quantity.
        uint32 allowlistedQuantity;
        // The signed quantity.
        uint32 signedQuantity;
        // The signed claim ticket.
        uint32 signedClaimTicket;
        // The affiliate address.
        address affiliate;
        // Whether the affiliate address is affiliated.
        bool affiliated;
        // The total price paid, inclusive of all fees.
        uint256 requiredEtherValue;
        // The price per token.
        uint256 unitPrice;
        // The total platform fees.
        uint256 platformFee;
        // The total platform flat fees.
        uint256 platformFlatFee;
        // The total affiliate fees.
        uint256 affiliateFee;
    }

    /**
     * @dev A struct to hold the fee configuration for a platform and a tier.
     */
    struct PlatformFeeConfig {
        // The per-transaction flat fee.
        uint96 perTxFlat;
        // The per-token flat fee.
        uint96 perMintFlat;
        // The per-token fee BPS.
        uint16 perMintBPS;
        // Whether the fees are active.
        bool active;
    }

    /**
     * @dev A struct containing the mint information.
     */
    struct MintInfo {
        // The mint ID.
        address edition;
        // The tier of the mint.
        uint8 tier;
        // The edition-tier schedule number.
        uint8 scheduleNum;
        // The platform address.
        address platform;
        // The base price per token.
        // For `VERIFY_SIGNATURE` this will be the minimum limit of the signed price.
        // If the `tier` is `GA_TIER`, and the `mode` is NOT `VERIFY_SIGNATURE`,
        // this value will be the GA price instead.
        uint96 price;
        // The start time of the mint.
        uint32 startTime;
        // The end time of the mint.
        uint32 endTime;
        // The maximum number of tokens an account can mint in this mint.
        uint32 maxMintablePerAccount;
        // The maximum number of tokens mintable.
        uint32 maxMintable;
        // The total number of tokens minted.
        uint32 minted;
        // The affiliate fee BPS.
        uint16 affiliateFeeBPS;
        // The mode of the mint.
        uint8 mode;
        // Whether the mint is paused.
        bool paused;
        // Whether the mint already has mints.
        bool hasMints;
        // The affiliate Merkle root, if any.
        bytes32 affiliateMerkleRoot;
        // The Merkle root hash, required if `mode` is `VERIFY_MERKLE`.
        bytes32 merkleRoot;
        // The signer address, required if `mode` is `VERIFY_SIGNATURE`.
        // This value will be the platform signer instead if it is configured to be `address(1)`.
        address signer;
        // Whether the platform signer is being used instead
        // (i.e. `signer` configured to be `address(1)`).
        bool usePlatformSigner;
    }

    // =============================================================
    //                            EVENTS
    // =============================================================

    /**
     * @dev Emitted when a new mint is created.
     * @param edition       The address of the Sound Edition.
     * @param tier          The tier.
     * @param scheduleNum   The edition-tier schedule number.
     * @param creation      The mint creation struct.
     */
    event MintCreated(address indexed edition, uint8 tier, uint8 scheduleNum, MintCreation creation);

    /**
     * @dev Emitted when a mint is paused or un-paused.
     * @param edition       The address of the Sound Edition.
     * @param tier          The tier.
     * @param scheduleNum   The edition-tier schedule number.
     * @param paused        Whether the mint is paused.
     */
    event PausedSet(address indexed edition, uint8 tier, uint8 scheduleNum, bool paused);

    /**
     * @dev Emitted when the time range of a mint is updated.
     * @param edition       The address of the Sound Edition.
     * @param tier          The tier.
     * @param scheduleNum   The edition-tier schedule number.
     * @param startTime     The start time.
     * @param endTime       The end time.
     */
    event TimeRangeSet(address indexed edition, uint8 tier, uint8 scheduleNum, uint32 startTime, uint32 endTime);

    /**
     * @dev Emitted when the base per-token price of a mint is updated.
     * @param edition       The address of the Sound Edition.
     * @param tier          The tier.
     * @param scheduleNum   The edition-tier schedule number.
     * @param price         The base per-token price.
     */
    event PriceSet(address indexed edition, uint8 tier, uint8 scheduleNum, uint96 price);

    /**
     * @dev Emitted when the max mintable per account for a mint is updated.
     * @param edition       The address of the Sound Edition.
     * @param tier          The tier.
     * @param scheduleNum   The edition-tier schedule number.
     * @param value         The max mintable per account.
     */
    event MaxMintablePerAccountSet(address indexed edition, uint8 tier, uint8 scheduleNum, uint32 value);

    /**
     * @dev Emitted when the max mintable for a mint is updated.
     * @param edition       The address of the Sound Edition.
     * @param tier          The tier.
     * @param scheduleNum   The edition-tier schedule number.
     * @param value         The max mintable for the mint.
     */
    event MaxMintableSet(address indexed edition, uint8 tier, uint8 scheduleNum, uint32 value);

    /**
     * @dev Emitted when the Merkle root of a mint is updated.
     * @param edition       The address of the Sound Edition.
     * @param tier          The tier.
     * @param scheduleNum   The edition-tier schedule number.
     * @param merkleRoot    The Merkle root of the mint.
     */
    event MerkleRootSet(address indexed edition, uint8 tier, uint8 scheduleNum, bytes32 merkleRoot);

    /**
     * @dev Emitted when the signer of a mint is updated.
     * @param edition       The address of the Sound Edition.
     * @param tier          The tier.
     * @param scheduleNum   The edition-tier schedule number.
     * @param signer        The signer of the mint.
     */
    event SignerSet(address indexed edition, uint8 tier, uint8 scheduleNum, address signer);

    /**
     * @dev Emitted when the affiliate fee BPS for a mint is updated.
     * @param edition       The address of the Sound Edition.
     * @param tier          The tier.
     * @param scheduleNum   The edition-tier schedule number.
     * @param bps           The affiliate fee BPS.
     */
    event AffiliateFeeSet(address indexed edition, uint8 tier, uint8 scheduleNum, uint16 bps);

    /**
     * @dev Emitted when the affiliate Merkle root for a mint is updated.
     * @param edition       The address of the Sound Edition.
     * @param tier          The tier.
     * @param scheduleNum   The edition-tier schedule number.
     * @param root          The affiliate Merkle root hash.
     */
    event AffiliateMerkleRootSet(address indexed edition, uint8 tier, uint8 scheduleNum, bytes32 root);

    /**
     * @dev Emitted when tokens are minted.
     * @param edition       The address of the Sound Edition.
     * @param tier          The tier.
     * @param scheduleNum   The edition-tier schedule number.
     * @param to            The recipient of the tokens minted.
     * @param data          The mint-to log data.
     * @param attributionId The optional attribution ID.
     */
    event Minted(
        address indexed edition,
        uint8 tier,
        uint8 scheduleNum,
        address indexed to,
        MintedLogData data,
        uint256 indexed attributionId
    );

    /**
     * @dev Emitted when the platform fee configuration for `tier` is updated.
     * @param platform The platform address.
     * @param tier     The tier of the mint.
     * @param config   The platform fee configuration.
     */
    event PlatformFeeConfigSet(address indexed platform, uint8 tier, PlatformFeeConfig config);

    /**
     * @dev Emitted when the default platform fee configuration is updated.
     * @param platform The platform address.
     * @param config   The platform fee configuration.
     */
    event DefaultPlatformFeeConfigSet(address indexed platform, PlatformFeeConfig config);

    /**
     * @dev Emitted when affiliate fees are withdrawn.
     * @param affiliate The recipient of the fees.
     * @param accrued   The amount of Ether accrued and withdrawn.
     */
    event AffiliateFeesWithdrawn(address indexed affiliate, uint256 accrued);

    /**
     * @dev Emitted when platform fees are withdrawn.
     * @param platform  The platform address.
     * @param accrued   The amount of Ether accrued and withdrawn.
     */
    event PlatformFeesWithdrawn(address indexed platform, uint256 accrued);

    /**
     * @dev Emitted when the platform fee recipient address is updated.
     * @param platform  The platform address.
     * @param recipient The platform fee recipient address.
     */
    event PlatformFeeAddressSet(address indexed platform, address recipient);

    /**
     * @dev Emitted when the per-token price for the GA tier is set.
     * @param platform The platform address.
     * @param price    The price per token for the GA tier.
     */
    event GAPriceSet(address indexed platform, uint96 price);

    /**
     * @dev Emitted when the signer for a platform is set.
     * @param platform The platform address.
     * @param signer   The signer for the platform.
     */
    event PlatformSignerSet(address indexed platform, address signer);

    // =============================================================
    //                            ERRORS
    // =============================================================

    /**
     * @dev Exact payment required.
     * @param paid The amount of Ether paid.
     * @param required The amount of Ether required.
     */
    error WrongPayment(uint256 paid, uint256 required);

    /**
     * @dev The mint is not opened.
     * @param blockTimestamp The current block timestamp.
     * @param startTime      The opening time of the mint.
     * @param endTime        The closing time of the mint.
     */
    error MintNotOpen(uint256 blockTimestamp, uint32 startTime, uint32 endTime);

    /**
     * @dev The mint is paused.
     */
    error MintPaused();

    /**
     * @dev Cannot perform the operation when any mints exist.
     */
    error MintsAlreadyExist();

    /**
     * @dev The time range is invalid.
     */
    error InvalidTimeRange();

    /**
     * @dev The max mintable range is invalid.
     */
    error InvalidMaxMintableRange();

    /**
     * @dev The affiliate fee BPS cannot exceed the limit.
     */
    error InvalidAffiliateFeeBPS();

    /**
     * @dev The affiliate fee BPS cannot exceed the limit.
     */
    error InvalidPlatformFeeBPS();

    /**
     * @dev The affiliate fee BPS cannot exceed the limit.
     */
    error InvalidPlatformFlatFee();

    /**
     * @dev Cannot mint more than the maximum limit per account.
     */
    error ExceedsMaxPerAccount();

    /**
     * @dev Cannot mint more than the maximum supply.
     */
    error ExceedsMintSupply();

    /**
     * @dev Cannot mint more than the signed quantity.
     */
    error ExceedsSignedQuantity();

    /**
     * @dev The signature is invalid.
     */
    error InvalidSignature();

    /**
     * @dev The signature has expired.
     */
    error SignatureExpired();

    /**
     * @dev The signature claim ticket has already been used.
     */
    error SignatureAlreadyUsed();

    /**
     * @dev The signer cannot be the zero address.
     */
    error SignerIsZeroAddress();

    /**
     * @dev The Merkle root cannot be empty.
     */
    error MerkleRootIsEmpty();

    /**
     * @dev The Merkle proof is invalid.
     */
    error InvalidMerkleProof();

    /**
     * @dev The caller has not been delegated via delegate cash.
     */
    error CallerNotDelegated();

    /**
     * @dev The max mintable amount per account cannot be zero.
     */
    error MaxMintablePerAccountIsZero();

    /**
     * @dev The max mintable value cannot be zero.
     */
    error MaxMintableIsZero();

    /**
     * @dev The plaform fee address cannot be the zero address.
     */
    error PlatformFeeAddressIsZero();

    /**
     * @dev The mint does not exist.
     */
    error MintDoesNotExist();

    /**
     * @dev The affiliate provided is invalid.
     */
    error InvalidAffiliate();

    /**
     * @dev The mint mode provided is invalid.
     */
    error InvalidMode();

    /**
     * @dev The signed price is too low.
     */
    error SignedPriceTooLow();

    /**
     * @dev The platform fee configuration provided is invalid.
     */
    error InvalidPlatformFeeConfig();

    /**
     * @dev The parameter cannot be configured.
     */
    error NotConfigurable();

    // =============================================================
    //               PUBLIC / EXTERNAL WRITE FUNCTIONS
    // =============================================================

    /**
     * @dev Creates a mint.
     * @param c The mint creation struct.
     * @return scheduleNum The mint ID.
     */
    function createEditionMint(MintCreation calldata c) external returns (uint8 scheduleNum);

    /**
     * @dev Performs a mint.
     * @param p The mint-to parameters.
     */
    function mintTo(MintTo calldata p) external payable;

    /**
     * @dev Sets the price of the mint.
     * @param edition       The address of the Sound Edition.
     * @param tier          The tier.
     * @param scheduleNum   The edition-tier schedule number.
     * @param price         The price per token.
     */
    function setPrice(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        uint96 price
    ) external;

    /**
     * @dev Pause or unpase the the mint.
     * @param edition       The address of the Sound Edition.
     * @param tier          The tier.
     * @param scheduleNum   The edition-tier schedule number.
     * @param paused        Whether to pause the mint.
     */
    function setPaused(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        bool paused
    ) external;

    /**
     * @dev Sets the time range for the the mint.
     * @param edition       The address of the Sound Edition.
     * @param tier          The tier.
     * @param scheduleNum   The edition-tier schedule number.
     * @param startTime     The mint start time.
     * @param endTime       The mint end time.
     */
    function setTimeRange(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        uint32 startTime,
        uint32 endTime
    ) external;

    /**
     * @dev Sets the start time for the the mint.
     * @param edition       The address of the Sound Edition.
     * @param tier          The tier.
     * @param scheduleNum   The edition-tier schedule number.
     * @param startTime     The mint start time.
     */
    function setStartTime(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        uint32 startTime
    ) external;

    /**
     * @dev Sets the affiliate fee BPS for the mint.
     * @param edition       The address of the Sound Edition.
     * @param tier          The tier.
     * @param scheduleNum   The edition-tier schedule number.
     * @param bps           The fee BPS.
     */
    function setAffiliateFee(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        uint16 bps
    ) external;

    /**
     * @dev Sets the affiliate Merkle root for the mint.
     * @param edition       The address of the Sound Edition.
     * @param tier          The tier.
     * @param scheduleNum   The edition-tier schedule number.
     * @param root          The affiliate Merkle root.
     */
    function setAffiliateMerkleRoot(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        bytes32 root
    ) external;

    /**
     * @dev Sets the max mintable per account.
     * @param edition       The address of the Sound Edition.
     * @param tier          The tier.
     * @param scheduleNum   The edition-tier schedule number.
     * @param value         The max mintable per account.
     */
    function setMaxMintablePerAccount(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        uint32 value
    ) external;

    /**
     * @dev Sets the max mintable for the mint.
     * @param edition       The address of the Sound Edition.
     * @param tier          The tier.
     * @param scheduleNum   The edition-tier schedule number.
     * @param value         The max mintable for the mint.
     */
    function setMaxMintable(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        uint32 value
    ) external;

    /**
     * @dev Sets the mode for the mint. The mint mode must be `VERIFY_MERKLE`.
     * @param edition       The address of the Sound Edition.
     * @param tier          The tier.
     * @param scheduleNum   The edition-tier schedule number.
     * @param merkleRoot    The Merkle root of the mint.
     */
    function setMerkleRoot(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        bytes32 merkleRoot
    ) external;

    /**
     * @dev Sets the signer for the mint. The mint mode must be `VERIFY_SIGNATURE`.
     * @param edition       The address of the Sound Edition.
     * @param tier          The tier.
     * @param scheduleNum   The edition-tier schedule number.
     * @param signer        The signer of the mint.
     */
    function setSigner(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        address signer
    ) external;

    /**
     * @dev Withdraws all accrued fees of the affiliate, to the affiliate.
     * @param affiliate The affiliate address.
     */
    function withdrawForAffiliate(address affiliate) external;

    /**
     * @dev Withdraws all accrued fees of the platform, to the their fee address.
     * @param platform The platform address.
     */
    function withdrawForPlatform(address platform) external;

    /**
     * @dev Allows the caller, as a platform, to set their fee address
     * @param recipient The platform fee address of the caller.
     */
    function setPlatformFeeAddress(address recipient) external;

    /**
     * @dev Allows the caller, as a platform, to set their per-tier fee configuration.
     * @param tier The tier of the mint.
     * @param c    The platform fee configuration struct.
     */
    function setPlatformFeeConfig(uint8 tier, PlatformFeeConfig memory c) external;

    /**
     * @dev Allows the caller, as a platform, to set their default fee configuration.
     * @param c    The platform fee configuration struct.
     */
    function setDefaultPlatformFeeConfig(PlatformFeeConfig memory c) external;

    /**
     * @dev Allows the platform to set the price for the GA tier.
     * @param price The price per token for the GA tier.
     */
    function setGAPrice(uint96 price) external;

    /**
     * @dev Allows the platform to set their signer.
     * @param signer The signer for the platform.
     */
    function setPlatformSigner(address signer) external;

    // =============================================================
    //               PUBLIC / EXTERNAL VIEW FUNCTIONS
    // =============================================================

    /**
     * @dev Returns the GA tier. Which is 0.
     * @return The constant value.
     */
    function GA_TIER() external pure returns (uint8);

    /**
     * @dev The EIP-712 typehash for signed mints.
     * @return The constant value.
     */
    function MINT_TO_TYPEHASH() external pure returns (bytes32);

    /**
     * @dev The default mint mode.
     * @return The constant value.
     */
    function DEFAULT() external pure returns (uint8);

    /**
     * @dev The mint mode for Merkle drops.
     * @return The constant value.
     */
    function VERIFY_MERKLE() external pure returns (uint8);

    /**
     * @dev The mint mode for Merkle drops.
     * @return The constant value.
     */
    function VERIFY_SIGNATURE() external pure returns (uint8);

    /**
     * @dev The denominator used in BPS fee calculations.
     * @return The constant value.
     */
    function BPS_DENOMINATOR() external pure returns (uint16);

    /**
     * @dev The maximum affiliate fee BPS.
     * @return The constant value.
     */
    function MAX_AFFILIATE_FEE_BPS() external pure returns (uint16);

    /**
     * @dev The maximum per-mint platform fee BPS.
     * @return The constant value.
     */
    function MAX_PLATFORM_PER_MINT_FEE_BPS() external pure returns (uint16);

    /**
     * @dev The maximum platform per-mint flat fee.
     * @return The constant value.
     */
    function MAX_PLATFORM_PER_MINT_FLAT_FEE() external pure returns (uint96);

    /**
     * @dev The maximum platform per-transaction flat fee.
     * @return The constant value.
     */
    function MAX_PLATFORM_PER_TX_FLAT_FEE() external pure returns (uint96);

    /**
     * @dev Returns the amount of fees accrued by the platform.
     * @param platform The platform address.
     * @return The latest value.
     */
    function platformFeesAccrued(address platform) external view returns (uint256);

    /**
     * @dev Returns the fee recipient for the platform.
     * @param platform The platform address.
     * @return The configured value.
     */
    function platformFeeAddress(address platform) external view returns (address);

    /**
     * @dev Returns the amount of fees accrued by the affiliate.
     * @param affiliate The affiliate address.
     * @return The latest value.
     */
    function affiliateFeesAccrued(address affiliate) external view returns (uint256);

    /**
     * @dev Returns the EIP-712 digest of the mint-to data for signature mints.
     * @param p The mint-to parameters.
     * @return The computed value.
     */
    function computeMintToDigest(MintTo calldata p) external view returns (bytes32);

    /**
     * @dev Returns the total price and fees for the mint.
     * @param edition       The address of the Sound Edition.
     * @param tier          The tier.
     * @param scheduleNum   The edition-tier schedule number.
     * @param quantity      How many tokens to mint.
     * @return A struct containing the total price and fees.
     */
    function totalPriceAndFees(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        uint32 quantity
    ) external view returns (TotalPriceAndFees memory);

    /**
     * @dev Returns the total price and fees for the mint.
     * @param edition       The address of the Sound Edition.
     * @param tier          The tier.
     * @param scheduleNum   The edition-tier schedule number.
     * @param quantity      How many tokens to mint.
     * @param signedPrice   The signed price.
     * @return A struct containing the total price and fees.
     */
    function totalPriceAndFeesWithSignedPrice(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        uint32 quantity,
        uint96 signedPrice
    ) external view returns (TotalPriceAndFees memory);

    /**
     * @dev Returns the GA price for the platform.
     * @param platform The platform address.
     * @return The configured value.
     */
    function gaPrice(address platform) external view returns (uint96);

    /**
     * @dev Returns the signer for the platform.
     * @param platform The platform address.
     * @return The configured value.
     */
    function platformSigner(address platform) external view returns (address);

    /**
     * @dev Returns the next mint schedule number for the edition-tier.
     * @param edition The Sound Edition address.
     * @param tier    The tier.
     * @return The next schedule number for the edition-tier.
     */
    function nextScheduleNum(address edition, uint8 tier) external view returns (uint8);

    /**
     * @dev Returns the number of tokens minted by `collector` for the mint.
     * @param edition       The address of the Sound Edition.
     * @param tier          The tier.
     * @param scheduleNum   The edition-tier schedule number.
     * @param collector     The address which tokens are minted to,
     *                      or in the case of `VERIFY_MERKLE`, is the allowlisted address.
     * @return The number of tokens minted.
     */
    function numberMinted(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        address collector
    ) external view returns (uint32);

    /**
     * @dev Returns whether the affiliate is affiliated for the mint
     * @param edition        The address of the Sound Edition.
     * @param tier           The tier.
     * @param scheduleNum    The edition-tier schedule number.
     * @param affiliate      The affiliate address.
     * @param affiliateProof The Merkle proof for the affiliate.
     * @return The result.
     */
    function isAffiliatedWithProof(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        address affiliate,
        bytes32[] calldata affiliateProof
    ) external view returns (bool);

    /**
     * @dev Returns whether the affiliate is affiliated for the mint.
     * @param edition       The address of the Sound Edition.
     * @param tier          The tier.
     * @param scheduleNum   The edition-tier schedule number.
     * @param affiliate     The affiliate address.
     * @return A boolean on whether the affiliate is affiliated for the mint.
     */
    function isAffiliated(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        address affiliate
    ) external view returns (bool);

    /**
     * @dev Returns whether the claim tickets have been used.
     * @param edition       The address of the Sound Edition.
     * @param tier          The tier.
     * @param scheduleNum   The edition-tier schedule number.
     * @param claimTickets  An array of claim tickets.
     * @return An array of bools, where true means that a ticket has been used.
     */
    function checkClaimTickets(
        address edition,
        uint8 tier,
        uint8 scheduleNum,
        uint32[] calldata claimTickets
    ) external view returns (bool[] memory);

    /**
     * @dev Returns the platform fee configuration for the tier.
     * @param platform The platform address.
     * @param tier     The tier of the mint.
     * @return The platform fee configuration struct.
     */
    function platformFeeConfig(address platform, uint8 tier) external view returns (PlatformFeeConfig memory);

    /**
     * @dev Returns the default platform fee configuration.
     * @param platform The platform address.
     * @return The platform fee configuration struct.
     */
    function defaultPlatformFeeConfig(address platform) external view returns (PlatformFeeConfig memory);

    /**
     * @dev Returns the effective platform fee configuration.
     * @param platform The platform address.
     * @param tier     The tier of the mint.
     * @return The platform fee configuration struct.
     */
    function effectivePlatformFeeConfig(address platform, uint8 tier) external view returns (PlatformFeeConfig memory);

    /**
     * @dev Returns an array of mint information structs pertaining to the mint.
     * @param edition The Sound Edition address.
     * @return An array of mint information structs.
     */
    function mintInfoList(address edition) external view returns (MintInfo[] memory);

    /**
     * @dev Returns information pertaining to the mint.
     * @param edition       The address of the Sound Edition.
     * @param tier          The tier.
     * @param scheduleNum   The edition-tier schedule number.
     * @return The mint info struct.
     */
    function mintInfo(
        address edition,
        uint8 tier,
        uint8 scheduleNum
    ) external view returns (MintInfo memory);

    /**
     * @dev Retuns the EIP-712 name for the contract.
     * @return The constant value.
     */
    function name() external pure returns (string memory);

    /**
     * @dev Retuns the EIP-712 version for the contract.
     * @return The constant value.
     */
    function version() external pure returns (string memory);
}

File 5 of 21 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 6 of 21 : SafeTransferLib.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
///
/// @dev Note:
/// - For ETH transfers, please use `forceSafeTransferETH` for DoS protection.
/// - For ERC20s, this implementation won't check that a token has code,
///   responsibility is delegated to the caller.
library SafeTransferLib {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       CUSTOM ERRORS                        */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The ETH transfer has failed.
    error ETHTransferFailed();

    /// @dev The ERC20 `transferFrom` has failed.
    error TransferFromFailed();

    /// @dev The ERC20 `transfer` has failed.
    error TransferFailed();

    /// @dev The ERC20 `approve` has failed.
    error ApproveFailed();

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         CONSTANTS                          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Suggested gas stipend for contract receiving ETH that disallows any storage writes.
    uint256 internal constant GAS_STIPEND_NO_STORAGE_WRITES = 2300;

    /// @dev Suggested gas stipend for contract receiving ETH to perform a few
    /// storage reads and writes, but low enough to prevent griefing.
    uint256 internal constant GAS_STIPEND_NO_GRIEF = 100000;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       ETH OPERATIONS                       */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    // If the ETH transfer MUST succeed with a reasonable gas budget, use the force variants.
    //
    // The regular variants:
    // - Forwards all remaining gas to the target.
    // - Reverts if the target reverts.
    // - Reverts if the current contract has insufficient balance.
    //
    // The force variants:
    // - Forwards with an optional gas stipend
    //   (defaults to `GAS_STIPEND_NO_GRIEF`, which is sufficient for most cases).
    // - If the target reverts, or if the gas stipend is exhausted,
    //   creates a temporary contract to force send the ETH via `SELFDESTRUCT`.
    //   Future compatible with `SENDALL`: https://eips.ethereum.org/EIPS/eip-4758.
    // - Reverts if the current contract has insufficient balance.
    //
    // The try variants:
    // - Forwards with a mandatory gas stipend.
    // - Instead of reverting, returns whether the transfer succeeded.

    /// @dev Sends `amount` (in wei) ETH to `to`.
    function safeTransferETH(address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(call(gas(), to, amount, gas(), 0x00, gas(), 0x00)) {
                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
                revert(0x1c, 0x04)
            }
        }
    }

    /// @dev Sends all the ETH in the current contract to `to`.
    function safeTransferAllETH(address to) internal {
        /// @solidity memory-safe-assembly
        assembly {
            // Transfer all the ETH and check if it succeeded or not.
            if iszero(call(gas(), to, selfbalance(), gas(), 0x00, gas(), 0x00)) {
                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
                revert(0x1c, 0x04)
            }
        }
    }

    /// @dev Force sends `amount` (in wei) ETH to `to`, with a `gasStipend`.
    function forceSafeTransferETH(address to, uint256 amount, uint256 gasStipend) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if lt(selfbalance(), amount) {
                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
                revert(0x1c, 0x04)
            }
            if iszero(call(gasStipend, to, amount, gas(), 0x00, gas(), 0x00)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                if iszero(create(amount, 0x0b, 0x16)) {
                    returndatacopy(gas(), returndatasize(), shr(20, gas())) // For gas estimation.
                }
            }
        }
    }

    /// @dev Force sends all the ETH in the current contract to `to`, with a `gasStipend`.
    function forceSafeTransferAllETH(address to, uint256 gasStipend) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(call(gasStipend, to, selfbalance(), gas(), 0x00, gas(), 0x00)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                if iszero(create(selfbalance(), 0x0b, 0x16)) {
                    returndatacopy(gas(), returndatasize(), shr(20, gas())) // For gas estimation.
                }
            }
        }
    }

    /// @dev Force sends `amount` (in wei) ETH to `to`, with `GAS_STIPEND_NO_GRIEF`.
    function forceSafeTransferETH(address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if lt(selfbalance(), amount) {
                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
                revert(0x1c, 0x04)
            }
            if iszero(call(GAS_STIPEND_NO_GRIEF, to, amount, gas(), 0x00, gas(), 0x00)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                if iszero(create(amount, 0x0b, 0x16)) {
                    returndatacopy(gas(), returndatasize(), shr(20, gas())) // For gas estimation.
                }
            }
        }
    }

    /// @dev Force sends all the ETH in the current contract to `to`, with `GAS_STIPEND_NO_GRIEF`.
    function forceSafeTransferAllETH(address to) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(call(GAS_STIPEND_NO_GRIEF, to, selfbalance(), gas(), 0x00, gas(), 0x00)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                if iszero(create(selfbalance(), 0x0b, 0x16)) {
                    returndatacopy(gas(), returndatasize(), shr(20, gas())) // For gas estimation.
                }
            }
        }
    }

    /// @dev Sends `amount` (in wei) ETH to `to`, with a `gasStipend`.
    function trySafeTransferETH(address to, uint256 amount, uint256 gasStipend)
        internal
        returns (bool success)
    {
        /// @solidity memory-safe-assembly
        assembly {
            success := call(gasStipend, to, amount, gas(), 0x00, gas(), 0x00)
        }
    }

    /// @dev Sends all the ETH in the current contract to `to`, with a `gasStipend`.
    function trySafeTransferAllETH(address to, uint256 gasStipend)
        internal
        returns (bool success)
    {
        /// @solidity memory-safe-assembly
        assembly {
            success := call(gasStipend, to, selfbalance(), gas(), 0x00, gas(), 0x00)
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                      ERC20 OPERATIONS                      */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Sends `amount` of ERC20 `token` from `from` to `to`.
    /// Reverts upon failure.
    ///
    /// The `from` account must have at least `amount` approved for
    /// the current contract to manage.
    function safeTransferFrom(address token, address from, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40) // Cache the free memory pointer.
            mstore(0x60, amount) // Store the `amount` argument.
            mstore(0x40, to) // Store the `to` argument.
            mstore(0x2c, shl(96, from)) // Store the `from` argument.
            mstore(0x0c, 0x23b872dd000000000000000000000000) // `transferFrom(address,address,uint256)`.
            // Perform the transfer, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x60, 0) // Restore the zero slot to zero.
            mstore(0x40, m) // Restore the free memory pointer.
        }
    }

    /// @dev Sends all of ERC20 `token` from `from` to `to`.
    /// Reverts upon failure.
    ///
    /// The `from` account must have their entire balance approved for
    /// the current contract to manage.
    function safeTransferAllFrom(address token, address from, address to)
        internal
        returns (uint256 amount)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40) // Cache the free memory pointer.
            mstore(0x40, to) // Store the `to` argument.
            mstore(0x2c, shl(96, from)) // Store the `from` argument.
            mstore(0x0c, 0x70a08231000000000000000000000000) // `balanceOf(address)`.
            // Read the balance, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    gt(returndatasize(), 0x1f), // At least 32 bytes returned.
                    staticcall(gas(), token, 0x1c, 0x24, 0x60, 0x20)
                )
            ) {
                mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x00, 0x23b872dd) // `transferFrom(address,address,uint256)`.
            amount := mload(0x60) // The `amount` is already at 0x60. We'll need to return it.
            // Perform the transfer, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x60, 0) // Restore the zero slot to zero.
            mstore(0x40, m) // Restore the free memory pointer.
        }
    }

    /// @dev Sends `amount` of ERC20 `token` from the current contract to `to`.
    /// Reverts upon failure.
    function safeTransfer(address token, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, to) // Store the `to` argument.
            mstore(0x34, amount) // Store the `amount` argument.
            mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`.
            // Perform the transfer, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    /// @dev Sends all of ERC20 `token` from the current contract to `to`.
    /// Reverts upon failure.
    function safeTransferAll(address token, address to) internal returns (uint256 amount) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, 0x70a08231) // Store the function selector of `balanceOf(address)`.
            mstore(0x20, address()) // Store the address of the current contract.
            // Read the balance, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    gt(returndatasize(), 0x1f), // At least 32 bytes returned.
                    staticcall(gas(), token, 0x1c, 0x24, 0x34, 0x20)
                )
            ) {
                mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x14, to) // Store the `to` argument.
            amount := mload(0x34) // The `amount` is already at 0x34. We'll need to return it.
            mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`.
            // Perform the transfer, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.
    /// Reverts upon failure.
    function safeApprove(address token, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, to) // Store the `to` argument.
            mstore(0x34, amount) // Store the `amount` argument.
            mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
            // Perform the approval, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.
    /// If the initial attempt to approve fails, attempts to reset the approved amount to zero,
    /// then retries the approval again (some tokens, e.g. USDT, requires this).
    /// Reverts upon failure.
    function safeApproveWithRetry(address token, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, to) // Store the `to` argument.
            mstore(0x34, amount) // Store the `amount` argument.
            mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
            // Perform the approval, retrying upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                )
            ) {
                mstore(0x34, 0) // Store 0 for the `amount`.
                mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
                pop(call(gas(), token, 0, 0x10, 0x44, 0x00, 0x00)) // Reset the approval.
                mstore(0x34, amount) // Store back the original `amount`.
                // Retry the approval, reverting upon failure.
                if iszero(
                    and(
                        or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                        call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                    )
                ) {
                    mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`.
                    revert(0x1c, 0x04)
                }
            }
            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    /// @dev Returns the amount of ERC20 `token` owned by `account`.
    /// Returns zero if the `token` does not exist.
    function balanceOf(address token, address account) internal view returns (uint256 amount) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, account) // Store the `account` argument.
            mstore(0x00, 0x70a08231000000000000000000000000) // `balanceOf(address)`.
            amount :=
                mul(
                    mload(0x20),
                    and( // The arguments of `and` are evaluated from right to left.
                        gt(returndatasize(), 0x1f), // At least 32 bytes returned.
                        staticcall(gas(), token, 0x10, 0x24, 0x20, 0x20)
                    )
                )
        }
    }
}

File 7 of 21 : EIP712.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Contract for EIP-712 typed structured data hashing and signing.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/EIP712.sol)
/// @author Modified from Solbase (https://github.com/Sol-DAO/solbase/blob/main/src/utils/EIP712.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/EIP712.sol)
///
/// @dev Note, this implementation:
/// - Uses `address(this)` for the `verifyingContract` field.
/// - Does NOT use the optional EIP-712 salt.
/// - Does NOT use any EIP-712 extensions.
/// This is for simplicity and to save gas.
/// If you need to customize, please fork / modify accordingly.
abstract contract EIP712 {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                  CONSTANTS AND IMMUTABLES                  */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev `keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")`.
    bytes32 internal constant _DOMAIN_TYPEHASH =
        0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;

    address private immutable _cachedThis;
    uint256 private immutable _cachedChainId;
    bytes32 private immutable _cachedNameHash;
    bytes32 private immutable _cachedVersionHash;
    bytes32 private immutable _cachedDomainSeparator;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                        CONSTRUCTOR                         */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Cache the hashes for cheaper runtime gas costs.
    /// In the case of upgradeable contracts (i.e. proxies),
    /// or if the chain id changes due to a hard fork,
    /// the domain separator will be seamlessly calculated on-the-fly.
    constructor() {
        _cachedThis = address(this);
        _cachedChainId = block.chainid;

        string memory name;
        string memory version;
        if (!_domainNameAndVersionMayChange()) (name, version) = _domainNameAndVersion();
        bytes32 nameHash = _domainNameAndVersionMayChange() ? bytes32(0) : keccak256(bytes(name));
        bytes32 versionHash =
            _domainNameAndVersionMayChange() ? bytes32(0) : keccak256(bytes(version));
        _cachedNameHash = nameHash;
        _cachedVersionHash = versionHash;

        bytes32 separator;
        if (!_domainNameAndVersionMayChange()) {
            /// @solidity memory-safe-assembly
            assembly {
                let m := mload(0x40) // Load the free memory pointer.
                mstore(m, _DOMAIN_TYPEHASH)
                mstore(add(m, 0x20), nameHash)
                mstore(add(m, 0x40), versionHash)
                mstore(add(m, 0x60), chainid())
                mstore(add(m, 0x80), address())
                separator := keccak256(m, 0xa0)
            }
        }
        _cachedDomainSeparator = separator;
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                   FUNCTIONS TO OVERRIDE                    */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Please override this function to return the domain name and version.
    /// ```
    ///     function _domainNameAndVersion()
    ///         internal
    ///         pure
    ///         virtual
    ///         returns (string memory name, string memory version)
    ///     {
    ///         name = "Solady";
    ///         version = "1";
    ///     }
    /// ```
    ///
    /// Note: If the returned result may change after the contract has been deployed,
    /// you must override `_domainNameAndVersionMayChange()` to return true.
    function _domainNameAndVersion()
        internal
        view
        virtual
        returns (string memory name, string memory version);

    /// @dev Returns if `_domainNameAndVersion()` may change
    /// after the contract has been deployed (i.e. after the constructor).
    /// Default: false.
    function _domainNameAndVersionMayChange() internal pure virtual returns (bool result) {}

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                     HASHING OPERATIONS                     */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns the EIP-712 domain separator.
    function _domainSeparator() internal view virtual returns (bytes32 separator) {
        if (_domainNameAndVersionMayChange()) {
            separator = _buildDomainSeparator();
        } else {
            separator = _cachedDomainSeparator;
            if (_cachedDomainSeparatorInvalidated()) separator = _buildDomainSeparator();
        }
    }

    /// @dev Returns the hash of the fully encoded EIP-712 message for this domain,
    /// given `structHash`, as defined in
    /// https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct.
    ///
    /// The hash can be used together with {ECDSA-recover} to obtain the signer of a message:
    /// ```
    ///     bytes32 digest = _hashTypedData(keccak256(abi.encode(
    ///         keccak256("Mail(address to,string contents)"),
    ///         mailTo,
    ///         keccak256(bytes(mailContents))
    ///     )));
    ///     address signer = ECDSA.recover(digest, signature);
    /// ```
    function _hashTypedData(bytes32 structHash) internal view virtual returns (bytes32 digest) {
        bytes32 separator;
        if (_domainNameAndVersionMayChange()) {
            separator = _buildDomainSeparator();
        } else {
            separator = _cachedDomainSeparator;
            if (_cachedDomainSeparatorInvalidated()) separator = _buildDomainSeparator();
        }
        /// @solidity memory-safe-assembly
        assembly {
            // Compute the digest.
            mstore(0x00, 0x1901000000000000) // Store "\x19\x01".
            mstore(0x1a, separator) // Store the domain separator.
            mstore(0x3a, structHash) // Store the struct hash.
            digest := keccak256(0x18, 0x42)
            // Restore the part of the free memory slot that was overwritten.
            mstore(0x3a, 0)
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                    EIP-5267 OPERATIONS                     */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev See: https://eips.ethereum.org/EIPS/eip-5267
    function eip712Domain()
        public
        view
        virtual
        returns (
            bytes1 fields,
            string memory name,
            string memory version,
            uint256 chainId,
            address verifyingContract,
            bytes32 salt,
            uint256[] memory extensions
        )
    {
        fields = hex"0f"; // `0b01111`.
        (name, version) = _domainNameAndVersion();
        chainId = block.chainid;
        verifyingContract = address(this);
        salt = salt; // `bytes32(0)`.
        extensions = extensions; // `new uint256[](0)`.
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                      PRIVATE HELPERS                       */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns the EIP-712 domain separator.
    function _buildDomainSeparator() private view returns (bytes32 separator) {
        bytes32 nameHash;
        bytes32 versionHash;
        if (_domainNameAndVersionMayChange()) {
            (string memory name, string memory version) = _domainNameAndVersion();
            nameHash = keccak256(bytes(name));
            versionHash = keccak256(bytes(version));
        } else {
            nameHash = _cachedNameHash;
            versionHash = _cachedVersionHash;
        }
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40) // Load the free memory pointer.
            mstore(m, _DOMAIN_TYPEHASH)
            mstore(add(m, 0x20), nameHash)
            mstore(add(m, 0x40), versionHash)
            mstore(add(m, 0x60), chainid())
            mstore(add(m, 0x80), address())
            separator := keccak256(m, 0xa0)
        }
    }

    /// @dev Returns if the cached domain separator has been invalidated.
    function _cachedDomainSeparatorInvalidated() private view returns (bool result) {
        uint256 cachedChainId = _cachedChainId;
        address cachedThis = _cachedThis;
        /// @solidity memory-safe-assembly
        assembly {
            result := iszero(and(eq(chainid(), cachedChainId), eq(address(), cachedThis)))
        }
    }
}

File 8 of 21 : MerkleProofLib.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Gas optimized verification of proof of inclusion for a leaf in a Merkle tree.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/MerkleProofLib.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/MerkleProofLib.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/MerkleProof.sol)
library MerkleProofLib {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*            MERKLE PROOF VERIFICATION OPERATIONS            */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns whether `leaf` exists in the Merkle tree with `root`, given `proof`.
    function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf)
        internal
        pure
        returns (bool isValid)
    {
        /// @solidity memory-safe-assembly
        assembly {
            if mload(proof) {
                // Initialize `offset` to the offset of `proof` elements in memory.
                let offset := add(proof, 0x20)
                // Left shift by 5 is equivalent to multiplying by 0x20.
                let end := add(offset, shl(5, mload(proof)))
                // Iterate over proof elements to compute root hash.
                for {} 1 {} {
                    // Slot of `leaf` in scratch space.
                    // If the condition is true: 0x20, otherwise: 0x00.
                    let scratch := shl(5, gt(leaf, mload(offset)))
                    // Store elements to hash contiguously in scratch space.
                    // Scratch space is 64 bytes (0x00 - 0x3f) and both elements are 32 bytes.
                    mstore(scratch, leaf)
                    mstore(xor(scratch, 0x20), mload(offset))
                    // Reuse `leaf` to store the hash to reduce stack operations.
                    leaf := keccak256(0x00, 0x40)
                    offset := add(offset, 0x20)
                    if iszero(lt(offset, end)) { break }
                }
            }
            isValid := eq(leaf, root)
        }
    }

    /// @dev Returns whether `leaf` exists in the Merkle tree with `root`, given `proof`.
    function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf)
        internal
        pure
        returns (bool isValid)
    {
        /// @solidity memory-safe-assembly
        assembly {
            if proof.length {
                // Left shift by 5 is equivalent to multiplying by 0x20.
                let end := add(proof.offset, shl(5, proof.length))
                // Initialize `offset` to the offset of `proof` in the calldata.
                let offset := proof.offset
                // Iterate over proof elements to compute root hash.
                for {} 1 {} {
                    // Slot of `leaf` in scratch space.
                    // If the condition is true: 0x20, otherwise: 0x00.
                    let scratch := shl(5, gt(leaf, calldataload(offset)))
                    // Store elements to hash contiguously in scratch space.
                    // Scratch space is 64 bytes (0x00 - 0x3f) and both elements are 32 bytes.
                    mstore(scratch, leaf)
                    mstore(xor(scratch, 0x20), calldataload(offset))
                    // Reuse `leaf` to store the hash to reduce stack operations.
                    leaf := keccak256(0x00, 0x40)
                    offset := add(offset, 0x20)
                    if iszero(lt(offset, end)) { break }
                }
            }
            isValid := eq(leaf, root)
        }
    }

    /// @dev Returns whether all `leaves` exist in the Merkle tree with `root`,
    /// given `proof` and `flags`.
    ///
    /// Note:
    /// - Breaking the invariant `flags.length == (leaves.length - 1) + proof.length`
    ///   will always return false.
    /// - The sum of the lengths of `proof` and `leaves` must never overflow.
    /// - Any non-zero word in the `flags` array is treated as true.
    /// - The memory offset of `proof` must be be non-zero
    ///   (i.e. `proof` is not pointing to the scratch space).
    function verifyMultiProof(
        bytes32[] memory proof,
        bytes32 root,
        bytes32[] memory leaves,
        bool[] memory flags
    ) internal pure returns (bool isValid) {
        // Rebuilds the root by consuming and producing values on a queue.
        // The queue starts with the `leaves` array, and goes into a `hashes` array.
        // After the process, the last element on the queue is verified
        // to be equal to the `root`.
        //
        // The `flags` array denotes whether the sibling
        // should be popped from the queue (`flag == true`), or
        // should be popped from the `proof` (`flag == false`).
        /// @solidity memory-safe-assembly
        assembly {
            // Cache the lengths of the arrays.
            let leavesLength := mload(leaves)
            let proofLength := mload(proof)
            let flagsLength := mload(flags)

            // Advance the pointers of the arrays to point to the data.
            leaves := add(0x20, leaves)
            proof := add(0x20, proof)
            flags := add(0x20, flags)

            // If the number of flags is correct.
            for {} eq(add(leavesLength, proofLength), add(flagsLength, 1)) {} {
                // For the case where `proof.length + leaves.length == 1`.
                if iszero(flagsLength) {
                    // `isValid = (proof.length == 1 ? proof[0] : leaves[0]) == root`.
                    isValid := eq(mload(xor(leaves, mul(xor(proof, leaves), proofLength))), root)
                    break
                }

                // The required final proof offset if `flagsLength` is not zero, otherwise zero.
                let proofEnd := add(proof, shl(5, proofLength))
                // We can use the free memory space for the queue.
                // We don't need to allocate, since the queue is temporary.
                let hashesFront := mload(0x40)
                // Copy the leaves into the hashes.
                // Sometimes, a little memory expansion costs less than branching.
                // Should cost less, even with a high free memory offset of 0x7d00.
                leavesLength := shl(5, leavesLength)
                for { let i := 0 } iszero(eq(i, leavesLength)) { i := add(i, 0x20) } {
                    mstore(add(hashesFront, i), mload(add(leaves, i)))
                }
                // Compute the back of the hashes.
                let hashesBack := add(hashesFront, leavesLength)
                // This is the end of the memory for the queue.
                // We recycle `flagsLength` to save on stack variables (sometimes save gas).
                flagsLength := add(hashesBack, shl(5, flagsLength))

                for {} 1 {} {
                    // Pop from `hashes`.
                    let a := mload(hashesFront)
                    // Pop from `hashes`.
                    let b := mload(add(hashesFront, 0x20))
                    hashesFront := add(hashesFront, 0x40)

                    // If the flag is false, load the next proof,
                    // else, pops from the queue.
                    if iszero(mload(flags)) {
                        // Loads the next proof.
                        b := mload(proof)
                        proof := add(proof, 0x20)
                        // Unpop from `hashes`.
                        hashesFront := sub(hashesFront, 0x20)
                    }

                    // Advance to the next flag.
                    flags := add(flags, 0x20)

                    // Slot of `a` in scratch space.
                    // If the condition is true: 0x20, otherwise: 0x00.
                    let scratch := shl(5, gt(a, b))
                    // Hash the scratch space and push the result onto the queue.
                    mstore(scratch, a)
                    mstore(xor(scratch, 0x20), b)
                    mstore(hashesBack, keccak256(0x00, 0x40))
                    hashesBack := add(hashesBack, 0x20)
                    if iszero(lt(hashesBack, flagsLength)) { break }
                }
                isValid :=
                    and(
                        // Checks if the last value in the queue is same as the root.
                        eq(mload(sub(hashesBack, 0x20)), root),
                        // And whether all the proofs are used, if required.
                        eq(proofEnd, proof)
                    )
                break
            }
        }
    }

    /// @dev Returns whether all `leaves` exist in the Merkle tree with `root`,
    /// given `proof` and `flags`.
    ///
    /// Note:
    /// - Breaking the invariant `flags.length == (leaves.length - 1) + proof.length`
    ///   will always return false.
    /// - Any non-zero word in the `flags` array is treated as true.
    /// - The calldata offset of `proof` must be non-zero
    ///   (i.e. `proof` is from a regular Solidity function with a 4-byte selector).
    function verifyMultiProofCalldata(
        bytes32[] calldata proof,
        bytes32 root,
        bytes32[] calldata leaves,
        bool[] calldata flags
    ) internal pure returns (bool isValid) {
        // Rebuilds the root by consuming and producing values on a queue.
        // The queue starts with the `leaves` array, and goes into a `hashes` array.
        // After the process, the last element on the queue is verified
        // to be equal to the `root`.
        //
        // The `flags` array denotes whether the sibling
        // should be popped from the queue (`flag == true`), or
        // should be popped from the `proof` (`flag == false`).
        /// @solidity memory-safe-assembly
        assembly {
            // If the number of flags is correct.
            for {} eq(add(leaves.length, proof.length), add(flags.length, 1)) {} {
                // For the case where `proof.length + leaves.length == 1`.
                if iszero(flags.length) {
                    // `isValid = (proof.length == 1 ? proof[0] : leaves[0]) == root`.
                    // forgefmt: disable-next-item
                    isValid := eq(
                        calldataload(
                            xor(leaves.offset, mul(xor(proof.offset, leaves.offset), proof.length))
                        ),
                        root
                    )
                    break
                }

                // The required final proof offset if `flagsLength` is not zero, otherwise zero.
                let proofEnd := add(proof.offset, shl(5, proof.length))
                // We can use the free memory space for the queue.
                // We don't need to allocate, since the queue is temporary.
                let hashesFront := mload(0x40)
                // Copy the leaves into the hashes.
                // Sometimes, a little memory expansion costs less than branching.
                // Should cost less, even with a high free memory offset of 0x7d00.
                calldatacopy(hashesFront, leaves.offset, shl(5, leaves.length))
                // Compute the back of the hashes.
                let hashesBack := add(hashesFront, shl(5, leaves.length))
                // This is the end of the memory for the queue.
                // We recycle `flagsLength` to save on stack variables (sometimes save gas).
                flags.length := add(hashesBack, shl(5, flags.length))

                // We don't need to make a copy of `proof.offset` or `flags.offset`,
                // as they are pass-by-value (this trick may not always save gas).

                for {} 1 {} {
                    // Pop from `hashes`.
                    let a := mload(hashesFront)
                    // Pop from `hashes`.
                    let b := mload(add(hashesFront, 0x20))
                    hashesFront := add(hashesFront, 0x40)

                    // If the flag is false, load the next proof,
                    // else, pops from the queue.
                    if iszero(calldataload(flags.offset)) {
                        // Loads the next proof.
                        b := calldataload(proof.offset)
                        proof.offset := add(proof.offset, 0x20)
                        // Unpop from `hashes`.
                        hashesFront := sub(hashesFront, 0x20)
                    }

                    // Advance to the next flag offset.
                    flags.offset := add(flags.offset, 0x20)

                    // Slot of `a` in scratch space.
                    // If the condition is true: 0x20, otherwise: 0x00.
                    let scratch := shl(5, gt(a, b))
                    // Hash the scratch space and push the result onto the queue.
                    mstore(scratch, a)
                    mstore(xor(scratch, 0x20), b)
                    mstore(hashesBack, keccak256(0x00, 0x40))
                    hashesBack := add(hashesBack, 0x20)
                    if iszero(lt(hashesBack, flags.length)) { break }
                }
                isValid :=
                    and(
                        // Checks if the last value in the queue is same as the root.
                        eq(mload(sub(hashesBack, 0x20)), root),
                        // And whether all the proofs are used, if required.
                        eq(proofEnd, proof.offset)
                    )
                break
            }
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                   EMPTY CALLDATA HELPERS                   */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns an empty calldata bytes32 array.
    function emptyProof() internal pure returns (bytes32[] calldata proof) {
        /// @solidity memory-safe-assembly
        assembly {
            proof.length := 0
        }
    }

    /// @dev Returns an empty calldata bytes32 array.
    function emptyLeaves() internal pure returns (bytes32[] calldata leaves) {
        /// @solidity memory-safe-assembly
        assembly {
            leaves.length := 0
        }
    }

    /// @dev Returns an empty calldata bool array.
    function emptyFlags() internal pure returns (bool[] calldata flags) {
        /// @solidity memory-safe-assembly
        assembly {
            flags.length := 0
        }
    }
}

File 9 of 21 : LibBitmap.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import {LibBit} from "./LibBit.sol";

/// @notice Library for storage of packed unsigned booleans.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibBitmap.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibBitmap.sol)
/// @author Modified from Solidity-Bits (https://github.com/estarriolvetch/solidity-bits/blob/main/contracts/BitMaps.sol)
library LibBitmap {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         CONSTANTS                          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The constant returned when a bitmap scan does not find a result.
    uint256 internal constant NOT_FOUND = type(uint256).max;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                          STRUCTS                           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev A bitmap in storage.
    struct Bitmap {
        mapping(uint256 => uint256) map;
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         OPERATIONS                         */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns the boolean value of the bit at `index` in `bitmap`.
    function get(Bitmap storage bitmap, uint256 index) internal view returns (bool isSet) {
        // It is better to set `isSet` to either 0 or 1, than zero vs non-zero.
        // Both cost the same amount of gas, but the former allows the returned value
        // to be reused without cleaning the upper bits.
        uint256 b = (bitmap.map[index >> 8] >> (index & 0xff)) & 1;
        /// @solidity memory-safe-assembly
        assembly {
            isSet := b
        }
    }

    /// @dev Updates the bit at `index` in `bitmap` to true.
    function set(Bitmap storage bitmap, uint256 index) internal {
        bitmap.map[index >> 8] |= (1 << (index & 0xff));
    }

    /// @dev Updates the bit at `index` in `bitmap` to false.
    function unset(Bitmap storage bitmap, uint256 index) internal {
        bitmap.map[index >> 8] &= ~(1 << (index & 0xff));
    }

    /// @dev Flips the bit at `index` in `bitmap`.
    /// Returns the boolean result of the flipped bit.
    function toggle(Bitmap storage bitmap, uint256 index) internal returns (bool newIsSet) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, shr(8, index))
            mstore(0x20, bitmap.slot)
            let storageSlot := keccak256(0x00, 0x40)
            let shift := and(index, 0xff)
            let storageValue := sload(storageSlot)

            let mask := shl(shift, 1)
            storageValue := xor(storageValue, mask)
            // It makes sense to return the `newIsSet`,
            // as it allow us to skip an additional warm `sload`,
            // and it costs minimal gas (about 15),
            // which may be optimized away if the returned value is unused.
            newIsSet := iszero(iszero(and(storageValue, mask)))
            sstore(storageSlot, storageValue)
        }
    }

    /// @dev Updates the bit at `index` in `bitmap` to `shouldSet`.
    function setTo(Bitmap storage bitmap, uint256 index, bool shouldSet) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x20, bitmap.slot)
            mstore(0x00, shr(8, index))
            let storageSlot := keccak256(0x00, 0x40)
            let storageValue := sload(storageSlot)
            let shift := and(index, 0xff)

            sstore(
                storageSlot,
                // Unsets the bit at `shift` via `and`, then sets its new value via `or`.
                or(and(storageValue, not(shl(shift, 1))), shl(shift, iszero(iszero(shouldSet))))
            )
        }
    }

    /// @dev Consecutively sets `amount` of bits starting from the bit at `start`.
    function setBatch(Bitmap storage bitmap, uint256 start, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            let max := not(0)
            let shift := and(start, 0xff)
            mstore(0x20, bitmap.slot)
            mstore(0x00, shr(8, start))
            if iszero(lt(add(shift, amount), 257)) {
                let storageSlot := keccak256(0x00, 0x40)
                sstore(storageSlot, or(sload(storageSlot), shl(shift, max)))
                let bucket := add(mload(0x00), 1)
                let bucketEnd := add(mload(0x00), shr(8, add(amount, shift)))
                amount := and(add(amount, shift), 0xff)
                shift := 0
                for {} iszero(eq(bucket, bucketEnd)) { bucket := add(bucket, 1) } {
                    mstore(0x00, bucket)
                    sstore(keccak256(0x00, 0x40), max)
                }
                mstore(0x00, bucket)
            }
            let storageSlot := keccak256(0x00, 0x40)
            sstore(storageSlot, or(sload(storageSlot), shl(shift, shr(sub(256, amount), max))))
        }
    }

    /// @dev Consecutively unsets `amount` of bits starting from the bit at `start`.
    function unsetBatch(Bitmap storage bitmap, uint256 start, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            let shift := and(start, 0xff)
            mstore(0x20, bitmap.slot)
            mstore(0x00, shr(8, start))
            if iszero(lt(add(shift, amount), 257)) {
                let storageSlot := keccak256(0x00, 0x40)
                sstore(storageSlot, and(sload(storageSlot), not(shl(shift, not(0)))))
                let bucket := add(mload(0x00), 1)
                let bucketEnd := add(mload(0x00), shr(8, add(amount, shift)))
                amount := and(add(amount, shift), 0xff)
                shift := 0
                for {} iszero(eq(bucket, bucketEnd)) { bucket := add(bucket, 1) } {
                    mstore(0x00, bucket)
                    sstore(keccak256(0x00, 0x40), 0)
                }
                mstore(0x00, bucket)
            }
            let storageSlot := keccak256(0x00, 0x40)
            sstore(
                storageSlot, and(sload(storageSlot), not(shl(shift, shr(sub(256, amount), not(0)))))
            )
        }
    }

    /// @dev Returns number of set bits within a range by
    /// scanning `amount` of bits starting from the bit at `start`.
    function popCount(Bitmap storage bitmap, uint256 start, uint256 amount)
        internal
        view
        returns (uint256 count)
    {
        unchecked {
            uint256 bucket = start >> 8;
            uint256 shift = start & 0xff;
            if (!(amount + shift < 257)) {
                count = LibBit.popCount(bitmap.map[bucket] >> shift);
                uint256 bucketEnd = bucket + ((amount + shift) >> 8);
                amount = (amount + shift) & 0xff;
                shift = 0;
                for (++bucket; bucket != bucketEnd; ++bucket) {
                    count += LibBit.popCount(bitmap.map[bucket]);
                }
            }
            count += LibBit.popCount((bitmap.map[bucket] >> shift) << (256 - amount));
        }
    }

    /// @dev Returns the index of the most significant set bit before the bit at `before`.
    /// If no set bit is found, returns `NOT_FOUND`.
    function findLastSet(Bitmap storage bitmap, uint256 before)
        internal
        view
        returns (uint256 setBitIndex)
    {
        uint256 bucket;
        uint256 bucketBits;
        /// @solidity memory-safe-assembly
        assembly {
            setBitIndex := not(0)
            bucket := shr(8, before)
            mstore(0x00, bucket)
            mstore(0x20, bitmap.slot)
            let offset := and(0xff, not(before)) // `256 - (255 & before) - 1`.
            bucketBits := shr(offset, shl(offset, sload(keccak256(0x00, 0x40))))
            if iszero(bucketBits) {
                for {} bucket {} {
                    bucket := add(bucket, setBitIndex) // `sub(bucket, 1)`.
                    mstore(0x00, bucket)
                    bucketBits := sload(keccak256(0x00, 0x40))
                    if bucketBits { break }
                }
            }
        }
        if (bucketBits != 0) {
            setBitIndex = (bucket << 8) | LibBit.fls(bucketBits);
            /// @solidity memory-safe-assembly
            assembly {
                setBitIndex := or(setBitIndex, sub(0, gt(setBitIndex, before)))
            }
        }
    }
}

File 10 of 21 : SignatureCheckerLib.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Signature verification helper that supports both ECDSA signatures from EOAs
/// and ERC1271 signatures from smart contract wallets like Argent and Gnosis safe.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SignatureCheckerLib.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/SignatureChecker.sol)
///
/// @dev Note:
/// - The signature checking functions use the ecrecover precompile (0x1).
/// - The `bytes memory signature` variants use the identity precompile (0x4)
///   to copy memory internally.
/// - Unlike ECDSA signatures, contract signatures are revocable.
///
/// WARNING! Do NOT use signatures as unique identifiers.
/// Please use EIP712 with a nonce included in the digest to prevent replay attacks.
/// This implementation does NOT check if a signature is non-malleable.
library SignatureCheckerLib {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*               SIGNATURE CHECKING OPERATIONS                */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns whether `signature` is valid for `signer` and `hash`.
    /// If `signer` is a smart contract, the signature is validated with ERC1271.
    /// Otherwise, the signature is validated with `ECDSA.recover`.
    function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature)
        internal
        view
        returns (bool isValid)
    {
        /// @solidity memory-safe-assembly
        assembly {
            // Clean the upper 96 bits of `signer` in case they are dirty.
            for { signer := shr(96, shl(96, signer)) } signer {} {
                let m := mload(0x40)
                if eq(mload(signature), 65) {
                    mstore(0x00, hash)
                    mstore(0x20, byte(0, mload(add(signature, 0x60)))) // `v`.
                    mstore(0x40, mload(add(signature, 0x20))) // `r`.
                    mstore(0x60, mload(add(signature, 0x40))) // `s`.
                    let t :=
                        staticcall(
                            gas(), // Amount of gas left for the transaction.
                            1, // Address of `ecrecover`.
                            0x00, // Start of input.
                            0x80, // Size of input.
                            0x01, // Start of output.
                            0x20 // Size of output.
                        )
                    // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
                    if iszero(or(iszero(returndatasize()), xor(signer, mload(t)))) {
                        isValid := 1
                        mstore(0x60, 0) // Restore the zero slot.
                        mstore(0x40, m) // Restore the free memory pointer.
                        break
                    }
                }
                mstore(0x60, 0) // Restore the zero slot.
                mstore(0x40, m) // Restore the free memory pointer.

                let f := shl(224, 0x1626ba7e)
                mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`.
                mstore(add(m, 0x04), hash)
                let d := add(m, 0x24)
                mstore(d, 0x40) // The offset of the `signature` in the calldata.
                // Copy the `signature` over.
                let n := add(0x20, mload(signature))
                pop(staticcall(gas(), 4, signature, n, add(m, 0x44), n))
                // forgefmt: disable-next-item
                isValid := and(
                    // Whether the returndata is the magic value `0x1626ba7e` (left-aligned).
                    eq(mload(d), f),
                    // Whether the staticcall does not revert.
                    // This must be placed at the end of the `and` clause,
                    // as the arguments are evaluated from right to left.
                    staticcall(
                        gas(), // Remaining gas.
                        signer, // The `signer` address.
                        m, // Offset of calldata in memory.
                        add(returndatasize(), 0x44), // Length of calldata in memory.
                        d, // Offset of returndata.
                        0x20 // Length of returndata to write.
                    )
                )
                break
            }
        }
    }

    /// @dev Returns whether `signature` is valid for `signer` and `hash`.
    /// If `signer` is a smart contract, the signature is validated with ERC1271.
    /// Otherwise, the signature is validated with `ECDSA.recover`.
    function isValidSignatureNowCalldata(address signer, bytes32 hash, bytes calldata signature)
        internal
        view
        returns (bool isValid)
    {
        /// @solidity memory-safe-assembly
        assembly {
            // Clean the upper 96 bits of `signer` in case they are dirty.
            for { signer := shr(96, shl(96, signer)) } signer {} {
                let m := mload(0x40)
                if eq(signature.length, 65) {
                    mstore(0x00, hash)
                    mstore(0x20, byte(0, calldataload(add(signature.offset, 0x40)))) // `v`.
                    calldatacopy(0x40, signature.offset, 0x40) // `r`, `s`.
                    let t :=
                        staticcall(
                            gas(), // Amount of gas left for the transaction.
                            1, // Address of `ecrecover`.
                            0x00, // Start of input.
                            0x80, // Size of input.
                            0x01, // Start of output.
                            0x20 // Size of output.
                        )
                    // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
                    if iszero(or(iszero(returndatasize()), xor(signer, mload(t)))) {
                        isValid := 1
                        mstore(0x60, 0) // Restore the zero slot.
                        mstore(0x40, m) // Restore the free memory pointer.
                        break
                    }
                }
                mstore(0x60, 0) // Restore the zero slot.
                mstore(0x40, m) // Restore the free memory pointer.

                let f := shl(224, 0x1626ba7e)
                mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`.
                mstore(add(m, 0x04), hash)
                let d := add(m, 0x24)
                mstore(d, 0x40) // The offset of the `signature` in the calldata.
                mstore(add(m, 0x44), signature.length)
                // Copy the `signature` over.
                calldatacopy(add(m, 0x64), signature.offset, signature.length)
                // forgefmt: disable-next-item
                isValid := and(
                    // Whether the returndata is the magic value `0x1626ba7e` (left-aligned).
                    eq(mload(d), f),
                    // Whether the staticcall does not revert.
                    // This must be placed at the end of the `and` clause,
                    // as the arguments are evaluated from right to left.
                    staticcall(
                        gas(), // Remaining gas.
                        signer, // The `signer` address.
                        m, // Offset of calldata in memory.
                        add(signature.length, 0x64), // Length of calldata in memory.
                        d, // Offset of returndata.
                        0x20 // Length of returndata to write.
                    )
                )
                break
            }
        }
    }

    /// @dev Returns whether the signature (`r`, `vs`) is valid for `signer` and `hash`.
    /// If `signer` is a smart contract, the signature is validated with ERC1271.
    /// Otherwise, the signature is validated with `ECDSA.recover`.
    function isValidSignatureNow(address signer, bytes32 hash, bytes32 r, bytes32 vs)
        internal
        view
        returns (bool isValid)
    {
        /// @solidity memory-safe-assembly
        assembly {
            // Clean the upper 96 bits of `signer` in case they are dirty.
            for { signer := shr(96, shl(96, signer)) } signer {} {
                let m := mload(0x40)
                mstore(0x00, hash)
                mstore(0x20, add(shr(255, vs), 27)) // `v`.
                mstore(0x40, r) // `r`.
                mstore(0x60, shr(1, shl(1, vs))) // `s`.
                let t :=
                    staticcall(
                        gas(), // Amount of gas left for the transaction.
                        1, // Address of `ecrecover`.
                        0x00, // Start of input.
                        0x80, // Size of input.
                        0x01, // Start of output.
                        0x20 // Size of output.
                    )
                // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
                if iszero(or(iszero(returndatasize()), xor(signer, mload(t)))) {
                    isValid := 1
                    mstore(0x60, 0) // Restore the zero slot.
                    mstore(0x40, m) // Restore the free memory pointer.
                    break
                }

                let f := shl(224, 0x1626ba7e)
                mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`.
                mstore(add(m, 0x04), hash)
                let d := add(m, 0x24)
                mstore(d, 0x40) // The offset of the `signature` in the calldata.
                mstore(add(m, 0x44), 65) // Length of the signature.
                mstore(add(m, 0x64), r) // `r`.
                mstore(add(m, 0x84), mload(0x60)) // `s`.
                mstore8(add(m, 0xa4), mload(0x20)) // `v`.
                // forgefmt: disable-next-item
                isValid := and(
                    // Whether the returndata is the magic value `0x1626ba7e` (left-aligned).
                    eq(mload(d), f),
                    // Whether the staticcall does not revert.
                    // This must be placed at the end of the `and` clause,
                    // as the arguments are evaluated from right to left.
                    staticcall(
                        gas(), // Remaining gas.
                        signer, // The `signer` address.
                        m, // Offset of calldata in memory.
                        0xa5, // Length of calldata in memory.
                        d, // Offset of returndata.
                        0x20 // Length of returndata to write.
                    )
                )
                mstore(0x60, 0) // Restore the zero slot.
                mstore(0x40, m) // Restore the free memory pointer.
                break
            }
        }
    }

    /// @dev Returns whether the signature (`v`, `r`, `s`) is valid for `signer` and `hash`.
    /// If `signer` is a smart contract, the signature is validated with ERC1271.
    /// Otherwise, the signature is validated with `ECDSA.recover`.
    function isValidSignatureNow(address signer, bytes32 hash, uint8 v, bytes32 r, bytes32 s)
        internal
        view
        returns (bool isValid)
    {
        /// @solidity memory-safe-assembly
        assembly {
            // Clean the upper 96 bits of `signer` in case they are dirty.
            for { signer := shr(96, shl(96, signer)) } signer {} {
                let m := mload(0x40)
                mstore(0x00, hash)
                mstore(0x20, and(v, 0xff)) // `v`.
                mstore(0x40, r) // `r`.
                mstore(0x60, s) // `s`.
                let t :=
                    staticcall(
                        gas(), // Amount of gas left for the transaction.
                        1, // Address of `ecrecover`.
                        0x00, // Start of input.
                        0x80, // Size of input.
                        0x01, // Start of output.
                        0x20 // Size of output.
                    )
                // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
                if iszero(or(iszero(returndatasize()), xor(signer, mload(t)))) {
                    isValid := 1
                    mstore(0x60, 0) // Restore the zero slot.
                    mstore(0x40, m) // Restore the free memory pointer.
                    break
                }

                let f := shl(224, 0x1626ba7e)
                mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`.
                mstore(add(m, 0x04), hash)
                let d := add(m, 0x24)
                mstore(d, 0x40) // The offset of the `signature` in the calldata.
                mstore(add(m, 0x44), 65) // Length of the signature.
                mstore(add(m, 0x64), r) // `r`.
                mstore(add(m, 0x84), s) // `s`.
                mstore8(add(m, 0xa4), v) // `v`.
                // forgefmt: disable-next-item
                isValid := and(
                    // Whether the returndata is the magic value `0x1626ba7e` (left-aligned).
                    eq(mload(d), f),
                    // Whether the staticcall does not revert.
                    // This must be placed at the end of the `and` clause,
                    // as the arguments are evaluated from right to left.
                    staticcall(
                        gas(), // Remaining gas.
                        signer, // The `signer` address.
                        m, // Offset of calldata in memory.
                        0xa5, // Length of calldata in memory.
                        d, // Offset of returndata.
                        0x20 // Length of returndata to write.
                    )
                )
                mstore(0x60, 0) // Restore the zero slot.
                mstore(0x40, m) // Restore the free memory pointer.
                break
            }
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                     ERC1271 OPERATIONS                     */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns whether `signature` is valid for `hash`
    /// for an ERC1271 `signer` contract.
    function isValidERC1271SignatureNow(address signer, bytes32 hash, bytes memory signature)
        internal
        view
        returns (bool isValid)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            let f := shl(224, 0x1626ba7e)
            mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`.
            mstore(add(m, 0x04), hash)
            let d := add(m, 0x24)
            mstore(d, 0x40) // The offset of the `signature` in the calldata.
            // Copy the `signature` over.
            let n := add(0x20, mload(signature))
            pop(staticcall(gas(), 4, signature, n, add(m, 0x44), n))
            // forgefmt: disable-next-item
            isValid := and(
                // Whether the returndata is the magic value `0x1626ba7e` (left-aligned).
                eq(mload(d), f),
                // Whether the staticcall does not revert.
                // This must be placed at the end of the `and` clause,
                // as the arguments are evaluated from right to left.
                staticcall(
                    gas(), // Remaining gas.
                    signer, // The `signer` address.
                    m, // Offset of calldata in memory.
                    add(returndatasize(), 0x44), // Length of calldata in memory.
                    d, // Offset of returndata.
                    0x20 // Length of returndata to write.
                )
            )
        }
    }

    /// @dev Returns whether `signature` is valid for `hash`
    /// for an ERC1271 `signer` contract.
    function isValidERC1271SignatureNowCalldata(
        address signer,
        bytes32 hash,
        bytes calldata signature
    ) internal view returns (bool isValid) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            let f := shl(224, 0x1626ba7e)
            mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`.
            mstore(add(m, 0x04), hash)
            let d := add(m, 0x24)
            mstore(d, 0x40) // The offset of the `signature` in the calldata.
            mstore(add(m, 0x44), signature.length)
            // Copy the `signature` over.
            calldatacopy(add(m, 0x64), signature.offset, signature.length)
            // forgefmt: disable-next-item
            isValid := and(
                // Whether the returndata is the magic value `0x1626ba7e` (left-aligned).
                eq(mload(d), f),
                // Whether the staticcall does not revert.
                // This must be placed at the end of the `and` clause,
                // as the arguments are evaluated from right to left.
                staticcall(
                    gas(), // Remaining gas.
                    signer, // The `signer` address.
                    m, // Offset of calldata in memory.
                    add(signature.length, 0x64), // Length of calldata in memory.
                    d, // Offset of returndata.
                    0x20 // Length of returndata to write.
                )
            )
        }
    }

    /// @dev Returns whether the signature (`r`, `vs`) is valid for `hash`
    /// for an ERC1271 `signer` contract.
    function isValidERC1271SignatureNow(address signer, bytes32 hash, bytes32 r, bytes32 vs)
        internal
        view
        returns (bool isValid)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            let f := shl(224, 0x1626ba7e)
            mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`.
            mstore(add(m, 0x04), hash)
            let d := add(m, 0x24)
            mstore(d, 0x40) // The offset of the `signature` in the calldata.
            mstore(add(m, 0x44), 65) // Length of the signature.
            mstore(add(m, 0x64), r) // `r`.
            mstore(add(m, 0x84), shr(1, shl(1, vs))) // `s`.
            mstore8(add(m, 0xa4), add(shr(255, vs), 27)) // `v`.
            // forgefmt: disable-next-item
            isValid := and(
                // Whether the returndata is the magic value `0x1626ba7e` (left-aligned).
                eq(mload(d), f),
                // Whether the staticcall does not revert.
                // This must be placed at the end of the `and` clause,
                // as the arguments are evaluated from right to left.
                staticcall(
                    gas(), // Remaining gas.
                    signer, // The `signer` address.
                    m, // Offset of calldata in memory.
                    0xa5, // Length of calldata in memory.
                    d, // Offset of returndata.
                    0x20 // Length of returndata to write.
                )
            )
        }
    }

    /// @dev Returns whether the signature (`v`, `r`, `s`) is valid for `hash`
    /// for an ERC1271 `signer` contract.
    function isValidERC1271SignatureNow(address signer, bytes32 hash, uint8 v, bytes32 r, bytes32 s)
        internal
        view
        returns (bool isValid)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            let f := shl(224, 0x1626ba7e)
            mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`.
            mstore(add(m, 0x04), hash)
            let d := add(m, 0x24)
            mstore(d, 0x40) // The offset of the `signature` in the calldata.
            mstore(add(m, 0x44), 65) // Length of the signature.
            mstore(add(m, 0x64), r) // `r`.
            mstore(add(m, 0x84), s) // `s`.
            mstore8(add(m, 0xa4), v) // `v`.
            // forgefmt: disable-next-item
            isValid := and(
                // Whether the returndata is the magic value `0x1626ba7e` (left-aligned).
                eq(mload(d), f),
                // Whether the staticcall does not revert.
                // This must be placed at the end of the `and` clause,
                // as the arguments are evaluated from right to left.
                staticcall(
                    gas(), // Remaining gas.
                    signer, // The `signer` address.
                    m, // Offset of calldata in memory.
                    0xa5, // Length of calldata in memory.
                    d, // Offset of returndata.
                    0x20 // Length of returndata to write.
                )
            )
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                   EMPTY CALLDATA HELPERS                   */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns an empty calldata bytes.
    function emptySignature() internal pure returns (bytes calldata signature) {
        /// @solidity memory-safe-assembly
        assembly {
            signature.length := 0
        }
    }
}

File 11 of 21 : LibZip.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Library for compressing and decompressing bytes.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibZip.sol)
/// @author Calldata compression by clabby (https://github.com/clabby/op-kompressor)
/// @author FastLZ by ariya (https://github.com/ariya/FastLZ)
///
/// @dev Note:
/// The accompanying solady.js library includes implementations of
/// FastLZ and calldata operations for convenience.
library LibZip {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                     FAST LZ OPERATIONS                     */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    // LZ77 implementation based on FastLZ.
    // Equivalent to level 1 compression and decompression at the following commit:
    // https://github.com/ariya/FastLZ/commit/344eb4025f9ae866ebf7a2ec48850f7113a97a42
    // Decompression is backwards compatible.

    /// @dev Returns the compressed `data`.
    function flzCompress(bytes memory data) internal pure returns (bytes memory result) {
        /// @solidity memory-safe-assembly
        assembly {
            function ms8(d_, v_) -> _d {
                mstore8(d_, v_)
                _d := add(d_, 1)
            }
            function u24(p_) -> _u {
                let w := mload(p_)
                _u := or(shl(16, byte(2, w)), or(shl(8, byte(1, w)), byte(0, w)))
            }
            function cmp(p_, q_, e_) -> _l {
                for { e_ := sub(e_, q_) } lt(_l, e_) { _l := add(_l, 1) } {
                    e_ := mul(iszero(byte(0, xor(mload(add(p_, _l)), mload(add(q_, _l))))), e_)
                }
            }
            function literals(runs_, src_, dest_) -> _o {
                for { _o := dest_ } iszero(lt(runs_, 0x20)) { runs_ := sub(runs_, 0x20) } {
                    mstore(ms8(_o, 31), mload(src_))
                    _o := add(_o, 0x21)
                    src_ := add(src_, 0x20)
                }
                if iszero(runs_) { leave }
                mstore(ms8(_o, sub(runs_, 1)), mload(src_))
                _o := add(1, add(_o, runs_))
            }
            function match(l_, d_, o_) -> _o {
                for { d_ := sub(d_, 1) } iszero(lt(l_, 263)) { l_ := sub(l_, 262) } {
                    o_ := ms8(ms8(ms8(o_, add(224, shr(8, d_))), 253), and(0xff, d_))
                }
                if iszero(lt(l_, 7)) {
                    _o := ms8(ms8(ms8(o_, add(224, shr(8, d_))), sub(l_, 7)), and(0xff, d_))
                    leave
                }
                _o := ms8(ms8(o_, add(shl(5, l_), shr(8, d_))), and(0xff, d_))
            }
            function setHash(i_, v_) {
                let p := add(mload(0x40), shl(2, i_))
                mstore(p, xor(mload(p), shl(224, xor(shr(224, mload(p)), v_))))
            }
            function getHash(i_) -> _h {
                _h := shr(224, mload(add(mload(0x40), shl(2, i_))))
            }
            function hash(v_) -> _r {
                _r := and(shr(19, mul(2654435769, v_)), 0x1fff)
            }
            function setNextHash(ip_, ipStart_) -> _ip {
                setHash(hash(u24(ip_)), sub(ip_, ipStart_))
                _ip := add(ip_, 1)
            }
            codecopy(mload(0x40), codesize(), 0x8000) // Zeroize the hashmap.
            let op := add(mload(0x40), 0x8000)
            let a := add(data, 0x20)
            let ipStart := a
            let ipLimit := sub(add(ipStart, mload(data)), 13)
            for { let ip := add(2, a) } lt(ip, ipLimit) {} {
                let r := 0
                let d := 0
                for {} 1 {} {
                    let s := u24(ip)
                    let h := hash(s)
                    r := add(ipStart, getHash(h))
                    setHash(h, sub(ip, ipStart))
                    d := sub(ip, r)
                    if iszero(lt(ip, ipLimit)) { break }
                    ip := add(ip, 1)
                    if iszero(gt(d, 0x1fff)) { if eq(s, u24(r)) { break } }
                }
                if iszero(lt(ip, ipLimit)) { break }
                ip := sub(ip, 1)
                if gt(ip, a) { op := literals(sub(ip, a), a, op) }
                let l := cmp(add(r, 3), add(ip, 3), add(ipLimit, 9))
                op := match(l, d, op)
                ip := setNextHash(setNextHash(add(ip, l), ipStart), ipStart)
                a := ip
            }
            op := literals(sub(add(ipStart, mload(data)), a), a, op)
            result := mload(0x40)
            let t := add(result, 0x8000)
            let n := sub(op, t)
            mstore(result, n) // Store the length.
            // Copy the result to compact the memory, overwriting the hashmap.
            let o := add(result, 0x20)
            for { let i } lt(i, n) { i := add(i, 0x20) } { mstore(add(o, i), mload(add(t, i))) }
            mstore(add(o, n), 0) // Zeroize the slot after the string.
            mstore(0x40, add(add(o, n), 0x20)) // Allocate the memory.
        }
    }

    /// @dev Returns the decompressed `data`.
    function flzDecompress(bytes memory data) internal pure returns (bytes memory result) {
        /// @solidity memory-safe-assembly
        assembly {
            let n := 0
            let end := add(add(data, 0x20), mload(data))
            result := mload(0x40)
            let op := add(result, 0x20)
            for { data := add(data, 0x20) } lt(data, end) {} {
                let w := mload(data)
                let c := byte(0, w)
                let t := shr(5, c)
                if iszero(t) {
                    mstore(add(op, n), mload(add(data, 1)))
                    data := add(data, add(2, c))
                    n := add(n, add(1, c))
                    continue
                }
                let g := eq(t, 7)
                let l := add(2, xor(t, mul(g, xor(t, add(7, byte(1, w))))))
                for {
                    let s := add(add(shl(8, and(0x1f, c)), byte(add(1, g), w)), 1)
                    let r := add(op, sub(n, s))
                    let o := add(op, n)
                    let f := xor(s, mul(gt(s, 0x20), xor(s, 0x20)))
                    let j := 0
                } 1 {} {
                    mstore(add(o, j), mload(add(r, j)))
                    j := add(j, f)
                    if iszero(lt(j, l)) { break }
                }
                data := add(data, add(2, g))
                n := add(n, l)
            }
            mstore(result, n) // Store the length.
            let o := add(add(result, 0x20), n)
            mstore(o, 0) // Zeroize the slot after the string.
            mstore(0x40, add(o, 0x20)) // Allocate the memory.
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                    CALLDATA OPERATIONS                     */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    // Calldata compression and decompression using selective run length encoding:
    // - Sequences of 0x00 (up to 128 consecutive).
    // - Sequences of 0xff (up to 32 consecutive).
    //
    // A run length encoded block consists of two bytes:
    // (0) 0x00
    // (1) A control byte with the following bit layout:
    //     - [7]     `0: 0x00, 1: 0xff`.
    //     - [0..6]  `runLength - 1`.
    //
    // The first 4 bytes are bitwise negated so that the compressed calldata
    // can be dispatched into the `fallback` and `receive` functions.

    /// @dev Returns the compressed `data`.
    function cdCompress(bytes memory data) internal pure returns (bytes memory result) {
        /// @solidity memory-safe-assembly
        assembly {
            function rle(v_, o_, d_) -> _o, _d {
                mstore(o_, shl(240, or(and(0xff, add(d_, 0xff)), and(0x80, v_))))
                _o := add(o_, 2)
            }
            result := mload(0x40)
            let o := add(result, 0x20)
            let z := 0 // Number of consecutive 0x00.
            let y := 0 // Number of consecutive 0xff.
            for { let end := add(data, mload(data)) } iszero(eq(data, end)) {} {
                data := add(data, 1)
                let c := byte(31, mload(data))
                if iszero(c) {
                    if y { o, y := rle(0xff, o, y) }
                    z := add(z, 1)
                    if eq(z, 0x80) { o, z := rle(0x00, o, 0x80) }
                    continue
                }
                if eq(c, 0xff) {
                    if z { o, z := rle(0x00, o, z) }
                    y := add(y, 1)
                    if eq(y, 0x20) { o, y := rle(0xff, o, 0x20) }
                    continue
                }
                if y { o, y := rle(0xff, o, y) }
                if z { o, z := rle(0x00, o, z) }
                mstore8(o, c)
                o := add(o, 1)
            }
            if y { o, y := rle(0xff, o, y) }
            if z { o, z := rle(0x00, o, z) }
            // Bitwise negate the first 4 bytes.
            mstore(add(result, 4), not(mload(add(result, 4))))
            mstore(result, sub(o, add(result, 0x20))) // Store the length.
            mstore(o, 0) // Zeroize the slot after the string.
            mstore(0x40, add(o, 0x20)) // Allocate the memory.
        }
    }

    /// @dev Returns the decompressed `data`.
    function cdDecompress(bytes memory data) internal pure returns (bytes memory result) {
        /// @solidity memory-safe-assembly
        assembly {
            if mload(data) {
                result := mload(0x40)
                let o := add(result, 0x20)
                let s := add(data, 4)
                let v := mload(s)
                let end := add(data, mload(data))
                mstore(s, not(v)) // Bitwise negate the first 4 bytes.
                for {} lt(data, end) {} {
                    data := add(data, 1)
                    let c := byte(31, mload(data))
                    if iszero(c) {
                        data := add(data, 1)
                        let d := byte(31, mload(data))
                        // Fill with either 0xff or 0x00.
                        mstore(o, not(0))
                        if iszero(gt(d, 0x7f)) { codecopy(o, codesize(), add(d, 1)) }
                        o := add(o, add(and(d, 0x7f), 1))
                        continue
                    }
                    mstore8(o, c)
                    o := add(o, 1)
                }
                mstore(s, v) // Restore the first 4 bytes.
                mstore(result, sub(o, add(result, 0x20))) // Store the length.
                mstore(o, 0) // Zeroize the slot after the string.
                mstore(0x40, add(o, 0x20)) // Allocate the memory.
            }
        }
    }

    /// @dev To be called in the `receive` and `fallback` functions.
    /// ```
    ///     receive() external payable { LibZip.cdFallback(); }
    ///     fallback() external payable { LibZip.cdFallback(); }
    /// ```
    /// For efficiency, this function will directly return the results, terminating the context.
    /// If called internally, it must be called at the end of the function.
    function cdFallback() internal {
        assembly {
            if iszero(calldatasize()) { return(calldatasize(), calldatasize()) }
            let o := 0
            let f := not(3) // For negating the first 4 bytes.
            for { let i := 0 } lt(i, calldatasize()) {} {
                let c := byte(0, xor(add(i, f), calldataload(i)))
                i := add(i, 1)
                if iszero(c) {
                    let d := byte(0, xor(add(i, f), calldataload(i)))
                    i := add(i, 1)
                    // Fill with either 0xff or 0x00.
                    mstore(o, not(0))
                    if iszero(gt(d, 0x7f)) { codecopy(o, codesize(), add(d, 1)) }
                    o := add(o, add(and(d, 0x7f), 1))
                    continue
                }
                mstore8(o, c)
                o := add(o, 1)
            }
            let success := delegatecall(gas(), address(), 0x00, o, 0x00, 0x00)
            returndatacopy(0x00, 0x00, returndatasize())
            if iszero(success) { revert(0x00, returndatasize()) }
            return(0x00, returndatasize())
        }
    }
}

File 12 of 21 : LibMap.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Library for storage of packed unsigned integers.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibMap.sol)
library LibMap {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                          STRUCTS                           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev A uint8 map in storage.
    struct Uint8Map {
        mapping(uint256 => uint256) map;
    }

    /// @dev A uint16 map in storage.
    struct Uint16Map {
        mapping(uint256 => uint256) map;
    }

    /// @dev A uint32 map in storage.
    struct Uint32Map {
        mapping(uint256 => uint256) map;
    }

    /// @dev A uint40 map in storage. Useful for storing timestamps up to 34841 A.D.
    struct Uint40Map {
        mapping(uint256 => uint256) map;
    }

    /// @dev A uint64 map in storage.
    struct Uint64Map {
        mapping(uint256 => uint256) map;
    }

    /// @dev A uint128 map in storage.
    struct Uint128Map {
        mapping(uint256 => uint256) map;
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                     GETTERS / SETTERS                      */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns the uint8 value at `index` in `map`.
    function get(Uint8Map storage map, uint256 index) internal view returns (uint8 result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x20, map.slot)
            mstore(0x00, shr(5, index))
            result := byte(and(31, not(index)), sload(keccak256(0x00, 0x40)))
        }
    }

    /// @dev Updates the uint8 value at `index` in `map`.
    function set(Uint8Map storage map, uint256 index, uint8 value) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x20, map.slot)
            mstore(0x00, shr(5, index))
            let s := keccak256(0x00, 0x40) // Storage slot.
            mstore(0x00, sload(s))
            mstore8(and(31, not(index)), value)
            sstore(s, mload(0x00))
        }
    }

    /// @dev Returns the uint16 value at `index` in `map`.
    function get(Uint16Map storage map, uint256 index) internal view returns (uint16 result) {
        result = uint16(map.map[index >> 4] >> ((index & 15) << 4));
    }

    /// @dev Updates the uint16 value at `index` in `map`.
    function set(Uint16Map storage map, uint256 index, uint16 value) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x20, map.slot)
            mstore(0x00, shr(4, index))
            let s := keccak256(0x00, 0x40) // Storage slot.
            let o := shl(4, and(index, 15)) // Storage slot offset (bits).
            let v := sload(s) // Storage slot value.
            let m := 0xffff // Value mask.
            sstore(s, xor(v, shl(o, and(m, xor(shr(o, v), value)))))
        }
    }

    /// @dev Returns the uint32 value at `index` in `map`.
    function get(Uint32Map storage map, uint256 index) internal view returns (uint32 result) {
        result = uint32(map.map[index >> 3] >> ((index & 7) << 5));
    }

    /// @dev Updates the uint32 value at `index` in `map`.
    function set(Uint32Map storage map, uint256 index, uint32 value) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x20, map.slot)
            mstore(0x00, shr(3, index))
            let s := keccak256(0x00, 0x40) // Storage slot.
            let o := shl(5, and(index, 7)) // Storage slot offset (bits).
            let v := sload(s) // Storage slot value.
            let m := 0xffffffff // Value mask.
            sstore(s, xor(v, shl(o, and(m, xor(shr(o, v), value)))))
        }
    }

    /// @dev Returns the uint40 value at `index` in `map`.
    function get(Uint40Map storage map, uint256 index) internal view returns (uint40 result) {
        unchecked {
            result = uint40(map.map[index / 6] >> ((index % 6) * 40));
        }
    }

    /// @dev Updates the uint40 value at `index` in `map`.
    function set(Uint40Map storage map, uint256 index, uint40 value) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x20, map.slot)
            mstore(0x00, div(index, 6))
            let s := keccak256(0x00, 0x40) // Storage slot.
            let o := mul(40, mod(index, 6)) // Storage slot offset (bits).
            let v := sload(s) // Storage slot value.
            let m := 0xffffffffff // Value mask.
            sstore(s, xor(v, shl(o, and(m, xor(shr(o, v), value)))))
        }
    }

    /// @dev Returns the uint64 value at `index` in `map`.
    function get(Uint64Map storage map, uint256 index) internal view returns (uint64 result) {
        result = uint64(map.map[index >> 2] >> ((index & 3) << 6));
    }

    /// @dev Updates the uint64 value at `index` in `map`.
    function set(Uint64Map storage map, uint256 index, uint64 value) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x20, map.slot)
            mstore(0x00, shr(2, index))
            let s := keccak256(0x00, 0x40) // Storage slot.
            let o := shl(6, and(index, 3)) // Storage slot offset (bits).
            let v := sload(s) // Storage slot value.
            let m := 0xffffffffffffffff // Value mask.
            sstore(s, xor(v, shl(o, and(m, xor(shr(o, v), value)))))
        }
    }

    /// @dev Returns the uint128 value at `index` in `map`.
    function get(Uint128Map storage map, uint256 index) internal view returns (uint128 result) {
        result = uint128(map.map[index >> 1] >> ((index & 1) << 7));
    }

    /// @dev Updates the uint128 value at `index` in `map`.
    function set(Uint128Map storage map, uint256 index, uint128 value) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x20, map.slot)
            mstore(0x00, shr(1, index))
            let s := keccak256(0x00, 0x40) // Storage slot.
            let o := shl(7, and(index, 1)) // Storage slot offset (bits).
            let v := sload(s) // Storage slot value.
            let m := 0xffffffffffffffffffffffffffffffff // Value mask.
            sstore(s, xor(v, shl(o, and(m, xor(shr(o, v), value)))))
        }
    }

    /// @dev Returns the value at `index` in `map`.
    function get(mapping(uint256 => uint256) storage map, uint256 index, uint256 bitWidth)
        internal
        view
        returns (uint256 result)
    {
        unchecked {
            uint256 d = _rawDiv(256, bitWidth); // Bucket size.
            uint256 m = (1 << bitWidth) - 1; // Value mask.
            result = (map[_rawDiv(index, d)] >> (_rawMod(index, d) * bitWidth)) & m;
        }
    }

    /// @dev Updates the value at `index` in `map`.
    function set(
        mapping(uint256 => uint256) storage map,
        uint256 index,
        uint256 value,
        uint256 bitWidth
    ) internal {
        unchecked {
            uint256 d = _rawDiv(256, bitWidth); // Bucket size.
            uint256 m = (1 << bitWidth) - 1; // Value mask.
            uint256 o = _rawMod(index, d) * bitWidth; // Storage slot offset (bits).
            map[_rawDiv(index, d)] ^= (((map[_rawDiv(index, d)] >> o) ^ value) & m) << o;
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       BINARY SEARCH                        */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    // The following functions search in the range of [`start`, `end`)
    // (i.e. `start <= index < end`).
    // The range must be sorted in ascending order.
    // `index` precedence: equal to > nearest before > nearest after.
    // An invalid search range will simply return `(found = false, index = start)`.

    /// @dev Returns whether `map` contains `needle`, and the index of `needle`.
    function searchSorted(Uint8Map storage map, uint8 needle, uint256 start, uint256 end)
        internal
        view
        returns (bool found, uint256 index)
    {
        return searchSorted(map.map, needle, start, end, 8);
    }

    /// @dev Returns whether `map` contains `needle`, and the index of `needle`.
    function searchSorted(Uint16Map storage map, uint16 needle, uint256 start, uint256 end)
        internal
        view
        returns (bool found, uint256 index)
    {
        return searchSorted(map.map, needle, start, end, 16);
    }

    /// @dev Returns whether `map` contains `needle`, and the index of `needle`.
    function searchSorted(Uint32Map storage map, uint32 needle, uint256 start, uint256 end)
        internal
        view
        returns (bool found, uint256 index)
    {
        return searchSorted(map.map, needle, start, end, 32);
    }

    /// @dev Returns whether `map` contains `needle`, and the index of `needle`.
    function searchSorted(Uint40Map storage map, uint40 needle, uint256 start, uint256 end)
        internal
        view
        returns (bool found, uint256 index)
    {
        return searchSorted(map.map, needle, start, end, 40);
    }

    /// @dev Returns whether `map` contains `needle`, and the index of `needle`.
    function searchSorted(Uint64Map storage map, uint64 needle, uint256 start, uint256 end)
        internal
        view
        returns (bool found, uint256 index)
    {
        return searchSorted(map.map, needle, start, end, 64);
    }

    /// @dev Returns whether `map` contains `needle`, and the index of `needle`.
    function searchSorted(Uint128Map storage map, uint128 needle, uint256 start, uint256 end)
        internal
        view
        returns (bool found, uint256 index)
    {
        return searchSorted(map.map, needle, start, end, 128);
    }

    /// @dev Returns whether `map` contains `needle`, and the index of `needle`.
    function searchSorted(
        mapping(uint256 => uint256) storage map,
        uint256 needle,
        uint256 start,
        uint256 end,
        uint256 bitWidth
    ) internal view returns (bool found, uint256 index) {
        unchecked {
            if (start >= end) end = start;
            uint256 t;
            uint256 o = start - 1; // Offset to derive the actual index.
            uint256 l = 1; // Low.
            uint256 d = _rawDiv(256, bitWidth); // Bucket size.
            uint256 m = (1 << bitWidth) - 1; // Value mask.
            uint256 h = end - start; // High.
            while (true) {
                index = (l & h) + ((l ^ h) >> 1);
                if (l > h) break;
                t = (map[_rawDiv(index + o, d)] >> (_rawMod(index + o, d) * bitWidth)) & m;
                if (t == needle) break;
                if (needle <= t) h = index - 1;
                else l = index + 1;
            }
            /// @solidity memory-safe-assembly
            assembly {
                m := or(iszero(index), iszero(bitWidth))
                found := iszero(or(xor(t, needle), m))
                index := add(o, xor(index, mul(xor(index, 1), m)))
            }
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                      PRIVATE HELPERS                       */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns `x / y`, returning 0 if `y` is zero.
    function _rawDiv(uint256 x, uint256 y) private pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            z := div(x, y)
        }
    }

    /// @dev Returns `x % y`, returning 0 if `y` is zero.
    function _rawMod(uint256 x, uint256 y) private pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            z := mod(x, y)
        }
    }
}

File 13 of 21 : DelegateCashLib.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

library DelegateCashLib {
    address internal constant REGISTRY_V2 = 0x00000000000000447e69651d841bD8D104Bed493;

    function checkDelegateForAll(address delegate, address vault) internal view returns (bool result) {
        assembly {
            // Cache the free memory pointer.
            let m := mload(0x40)
            // Store the function selector of `checkDelegateForAll(address,address,bytes32)`.
            mstore(0x00, 0xe839bd53)
            // Store the `delegate`.
            mstore(0x20, delegate)
            // Store the `vault`.
            mstore(0x40, vault)
            // The `bytes32 right` argument points to 0x60, which is zero.

            // Arguments are evaulated last to first.
            result := and(
                // The returndata is 1, which represents a bool true.
                eq(mload(0x00), 1),
                // The staticcall is successful.
                staticcall(gas(), REGISTRY_V2, 0x1c, 0x64, 0x00, 0x20)
            )

            // Restore the free memory pointer.
            mstore(0x40, m)
        }
    }
}

File 14 of 21 : LibOps.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;

/**
 * @title LibOps
 * @dev Shared utilities.
 */
library LibOps {
    // =============================================================
    //                            ERRORS
    // =============================================================

    /**
     * @dev Error for overflows.
     */
    error Overflow();

    /**
     * @dev Error for unauthorized access.
     */
    error Unauthorized();

    // =============================================================
    //                           CONSTANTS
    // =============================================================

    /**
     * @dev A role every minter module must have in order to mint new tokens.
     *      IMPORTANT: This constant must NEVER be changed!
     *      It will always be 2 across all past and future sound protocol contracts.
     */
    uint256 internal constant MINTER_ROLE = 1 << 1;

    /**
     * @dev A role the owner can grant for performing admin actions.
     *      IMPORTANT: This constant must NEVER be changed!
     *      It will always be 1 across all past and future sound protocol contracts.
     */
    uint256 internal constant ADMIN_ROLE = 1 << 0;

    /**
     * @dev Basis points denominator used in fee calculations.
     *      IMPORTANT: This constant must NEVER be changed!
     *      It will always be 10000 across all past and future sound protocol contracts.
     */
    uint16 internal constant BPS_DENOMINATOR = 10000;

    // =============================================================
    //                           FUNCTIONS
    // =============================================================

    /**
     * @dev `isOn ? flag : 0`.
     */
    function toFlag(bool isOn, uint8 flag) internal pure returns (uint8 result) {
        assembly {
            result := mul(iszero(iszero(isOn)), flag)
        }
    }

    /**
     * @dev `(flags & flag != 0) != isOn ? flags ^ flag : flags`.
     *      Sets `flag` in `flags` to 1 if `isOn` is true.
     *      Sets `flag` in `flags` to 0 if `isOn` is false.
     */
    function setFlagTo(
        uint8 flags,
        uint8 flag,
        bool isOn
    ) internal pure returns (uint8 result) {
        assembly {
            result := xor(flags, mul(xor(iszero(and(0xff, and(flags, flag))), iszero(isOn)), flag))
        }
    }

    /**
     * @dev `x > y ? x : y`.
     */
    function max(uint256 x, uint256 y) internal pure returns (uint256 z) {
        assembly {
            z := xor(x, mul(xor(x, y), gt(y, x)))
        }
    }

    /**
     * @dev `x < y ? x : y`.
     */
    function min(uint256 x, uint256 y) internal pure returns (uint256 z) {
        assembly {
            z := xor(x, mul(xor(x, y), lt(y, x)))
        }
    }

    /**
     * @dev `(a * b) / d`. Returns 0 if `d` is zero.
     */
    function rawMulDiv(
        uint256 a,
        uint256 b,
        uint256 d
    ) internal pure returns (uint256 z) {
        assembly {
            z := div(mul(a, b), d)
        }
    }

    /**
     * @dev `a / d`. Returns 0 if `d` is zero.
     */
    function rawMod(uint256 a, uint256 d) internal pure returns (uint256 z) {
        assembly {
            z := mod(a, d)
        }
    }

    /**
     * @dev `a | b`.
     */
    function or(bool a, bool b) internal pure returns (bool z) {
        assembly {
            z := or(iszero(iszero(a)), iszero(iszero(b)))
        }
    }

    /**
     * @dev `a | b | c`.
     */
    function or(
        bool a,
        bool b,
        bool c
    ) internal pure returns (bool z) {
        z = or(a, or(b, c));
    }

    /**
     * @dev `a | b | c | d`.
     */
    function or(
        bool a,
        bool b,
        bool c,
        bool d
    ) internal pure returns (bool z) {
        z = or(a, or(b, or(c, d)));
    }

    /**
     * @dev `a & b`.
     */
    function and(bool a, bool b) internal pure returns (bool z) {
        assembly {
            z := and(iszero(iszero(a)), iszero(iszero(b)))
        }
    }

    /**
     * @dev `x == 0 ? type(uint256).max : x`
     */
    function maxIfZero(uint256 x) internal pure returns (uint256 z) {
        assembly {
            z := sub(x, iszero(x))
        }
    }

    /**
     * @dev Packs an address and an index to create an unique identifier.
     * @param a The address.
     * @param i The index.
     * @return result The packed result.
     */
    function packId(address a, uint96 i) internal pure returns (uint256 result) {
        assembly {
            result := or(shl(96, a), shr(160, shl(160, i)))
        }
    }

    /**
     * @dev Packs `edition`, `tier`, `scheduleNum` to create an unique identifier.
     * @param edition     The address of the Sound Edition.
     * @param tier        The tier.
     * @param scheduleNum The edition-tier schedule number.
     * @return result The packed result.
     */
    function packId(
        address edition,
        uint8 tier,
        uint8 scheduleNum
    ) internal pure returns (uint256 result) {
        assembly {
            mstore(0x00, shl(96, edition))
            mstore8(0x1e, tier)
            mstore8(0x1f, scheduleNum)
            result := mload(0x00)
        }
    }

    /**
     * @dev `revert Overflow()`.
     */
    function revertOverflow() internal pure {
        assembly {
            mstore(0x00, 0x35278d12) // `Overflow()`.
            revert(0x1c, 0x04)
        }
    }

    /**
     * @dev `revert Unauthorized()`.
     */
    function revertUnauthorized() internal pure {
        assembly {
            mstore(0x00, 0x82b42900) // `Unauthorized()`.
            revert(0x1c, 0x04)
        }
    }
}

File 15 of 21 : LibMulticaller.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/**
 * @title LibMulticaller
 * @author vectorized.eth
 * @notice Library to read the `msg.sender` of the multicaller with sender contract.
 */
library LibMulticaller {
    /**
     * @dev The address of the multicaller contract.
     */
    address internal constant MULTICALLER = 0x0000000000009448722dAF1A55EF6D1E71FB162d;

    /**
     * @dev The address of the multicaller with sender contract.
     */
    address internal constant MULTICALLER_WITH_SENDER = 0x00000000002Fd5Aeb385D324B580FCa7c83823A0;

    /**
     * @dev The address of the multicaller with signer contract.
     */
    address internal constant MULTICALLER_WITH_SIGNER = 0x000000000000a89360A6a4786b9B33266F208AF4;

    /**
     * @dev Returns the caller of `aggregateWithSender` on `MULTICALLER_WITH_SENDER`.
     */
    function multicallerSender() internal view returns (address result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, 0x00)
            if iszero(staticcall(gas(), MULTICALLER_WITH_SENDER, 0x00, 0x00, 0x00, 0x20)) {
                revert(0x00, 0x00) // For better gas estimation.
            }
            result := mload(0x00)
        }
    }

    /**
     * @dev Returns the signer of `aggregateWithSigner` on `MULTICALLER_WITH_SIGNER`.
     */
    function multicallerSigner() internal view returns (address result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, 0x00)
            if iszero(staticcall(gas(), MULTICALLER_WITH_SIGNER, 0x00, 0x00, 0x00, 0x20)) {
                revert(0x00, 0x00) // For better gas estimation.
            }
            result := mload(0x00)
        }
    }

    /**
     * @dev Returns the caller of `aggregateWithSender` on `MULTICALLER_WITH_SENDER`,
     *      if the current context's `msg.sender` is `MULTICALLER_WITH_SENDER`.
     *      Otherwise, returns `msg.sender`.
     */
    function sender() internal view returns (address result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, caller())
            let withSender := MULTICALLER_WITH_SENDER
            if eq(caller(), withSender) {
                if iszero(staticcall(gas(), withSender, 0x00, 0x00, 0x00, 0x20)) {
                    revert(0x00, 0x00) // For better gas estimation.
                }
            }
            result := mload(0x00)
        }
    }

    /**
     * @dev Returns the caller of `aggregateWithSender` on `MULTICALLER_WITH_SENDER`,
     *      if the current context's `msg.sender` is `MULTICALLER_WITH_SENDER`.
     *      Returns the signer of `aggregateWithSigner` on `MULTICALLER_WITH_SIGNER`,
     *      if the current context's `msg.sender` is `MULTICALLER_WITH_SIGNER`.
     *      Otherwise, returns `msg.sender`.
     */
    function senderOrSigner() internal view returns (address result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, caller())
            let withSender := MULTICALLER_WITH_SENDER
            if eq(caller(), withSender) {
                if iszero(staticcall(gas(), withSender, 0x00, 0x00, 0x00, 0x20)) {
                    revert(0x00, 0x00) // For better gas estimation.
                }
            }
            let withSigner := MULTICALLER_WITH_SIGNER
            if eq(caller(), withSigner) {
                if iszero(staticcall(gas(), withSigner, 0x00, 0x00, 0x00, 0x20)) {
                    revert(0x00, 0x00) // For better gas estimation.
                }
            }
            result := mload(0x00)
        }
    }
}

File 16 of 21 : Ownable.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Simple single owner authorization mixin.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol)
///
/// @dev Note:
/// This implementation does NOT auto-initialize the owner to `msg.sender`.
/// You MUST call the `_initializeOwner` in the constructor / initializer.
///
/// While the ownable portion follows
/// [EIP-173](https://eips.ethereum.org/EIPS/eip-173) for compatibility,
/// the nomenclature for the 2-step ownership handover may be unique to this codebase.
abstract contract Ownable {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       CUSTOM ERRORS                        */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The caller is not authorized to call the function.
    error Unauthorized();

    /// @dev The `newOwner` cannot be the zero address.
    error NewOwnerIsZeroAddress();

    /// @dev The `pendingOwner` does not have a valid handover request.
    error NoHandoverRequest();

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                           EVENTS                           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The ownership is transferred from `oldOwner` to `newOwner`.
    /// This event is intentionally kept the same as OpenZeppelin's Ownable to be
    /// compatible with indexers and [EIP-173](https://eips.ethereum.org/EIPS/eip-173),
    /// despite it not being as lightweight as a single argument event.
    event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);

    /// @dev An ownership handover to `pendingOwner` has been requested.
    event OwnershipHandoverRequested(address indexed pendingOwner);

    /// @dev The ownership handover to `pendingOwner` has been canceled.
    event OwnershipHandoverCanceled(address indexed pendingOwner);

    /// @dev `keccak256(bytes("OwnershipTransferred(address,address)"))`.
    uint256 private constant _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE =
        0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0;

    /// @dev `keccak256(bytes("OwnershipHandoverRequested(address)"))`.
    uint256 private constant _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE =
        0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d;

    /// @dev `keccak256(bytes("OwnershipHandoverCanceled(address)"))`.
    uint256 private constant _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE =
        0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                          STORAGE                           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The owner slot is given by: `not(_OWNER_SLOT_NOT)`.
    /// It is intentionally chosen to be a high value
    /// to avoid collision with lower slots.
    /// The choice of manual storage layout is to enable compatibility
    /// with both regular and upgradeable contracts.
    uint256 private constant _OWNER_SLOT_NOT = 0x8b78c6d8;

    /// The ownership handover slot of `newOwner` is given by:
    /// ```
    ///     mstore(0x00, or(shl(96, user), _HANDOVER_SLOT_SEED))
    ///     let handoverSlot := keccak256(0x00, 0x20)
    /// ```
    /// It stores the expiry timestamp of the two-step ownership handover.
    uint256 private constant _HANDOVER_SLOT_SEED = 0x389a75e1;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                     INTERNAL FUNCTIONS                     */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Initializes the owner directly without authorization guard.
    /// This function must be called upon initialization,
    /// regardless of whether the contract is upgradeable or not.
    /// This is to enable generalization to both regular and upgradeable contracts,
    /// and to save gas in case the initial owner is not the caller.
    /// For performance reasons, this function will not check if there
    /// is an existing owner.
    function _initializeOwner(address newOwner) internal virtual {
        /// @solidity memory-safe-assembly
        assembly {
            // Clean the upper 96 bits.
            newOwner := shr(96, shl(96, newOwner))
            // Store the new value.
            sstore(not(_OWNER_SLOT_NOT), newOwner)
            // Emit the {OwnershipTransferred} event.
            log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)
        }
    }

    /// @dev Sets the owner directly without authorization guard.
    function _setOwner(address newOwner) internal virtual {
        /// @solidity memory-safe-assembly
        assembly {
            let ownerSlot := not(_OWNER_SLOT_NOT)
            // Clean the upper 96 bits.
            newOwner := shr(96, shl(96, newOwner))
            // Emit the {OwnershipTransferred} event.
            log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)
            // Store the new value.
            sstore(ownerSlot, newOwner)
        }
    }

    /// @dev Throws if the sender is not the owner.
    function _checkOwner() internal view virtual {
        /// @solidity memory-safe-assembly
        assembly {
            // If the caller is not the stored owner, revert.
            if iszero(eq(caller(), sload(not(_OWNER_SLOT_NOT)))) {
                mstore(0x00, 0x82b42900) // `Unauthorized()`.
                revert(0x1c, 0x04)
            }
        }
    }

    /// @dev Returns how long a two-step ownership handover is valid for in seconds.
    /// Override to return a different value if needed.
    /// Made internal to conserve bytecode. Wrap it in a public function if needed.
    function _ownershipHandoverValidFor() internal view virtual returns (uint64) {
        return 48 * 3600;
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                  PUBLIC UPDATE FUNCTIONS                   */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Allows the owner to transfer the ownership to `newOwner`.
    function transferOwnership(address newOwner) public payable virtual onlyOwner {
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(shl(96, newOwner)) {
                mstore(0x00, 0x7448fbae) // `NewOwnerIsZeroAddress()`.
                revert(0x1c, 0x04)
            }
        }
        _setOwner(newOwner);
    }

    /// @dev Allows the owner to renounce their ownership.
    function renounceOwnership() public payable virtual onlyOwner {
        _setOwner(address(0));
    }

    /// @dev Request a two-step ownership handover to the caller.
    /// The request will automatically expire in 48 hours (172800 seconds) by default.
    function requestOwnershipHandover() public payable virtual {
        unchecked {
            uint256 expires = block.timestamp + _ownershipHandoverValidFor();
            /// @solidity memory-safe-assembly
            assembly {
                // Compute and set the handover slot to `expires`.
                mstore(0x0c, _HANDOVER_SLOT_SEED)
                mstore(0x00, caller())
                sstore(keccak256(0x0c, 0x20), expires)
                // Emit the {OwnershipHandoverRequested} event.
                log2(0, 0, _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE, caller())
            }
        }
    }

    /// @dev Cancels the two-step ownership handover to the caller, if any.
    function cancelOwnershipHandover() public payable virtual {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute and set the handover slot to 0.
            mstore(0x0c, _HANDOVER_SLOT_SEED)
            mstore(0x00, caller())
            sstore(keccak256(0x0c, 0x20), 0)
            // Emit the {OwnershipHandoverCanceled} event.
            log2(0, 0, _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE, caller())
        }
    }

    /// @dev Allows the owner to complete the two-step ownership handover to `pendingOwner`.
    /// Reverts if there is no existing ownership handover requested by `pendingOwner`.
    function completeOwnershipHandover(address pendingOwner) public payable virtual onlyOwner {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute and set the handover slot to 0.
            mstore(0x0c, _HANDOVER_SLOT_SEED)
            mstore(0x00, pendingOwner)
            let handoverSlot := keccak256(0x0c, 0x20)
            // If the handover does not exist, or has expired.
            if gt(timestamp(), sload(handoverSlot)) {
                mstore(0x00, 0x6f5e8818) // `NoHandoverRequest()`.
                revert(0x1c, 0x04)
            }
            // Set the handover slot to 0.
            sstore(handoverSlot, 0)
        }
        _setOwner(pendingOwner);
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                   PUBLIC READ FUNCTIONS                    */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns the owner of the contract.
    function owner() public view virtual returns (address result) {
        /// @solidity memory-safe-assembly
        assembly {
            result := sload(not(_OWNER_SLOT_NOT))
        }
    }

    /// @dev Returns the expiry timestamp for the two-step ownership handover to `pendingOwner`.
    function ownershipHandoverExpiresAt(address pendingOwner)
        public
        view
        virtual
        returns (uint256 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute the handover slot.
            mstore(0x0c, _HANDOVER_SLOT_SEED)
            mstore(0x00, pendingOwner)
            // Load the handover slot.
            result := sload(keccak256(0x0c, 0x20))
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         MODIFIERS                          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Marks a function as only callable by the owner.
    modifier onlyOwner() virtual {
        _checkOwner();
        _;
    }
}

File 17 of 21 : IERC721AUpgradeable.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;

/**
 * @dev Interface of ERC721A.
 */
interface IERC721AUpgradeable {
    /**
     * The caller must own the token or be an approved operator.
     */
    error ApprovalCallerNotOwnerNorApproved();

    /**
     * The token does not exist.
     */
    error ApprovalQueryForNonexistentToken();

    /**
     * Cannot query the balance for the zero address.
     */
    error BalanceQueryForZeroAddress();

    /**
     * Cannot mint to the zero address.
     */
    error MintToZeroAddress();

    /**
     * The quantity of tokens minted must be more than zero.
     */
    error MintZeroQuantity();

    /**
     * The token does not exist.
     */
    error OwnerQueryForNonexistentToken();

    /**
     * The caller must own the token or be an approved operator.
     */
    error TransferCallerNotOwnerNorApproved();

    /**
     * The token must be owned by `from`.
     */
    error TransferFromIncorrectOwner();

    /**
     * Cannot safely transfer to a contract that does not implement the
     * ERC721Receiver interface.
     */
    error TransferToNonERC721ReceiverImplementer();

    /**
     * Cannot transfer to the zero address.
     */
    error TransferToZeroAddress();

    /**
     * The token does not exist.
     */
    error URIQueryForNonexistentToken();

    /**
     * The `quantity` minted with ERC2309 exceeds the safety limit.
     */
    error MintERC2309QuantityExceedsLimit();

    /**
     * The `extraData` cannot be set on an unintialized ownership slot.
     */
    error OwnershipNotInitializedForExtraData();

    // =============================================================
    //                            STRUCTS
    // =============================================================

    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Stores the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        // Whether the token has been burned.
        bool burned;
        // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}.
        uint24 extraData;
    }

    // =============================================================
    //                         TOKEN COUNTERS
    // =============================================================

    /**
     * @dev Returns the total number of tokens in existence.
     * Burned tokens will reduce the count.
     * To get the total number of tokens minted, please see {_totalMinted}.
     */
    function totalSupply() external view returns (uint256);

    // =============================================================
    //                            IERC165
    // =============================================================

    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);

    // =============================================================
    //                            IERC721
    // =============================================================

    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables
     * (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in `owner`'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`,
     * checking first that contract recipients are aware of the ERC721 protocol
     * to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move
     * this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement
     * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external payable;

    /**
     * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external payable;

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom}
     * whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token
     * by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external payable;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the
     * zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external payable;

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom}
     * for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}.
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    // =============================================================
    //                        IERC721Metadata
    // =============================================================

    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the token collection symbol.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);

    // =============================================================
    //                           IERC2309
    // =============================================================

    /**
     * @dev Emitted when tokens in `fromTokenId` to `toTokenId`
     * (inclusive) is transferred from `from` to `to`, as defined in the
     * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard.
     *
     * See {_mintERC2309} for more details.
     */
    event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to);
}

File 18 of 21 : IERC2981Upgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol)

pragma solidity ^0.8.0;

import "../utils/introspection/IERC165Upgradeable.sol";

/**
 * @dev Interface for the NFT Royalty Standard.
 *
 * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal
 * support for royalty payments across all NFT marketplaces and ecosystem participants.
 *
 * _Available since v4.5._
 */
interface IERC2981Upgradeable is IERC165Upgradeable {
    /**
     * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of
     * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.
     */
    function royaltyInfo(uint256 tokenId, uint256 salePrice)
        external
        view
        returns (address receiver, uint256 royaltyAmount);
}

File 19 of 21 : IERC165Upgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165Upgradeable {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 20 of 21 : IMetadataModule.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;

/**
 * @title IMetadataModule
 * @notice The interface for custom metadata modules.
 */
interface IMetadataModule {
    /**
     * @dev When implemented, SoundEdition's `tokenURI` redirects execution to this `tokenURI`.
     * @param tokenId The token ID to retrieve the token URI for.
     * @return The token URI string.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

File 21 of 21 : LibBit.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Library for bit twiddling and boolean operations.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibBit.sol)
/// @author Inspired by (https://graphics.stanford.edu/~seander/bithacks.html)
library LibBit {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                  BIT TWIDDLING OPERATIONS                  */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Find last set.
    /// Returns the index of the most significant bit of `x`,
    /// counting from the least significant bit position.
    /// If `x` is zero, returns 256.
    function fls(uint256 x) internal pure returns (uint256 r) {
        /// @solidity memory-safe-assembly
        assembly {
            r := or(shl(8, iszero(x)), shl(7, lt(0xffffffffffffffffffffffffffffffff, x)))
            r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))
            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))
            r := or(r, shl(4, lt(0xffff, shr(r, x))))
            r := or(r, shl(3, lt(0xff, shr(r, x))))
            r := or(r, shl(2, lt(0xf, shr(r, x))))
            r := or(r, byte(shr(r, x), hex"00000101020202020303030303030303"))
        }
    }

    /// @dev Count leading zeros.
    /// Returns the number of zeros preceding the most significant one bit.
    /// If `x` is zero, returns 256.
    function clz(uint256 x) internal pure returns (uint256 r) {
        /// @solidity memory-safe-assembly
        assembly {
            r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))
            r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))
            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))
            r := or(r, shl(4, lt(0xffff, shr(r, x))))
            r := or(r, shl(3, lt(0xff, shr(r, x))))
            r := or(r, shl(2, lt(0xf, shr(r, x))))
            // forgefmt: disable-next-item
            r := add(iszero(x), xor(255,
                or(r, byte(shr(r, x), hex"00000101020202020303030303030303"))))
        }
    }

    /// @dev Find first set.
    /// Returns the index of the least significant bit of `x`,
    /// counting from the least significant bit position.
    /// If `x` is zero, returns 256.
    /// Equivalent to `ctz` (count trailing zeros), which gives
    /// the number of zeros following the least significant one bit.
    function ffs(uint256 x) internal pure returns (uint256 r) {
        /// @solidity memory-safe-assembly
        assembly {
            // Isolate the least significant bit.
            let b := and(x, add(not(x), 1))

            r := or(shl(8, iszero(x)), shl(7, lt(0xffffffffffffffffffffffffffffffff, b)))
            r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, b))))
            r := or(r, shl(5, lt(0xffffffff, shr(r, b))))

            // For the remaining 32 bits, use a De Bruijn lookup.
            // forgefmt: disable-next-item
            r := or(r, byte(and(div(0xd76453e0, shr(r, b)), 0x1f),
                0x001f0d1e100c1d070f090b19131c1706010e11080a1a141802121b1503160405))
        }
    }

    /// @dev Returns the number of set bits in `x`.
    function popCount(uint256 x) internal pure returns (uint256 c) {
        /// @solidity memory-safe-assembly
        assembly {
            let max := not(0)
            let isMax := eq(x, max)
            x := sub(x, and(shr(1, x), div(max, 3)))
            x := add(and(x, div(max, 5)), and(shr(2, x), div(max, 5)))
            x := and(add(x, shr(4, x)), div(max, 17))
            c := or(shl(8, isMax), shr(248, mul(x, div(max, 255))))
        }
    }

    /// @dev Returns whether `x` is a power of 2.
    function isPo2(uint256 x) internal pure returns (bool result) {
        /// @solidity memory-safe-assembly
        assembly {
            // Equivalent to `x && !(x & (x - 1))`.
            result := iszero(add(and(x, sub(x, 1)), iszero(x)))
        }
    }

    /// @dev Returns `x` reversed at the bit level.
    function reverseBits(uint256 x) internal pure returns (uint256 r) {
        /// @solidity memory-safe-assembly
        assembly {
            // Computing masks on-the-fly reduces bytecode size by about 500 bytes.
            let m := not(0)
            r := x
            for { let s := 128 } 1 {} {
                m := xor(m, shl(s, m))
                r := or(and(shr(s, r), m), and(shl(s, r), not(m)))
                s := shr(1, s)
                if iszero(s) { break }
            }
        }
    }

    /// @dev Returns `x` reversed at the byte level.
    function reverseBytes(uint256 x) internal pure returns (uint256 r) {
        /// @solidity memory-safe-assembly
        assembly {
            // Computing masks on-the-fly reduces bytecode size by about 200 bytes.
            let m := not(0)
            r := x
            for { let s := 128 } 1 {} {
                m := xor(m, shl(s, m))
                r := or(and(shr(s, r), m), and(shl(s, r), not(m)))
                s := shr(1, s)
                if eq(s, 4) { break }
            }
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                     BOOLEAN OPERATIONS                     */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    // A Solidity bool on the stack or memory is represented as a 256-bit word.
    // Non-zero values are true, zero is false.
    // A clean bool is either 0 (false) or 1 (true) under the hood.
    // Usually, if not always, the bool result of a regular Solidity expression,
    // or the argument of a public/external function will be a clean bool.
    // You can usually use the raw variants for more performance.
    // If uncertain, test (best with exact compiler settings).
    // Or use the non-raw variants (compiler can sometimes optimize out the double `iszero`s).

    /// @dev Returns `x & y`. Inputs must be clean.
    function rawAnd(bool x, bool y) internal pure returns (bool z) {
        /// @solidity memory-safe-assembly
        assembly {
            z := and(x, y)
        }
    }

    /// @dev Returns `x & y`.
    function and(bool x, bool y) internal pure returns (bool z) {
        /// @solidity memory-safe-assembly
        assembly {
            z := and(iszero(iszero(x)), iszero(iszero(y)))
        }
    }

    /// @dev Returns `x | y`. Inputs must be clean.
    function rawOr(bool x, bool y) internal pure returns (bool z) {
        /// @solidity memory-safe-assembly
        assembly {
            z := or(x, y)
        }
    }

    /// @dev Returns `x | y`.
    function or(bool x, bool y) internal pure returns (bool z) {
        /// @solidity memory-safe-assembly
        assembly {
            z := or(iszero(iszero(x)), iszero(iszero(y)))
        }
    }

    /// @dev Returns 1 if `b` is true, else 0. Input must be clean.
    function rawToUint(bool b) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            z := b
        }
    }

    /// @dev Returns 1 if `b` is true, else 0.
    function toUint(bool b) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            z := iszero(iszero(b))
        }
    }
}

Settings
{
  "remappings": [
    "openzeppelin/=lib/openzeppelin-contracts/contracts/",
    "openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
    "chiru-labs/ERC721A-Upgradeable/=lib/ERC721A-Upgradeable/contracts/",
    "solady/=lib/solady/src/",
    "closedsea/=lib/closedsea/src/",
    "preapprove/=lib/preapprove/src/",
    "multicaller/=lib/multicaller/src/",
    "@core/=contracts/core/",
    "@modules/=contracts/modules/",
    "forge-std/=lib/forge-std/src/",
    "ERC721A-Upgradeable/=lib/ERC721A-Upgradeable/contracts/",
    "ds-test/=lib/solady/lib/ds-test/src/",
    "erc4626-tests/=lib/closedsea/lib/openzeppelin-contracts/lib/erc4626-tests/",
    "erc721a-upgradeable/=lib/multicaller/lib/erc721a-upgradeable/contracts/",
    "erc721a/=lib/multicaller/lib/erc721a/contracts/",
    "murky/=lib/murky/src/",
    "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "operator-filter-registry/=lib/closedsea/lib/operator-filter-registry/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[],"name":"CallerNotDelegated","type":"error"},{"inputs":[],"name":"ExceedsMaxPerAccount","type":"error"},{"inputs":[],"name":"ExceedsMintSupply","type":"error"},{"inputs":[],"name":"ExceedsSignedQuantity","type":"error"},{"inputs":[],"name":"InvalidAffiliate","type":"error"},{"inputs":[],"name":"InvalidAffiliateFeeBPS","type":"error"},{"inputs":[],"name":"InvalidMaxMintableRange","type":"error"},{"inputs":[],"name":"InvalidMerkleProof","type":"error"},{"inputs":[],"name":"InvalidMode","type":"error"},{"inputs":[],"name":"InvalidPlatformFeeBPS","type":"error"},{"inputs":[],"name":"InvalidPlatformFeeConfig","type":"error"},{"inputs":[],"name":"InvalidPlatformFlatFee","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[],"name":"InvalidTimeRange","type":"error"},{"inputs":[],"name":"MaxMintableIsZero","type":"error"},{"inputs":[],"name":"MaxMintablePerAccountIsZero","type":"error"},{"inputs":[],"name":"MerkleRootIsEmpty","type":"error"},{"inputs":[],"name":"MintDoesNotExist","type":"error"},{"inputs":[{"internalType":"uint256","name":"blockTimestamp","type":"uint256"},{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"endTime","type":"uint32"}],"name":"MintNotOpen","type":"error"},{"inputs":[],"name":"MintPaused","type":"error"},{"inputs":[],"name":"MintsAlreadyExist","type":"error"},{"inputs":[],"name":"NotConfigurable","type":"error"},{"inputs":[],"name":"PlatformFeeAddressIsZero","type":"error"},{"inputs":[],"name":"SignatureAlreadyUsed","type":"error"},{"inputs":[],"name":"SignatureExpired","type":"error"},{"inputs":[],"name":"SignedPriceTooLow","type":"error"},{"inputs":[],"name":"SignerIsZeroAddress","type":"error"},{"inputs":[{"internalType":"uint256","name":"paid","type":"uint256"},{"internalType":"uint256","name":"required","type":"uint256"}],"name":"WrongPayment","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint8","name":"tier","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"indexed":false,"internalType":"uint16","name":"bps","type":"uint16"}],"name":"AffiliateFeeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"affiliate","type":"address"},{"indexed":false,"internalType":"uint256","name":"accrued","type":"uint256"}],"name":"AffiliateFeesWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint8","name":"tier","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"indexed":false,"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"AffiliateMerkleRootSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"platform","type":"address"},{"components":[{"internalType":"uint96","name":"perTxFlat","type":"uint96"},{"internalType":"uint96","name":"perMintFlat","type":"uint96"},{"internalType":"uint16","name":"perMintBPS","type":"uint16"},{"internalType":"bool","name":"active","type":"bool"}],"indexed":false,"internalType":"struct ISuperMinter.PlatformFeeConfig","name":"config","type":"tuple"}],"name":"DefaultPlatformFeeConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"platform","type":"address"},{"indexed":false,"internalType":"uint96","name":"price","type":"uint96"}],"name":"GAPriceSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint8","name":"tier","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"indexed":false,"internalType":"uint32","name":"value","type":"uint32"}],"name":"MaxMintablePerAccountSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint8","name":"tier","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"indexed":false,"internalType":"uint32","name":"value","type":"uint32"}],"name":"MaxMintableSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint8","name":"tier","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"indexed":false,"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"name":"MerkleRootSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint8","name":"tier","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"components":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint96","name":"price","type":"uint96"},{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"endTime","type":"uint32"},{"internalType":"uint32","name":"maxMintablePerAccount","type":"uint32"},{"internalType":"uint32","name":"maxMintable","type":"uint32"},{"internalType":"uint16","name":"affiliateFeeBPS","type":"uint16"},{"internalType":"bytes32","name":"affiliateMerkleRoot","type":"bytes32"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"address","name":"platform","type":"address"},{"internalType":"uint8","name":"mode","type":"uint8"},{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"indexed":false,"internalType":"struct ISuperMinter.MintCreation","name":"creation","type":"tuple"}],"name":"MintCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint8","name":"tier","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"components":[{"internalType":"uint32","name":"quantity","type":"uint32"},{"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"internalType":"address","name":"allowlisted","type":"address"},{"internalType":"uint32","name":"allowlistedQuantity","type":"uint32"},{"internalType":"uint32","name":"signedQuantity","type":"uint32"},{"internalType":"uint32","name":"signedClaimTicket","type":"uint32"},{"internalType":"address","name":"affiliate","type":"address"},{"internalType":"bool","name":"affiliated","type":"bool"},{"internalType":"uint256","name":"requiredEtherValue","type":"uint256"},{"internalType":"uint256","name":"unitPrice","type":"uint256"},{"internalType":"uint256","name":"platformFee","type":"uint256"},{"internalType":"uint256","name":"platformFlatFee","type":"uint256"},{"internalType":"uint256","name":"affiliateFee","type":"uint256"}],"indexed":false,"internalType":"struct ISuperMinter.MintedLogData","name":"data","type":"tuple"},{"indexed":true,"internalType":"uint256","name":"attributionId","type":"uint256"}],"name":"Minted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint8","name":"tier","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"indexed":false,"internalType":"bool","name":"paused","type":"bool"}],"name":"PausedSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"platform","type":"address"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"}],"name":"PlatformFeeAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"platform","type":"address"},{"indexed":false,"internalType":"uint8","name":"tier","type":"uint8"},{"components":[{"internalType":"uint96","name":"perTxFlat","type":"uint96"},{"internalType":"uint96","name":"perMintFlat","type":"uint96"},{"internalType":"uint16","name":"perMintBPS","type":"uint16"},{"internalType":"bool","name":"active","type":"bool"}],"indexed":false,"internalType":"struct ISuperMinter.PlatformFeeConfig","name":"config","type":"tuple"}],"name":"PlatformFeeConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"platform","type":"address"},{"indexed":false,"internalType":"uint256","name":"accrued","type":"uint256"}],"name":"PlatformFeesWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"platform","type":"address"},{"indexed":false,"internalType":"address","name":"signer","type":"address"}],"name":"PlatformSignerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint8","name":"tier","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"indexed":false,"internalType":"uint96","name":"price","type":"uint96"}],"name":"PriceSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint8","name":"tier","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"indexed":false,"internalType":"address","name":"signer","type":"address"}],"name":"SignerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint8","name":"tier","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"indexed":false,"internalType":"uint32","name":"startTime","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"endTime","type":"uint32"}],"name":"TimeRangeSet","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"BPS_DENOMINATOR","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GA_TIER","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_AFFILIATE_FEE_BPS","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PLATFORM_PER_MINT_FEE_BPS","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PLATFORM_PER_MINT_FLAT_FEE","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PLATFORM_PER_TX_FLAT_FEE","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINT_TO_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERIFY_MERKLE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERIFY_SIGNATURE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"affiliateFeesAccrued","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"uint32[]","name":"claimTickets","type":"uint32[]"}],"name":"checkClaimTickets","outputs":[{"internalType":"bool[]","name":"claimed","type":"bool[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint32","name":"quantity","type":"uint32"},{"internalType":"address","name":"allowlisted","type":"address"},{"internalType":"uint32","name":"allowlistedQuantity","type":"uint32"},{"internalType":"bytes32[]","name":"allowlistProof","type":"bytes32[]"},{"internalType":"uint96","name":"signedPrice","type":"uint96"},{"internalType":"uint32","name":"signedQuantity","type":"uint32"},{"internalType":"uint32","name":"signedClaimTicket","type":"uint32"},{"internalType":"uint32","name":"signedDeadline","type":"uint32"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"address","name":"affiliate","type":"address"},{"internalType":"bytes32[]","name":"affiliateProof","type":"bytes32[]"},{"internalType":"uint256","name":"attributionId","type":"uint256"}],"internalType":"struct ISuperMinter.MintTo","name":"p","type":"tuple"}],"name":"computeMintToDigest","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint96","name":"price","type":"uint96"},{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"endTime","type":"uint32"},{"internalType":"uint32","name":"maxMintablePerAccount","type":"uint32"},{"internalType":"uint32","name":"maxMintable","type":"uint32"},{"internalType":"uint16","name":"affiliateFeeBPS","type":"uint16"},{"internalType":"bytes32","name":"affiliateMerkleRoot","type":"bytes32"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"address","name":"platform","type":"address"},{"internalType":"uint8","name":"mode","type":"uint8"},{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"internalType":"struct ISuperMinter.MintCreation","name":"c","type":"tuple"}],"name":"createEditionMint","outputs":[{"internalType":"uint8","name":"scheduleNum","type":"uint8"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"platform","type":"address"}],"name":"defaultPlatformFeeConfig","outputs":[{"components":[{"internalType":"uint96","name":"perTxFlat","type":"uint96"},{"internalType":"uint96","name":"perMintFlat","type":"uint96"},{"internalType":"uint16","name":"perMintBPS","type":"uint16"},{"internalType":"bool","name":"active","type":"bool"}],"internalType":"struct ISuperMinter.PlatformFeeConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"platform","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"}],"name":"effectivePlatformFeeConfig","outputs":[{"components":[{"internalType":"uint96","name":"perTxFlat","type":"uint96"},{"internalType":"uint96","name":"perMintFlat","type":"uint96"},{"internalType":"uint16","name":"perMintBPS","type":"uint16"},{"internalType":"bool","name":"active","type":"bool"}],"internalType":"struct ISuperMinter.PlatformFeeConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"gaPrice","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"address","name":"affiliate","type":"address"}],"name":"isAffiliated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"address","name":"affiliate","type":"address"},{"internalType":"bytes32[]","name":"affiliateProof","type":"bytes32[]"}],"name":"isAffiliatedWithProof","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"}],"name":"mintInfo","outputs":[{"components":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"address","name":"platform","type":"address"},{"internalType":"uint96","name":"price","type":"uint96"},{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"endTime","type":"uint32"},{"internalType":"uint32","name":"maxMintablePerAccount","type":"uint32"},{"internalType":"uint32","name":"maxMintable","type":"uint32"},{"internalType":"uint32","name":"minted","type":"uint32"},{"internalType":"uint16","name":"affiliateFeeBPS","type":"uint16"},{"internalType":"uint8","name":"mode","type":"uint8"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bool","name":"hasMints","type":"bool"},{"internalType":"bytes32","name":"affiliateMerkleRoot","type":"bytes32"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"internalType":"address","name":"signer","type":"address"},{"internalType":"bool","name":"usePlatformSigner","type":"bool"}],"internalType":"struct ISuperMinter.MintInfo","name":"info","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"}],"name":"mintInfoList","outputs":[{"components":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"address","name":"platform","type":"address"},{"internalType":"uint96","name":"price","type":"uint96"},{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"endTime","type":"uint32"},{"internalType":"uint32","name":"maxMintablePerAccount","type":"uint32"},{"internalType":"uint32","name":"maxMintable","type":"uint32"},{"internalType":"uint32","name":"minted","type":"uint32"},{"internalType":"uint16","name":"affiliateFeeBPS","type":"uint16"},{"internalType":"uint8","name":"mode","type":"uint8"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bool","name":"hasMints","type":"bool"},{"internalType":"bytes32","name":"affiliateMerkleRoot","type":"bytes32"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"internalType":"address","name":"signer","type":"address"},{"internalType":"bool","name":"usePlatformSigner","type":"bool"}],"internalType":"struct ISuperMinter.MintInfo[]","name":"a","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint32","name":"quantity","type":"uint32"},{"internalType":"address","name":"allowlisted","type":"address"},{"internalType":"uint32","name":"allowlistedQuantity","type":"uint32"},{"internalType":"bytes32[]","name":"allowlistProof","type":"bytes32[]"},{"internalType":"uint96","name":"signedPrice","type":"uint96"},{"internalType":"uint32","name":"signedQuantity","type":"uint32"},{"internalType":"uint32","name":"signedClaimTicket","type":"uint32"},{"internalType":"uint32","name":"signedDeadline","type":"uint32"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"address","name":"affiliate","type":"address"},{"internalType":"bytes32[]","name":"affiliateProof","type":"bytes32[]"},{"internalType":"uint256","name":"attributionId","type":"uint256"}],"internalType":"struct ISuperMinter.MintTo","name":"p","type":"tuple"}],"name":"mintTo","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"name_","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"}],"name":"nextScheduleNum","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"address","name":"collector","type":"address"}],"name":"numberMinted","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"platformFeeAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"platform","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"}],"name":"platformFeeConfig","outputs":[{"components":[{"internalType":"uint96","name":"perTxFlat","type":"uint96"},{"internalType":"uint96","name":"perMintFlat","type":"uint96"},{"internalType":"uint16","name":"perMintBPS","type":"uint16"},{"internalType":"bool","name":"active","type":"bool"}],"internalType":"struct ISuperMinter.PlatformFeeConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"platformFeesAccrued","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"platformSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"uint16","name":"bps","type":"uint16"}],"name":"setAffiliateFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"setAffiliateMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint96","name":"perTxFlat","type":"uint96"},{"internalType":"uint96","name":"perMintFlat","type":"uint96"},{"internalType":"uint16","name":"perMintBPS","type":"uint16"},{"internalType":"bool","name":"active","type":"bool"}],"internalType":"struct ISuperMinter.PlatformFeeConfig","name":"c","type":"tuple"}],"name":"setDefaultPlatformFeeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint96","name":"price","type":"uint96"}],"name":"setGAPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"uint32","name":"value","type":"uint32"}],"name":"setMaxMintable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"uint32","name":"value","type":"uint32"}],"name":"setMaxMintablePerAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"bool","name":"paused","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"}],"name":"setPlatformFeeAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"tier","type":"uint8"},{"components":[{"internalType":"uint96","name":"perTxFlat","type":"uint96"},{"internalType":"uint96","name":"perMintFlat","type":"uint96"},{"internalType":"uint16","name":"perMintBPS","type":"uint16"},{"internalType":"bool","name":"active","type":"bool"}],"internalType":"struct ISuperMinter.PlatformFeeConfig","name":"c","type":"tuple"}],"name":"setPlatformFeeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"setPlatformSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"uint96","name":"price","type":"uint96"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"address","name":"signer","type":"address"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"uint32","name":"startTime","type":"uint32"}],"name":"setStartTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"endTime","type":"uint32"}],"name":"setTimeRange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"uint32","name":"quantity","type":"uint32"}],"name":"totalPriceAndFees","outputs":[{"components":[{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"uint256","name":"subTotal","type":"uint256"},{"internalType":"uint256","name":"unitPrice","type":"uint256"},{"internalType":"uint256","name":"platformFee","type":"uint256"},{"internalType":"uint256","name":"platformFlatFee","type":"uint256"},{"internalType":"uint256","name":"platformTxFlatFee","type":"uint256"},{"internalType":"uint256","name":"platformMintFlatFee","type":"uint256"},{"internalType":"uint256","name":"platformMintBPSFee","type":"uint256"},{"internalType":"uint256","name":"affiliateFee","type":"uint256"}],"internalType":"struct ISuperMinter.TotalPriceAndFees","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"uint32","name":"quantity","type":"uint32"},{"internalType":"uint96","name":"signedPrice","type":"uint96"}],"name":"totalPriceAndFeesWithSignedPrice","outputs":[{"components":[{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"uint256","name":"subTotal","type":"uint256"},{"internalType":"uint256","name":"unitPrice","type":"uint256"},{"internalType":"uint256","name":"platformFee","type":"uint256"},{"internalType":"uint256","name":"platformFlatFee","type":"uint256"},{"internalType":"uint256","name":"platformTxFlatFee","type":"uint256"},{"internalType":"uint256","name":"platformMintFlatFee","type":"uint256"},{"internalType":"uint256","name":"platformMintBPSFee","type":"uint256"},{"internalType":"uint256","name":"affiliateFee","type":"uint256"}],"internalType":"struct ISuperMinter.TotalPriceAndFees","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"version_","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"affiliate","type":"address"}],"name":"withdrawForAffiliate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"platform","type":"address"}],"name":"withdrawForPlatform","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

6101206040523480156200001257600080fd5b50306080524660a0526060806200005f604080518082018252600b81526a29bab832b926b4b73a32b960a91b602080830191909152825180840190935260018352603160f81b9083015291565b815160209283012081519183019190912060c082905260e0819052604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f8152938401929092529082015246606082015230608082015260a090206101005250620000c99050565b60805160a05160c05160e051610100516146496200010e6000396000613428015260006134e2015260006134bc0152600061346c0152600061344901526146496000f3fe6080604052600436106103035760003560e01c8063a01efa3411610190578063de9484af116100dc578063e62a61a711610095578063f57402961161006f578063f574029614610b4e578063f7b2f1bf14610b6e578063fb128c8314610ab2578063fe1c0c4b14610b8357610312565b8063e62a61a714610aee578063edb3a0a314610b0e578063edcf0e2114610b2e57610312565b8063de9484af14610a19578063e1a4521814610a39578063e1f3e17d14610a4f578063e3d47d5c14610a85578063e4f6a4f014610ab2578063e544144314610ace57610312565b8063b985423111610149578063cbd8aff211610123578063cbd8aff214610976578063d03206a41461067a578063d379ab5f146109c4578063d3ec6f59146109e457610312565b8063b9854231146108d4578063bd3e8fc9146108f4578063c4f0c1c21461092857610312565b8063a01efa3414610805578063a167fd5f14610825578063ab9868971461083a578063ac1fc22c14610867578063b057868814610894578063b276be35146108b457610312565b8063532cf5961161024f57806370304e2f1161020857806387d4d28c116101e257806387d4d28c146107985780639375da5a146107c557806393e8bcf914610371578063998eb8c2146107e557610312565b806370304e2f146106a3578063752d8e91146106d057806384b0196e1461077057610312565b8063532cf5961461055a57806354fd4d50146105875780635e7876821461059c57806361b26ea41461063a5780636a7319cf1461065a5780636c5f55f71461067a57610312565b80631e1846c8116102bc57806344a8246f1161029657806344a8246f146104e75780634618d76214610507578063498120a0146105275780634a04a1c91461054757610312565b80631e1846c8146103f857806320606b70146104855780633b79c44f146104c757610312565b806301ffc9a71461031a57806306fdde031461034f5780630a25dea91461037157806315329da0146103985780631542b7fc146103b85780631b98e510146103d857610312565b3661031257610310610ba3565b005b610310610ba3565b34801561032657600080fd5b5061033a6103353660046137de565b610c3b565b60405190151581526020015b60405180910390f35b34801561035b57600080fd5b50610364610c66565b604051610346919061384e565b34801561037d57600080fd5b50610386600081565b60405160ff9091168152602001610346565b3480156103a457600080fd5b506103106103b3366004613892565b610c76565b3480156103c457600080fd5b506103106103d33660046138ea565b610da9565b3480156103e457600080fd5b506103866103f3366004613937565b610e31565b34801561040457600080fd5b50610418610413366004613980565b610e69565b6040516103469190600061012082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e083015160e083015261010080840151818401525092915050565b34801561049157600080fd5b506104b97f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b604051908152602001610346565b3480156104d357600080fd5b506103106104e23660046139d6565b610e8a565b3480156104f357600080fd5b506103106105023660046139f3565b610efe565b34801561051357600080fd5b50610310610522366004613980565b610fe6565b34801561053357600080fd5b50610310610542366004613a71565b6110c4565b610310610555366004613abc565b611190565b34801561056657600080fd5b5061057a610575366004613937565b6116af565b6040516103469190613af8565b34801561059357600080fd5b506103646117d7565b3480156105a857600080fd5b5061057a6105b73660046139d6565b604080516080808201835260008083526020808401829052838501829052606093840182905294831b6101001781526006855283902083519182018452546001600160601b038082168352600160601b82041694820194909452600160c01b840461ffff1692810192909252600160d01b90920460ff1615159181019190915290565b34801561064657600080fd5b50610310610655366004613b3a565b6117e1565b34801561066657600080fd5b5061033a610675366004613ba1565b61185a565b34801561068657600080fd5b506106906103e881565b60405161ffff9091168152602001610346565b3480156106af57600080fd5b506106c36106be366004613c2b565b61188a565b6040516103469190613ca3565b3480156106dc57600080fd5b5061057a6106eb366004613937565b604080516080808201835260008083526020808401829052838501829052606093840182905295831b60ff9586161781526006865283902083519182018452546001600160601b038082168352600160601b82041695820195909552600160c01b850461ffff1692810192909252600160d01b90930490911615159181019190915290565b34801561077c57600080fd5b5061078561196e565b6040516103469796959493929190613ce9565b3480156107a457600080fd5b506104b96107b33660046139d6565b60006020819052908152604090205481565b3480156107d157600080fd5b506103106107e03660046139d6565b611995565b3480156107f157600080fd5b50610310610800366004613e7e565b611a0a565b34801561081157600080fd5b506103106108203660046138ea565b611ade565b34801561083157600080fd5b50610386600281565b34801561084657600080fd5b5061085a6108553660046139d6565b611b91565b6040516103469190613fe7565b34801561087357600080fd5b506104b96108823660046139d6565b60026020526000908152604090205481565b3480156108a057600080fd5b506103106108af366004613980565b611c87565b3480156108c057600080fd5b506103106108cf366004613980565b611d81565b3480156108e057600080fd5b506103106108ef36600461402a565b611dc9565b34801561090057600080fd5b506104b97fc03e2545e609fd0b7813d6074f00235b048ae7580a8e57070eed03901dd951ae81565b34801561093457600080fd5b5061095e6109433660046139d6565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610346565b34801561098257600080fd5b506109ac6109913660046139d6565b6003602052600090815260409020546001600160601b031681565b6040516001600160601b039091168152602001610346565b3480156109d057600080fd5b506103106109df366004614055565b611ead565b3480156109f057600080fd5b50610a046109ff366004613892565b611f4c565b60405163ffffffff9091168152602001610346565b348015610a2557600080fd5b50610386610a343660046140a0565b611f99565b348015610a4557600080fd5b5061069061271081565b348015610a5b57600080fd5b5061095e610a6a3660046139d6565b6001602052600090815260409020546001600160a01b031681565b348015610a9157600080fd5b50610aa5610aa0366004614192565b612462565b60405161034691906141d7565b348015610abe57600080fd5b506109ac67016345785d8a000081565b348015610ada57600080fd5b50610310610ae93660046141e6565b6125f1565b348015610afa57600080fd5b506104b9610b09366004613abc565b6126a6565b348015610b1a57600080fd5b50610310610b293660046139d6565b6127eb565b348015610b3a57600080fd5b50610418610b49366004614233565b612891565b348015610b5a57600080fd5b50610310610b693660046139d6565b6128c7565b348015610b7a57600080fd5b50610386600181565b348015610b8f57600080fd5b5061033a610b9e366004613892565b612948565b36610bac573636f35b6000805b80368210610bbe5750610c1a565b600180830192600319810190351860001a9081610c0a57600019855260028301933560021984011860001a607f808211610bf9578282013888395b16949094019093019250610bb09050565b8185538085019450505050610bb0565b50600080826000305af490503d6000803e80610c35573d6000fd5b503d6000f35b60006301ffc9a760e01b6001600160e01b0319831690811463028b35ad60e31b909114175b92915050565b6060610c70612958565b50919050565b83610c8081612995565b6000610c8d868686612a98565b90506000610c9a82612ab4565b6001810154909150600160e81b900460ff16600214610ccc5760405163d25a973560e01b815260040160405180910390fd5b610cd584612af7565b6001818101546001600160a01b03861690911490610d0a9060ff600160f01b9091041660048360ff8383161615901518021890565b82600101601e6101000a81548160ff021916908360ff16021790555080610d49576004820180546001600160a01b0319166001600160a01b0387161790555b6040805160ff808a168252881660208201526001600160a01b0387811692820192909252908916907fc82787a128aa35191b6a1df922a24f581a06500f78030b89582d624c6ae9b2c9906060015b60405180910390a25050505050505050565b83610db381612995565b6000610dc0868686612a98565b90506000610dcd82612ab4565b600281018590556040805160ff808a168252881660208201529081018690529091506001600160a01b038816907fe08051cfd6c9341327f7f5550f77e02e815f59c1ecba22a4ac006ddca62dec20906060015b60405180910390a250505050505050565b600060056000610e4385856000612a98565b8152602081019190915260400160002060010154600160e01b900460ff16905092915050565b610e716136fe565b610e7f858585856000612891565b90505b949350505050565b6000610e94612b21565b6001600160a01b0381811660008181526004602090815260409182902080546001600160a01b03191694881694851790559051928352929350917fb9aba67a9619eecb4b3e9fe6ded4a35c9bcdbfb1040f5122f91716de616a799391015b60405180910390a25050565b84610f0881612995565b6000610f15878787612a98565b90506000610f2282612ab4565b905060ff8716158015610f3b575063ffffffff84811614155b15610f595760405163d25a973560e01b815260040160405180910390fd5b610f638585612b59565b60018101805463ffffffff87811667ffffffffffffffff199092168217640100000000918816918202179092556040805160ff808c1682528a1660208201529081019190915260608101919091526001600160a01b038916907f41ad9ed088bad8a3ad3052c7360f6919b647b45d4b527e478d463edbb8f9a43590608001610d97565b83610ff081612995565b6000610ffd868686612a98565b9050600061100a82612ab4565b905060ff861615801561102957506001810154600160e81b900460ff16155b156110475760405163d25a973560e01b815260040160405180910390fd5b61105084612b86565b60018101805463ffffffff60601b1916600160601b63ffffffff8716908102919091179091556040805160ff808a16825288166020820152908101919091526001600160a01b038816907f5da54689220406b0ee18edb07d2007345f96968da27c7fd0f405f649d26040a890606001610e20565b836110ce81612995565b60006110db868686612a98565b905060006110e882612ab4565b905060ff861615801561110a57506001810154600160e81b900460ff16600214155b156111285760405163d25a973560e01b815260040160405180910390fd5b80546001600160601b038516600160a01b81026001600160a01b039283161783556040805160ff8a811682528916602082015290810191909152908816907f3b082de0ef84f822f97496af03a3df5a8d5f0c271ea658b5b210819f1310494f90606001610e20565b60006111cf6111ca6111a560208501856139d6565b6111b5604086016020870161428e565b6111c5606087016040880161428e565b612a98565b612ab4565b600181015490915042640100000000820463ffffffff9081168211921611171561123657600181015460405163296f4f6960e01b815242600482015263ffffffff808316602483015264010000000090920490911660448201526064015b60405180910390fd5b61124d8160010154600160f01b9004600216151590565b1561126b57604051636be9245d60e11b815260040160405180910390fd5b6001810154600160e81b900460ff1660001981016112925761128d8284612bad565b6112a8565b60011960ff8216016112a8576112a88284612d2e565b6112b3818385612e67565b60006112f06112c8604086016020870161428e565b846112d960a08801608089016142a9565b6112eb61012089016101008a01613b3a565b6130b1565b905060008082600001513414611325578251604051630374cb4760e21b8152346004820152602481019190915260440161122d565b6060830151835186546001600160a01b03166000908152602081905260409020805483019055039150611377856113646101c089016101a08a016139d6565b6113726101c08a018a6142c4565b613221565b905080156113c5576101008301519182900391600260006113a06101c08a016101a08b016139d6565b6001600160a01b03168152602081019190915260400160002080549091019055611409565b60006113d96101c088016101a089016139d6565b6001600160a01b031614611400576040516320d6c38960e01b815260040160405180910390fd5b60006101008401525b600061141860208801886139d6565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915290915061149460a0890160808a016142a9565b63ffffffff1681526001600160a01b03821663eebab8ef856114bc60408c0160208d0161428e565b6114cc60808d0160608e016139d6565b6114dc60a08e0160808f016142a9565b6040516001600160e01b031960e087901b16815260ff90931660048401526001600160a01b03909116602483015263ffffffff16604482015260640160206040518083038185885af1158015611536573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061155b919061430e565b602082015261157060c0890160a08a016139d6565b6001600160a01b0316604082015261158e60e0890160c08a016142a9565b63ffffffff1660608201526115ab61016089016101408a016142a9565b63ffffffff1660a08201526115c86101c089016101a08a016139d6565b6001600160a01b031660c082015282151560e08201528451610100808301919091526040860151610120830152606080870151610140840152608080880151610160850152918701516101808401526101e08a01359161162d91908b01908b016139d6565b6001600160a01b031661164360208b018b6139d6565b6001600160a01b03167f2a29f7402bd32f0e4bbe17d44be064f7f64d96ee174ed7cb27936d869bf9a88861167d60408d0160208e0161428e565b61168d60608e0160408f0161428e565b8660405161169d93929190614327565b60405180910390a45050505050505050565b604080516080808201835260008083526020808401829052838501829052606080850183905260ff87811689831b178452600683529286902086519485018752546001600160601b038082168652600160601b8204169285019290925261ffff600160c01b83041695840195909552600160d01b900416151592810183905290916117a15760066000606086901b6101001781526020808201929092526040908101600020815160808101835290546001600160601b038082168352600160601b82041693820193909352600160c01b830461ffff1691810191909152600160d01b90910460ff161515606082015290505b80606001516117d057506040805160808101825260008082526020820181905291810182905260608101919091525b9392505050565b6060610c60612958565b60006117eb612b21565b6001600160a01b03811660008181526003602090815260409182902080546bffffffffffffffffffffffff19166001600160601b038816908117909155915191825292935090917fed3d3f99e57c78ce76ac9a1704a72bb912e8f231cc25c6379fdf5354dbb6481b9101610ef2565b600080611868888888612a98565b905061187e61187682612ab4565b868686613221565b98975050505050505050565b60606000611899878787612a98565b60008181526008602052604090209091508367ffffffffffffffff8111156118c3576118c3613d7f565b6040519080825280602002602001820160405280156118ec578160200160208202803683370190505b50925060005b8085146119625761193886868381811061190e5761190e614418565b905060200201602081019061192391906142a9565b63ffffffff168361327590919063ffffffff16565b84828151811061194a5761194a614418565b911515602092830291909101909101526001016118f2565b50505095945050505050565b600f60f81b6060806000808083611983612958565b97989097965046955030945091925090565b600061199f612b21565b90506119aa82613297565b6001600160a01b0381811660008181526001602090815260409182902080546001600160a01b0319169487169485179055905192835290917f3a9b87574e9f01aaafa6d829c77645fe96010be0b3093259c7873f4a93de28e99101610ef2565b6000611a14612b21565b9050611a1f826132be565b606081811b61010017600090815260066020908152604091829020855181549287015187850151958801511515600160d01b0260ff60d01b1961ffff909716600160c01b029690961662ffffff60c01b196001600160601b03928316600160601b026001600160c01b0319909616929093169190911793909317169190911792909217909155516001600160a01b038216907fec59616fef2c95b1d9e549c69e956a02fc10d12473c9667d711355ff224a2fe690610ef2908590613af8565b83611ae881612995565b6000611af5868686612a98565b90506000611b0282612ab4565b600180820154919250600160e81b90910460ff1614611b345760405163d25a973560e01b815260040160405180910390fd5b611b3d84613337565b600381018490556040805160ff8089168252871660208201529081018590526001600160a01b038816907f0b0a6fe894fe7695ac067d44d6e0de766337e9c3b5f0ee0a61be727383aac5a790606001610e20565b606081811b6000908152600560205260409020600181015461ffff600160d01b8204811691600160c01b9004168167ffffffffffffffff811115611bd757611bd7613d7f565b604051908082528060200260200182016040528015611c1057816020015b611bfd61374a565b815260200190600190039081611bf55790505b5093505b8115611c7f5761ffff8116606086901b176000908152600560205260409020611c458660ff600885901c1684612462565b85846001900394508481518110611c5e57611c5e614418565b602090810291909101015260010154600160b01b900461ffff169050611c14565b505050919050565b83611c9181612995565b6000611c9e868686612a98565b90506000611cab82612ab4565b905060ff8616611cce5760405163d25a973560e01b815260040160405180910390fd5b6001810154600119600160e81b90910460ff1601611cff5760405163d25a973560e01b815260040160405180910390fd5b611d0884613355565b6001810180546bffffffff00000000000000001916600160401b63ffffffff8716908102919091179091556040805160ff808a16825288166020820152908101919091526001600160a01b038816907f674233c20daf715ad9e94f9e5818adc53482b77e9556564e5fe3766678246e8e90606001610e20565b6000611d8e858585612a98565b600081815260056020526040902060010154909150611dc2908690869086908690640100000000900463ffffffff16610efe565b5050505050565b6000611dd3612b21565b9050611dde826132be565b606081811b60ff851617600090815260066020908152604091829020855181549287015187850151958801511515600160d01b0260ff60d01b1961ffff909716600160c01b029690961662ffffff60c01b196001600160601b03928316600160601b026001600160c01b0319909616929093169190911793909317169190911792909217909155516001600160a01b038216907f2e28b985b43becdaa221ff743fd386f80ace62daa5b69941fd6b51445ddaf4ee90611ea0908690869061442e565b60405180910390a2505050565b83611eb781612995565b6000611ec4868686612a98565b90506000611ed182612ab4565b9050611edc8461337c565b60018101805461ffff60a01b1916600160a01b61ffff8716908102919091179091556040805160ff808a16825288166020820152908101919091526001600160a01b038816907fcdff4ec2999e249a9a848accff5e46b43263f82c4076334cd70300e07326472d90606001610e20565b600080611f5a868686612a98565b6001600160a01b0384166000908152600760209081526040808320600385901c845290915290205490915060e0600583901b161c5b9695505050505050565b6000611fa88260000151612995565b611fb58260c0015161337c565b61014082015160ff8116611fd85760006101608401819052610180840152612049565b60001960ff821601611fff57611ff2836101800151613337565b6000610160840152612049565b60011960ff82160161203057612019836101600151612af7565b600061018084015263ffffffff6080840152612049565b60405163a0042b1760e01b815260040160405180910390fd5b61010083015160ff1661208d5763ffffffff60608401819052608084015260ff811660021461207a57600060208401525b60ff811661208d5763ffffffff60a08401525b61209f83604001518460600151612b59565b6120ac8360800151613355565b6120b98360a00151612b86565b6000600560006120d486600001518761010001516000612a98565b815260208082019290925260409081016000908120875160601b8252600590935220600180830154600160e01b900460ff169550919250908401610100811061211f5761211f6133c6565b6001808401805460ff909316600160e01b0260ff60e01b19909316929092179091558181015461ffff600160d01b9091041601620100008110612164576121646133c6565b60018201805461ffff60d01b1916600160d01b61ffff84160217905585516101008701516000916121959188612a98565b9050600060016001600160a01b03168861016001516001600160a01b031614905060006005600084815260200190815260200160002090508861012001518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555088602001518160000160146101000a8154816001600160601b0302191690836001600160601b0316021790555088604001518160010160006101000a81548163ffffffff021916908363ffffffff16021790555088606001518160010160046101000a81548163ffffffff021916908363ffffffff16021790555088608001518160010160086101000a81548163ffffffff021916908363ffffffff1602179055508860a0015181600101600c6101000a81548163ffffffff021916908363ffffffff1602179055508860c001518160010160146101000a81548161ffff021916908361ffff16021790555088610140015181600101601d6101000a81548160ff021916908360ff1602179055506123168260049015150290565b6001828101805460ff60f01b198116600160f01b94841760ff908116959095029081178355928901805468ff000000000000ffff60b01b1990921661ffff60b01b1990941693909317600160c01b9182900461ffff16600160b01b02179091556101008c0151825461ffff60c01b1916938c1660089190911b61ff0016170291909117905560e0890151156123b05760e089015160028201555b610180890151156123c75761018089015160038201555b6101608901516001600160a01b0316156124085781612408576101608901516004820180546001600160a01b0319166001600160a01b039092169190911790555b88600001516001600160a01b03167fcbaa8cb5ab7e807c363e8c49ecb8b778bb2217e8e7d375826e911413a4c734f48a61010001518a8c60405161244e93929190614479565b60405180910390a250505050505050919050565b61246a61374a565b6000612477858585612a98565b9050600061248482612ab4565b6001600160a01b03808816855260ff808816602087018190529087166040870152825490911660608601529091501580156124ce57506001810154600160e81b900460ff16600214155b6124e9578054600160a01b90046001600160601b031661250d565b80546001600160a01b03166000908152600360205260409020546001600160601b03165b6001600160601b03166080840152600181015463ffffffff80821660a08601526401000000008204811660c0860152600160401b8204811660e0860152600160601b82048116610100860152600160801b820416610120850152600160a01b810461ffff16610140850152600160e81b810460ff166101608501526002600160f01b909104811615156101808501528101546101c084015260038101546101e08401526125b9816133d4565b6001600160a01b03166102008401526125df8160010154600160f01b9004600416151590565b15156102208401525090949350505050565b836125fb81612995565b6000612608868686612a98565b9050600061261582612ab4565b600181015490915061263e9060ff600160f01b9091041660028660ff8383161615901518021890565b60018201805460ff60f01b1916600160f01b60ff938416021790556040805188831681529187166020830152851515908201526001600160a01b038816907f81bd379475659273b35365d353d46c7de87aa468a01efc54544fcee90ae0d3b690606001610e20565b6000610c607fc03e2545e609fd0b7813d6074f00235b048ae7580a8e57070eed03901dd951ae6126d960208501856139d6565b6126e9604086016020870161428e565b6126f9606087016040880161428e565b61270960808801606089016139d6565b61271b61014089016101208a016142a9565b61272d6101608a016101408b016142a9565b61273f6101208b016101008c01613b3a565b6127516101808c016101608d016142a9565b6127636101c08d016101a08e016139d6565b60408051602081019b909b526001600160a01b03998a16908b015260ff97881660608b015296909516608089015292861660a088015263ffffffff91821660c0880152811660e08701526001600160601b0390911661010086015216610120840152166101408201526101600160405160208183030381529060405280519060200120613424565b6001600160a01b038082166000908152600160205260409020541661280f81613297565b6001600160a01b038216600090815260208190526040902054801561288c576001600160a01b038316600090815260208190526040812055612851828261353f565b826001600160a01b03167ffc7ad544ff6a06d6499925723d25b6fe70457a42939995b1d3d6f560fe33633382604051611ea091815260200190565b505050565b6128996136fe565b60006128a6878787612a98565b90506128bc866128b583612ab4565b86866130b1565b979650505050505050565b6001600160a01b0381166000908152600260205260409020548015612944576001600160a01b038216600090815260026020526040812055612909828261353f565b816001600160a01b03167f0a1adaaf9d9caba9cf65528900e946b718d511ebd66ae81d5eb71e7fd0122c4a82604051610ef291815260200190565b5050565b6000610e7f85858585368661185a565b604080518082018252600b81526a29bab832b926b4b73a32b960a91b602080830191909152825180840190935260018352603160f81b9083015291565b600061299f612b21565b9050816001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156129df573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a039190614592565b6001600160a01b0316816001600160a01b0316146129445760405163145398bf60e21b81526001600160a01b0382811660048301526001602483015283169063514e62fc90604401602060405180830381865afa158015612a68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a8c91906145af565b61294457612944613589565b60008360601b60005282601e5381601f53505060005192915050565b60008181526005602052604081206001808201549192600160f01b909204169003612af25760405163947dbacd60e01b815260040160405180910390fd5b919050565b6001600160a01b038116612b1e5760405163327effa960e11b815260040160405180910390fd5b50565b6000336000526e2fd5aeb385d324b580fca7c83823a0803303612b515760206000806000845afa612b5157600080fd5b505060005190565b8063ffffffff168263ffffffff1611156129445760405163536a71af60e01b815260040160405180910390fd5b8063ffffffff16600003612b1e57604051630ccae60160e31b815260040160405180910390fd5b6000612bbf60e0830160c084016142a9565b90506000612bd360c0840160a085016139d6565b90506001600160a01b038116612bfc5760405163582f497d60e11b815260040160405180910390fd5b63fffffffe1963ffffffff831601612c8757612c3b8460030154612c25836000526014600c2090565b612c3260e08701876142c4565b90929091613597565b158015612c645750612c628460030154612c258363ffffffff6004526000526018600c2090565b155b15612c825760405163582f497d60e11b815260040160405180910390fd5b612cbf565b612ca28460030154612c2583856004526000526018600c2090565b612cbf5760405163582f497d60e11b815260040160405180910390fd5b6000612cc9612b21565b9050612d036001600160a01b03838116908316811490612cef60808801606089016139d6565b6001600160a01b0316149015159015151790565b611dc257612d1181836135d1565b611dc25760405163fe736e0160e01b815260040160405180910390fd5b612d40610140820161012083016142a9565b63ffffffff16612d5660a08301608084016142a9565b63ffffffff161115612d7b576040516352ad28c360e11b815260040160405180910390fd5b6000612d86836133d4565b9050612da881612d95846126a6565b612da36101808601866145cc565b613612565b612dc557604051638baa579f60e01b815260040160405180910390fd5b612dd7610180830161016084016142a9565b63ffffffff16421115612dfd57604051630819bdcd60e01b815260040160405180910390fd5b6000612e0f6111a560208501856139d6565b9050612e44612e26610160850161014086016142a9565b60008381526008602052604090209063ffffffff908116906136bb16565b612e615760405163900bb2c960e01b815260040160405180910390fd5b50505050565b6000612e7960a08301608084016142a9565b600184015463ffffffff918216600160801b82048316019250600160601b900416811115612eba57604051637f70f90b60e01b815260040160405180910390fd5b60018301805463ffffffff60801b1916600160801b63ffffffff8416021790556000612eec6111a560208501856139d6565b905060001960ff861601612fe7576000600781612f0f60c0870160a088016139d6565b6001600160a01b0316815260208101919091526040016000209050612f3a60a08501608086016142a9565b63ffffffff16612f5383836133a390919063ffffffff16565b600187015463ffffffff918216929092019450612f9691600160401b9004168411612f8460e0870160c088016142a9565b63ffffffff1685119015159015151790565b15612fb457604051631b75136560e01b815260040160405180910390fd5b6020819052600382901c600090815260409020805460e0600585901b1681811c861863ffffffff16901b18905550611dc2565b6000600781612ffc60808701606088016139d6565b6001600160a01b031681526020810191909152604001600020905061302760a08501608086016142a9565b63ffffffff1661304083836133a390919063ffffffff16565b600187015463ffffffff918216929092019450600160401b9091041683111561307c57604051631b75136560e01b815260040160405180910390fd5b6020819052600382901c600090815260409020805460e0600585901b1681811c861863ffffffff16901b189055505050505050565b6130b96136fe565b83546000906130d1906001600160a01b0316876116af565b6001860154909150600090600119600160e81b90910460ff16016131355785546001600160601b03600160a01b909104811690851610156131255760405163dcdc2f1560e01b815260040160405180910390fd5b506001600160601b03831661317a565b60ff8716613166575084546001600160a01b03166000908152600360205260409020546001600160601b031661317a565b508454600160a01b90046001600160601b03165b604080840182905263ffffffff8616808302602080870182905285516001600160601b0390811660a08901819052918701511690920260c087018190529091016080860152908301516131d5919061ffff1661271091020490565b60e08401819052608084015101606084015260208301516001870154612710600160a01b90910461ffff1690910204610100840152505060808101516020820151018152949350505050565b6002840154600090806132415750506001600160a01b0383161515610e82565b611f8f6001600160a01b038616151561326c83613263896000526014600c2090565b88918891613597565b15159015151690565b600881901c6000908152602092909252604090912054600160ff9092161c1690565b6001600160a01b038116612b1e576040516362ccef3360e01b815260040160405180910390fd5b61331967016345785d8a00006001600160601b031682600001516001600160601b03161167016345785d8a00006001600160601b031683602001516001600160601b0316116103e861ffff16846040015161ffff16116136ea565b15612b1e5760405163b17424c360e01b815260040160405180910390fd5b80612b1e5760405163caa2867f60e01b815260040160405180910390fd5b8063ffffffff16600003612b1e5760405163a017714560e01b815260040160405180910390fd5b6103e861ffff82161115612b1e57604051631a52ce6f60e01b815260040160405180910390fd5b600381901c600090815260209290925260409091205460059190911b60e0161c90565b6335278d126000526004601cfd5b60006133ed8260010154600160f01b9004600416151590565b6134045760048201546001600160a01b0316610c60565b50546001600160a01b039081166000908152600460205260409020541690565b60007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000030147f00000000000000000000000000000000000000000000000000000000000000004614166135195750604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81527f000000000000000000000000000000000000000000000000000000000000000060208201527f00000000000000000000000000000000000000000000000000000000000000009181019190915246606082015230608082015260a090205b67190100000000000060005280601a5282603a52604260182091506000603a5250919050565b804710156135555763b12d13eb6000526004601cfd5b60005a60005a8486620186a0f161294457816000526073600b5360ff6020536016600b82f0612944575a60141c3d5a3e5050565b6382b429006000526004601cfd5b600083156135c9578360051b8501855b803580851160051b948552602094851852604060002093018181106135a75750505b501492915050565b600060405163e839bd536000528360205282604052602060006064601c6c447e69651d841bd8d104bed4935afa600160005114169150806040525092915050565b6001600160a01b039093169260008415610e8257604051604183036136705784600052604084013560001a602052604084604037602060016080600060015afa805187183d151761366e57506000606052604052506001610e82565b505b600060605280604052631626ba7e60e01b80825285600483015260248201604081528460448401528486606485013760208160648701858b5afa905190911416915050949350505050565b600881901c600090815260209290925260409091208054600160ff9093169290921b9182189081905516151590565b600083151583151583151517151517610e82565b6040518061012001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040805161024081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e08101829052610200810182905261022081019190915290565b6000602082840312156137f057600080fd5b81356001600160e01b0319811681146117d057600080fd5b6000815180845260005b8181101561382e57602081850181015186830182015201613812565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006117d06020830184613808565b6001600160a01b0381168114612b1e57600080fd5b8035612af281613861565b803560ff81168114612af257600080fd5b600080600080608085870312156138a857600080fd5b84356138b381613861565b93506138c160208601613881565b92506138cf60408601613881565b915060608501356138df81613861565b939692955090935050565b6000806000806080858703121561390057600080fd5b843561390b81613861565b935061391960208601613881565b925061392760408601613881565b9396929550929360600135925050565b6000806040838503121561394a57600080fd5b823561395581613861565b915061396360208401613881565b90509250929050565b803563ffffffff81168114612af257600080fd5b6000806000806080858703121561399657600080fd5b84356139a181613861565b93506139af60208601613881565b92506139bd60408601613881565b91506139cb6060860161396c565b905092959194509250565b6000602082840312156139e857600080fd5b81356117d081613861565b600080600080600060a08688031215613a0b57600080fd5b8535613a1681613861565b9450613a2460208701613881565b9350613a3260408701613881565b9250613a406060870161396c565b9150613a4e6080870161396c565b90509295509295909350565b80356001600160601b0381168114612af257600080fd5b60008060008060808587031215613a8757600080fd5b8435613a9281613861565b9350613aa060208601613881565b9250613aae60408601613881565b91506139cb60608601613a5a565b600060208284031215613ace57600080fd5b813567ffffffffffffffff811115613ae557600080fd5b820161020081850312156117d057600080fd5b60808101610c6082846001600160601b038082511683528060208301511660208401525061ffff60408201511660408301526060810151151560608301525050565b600060208284031215613b4c57600080fd5b6117d082613a5a565b60008083601f840112613b6757600080fd5b50813567ffffffffffffffff811115613b7f57600080fd5b6020830191508360208260051b8501011115613b9a57600080fd5b9250929050565b60008060008060008060a08789031215613bba57600080fd5b8635613bc581613861565b9550613bd360208801613881565b9450613be160408801613881565b93506060870135613bf181613861565b9250608087013567ffffffffffffffff811115613c0d57600080fd5b613c1989828a01613b55565b979a9699509497509295939492505050565b600080600080600060808688031215613c4357600080fd5b8535613c4e81613861565b9450613c5c60208701613881565b9350613c6a60408701613881565b9250606086013567ffffffffffffffff811115613c8657600080fd5b613c9288828901613b55565b969995985093965092949392505050565b6020808252825182820181905260009190848201906040850190845b81811015613cdd578351151583529284019291840191600101613cbf565b50909695505050505050565b60ff60f81b881681526000602060e081840152613d0960e084018a613808565b8381036040850152613d1b818a613808565b606085018990526001600160a01b038816608086015260a0850187905284810360c0860152855180825283870192509083019060005b81811015613d6d57835183529284019291840191600101613d51565b50909c9b505050505050505050505050565b634e487b7160e01b600052604160045260246000fd5b6040516101a0810167ffffffffffffffff81118282101715613dc757634e487b7160e01b600052604160045260246000fd5b60405290565b803561ffff81168114612af257600080fd5b8015158114612b1e57600080fd5b600060808284031215613dff57600080fd5b6040516080810181811067ffffffffffffffff82111715613e3057634e487b7160e01b600052604160045260246000fd5b604052905080613e3f83613a5a565b8152613e4d60208401613a5a565b6020820152613e5e60408401613dcd565b60408201526060830135613e7181613ddf565b6060919091015292915050565b600060808284031215613e9057600080fd5b6117d08383613ded565b80516001600160a01b031682526020810151613ebb602084018260ff169052565b506040810151613ed0604084018260ff169052565b506060810151613eeb60608401826001600160a01b03169052565b506080810151613f0660808401826001600160601b03169052565b5060a0810151613f1e60a084018263ffffffff169052565b5060c0810151613f3660c084018263ffffffff169052565b5060e0810151613f4e60e084018263ffffffff169052565b506101008181015163ffffffff9081169184019190915261012080830151909116908301526101408082015161ffff16908301526101608082015160ff1690830152610180808201511515908301526101a0808201511515908301526101c080820151908301526101e08082015190830152610200808201516001600160a01b0316908301526102208082015180151582850152612e61565b6020808252825182820181905260009190848201906040850190845b81811015613cdd57614016838551613e9a565b928401926102409290920191600101614003565b60008060a0838503121561403d57600080fd5b61404683613881565b91506139638460208501613ded565b6000806000806080858703121561406b57600080fd5b843561407681613861565b935061408460208601613881565b925061409260408601613881565b91506139cb60608601613dcd565b60006101a082840312156140b357600080fd5b6140bb613d95565b6140c483613876565b81526140d260208401613a5a565b60208201526140e36040840161396c565b60408201526140f46060840161396c565b60608201526141056080840161396c565b608082015261411660a0840161396c565b60a082015261412760c08401613dcd565b60c082015260e083013560e0820152610100614144818501613881565b90820152610120614156848201613876565b90820152610140614168848201613881565b9082015261016061417a848201613876565b90820152610180928301359281019290925250919050565b6000806000606084860312156141a757600080fd5b83356141b281613861565b92506141c060208501613881565b91506141ce60408501613881565b90509250925092565b6102408101610c608284613e9a565b600080600080608085870312156141fc57600080fd5b843561420781613861565b935061421560208601613881565b925061422360408601613881565b915060608501356138df81613ddf565b600080600080600060a0868803121561424b57600080fd5b853561425681613861565b945061426460208701613881565b935061427260408701613881565b92506142806060870161396c565b9150613a4e60808701613a5a565b6000602082840312156142a057600080fd5b6117d082613881565b6000602082840312156142bb57600080fd5b6117d08261396c565b6000808335601e198436030181126142db57600080fd5b83018035915067ffffffffffffffff8211156142f657600080fd5b6020019150600581901b3603821315613b9a57600080fd5b60006020828403121561432057600080fd5b5051919050565b60ff848116825283166020820152815163ffffffff1660408201526101e081016020830151606083015260408301516001600160a01b038116608084015250606083015163ffffffff811660a084015250608083015163ffffffff811660c08401525060a083015163ffffffff811660e08401525060c08301516101006143b8818501836001600160a01b03169052565b60e085015191506101206143cf8186018415159052565b908501516101408581019190915290850151610160808601919091529085015161018080860191909152908501516101a0850152909301516101c0909201919091529392505050565b634e487b7160e01b600052603260045260246000fd5b60ff8316815260a081016117d060208301846001600160601b038082511683528060208301511660208401525061ffff60408201511660408301526060810151151560608301525050565b60ff84811682528316602082015281516001600160a01b031660408201526101e0810160208301516001600160601b038116606084015250604083015163ffffffff8116608084015250606083015163ffffffff811660a084015250608083015163ffffffff811660c08401525060a083015163ffffffff811660e08401525060c08301516101006145108185018361ffff169052565b60e085015161012085810191909152908501519150610140906145378286018460ff169052565b8501519150610160614553858201846001600160a01b03169052565b9085015191506101809061456b8583018460ff169052565b8501516001600160a01b03166101a0850152909301516101c0909201919091529392505050565b6000602082840312156145a457600080fd5b81516117d081613861565b6000602082840312156145c157600080fd5b81516117d081613ddf565b6000808335601e198436030181126145e357600080fd5b83018035915067ffffffffffffffff8211156145fe57600080fd5b602001915036819003821315613b9a57600080fdfea264697066735822122082a9fe6d3c01d9f8932f133836ed974fec48211730542b3dc9d954d491f4065164736f6c63430008130033

Deployed Bytecode

0x6080604052600436106103035760003560e01c8063a01efa3411610190578063de9484af116100dc578063e62a61a711610095578063f57402961161006f578063f574029614610b4e578063f7b2f1bf14610b6e578063fb128c8314610ab2578063fe1c0c4b14610b8357610312565b8063e62a61a714610aee578063edb3a0a314610b0e578063edcf0e2114610b2e57610312565b8063de9484af14610a19578063e1a4521814610a39578063e1f3e17d14610a4f578063e3d47d5c14610a85578063e4f6a4f014610ab2578063e544144314610ace57610312565b8063b985423111610149578063cbd8aff211610123578063cbd8aff214610976578063d03206a41461067a578063d379ab5f146109c4578063d3ec6f59146109e457610312565b8063b9854231146108d4578063bd3e8fc9146108f4578063c4f0c1c21461092857610312565b8063a01efa3414610805578063a167fd5f14610825578063ab9868971461083a578063ac1fc22c14610867578063b057868814610894578063b276be35146108b457610312565b8063532cf5961161024f57806370304e2f1161020857806387d4d28c116101e257806387d4d28c146107985780639375da5a146107c557806393e8bcf914610371578063998eb8c2146107e557610312565b806370304e2f146106a3578063752d8e91146106d057806384b0196e1461077057610312565b8063532cf5961461055a57806354fd4d50146105875780635e7876821461059c57806361b26ea41461063a5780636a7319cf1461065a5780636c5f55f71461067a57610312565b80631e1846c8116102bc57806344a8246f1161029657806344a8246f146104e75780634618d76214610507578063498120a0146105275780634a04a1c91461054757610312565b80631e1846c8146103f857806320606b70146104855780633b79c44f146104c757610312565b806301ffc9a71461031a57806306fdde031461034f5780630a25dea91461037157806315329da0146103985780631542b7fc146103b85780631b98e510146103d857610312565b3661031257610310610ba3565b005b610310610ba3565b34801561032657600080fd5b5061033a6103353660046137de565b610c3b565b60405190151581526020015b60405180910390f35b34801561035b57600080fd5b50610364610c66565b604051610346919061384e565b34801561037d57600080fd5b50610386600081565b60405160ff9091168152602001610346565b3480156103a457600080fd5b506103106103b3366004613892565b610c76565b3480156103c457600080fd5b506103106103d33660046138ea565b610da9565b3480156103e457600080fd5b506103866103f3366004613937565b610e31565b34801561040457600080fd5b50610418610413366004613980565b610e69565b6040516103469190600061012082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e083015160e083015261010080840151818401525092915050565b34801561049157600080fd5b506104b97f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b604051908152602001610346565b3480156104d357600080fd5b506103106104e23660046139d6565b610e8a565b3480156104f357600080fd5b506103106105023660046139f3565b610efe565b34801561051357600080fd5b50610310610522366004613980565b610fe6565b34801561053357600080fd5b50610310610542366004613a71565b6110c4565b610310610555366004613abc565b611190565b34801561056657600080fd5b5061057a610575366004613937565b6116af565b6040516103469190613af8565b34801561059357600080fd5b506103646117d7565b3480156105a857600080fd5b5061057a6105b73660046139d6565b604080516080808201835260008083526020808401829052838501829052606093840182905294831b6101001781526006855283902083519182018452546001600160601b038082168352600160601b82041694820194909452600160c01b840461ffff1692810192909252600160d01b90920460ff1615159181019190915290565b34801561064657600080fd5b50610310610655366004613b3a565b6117e1565b34801561066657600080fd5b5061033a610675366004613ba1565b61185a565b34801561068657600080fd5b506106906103e881565b60405161ffff9091168152602001610346565b3480156106af57600080fd5b506106c36106be366004613c2b565b61188a565b6040516103469190613ca3565b3480156106dc57600080fd5b5061057a6106eb366004613937565b604080516080808201835260008083526020808401829052838501829052606093840182905295831b60ff9586161781526006865283902083519182018452546001600160601b038082168352600160601b82041695820195909552600160c01b850461ffff1692810192909252600160d01b90930490911615159181019190915290565b34801561077c57600080fd5b5061078561196e565b6040516103469796959493929190613ce9565b3480156107a457600080fd5b506104b96107b33660046139d6565b60006020819052908152604090205481565b3480156107d157600080fd5b506103106107e03660046139d6565b611995565b3480156107f157600080fd5b50610310610800366004613e7e565b611a0a565b34801561081157600080fd5b506103106108203660046138ea565b611ade565b34801561083157600080fd5b50610386600281565b34801561084657600080fd5b5061085a6108553660046139d6565b611b91565b6040516103469190613fe7565b34801561087357600080fd5b506104b96108823660046139d6565b60026020526000908152604090205481565b3480156108a057600080fd5b506103106108af366004613980565b611c87565b3480156108c057600080fd5b506103106108cf366004613980565b611d81565b3480156108e057600080fd5b506103106108ef36600461402a565b611dc9565b34801561090057600080fd5b506104b97fc03e2545e609fd0b7813d6074f00235b048ae7580a8e57070eed03901dd951ae81565b34801561093457600080fd5b5061095e6109433660046139d6565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610346565b34801561098257600080fd5b506109ac6109913660046139d6565b6003602052600090815260409020546001600160601b031681565b6040516001600160601b039091168152602001610346565b3480156109d057600080fd5b506103106109df366004614055565b611ead565b3480156109f057600080fd5b50610a046109ff366004613892565b611f4c565b60405163ffffffff9091168152602001610346565b348015610a2557600080fd5b50610386610a343660046140a0565b611f99565b348015610a4557600080fd5b5061069061271081565b348015610a5b57600080fd5b5061095e610a6a3660046139d6565b6001602052600090815260409020546001600160a01b031681565b348015610a9157600080fd5b50610aa5610aa0366004614192565b612462565b60405161034691906141d7565b348015610abe57600080fd5b506109ac67016345785d8a000081565b348015610ada57600080fd5b50610310610ae93660046141e6565b6125f1565b348015610afa57600080fd5b506104b9610b09366004613abc565b6126a6565b348015610b1a57600080fd5b50610310610b293660046139d6565b6127eb565b348015610b3a57600080fd5b50610418610b49366004614233565b612891565b348015610b5a57600080fd5b50610310610b693660046139d6565b6128c7565b348015610b7a57600080fd5b50610386600181565b348015610b8f57600080fd5b5061033a610b9e366004613892565b612948565b36610bac573636f35b6000805b80368210610bbe5750610c1a565b600180830192600319810190351860001a9081610c0a57600019855260028301933560021984011860001a607f808211610bf9578282013888395b16949094019093019250610bb09050565b8185538085019450505050610bb0565b50600080826000305af490503d6000803e80610c35573d6000fd5b503d6000f35b60006301ffc9a760e01b6001600160e01b0319831690811463028b35ad60e31b909114175b92915050565b6060610c70612958565b50919050565b83610c8081612995565b6000610c8d868686612a98565b90506000610c9a82612ab4565b6001810154909150600160e81b900460ff16600214610ccc5760405163d25a973560e01b815260040160405180910390fd5b610cd584612af7565b6001818101546001600160a01b03861690911490610d0a9060ff600160f01b9091041660048360ff8383161615901518021890565b82600101601e6101000a81548160ff021916908360ff16021790555080610d49576004820180546001600160a01b0319166001600160a01b0387161790555b6040805160ff808a168252881660208201526001600160a01b0387811692820192909252908916907fc82787a128aa35191b6a1df922a24f581a06500f78030b89582d624c6ae9b2c9906060015b60405180910390a25050505050505050565b83610db381612995565b6000610dc0868686612a98565b90506000610dcd82612ab4565b600281018590556040805160ff808a168252881660208201529081018690529091506001600160a01b038816907fe08051cfd6c9341327f7f5550f77e02e815f59c1ecba22a4ac006ddca62dec20906060015b60405180910390a250505050505050565b600060056000610e4385856000612a98565b8152602081019190915260400160002060010154600160e01b900460ff16905092915050565b610e716136fe565b610e7f858585856000612891565b90505b949350505050565b6000610e94612b21565b6001600160a01b0381811660008181526004602090815260409182902080546001600160a01b03191694881694851790559051928352929350917fb9aba67a9619eecb4b3e9fe6ded4a35c9bcdbfb1040f5122f91716de616a799391015b60405180910390a25050565b84610f0881612995565b6000610f15878787612a98565b90506000610f2282612ab4565b905060ff8716158015610f3b575063ffffffff84811614155b15610f595760405163d25a973560e01b815260040160405180910390fd5b610f638585612b59565b60018101805463ffffffff87811667ffffffffffffffff199092168217640100000000918816918202179092556040805160ff808c1682528a1660208201529081019190915260608101919091526001600160a01b038916907f41ad9ed088bad8a3ad3052c7360f6919b647b45d4b527e478d463edbb8f9a43590608001610d97565b83610ff081612995565b6000610ffd868686612a98565b9050600061100a82612ab4565b905060ff861615801561102957506001810154600160e81b900460ff16155b156110475760405163d25a973560e01b815260040160405180910390fd5b61105084612b86565b60018101805463ffffffff60601b1916600160601b63ffffffff8716908102919091179091556040805160ff808a16825288166020820152908101919091526001600160a01b038816907f5da54689220406b0ee18edb07d2007345f96968da27c7fd0f405f649d26040a890606001610e20565b836110ce81612995565b60006110db868686612a98565b905060006110e882612ab4565b905060ff861615801561110a57506001810154600160e81b900460ff16600214155b156111285760405163d25a973560e01b815260040160405180910390fd5b80546001600160601b038516600160a01b81026001600160a01b039283161783556040805160ff8a811682528916602082015290810191909152908816907f3b082de0ef84f822f97496af03a3df5a8d5f0c271ea658b5b210819f1310494f90606001610e20565b60006111cf6111ca6111a560208501856139d6565b6111b5604086016020870161428e565b6111c5606087016040880161428e565b612a98565b612ab4565b600181015490915042640100000000820463ffffffff9081168211921611171561123657600181015460405163296f4f6960e01b815242600482015263ffffffff808316602483015264010000000090920490911660448201526064015b60405180910390fd5b61124d8160010154600160f01b9004600216151590565b1561126b57604051636be9245d60e11b815260040160405180910390fd5b6001810154600160e81b900460ff1660001981016112925761128d8284612bad565b6112a8565b60011960ff8216016112a8576112a88284612d2e565b6112b3818385612e67565b60006112f06112c8604086016020870161428e565b846112d960a08801608089016142a9565b6112eb61012089016101008a01613b3a565b6130b1565b905060008082600001513414611325578251604051630374cb4760e21b8152346004820152602481019190915260440161122d565b6060830151835186546001600160a01b03166000908152602081905260409020805483019055039150611377856113646101c089016101a08a016139d6565b6113726101c08a018a6142c4565b613221565b905080156113c5576101008301519182900391600260006113a06101c08a016101a08b016139d6565b6001600160a01b03168152602081019190915260400160002080549091019055611409565b60006113d96101c088016101a089016139d6565b6001600160a01b031614611400576040516320d6c38960e01b815260040160405180910390fd5b60006101008401525b600061141860208801886139d6565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915290915061149460a0890160808a016142a9565b63ffffffff1681526001600160a01b03821663eebab8ef856114bc60408c0160208d0161428e565b6114cc60808d0160608e016139d6565b6114dc60a08e0160808f016142a9565b6040516001600160e01b031960e087901b16815260ff90931660048401526001600160a01b03909116602483015263ffffffff16604482015260640160206040518083038185885af1158015611536573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061155b919061430e565b602082015261157060c0890160a08a016139d6565b6001600160a01b0316604082015261158e60e0890160c08a016142a9565b63ffffffff1660608201526115ab61016089016101408a016142a9565b63ffffffff1660a08201526115c86101c089016101a08a016139d6565b6001600160a01b031660c082015282151560e08201528451610100808301919091526040860151610120830152606080870151610140840152608080880151610160850152918701516101808401526101e08a01359161162d91908b01908b016139d6565b6001600160a01b031661164360208b018b6139d6565b6001600160a01b03167f2a29f7402bd32f0e4bbe17d44be064f7f64d96ee174ed7cb27936d869bf9a88861167d60408d0160208e0161428e565b61168d60608e0160408f0161428e565b8660405161169d93929190614327565b60405180910390a45050505050505050565b604080516080808201835260008083526020808401829052838501829052606080850183905260ff87811689831b178452600683529286902086519485018752546001600160601b038082168652600160601b8204169285019290925261ffff600160c01b83041695840195909552600160d01b900416151592810183905290916117a15760066000606086901b6101001781526020808201929092526040908101600020815160808101835290546001600160601b038082168352600160601b82041693820193909352600160c01b830461ffff1691810191909152600160d01b90910460ff161515606082015290505b80606001516117d057506040805160808101825260008082526020820181905291810182905260608101919091525b9392505050565b6060610c60612958565b60006117eb612b21565b6001600160a01b03811660008181526003602090815260409182902080546bffffffffffffffffffffffff19166001600160601b038816908117909155915191825292935090917fed3d3f99e57c78ce76ac9a1704a72bb912e8f231cc25c6379fdf5354dbb6481b9101610ef2565b600080611868888888612a98565b905061187e61187682612ab4565b868686613221565b98975050505050505050565b60606000611899878787612a98565b60008181526008602052604090209091508367ffffffffffffffff8111156118c3576118c3613d7f565b6040519080825280602002602001820160405280156118ec578160200160208202803683370190505b50925060005b8085146119625761193886868381811061190e5761190e614418565b905060200201602081019061192391906142a9565b63ffffffff168361327590919063ffffffff16565b84828151811061194a5761194a614418565b911515602092830291909101909101526001016118f2565b50505095945050505050565b600f60f81b6060806000808083611983612958565b97989097965046955030945091925090565b600061199f612b21565b90506119aa82613297565b6001600160a01b0381811660008181526001602090815260409182902080546001600160a01b0319169487169485179055905192835290917f3a9b87574e9f01aaafa6d829c77645fe96010be0b3093259c7873f4a93de28e99101610ef2565b6000611a14612b21565b9050611a1f826132be565b606081811b61010017600090815260066020908152604091829020855181549287015187850151958801511515600160d01b0260ff60d01b1961ffff909716600160c01b029690961662ffffff60c01b196001600160601b03928316600160601b026001600160c01b0319909616929093169190911793909317169190911792909217909155516001600160a01b038216907fec59616fef2c95b1d9e549c69e956a02fc10d12473c9667d711355ff224a2fe690610ef2908590613af8565b83611ae881612995565b6000611af5868686612a98565b90506000611b0282612ab4565b600180820154919250600160e81b90910460ff1614611b345760405163d25a973560e01b815260040160405180910390fd5b611b3d84613337565b600381018490556040805160ff8089168252871660208201529081018590526001600160a01b038816907f0b0a6fe894fe7695ac067d44d6e0de766337e9c3b5f0ee0a61be727383aac5a790606001610e20565b606081811b6000908152600560205260409020600181015461ffff600160d01b8204811691600160c01b9004168167ffffffffffffffff811115611bd757611bd7613d7f565b604051908082528060200260200182016040528015611c1057816020015b611bfd61374a565b815260200190600190039081611bf55790505b5093505b8115611c7f5761ffff8116606086901b176000908152600560205260409020611c458660ff600885901c1684612462565b85846001900394508481518110611c5e57611c5e614418565b602090810291909101015260010154600160b01b900461ffff169050611c14565b505050919050565b83611c9181612995565b6000611c9e868686612a98565b90506000611cab82612ab4565b905060ff8616611cce5760405163d25a973560e01b815260040160405180910390fd5b6001810154600119600160e81b90910460ff1601611cff5760405163d25a973560e01b815260040160405180910390fd5b611d0884613355565b6001810180546bffffffff00000000000000001916600160401b63ffffffff8716908102919091179091556040805160ff808a16825288166020820152908101919091526001600160a01b038816907f674233c20daf715ad9e94f9e5818adc53482b77e9556564e5fe3766678246e8e90606001610e20565b6000611d8e858585612a98565b600081815260056020526040902060010154909150611dc2908690869086908690640100000000900463ffffffff16610efe565b5050505050565b6000611dd3612b21565b9050611dde826132be565b606081811b60ff851617600090815260066020908152604091829020855181549287015187850151958801511515600160d01b0260ff60d01b1961ffff909716600160c01b029690961662ffffff60c01b196001600160601b03928316600160601b026001600160c01b0319909616929093169190911793909317169190911792909217909155516001600160a01b038216907f2e28b985b43becdaa221ff743fd386f80ace62daa5b69941fd6b51445ddaf4ee90611ea0908690869061442e565b60405180910390a2505050565b83611eb781612995565b6000611ec4868686612a98565b90506000611ed182612ab4565b9050611edc8461337c565b60018101805461ffff60a01b1916600160a01b61ffff8716908102919091179091556040805160ff808a16825288166020820152908101919091526001600160a01b038816907fcdff4ec2999e249a9a848accff5e46b43263f82c4076334cd70300e07326472d90606001610e20565b600080611f5a868686612a98565b6001600160a01b0384166000908152600760209081526040808320600385901c845290915290205490915060e0600583901b161c5b9695505050505050565b6000611fa88260000151612995565b611fb58260c0015161337c565b61014082015160ff8116611fd85760006101608401819052610180840152612049565b60001960ff821601611fff57611ff2836101800151613337565b6000610160840152612049565b60011960ff82160161203057612019836101600151612af7565b600061018084015263ffffffff6080840152612049565b60405163a0042b1760e01b815260040160405180910390fd5b61010083015160ff1661208d5763ffffffff60608401819052608084015260ff811660021461207a57600060208401525b60ff811661208d5763ffffffff60a08401525b61209f83604001518460600151612b59565b6120ac8360800151613355565b6120b98360a00151612b86565b6000600560006120d486600001518761010001516000612a98565b815260208082019290925260409081016000908120875160601b8252600590935220600180830154600160e01b900460ff169550919250908401610100811061211f5761211f6133c6565b6001808401805460ff909316600160e01b0260ff60e01b19909316929092179091558181015461ffff600160d01b9091041601620100008110612164576121646133c6565b60018201805461ffff60d01b1916600160d01b61ffff84160217905585516101008701516000916121959188612a98565b9050600060016001600160a01b03168861016001516001600160a01b031614905060006005600084815260200190815260200160002090508861012001518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555088602001518160000160146101000a8154816001600160601b0302191690836001600160601b0316021790555088604001518160010160006101000a81548163ffffffff021916908363ffffffff16021790555088606001518160010160046101000a81548163ffffffff021916908363ffffffff16021790555088608001518160010160086101000a81548163ffffffff021916908363ffffffff1602179055508860a0015181600101600c6101000a81548163ffffffff021916908363ffffffff1602179055508860c001518160010160146101000a81548161ffff021916908361ffff16021790555088610140015181600101601d6101000a81548160ff021916908360ff1602179055506123168260049015150290565b6001828101805460ff60f01b198116600160f01b94841760ff908116959095029081178355928901805468ff000000000000ffff60b01b1990921661ffff60b01b1990941693909317600160c01b9182900461ffff16600160b01b02179091556101008c0151825461ffff60c01b1916938c1660089190911b61ff0016170291909117905560e0890151156123b05760e089015160028201555b610180890151156123c75761018089015160038201555b6101608901516001600160a01b0316156124085781612408576101608901516004820180546001600160a01b0319166001600160a01b039092169190911790555b88600001516001600160a01b03167fcbaa8cb5ab7e807c363e8c49ecb8b778bb2217e8e7d375826e911413a4c734f48a61010001518a8c60405161244e93929190614479565b60405180910390a250505050505050919050565b61246a61374a565b6000612477858585612a98565b9050600061248482612ab4565b6001600160a01b03808816855260ff808816602087018190529087166040870152825490911660608601529091501580156124ce57506001810154600160e81b900460ff16600214155b6124e9578054600160a01b90046001600160601b031661250d565b80546001600160a01b03166000908152600360205260409020546001600160601b03165b6001600160601b03166080840152600181015463ffffffff80821660a08601526401000000008204811660c0860152600160401b8204811660e0860152600160601b82048116610100860152600160801b820416610120850152600160a01b810461ffff16610140850152600160e81b810460ff166101608501526002600160f01b909104811615156101808501528101546101c084015260038101546101e08401526125b9816133d4565b6001600160a01b03166102008401526125df8160010154600160f01b9004600416151590565b15156102208401525090949350505050565b836125fb81612995565b6000612608868686612a98565b9050600061261582612ab4565b600181015490915061263e9060ff600160f01b9091041660028660ff8383161615901518021890565b60018201805460ff60f01b1916600160f01b60ff938416021790556040805188831681529187166020830152851515908201526001600160a01b038816907f81bd379475659273b35365d353d46c7de87aa468a01efc54544fcee90ae0d3b690606001610e20565b6000610c607fc03e2545e609fd0b7813d6074f00235b048ae7580a8e57070eed03901dd951ae6126d960208501856139d6565b6126e9604086016020870161428e565b6126f9606087016040880161428e565b61270960808801606089016139d6565b61271b61014089016101208a016142a9565b61272d6101608a016101408b016142a9565b61273f6101208b016101008c01613b3a565b6127516101808c016101608d016142a9565b6127636101c08d016101a08e016139d6565b60408051602081019b909b526001600160a01b03998a16908b015260ff97881660608b015296909516608089015292861660a088015263ffffffff91821660c0880152811660e08701526001600160601b0390911661010086015216610120840152166101408201526101600160405160208183030381529060405280519060200120613424565b6001600160a01b038082166000908152600160205260409020541661280f81613297565b6001600160a01b038216600090815260208190526040902054801561288c576001600160a01b038316600090815260208190526040812055612851828261353f565b826001600160a01b03167ffc7ad544ff6a06d6499925723d25b6fe70457a42939995b1d3d6f560fe33633382604051611ea091815260200190565b505050565b6128996136fe565b60006128a6878787612a98565b90506128bc866128b583612ab4565b86866130b1565b979650505050505050565b6001600160a01b0381166000908152600260205260409020548015612944576001600160a01b038216600090815260026020526040812055612909828261353f565b816001600160a01b03167f0a1adaaf9d9caba9cf65528900e946b718d511ebd66ae81d5eb71e7fd0122c4a82604051610ef291815260200190565b5050565b6000610e7f85858585368661185a565b604080518082018252600b81526a29bab832b926b4b73a32b960a91b602080830191909152825180840190935260018352603160f81b9083015291565b600061299f612b21565b9050816001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156129df573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a039190614592565b6001600160a01b0316816001600160a01b0316146129445760405163145398bf60e21b81526001600160a01b0382811660048301526001602483015283169063514e62fc90604401602060405180830381865afa158015612a68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a8c91906145af565b61294457612944613589565b60008360601b60005282601e5381601f53505060005192915050565b60008181526005602052604081206001808201549192600160f01b909204169003612af25760405163947dbacd60e01b815260040160405180910390fd5b919050565b6001600160a01b038116612b1e5760405163327effa960e11b815260040160405180910390fd5b50565b6000336000526e2fd5aeb385d324b580fca7c83823a0803303612b515760206000806000845afa612b5157600080fd5b505060005190565b8063ffffffff168263ffffffff1611156129445760405163536a71af60e01b815260040160405180910390fd5b8063ffffffff16600003612b1e57604051630ccae60160e31b815260040160405180910390fd5b6000612bbf60e0830160c084016142a9565b90506000612bd360c0840160a085016139d6565b90506001600160a01b038116612bfc5760405163582f497d60e11b815260040160405180910390fd5b63fffffffe1963ffffffff831601612c8757612c3b8460030154612c25836000526014600c2090565b612c3260e08701876142c4565b90929091613597565b158015612c645750612c628460030154612c258363ffffffff6004526000526018600c2090565b155b15612c825760405163582f497d60e11b815260040160405180910390fd5b612cbf565b612ca28460030154612c2583856004526000526018600c2090565b612cbf5760405163582f497d60e11b815260040160405180910390fd5b6000612cc9612b21565b9050612d036001600160a01b03838116908316811490612cef60808801606089016139d6565b6001600160a01b0316149015159015151790565b611dc257612d1181836135d1565b611dc25760405163fe736e0160e01b815260040160405180910390fd5b612d40610140820161012083016142a9565b63ffffffff16612d5660a08301608084016142a9565b63ffffffff161115612d7b576040516352ad28c360e11b815260040160405180910390fd5b6000612d86836133d4565b9050612da881612d95846126a6565b612da36101808601866145cc565b613612565b612dc557604051638baa579f60e01b815260040160405180910390fd5b612dd7610180830161016084016142a9565b63ffffffff16421115612dfd57604051630819bdcd60e01b815260040160405180910390fd5b6000612e0f6111a560208501856139d6565b9050612e44612e26610160850161014086016142a9565b60008381526008602052604090209063ffffffff908116906136bb16565b612e615760405163900bb2c960e01b815260040160405180910390fd5b50505050565b6000612e7960a08301608084016142a9565b600184015463ffffffff918216600160801b82048316019250600160601b900416811115612eba57604051637f70f90b60e01b815260040160405180910390fd5b60018301805463ffffffff60801b1916600160801b63ffffffff8416021790556000612eec6111a560208501856139d6565b905060001960ff861601612fe7576000600781612f0f60c0870160a088016139d6565b6001600160a01b0316815260208101919091526040016000209050612f3a60a08501608086016142a9565b63ffffffff16612f5383836133a390919063ffffffff16565b600187015463ffffffff918216929092019450612f9691600160401b9004168411612f8460e0870160c088016142a9565b63ffffffff1685119015159015151790565b15612fb457604051631b75136560e01b815260040160405180910390fd5b6020819052600382901c600090815260409020805460e0600585901b1681811c861863ffffffff16901b18905550611dc2565b6000600781612ffc60808701606088016139d6565b6001600160a01b031681526020810191909152604001600020905061302760a08501608086016142a9565b63ffffffff1661304083836133a390919063ffffffff16565b600187015463ffffffff918216929092019450600160401b9091041683111561307c57604051631b75136560e01b815260040160405180910390fd5b6020819052600382901c600090815260409020805460e0600585901b1681811c861863ffffffff16901b189055505050505050565b6130b96136fe565b83546000906130d1906001600160a01b0316876116af565b6001860154909150600090600119600160e81b90910460ff16016131355785546001600160601b03600160a01b909104811690851610156131255760405163dcdc2f1560e01b815260040160405180910390fd5b506001600160601b03831661317a565b60ff8716613166575084546001600160a01b03166000908152600360205260409020546001600160601b031661317a565b508454600160a01b90046001600160601b03165b604080840182905263ffffffff8616808302602080870182905285516001600160601b0390811660a08901819052918701511690920260c087018190529091016080860152908301516131d5919061ffff1661271091020490565b60e08401819052608084015101606084015260208301516001870154612710600160a01b90910461ffff1690910204610100840152505060808101516020820151018152949350505050565b6002840154600090806132415750506001600160a01b0383161515610e82565b611f8f6001600160a01b038616151561326c83613263896000526014600c2090565b88918891613597565b15159015151690565b600881901c6000908152602092909252604090912054600160ff9092161c1690565b6001600160a01b038116612b1e576040516362ccef3360e01b815260040160405180910390fd5b61331967016345785d8a00006001600160601b031682600001516001600160601b03161167016345785d8a00006001600160601b031683602001516001600160601b0316116103e861ffff16846040015161ffff16116136ea565b15612b1e5760405163b17424c360e01b815260040160405180910390fd5b80612b1e5760405163caa2867f60e01b815260040160405180910390fd5b8063ffffffff16600003612b1e5760405163a017714560e01b815260040160405180910390fd5b6103e861ffff82161115612b1e57604051631a52ce6f60e01b815260040160405180910390fd5b600381901c600090815260209290925260409091205460059190911b60e0161c90565b6335278d126000526004601cfd5b60006133ed8260010154600160f01b9004600416151590565b6134045760048201546001600160a01b0316610c60565b50546001600160a01b039081166000908152600460205260409020541690565b60007f7f88e5d4fe8478d2cbee68c8c08d5aeecbc339410172d285126b4c9b4a5e64947f0000000000000000000000000000000000cf4558c36229ac0026ee16d3ae35cd30147f00000000000000000000000000000000000000000000000000000000000000014614166135195750604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81527fa6cb2587267be99efde5eb570922efe1ef200501c220db4e8df4187255e6c05060208201527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc69181019190915246606082015230608082015260a090205b67190100000000000060005280601a5282603a52604260182091506000603a5250919050565b804710156135555763b12d13eb6000526004601cfd5b60005a60005a8486620186a0f161294457816000526073600b5360ff6020536016600b82f0612944575a60141c3d5a3e5050565b6382b429006000526004601cfd5b600083156135c9578360051b8501855b803580851160051b948552602094851852604060002093018181106135a75750505b501492915050565b600060405163e839bd536000528360205282604052602060006064601c6c447e69651d841bd8d104bed4935afa600160005114169150806040525092915050565b6001600160a01b039093169260008415610e8257604051604183036136705784600052604084013560001a602052604084604037602060016080600060015afa805187183d151761366e57506000606052604052506001610e82565b505b600060605280604052631626ba7e60e01b80825285600483015260248201604081528460448401528486606485013760208160648701858b5afa905190911416915050949350505050565b600881901c600090815260209290925260409091208054600160ff9093169290921b9182189081905516151590565b600083151583151583151517151517610e82565b6040518061012001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040805161024081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e08101829052610200810182905261022081019190915290565b6000602082840312156137f057600080fd5b81356001600160e01b0319811681146117d057600080fd5b6000815180845260005b8181101561382e57602081850181015186830182015201613812565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006117d06020830184613808565b6001600160a01b0381168114612b1e57600080fd5b8035612af281613861565b803560ff81168114612af257600080fd5b600080600080608085870312156138a857600080fd5b84356138b381613861565b93506138c160208601613881565b92506138cf60408601613881565b915060608501356138df81613861565b939692955090935050565b6000806000806080858703121561390057600080fd5b843561390b81613861565b935061391960208601613881565b925061392760408601613881565b9396929550929360600135925050565b6000806040838503121561394a57600080fd5b823561395581613861565b915061396360208401613881565b90509250929050565b803563ffffffff81168114612af257600080fd5b6000806000806080858703121561399657600080fd5b84356139a181613861565b93506139af60208601613881565b92506139bd60408601613881565b91506139cb6060860161396c565b905092959194509250565b6000602082840312156139e857600080fd5b81356117d081613861565b600080600080600060a08688031215613a0b57600080fd5b8535613a1681613861565b9450613a2460208701613881565b9350613a3260408701613881565b9250613a406060870161396c565b9150613a4e6080870161396c565b90509295509295909350565b80356001600160601b0381168114612af257600080fd5b60008060008060808587031215613a8757600080fd5b8435613a9281613861565b9350613aa060208601613881565b9250613aae60408601613881565b91506139cb60608601613a5a565b600060208284031215613ace57600080fd5b813567ffffffffffffffff811115613ae557600080fd5b820161020081850312156117d057600080fd5b60808101610c6082846001600160601b038082511683528060208301511660208401525061ffff60408201511660408301526060810151151560608301525050565b600060208284031215613b4c57600080fd5b6117d082613a5a565b60008083601f840112613b6757600080fd5b50813567ffffffffffffffff811115613b7f57600080fd5b6020830191508360208260051b8501011115613b9a57600080fd5b9250929050565b60008060008060008060a08789031215613bba57600080fd5b8635613bc581613861565b9550613bd360208801613881565b9450613be160408801613881565b93506060870135613bf181613861565b9250608087013567ffffffffffffffff811115613c0d57600080fd5b613c1989828a01613b55565b979a9699509497509295939492505050565b600080600080600060808688031215613c4357600080fd5b8535613c4e81613861565b9450613c5c60208701613881565b9350613c6a60408701613881565b9250606086013567ffffffffffffffff811115613c8657600080fd5b613c9288828901613b55565b969995985093965092949392505050565b6020808252825182820181905260009190848201906040850190845b81811015613cdd578351151583529284019291840191600101613cbf565b50909695505050505050565b60ff60f81b881681526000602060e081840152613d0960e084018a613808565b8381036040850152613d1b818a613808565b606085018990526001600160a01b038816608086015260a0850187905284810360c0860152855180825283870192509083019060005b81811015613d6d57835183529284019291840191600101613d51565b50909c9b505050505050505050505050565b634e487b7160e01b600052604160045260246000fd5b6040516101a0810167ffffffffffffffff81118282101715613dc757634e487b7160e01b600052604160045260246000fd5b60405290565b803561ffff81168114612af257600080fd5b8015158114612b1e57600080fd5b600060808284031215613dff57600080fd5b6040516080810181811067ffffffffffffffff82111715613e3057634e487b7160e01b600052604160045260246000fd5b604052905080613e3f83613a5a565b8152613e4d60208401613a5a565b6020820152613e5e60408401613dcd565b60408201526060830135613e7181613ddf565b6060919091015292915050565b600060808284031215613e9057600080fd5b6117d08383613ded565b80516001600160a01b031682526020810151613ebb602084018260ff169052565b506040810151613ed0604084018260ff169052565b506060810151613eeb60608401826001600160a01b03169052565b506080810151613f0660808401826001600160601b03169052565b5060a0810151613f1e60a084018263ffffffff169052565b5060c0810151613f3660c084018263ffffffff169052565b5060e0810151613f4e60e084018263ffffffff169052565b506101008181015163ffffffff9081169184019190915261012080830151909116908301526101408082015161ffff16908301526101608082015160ff1690830152610180808201511515908301526101a0808201511515908301526101c080820151908301526101e08082015190830152610200808201516001600160a01b0316908301526102208082015180151582850152612e61565b6020808252825182820181905260009190848201906040850190845b81811015613cdd57614016838551613e9a565b928401926102409290920191600101614003565b60008060a0838503121561403d57600080fd5b61404683613881565b91506139638460208501613ded565b6000806000806080858703121561406b57600080fd5b843561407681613861565b935061408460208601613881565b925061409260408601613881565b91506139cb60608601613dcd565b60006101a082840312156140b357600080fd5b6140bb613d95565b6140c483613876565b81526140d260208401613a5a565b60208201526140e36040840161396c565b60408201526140f46060840161396c565b60608201526141056080840161396c565b608082015261411660a0840161396c565b60a082015261412760c08401613dcd565b60c082015260e083013560e0820152610100614144818501613881565b90820152610120614156848201613876565b90820152610140614168848201613881565b9082015261016061417a848201613876565b90820152610180928301359281019290925250919050565b6000806000606084860312156141a757600080fd5b83356141b281613861565b92506141c060208501613881565b91506141ce60408501613881565b90509250925092565b6102408101610c608284613e9a565b600080600080608085870312156141fc57600080fd5b843561420781613861565b935061421560208601613881565b925061422360408601613881565b915060608501356138df81613ddf565b600080600080600060a0868803121561424b57600080fd5b853561425681613861565b945061426460208701613881565b935061427260408701613881565b92506142806060870161396c565b9150613a4e60808701613a5a565b6000602082840312156142a057600080fd5b6117d082613881565b6000602082840312156142bb57600080fd5b6117d08261396c565b6000808335601e198436030181126142db57600080fd5b83018035915067ffffffffffffffff8211156142f657600080fd5b6020019150600581901b3603821315613b9a57600080fd5b60006020828403121561432057600080fd5b5051919050565b60ff848116825283166020820152815163ffffffff1660408201526101e081016020830151606083015260408301516001600160a01b038116608084015250606083015163ffffffff811660a084015250608083015163ffffffff811660c08401525060a083015163ffffffff811660e08401525060c08301516101006143b8818501836001600160a01b03169052565b60e085015191506101206143cf8186018415159052565b908501516101408581019190915290850151610160808601919091529085015161018080860191909152908501516101a0850152909301516101c0909201919091529392505050565b634e487b7160e01b600052603260045260246000fd5b60ff8316815260a081016117d060208301846001600160601b038082511683528060208301511660208401525061ffff60408201511660408301526060810151151560608301525050565b60ff84811682528316602082015281516001600160a01b031660408201526101e0810160208301516001600160601b038116606084015250604083015163ffffffff8116608084015250606083015163ffffffff811660a084015250608083015163ffffffff811660c08401525060a083015163ffffffff811660e08401525060c08301516101006145108185018361ffff169052565b60e085015161012085810191909152908501519150610140906145378286018460ff169052565b8501519150610160614553858201846001600160a01b03169052565b9085015191506101809061456b8583018460ff169052565b8501516001600160a01b03166101a0850152909301516101c0909201919091529392505050565b6000602082840312156145a457600080fd5b81516117d081613861565b6000602082840312156145c157600080fd5b81516117d081613ddf565b6000808335601e198436030181126145e357600080fd5b83018035915067ffffffffffffffff8211156145fe57600080fd5b602001915036819003821315613b9a57600080fdfea264697066735822122082a9fe6d3c01d9f8932f133836ed974fec48211730542b3dc9d954d491f4065164736f6c63430008130033

Deployed Bytecode Sourcemap

1029:41530:3:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21878:19;:17;:19::i;:::-;1029:41530;;21755:19;:17;:19::i;28514:210::-;;;;;;;;;;-1:-1:-1;28514:210:3;;;;;:::i;:::-;;:::i;:::-;;;566:14:21;;559:22;541:41;;529:2;514:18;28514:210:3;;;;;;;;28178:112;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;3899:33::-;;;;;;;;;;;;3931:1;3899:33;;;;;1498:4:21;1486:17;;;1468:36;;1456:2;1441:18;3899:33:3;1326:184:21;18345:643:3;;;;;;;;;;-1:-1:-1;18345:643:3;;;;;:::i;:::-;;:::i;15962:407::-;;;;;;;;;;-1:-1:-1;15962:407:3;;;;;:::i;:::-;;:::i;23464:164::-;;;;;;;;;;-1:-1:-1;23464:164:3;;;;;:::i;:::-;;:::i;22701:274::-;;;;;;;;;;-1:-1:-1;22701:274:3;;;;;:::i;:::-;;:::i;:::-;;;;;;4063:4:21;4105:3;4094:9;4090:19;4082:27;;4142:6;4136:13;4125:9;4118:32;4206:4;4198:6;4194:17;4188:24;4181:4;4170:9;4166:20;4159:54;4269:4;4261:6;4257:17;4251:24;4244:4;4233:9;4229:20;4222:54;4332:4;4324:6;4320:17;4314:24;4307:4;4296:9;4292:20;4285:54;4395:4;4387:6;4383:17;4377:24;4370:4;4359:9;4355:20;4348:54;4458:4;4450:6;4446:17;4440:24;4433:4;4422:9;4418:20;4411:54;4521:4;4513:6;4509:17;4503:24;4496:4;4485:9;4481:20;4474:54;4584:4;4576:6;4572:17;4566:24;4559:4;4548:9;4544:20;4537:54;4610:6;4670:2;4662:6;4658:15;4652:22;4647:2;4636:9;4632:18;4625:50;;3901:780;;;;;3775:58:3;;;;;;;;;;-1:-1:-1;3775:58:3;1250:66:13;3775:58:3;;;;;4832:25:21;;;4820:2;4805:18;3775:58:3;4686:177:21;21414:196:3;;;;;;;;;;-1:-1:-1;21414:196:3;;;;;:::i;:::-;;:::i;14424:656::-;;;;;;;;;;-1:-1:-1;14424:656:3;;;;;:::i;:::-;;:::i;17166:569::-;;;;;;;;;;-1:-1:-1;17166:569:3;;;;;:::i;:::-;;:::i;13350:550::-;;;;;;;;;;-1:-1:-1;13350:550:3;;;;;:::i;:::-;;:::i;10437:2692::-;;;;;;:::i;:::-;;:::i;25860:387::-;;;;;;;;;;-1:-1:-1;25860:387:3;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;28344:121::-;;;;;;;;;;;;;:::i;25612:194::-;;;;;;;;;;-1:-1:-1;25612:194:3;;;;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4543:10:2;;;5459:3:3;4540:37:2;25728:71:3;;:19;:71;;;;;25721:78;;;;;;;;-1:-1:-1;;;;;25721:78:3;;;;;-1:-1:-1;;;25721:78:3;;;;;;;;;;-1:-1:-1;;;25721:78:3;;;;;;;;;;;-1:-1:-1;;;25721:78:3;;;;;;;;;;;;;;;25612:194;21189:171;;;;;;;;;;-1:-1:-1;21189:171:3;;;;;:::i;:::-;;:::i;24022:377::-;;;;;;;;;;-1:-1:-1;24022:377:3;;;;;:::i;:::-;;:::i;4345:51::-;;;;;;;;;;;;4392:4;4345:51;;;;;9152:6:21;9140:19;;;9122:38;;9110:2;9095:18;4345:51:3;8978:188:21;24782:544:3;;;;;;;;;;-1:-1:-1;24782:544:3;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;25380:178::-;;;;;;;;;;-1:-1:-1;25380:178:3;;;;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4543:10:2;;;25521:29:3;;;;4540:37:2;25501:50:3;;:19;:50;;;;;25494:57;;;;;;;;-1:-1:-1;;;;;25494:57:3;;;;;-1:-1:-1;;;25494:57:3;;;;;;;;;;-1:-1:-1;;;25494:57:3;;;;;;;;;;;-1:-1:-1;;;25494:57:3;;;;;;;;;;;;;;;;25380:178;6926:596:13;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;5720:54:3:-;;;;;;;;;;-1:-1:-1;5720:54:3;;;;;:::i;:::-;;;;;;;;;;;;;;;20171:265;;;;;;;;;;-1:-1:-1;20171:265:3;;;;;:::i;:::-;;:::i;20831:304::-;;;;;;;;;;-1:-1:-1;20831:304:3;;;;;:::i;:::-;;:::i;17789:502::-;;;;;;;;;;-1:-1:-1;17789:502:3;;;;;:::i;:::-;;:::i;4098:42::-;;;;;;;;;;;;4139:1;4098:42;;26301:751;;;;;;;;;;-1:-1:-1;26301:751:3;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;5983:55::-;;;;;;;;;;-1:-1:-1;5983:55:3;;;;;:::i;:::-;;;;;;;;;;;;;;16423:689;;;;;;;;;;-1:-1:-1;16423:689:3;;;;;:::i;:::-;;:::i;15134:296::-;;;;;;;;;;-1:-1:-1;15134:296:3;;;;;:::i;:::-;;:::i;20490:287::-;;;;;;;;;;-1:-1:-1;20490:287:3;;;;;:::i;:::-;;:::i;3230:468::-;;;;;;;;;;;;3308:390;3230:468;;6230:49;;;;;;;;;;-1:-1:-1;6230:49:3;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;6230:49:3;;;;;;-1:-1:-1;;;;;17325:32:21;;;17307:51;;17295:2;17280:18;6230:49:3;17161:203:21;6109:41:3;;;;;;;;;;-1:-1:-1;6109:41:3;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;6109:41:3;;;;;;-1:-1:-1;;;;;17531:39:21;;;17513:58;;17501:2;17486:18;6109:41:3;17369:208:21;15484:424:3;;;;;;;;;;-1:-1:-1;15484:424:3;;;;;:::i;:::-;;:::i;23682:286::-;;;;;;;;;;-1:-1:-1;23682:286:3;;;;;:::i;:::-;;:::i;:::-;;;18221:10:21;18209:23;;;18191:42;;18179:2;18164:18;23682:286:3;18047:192:21;7101:3282:3;;;;;;;;;;-1:-1:-1;7101:3282:3;;;;;:::i;:::-;;:::i;4216:63::-;;;;;;;;;;;;1495:5:2;4216:63:3;;5852:53;;;;;;;;;;-1:-1:-1;5852:53:3;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;5852:53:3;;;27106:1018;;;;;;;;;;-1:-1:-1;27106:1018:3;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;4604:65::-;;;;;;;;;;;;4660:9;4604:65;;13954:416;;;;;;;;;;-1:-1:-1;13954:416:3;;;;;:::i;:::-;;:::i;22151:496::-;;;;;;;;;;-1:-1:-1;22151:496:3;;;;;:::i;:::-;;:::i;19543:438::-;;;;;;;;;;-1:-1:-1;19543:438:3;;;;;:::i;:::-;;:::i;23029:381::-;;;;;;;;;;-1:-1:-1;23029:381:3;;;;;:::i;:::-;;:::i;19149:340::-;;;;;;;;;;-1:-1:-1;19149:340:3;;;;;:::i;:::-;;:::i;3994:39::-;;;;;;;;;;;;4032:1;3994:39;;24453:275;;;;;;;;;;-1:-1:-1;24453:275:3;;;;;:::i;:::-;;:::i;11272:1120:17:-;11346:14;11336:68;;11346:14;;11364:38;11336:68;11426:1;;11503:628;11522:21;11346:14;11525:1;11522:21;;;-1:-1:-1;;;11522:21:17;11643:1;11636:9;;;;-1:-1:-1;;11586:9:17;;11597:15;;11582:31;11426:1;11574:40;;;11662:394;;-1:-1:-1;;11856:17:17;;11718:9;11772;;;11729:15;-1:-1:-1;;11718:9:17;;11714:31;11426:1;11706:40;11910:4;11904:11;;;11894:61;;11643:1;11947;11943:9;11931:10;11928:1;11919:34;11894:61;11992:12;11981:28;;;;;;;;-1:-1:-1;11503:628:17;;-1:-1:-1;11503:628:17;11662:394;12084:1;12081;12073:13;11643:1;12112;12108:9;12103:14;;;;;11503:628;;;11507:14;11426:1;;12196;11426;12179:9;12172:5;12159:51;12144:66;;12250:16;11426:1;;12223:44;12290:7;12280:53;;12314:16;11426:1;12301:30;12280:53;;12359:16;11426:1;12346:30;28514:210:3;28590:4;-1:-1:-1;;;;;;;;;28623:45:3;;28670:46;;;-1:-1:-1;;;28623:45:3;;;3385:40:2;28613:104:3;28606:111;28514:210;-1:-1:-1;;28514:210:3:o;28178:112::-;28217:19;28260:23;:21;:23::i;:::-;-1:-1:-1;28248:35:3;28178:112;-1:-1:-1;28178:112:3:o;18345:643::-;18497:7;29168:40;29200:7;29168:31;:40::i;:::-;18516:14:::1;18533:41;18547:7;18556:4;18562:11;18533:13;:41::i;:::-;18516:58;;18584:18;18605:20;18618:6;18605:12;:20::i;:::-;18639:6;::::0;::::1;::::0;18584:41;;-1:-1:-1;;;;18639:6:3;::::1;:26;:6;4139:1;18639:26;18635:56;;18674:17;;-1:-1:-1::0;;;18674:17:3::1;;;;;;;;;;;18635:56;18701:23;18717:6;18701:15;:23::i;:::-;18777:1;18816:7:::0;;::::1;::::0;-1:-1:-1;;;;;18759:20:3;::::1;::::0;;::::1;::::0;18799:71:::1;::::0;18816:7:::1;-1:-1:-1::0;;;18816:7:3;;::::1;;5240:6;18759:20:::0;2304:4:2;2310:16;;;2300:27;2293:35;2330:12;;2289:54;2285:65;2274:77;;2109:258;18799:71:3::1;18789:1;:7;;;:81;;;;;;;;;;;;;;;;;;18885:17;18880:41;;18904:8;::::0;::::1;:17:::0;;-1:-1:-1;;;;;;18904:17:3::1;-1:-1:-1::0;;;;;18904:17:3;::::1;;::::0;;18880:41:::1;18936:45;::::0;;21419:4:21;21407:17;;;21389:36;;21461:17;;21456:2;21441:18;;21434:45;-1:-1:-1;;;;;21515:32:21;;;21495:18;;;21488:60;;;;18936:45:3;;::::1;::::0;::::1;::::0;21377:2:21;21362:18;18936:45:3::1;;;;;;;;18506:482;;;18345:643:::0;;;;;:::o;15962:407::-;16125:7;29168:40;29200:7;29168:31;:40::i;:::-;16144:14:::1;16161:41;16175:7;16184:4;16190:11;16161:13;:41::i;:::-;16144:58;;16212:18;16233:20;16246:6;16233:12;:20::i;:::-;16263:21;::::0;::::1;:28:::0;;;16306:56:::1;::::0;;21783:4:21;21771:17;;;21753:36;;21825:17;;21820:2;21805:18;;21798:45;21859:18;;;21852:34;;;16212:41:3;;-1:-1:-1;;;;;;16306:56:3;::::1;::::0;::::1;::::0;21741:2:21;21726:18;16306:56:3::1;;;;;;;;16134:235;;15962:407:::0;;;;;:::o;23464:164::-;23539:5;23563:9;:42;23573:31;23587:7;23596:4;23602:1;23573:13;:31::i;:::-;23563:42;;;;;;;;;;;-1:-1:-1;23563:42:3;:58;;;-1:-1:-1;;;23563:58:3;;;;;-1:-1:-1;23464:164:3;;;;:::o;22701:274::-;22852:24;;:::i;:::-;22895:73;22928:7;22937:4;22943:11;22956:8;22966:1;22895:32;:73::i;:::-;22888:80;;22701:274;;;;;;;:::o;21414:196::-;21474:14;21491:23;:21;:23::i;:::-;-1:-1:-1;;;;;21524:22:3;;;;;;;:14;:22;;;;;;;;;:31;;-1:-1:-1;;;;;;21524:31:3;;;;;;;;;21570:33;;17307:51:21;;;21524:22:3;;-1:-1:-1;21524:22:3;21570:33;;17280:18:21;21570:33:3;;;;;;;;21464:146;21414:196;:::o;14424:656::-;14605:7;29168:40;29200:7;29168:31;:40::i;:::-;14624:14:::1;14641:41;14655:7;14664:4;14670:11;14641:13;:41::i;:::-;14624:58;;14692:18;14713:20;14726:6;14713:12;:20::i;:::-;14692:41:::0;-1:-1:-1;14816:15:3::1;::::0;::::1;::::0;:46;::::1;;;-1:-1:-1::0;14846:16:3::1;14835:27:::0;;::::1;;;14816:46;14812:76;;;14871:17;;-1:-1:-1::0;;;14871:17:3::1;;;;;;;;;;;14812:76;14898:38;14917:9;14928:7;14898:18;:38::i;:::-;14946:11;::::0;::::1;:23:::0;;::::1;::::0;;::::1;-1:-1:-1::0;;14979:19:3;;;;;;;;::::1;::::0;;::::1;;::::0;;;15013:60:::1;::::0;;22146:4:21;22134:17;;;22116:36;;22188:17;;22183:2;22168:18;;22161:45;22251:18;;;22244:43;;;;22318:2;22303:18;;22296:43;;;;-1:-1:-1;;;;;15013:60:3;::::1;::::0;::::1;::::0;22103:3:21;22088:19;15013:60:3::1;21897:448:21::0;17166:569:3;17321:7;29168:40;29200:7;29168:31;:40::i;:::-;17340:14:::1;17357:41;17371:7;17380:4;17386:11;17357:13;:41::i;:::-;17340:58;;17408:18;17429:20;17442:6;17429:12;:20::i;:::-;17408:41:::0;-1:-1:-1;17534:15:3::1;::::0;::::1;::::0;:36;::::1;;;-1:-1:-1::0;17553:6:3::1;::::0;::::1;::::0;-1:-1:-1;;;17553:6:3;::::1;:17;:6;:17:::0;17534:36:::1;17530:66;;;17579:17;;-1:-1:-1::0;;;17579:17:3::1;;;;;;;;;;;17530:66;17606:27;17627:5;17606:20;:27::i;:::-;17643:13;::::0;::::1;:21:::0;;-1:-1:-1;;;;17643:21:3::1;-1:-1:-1::0;;;17643:21:3::1;::::0;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;17679:49:::1;::::0;;22572:4:21;22560:17;;;22542:36;;22614:17;;22609:2;22594:18;;22587:45;22648:18;;;22641:51;;;;-1:-1:-1;;;;;17679:49:3;::::1;::::0;::::1;::::0;22530:2:21;22515:18;17679:49:3::1;22350:348:21::0;13350:550:3;13499:7;29168:40;29200:7;29168:31;:40::i;:::-;13518:14:::1;13535:41;13549:7;13558:4;13564:11;13535:13;:41::i;:::-;13518:58;;13586:18;13607:20;13620:6;13607:12;:20::i;:::-;13586:41:::0;-1:-1:-1;13739:15:3::1;::::0;::::1;::::0;:45;::::1;;;-1:-1:-1::0;13758:6:3::1;::::0;::::1;::::0;-1:-1:-1;;;13758:6:3;::::1;:26;:6;4139:1;13758:26;;13739:45;13735:75;;;13793:17;;-1:-1:-1::0;;;13793:17:3::1;;;;;;;;;;;13735:75;13820:15:::0;;-1:-1:-1;;;;;13820:15:3;::::1;-1:-1:-1::0;;;13820:15:3;::::1;-1:-1:-1::0;;;;;13820:15:3;;::::1;;::::0;;13850:43:::1;::::0;;22925:4:21;22913:17;;;22895:36;;22967:17;;22962:2;22947:18;;22940:45;23001:18;;;22994:67;;;;13850:43:3;;::::1;::::0;::::1;::::0;22883:2:21;22868:18;13850:43:3::1;22703:364:21::0;10437:2692:3;10497:18;10518:61;10531:47;10545:9;;;;:1;:9;:::i;:::-;10556:6;;;;;;;;:::i;:::-;10564:13;;;;;;;;:::i;:::-;10531;:47::i;:::-;10518:12;:61::i;:::-;10734:11;;;;;;-1:-1:-1;10716:15:3;10765:9;;;10734:11;10765:9;;;-1:-1:-1;;10734:11:3;;-1:-1:-1;3385:40:2;10702:146:3;;;10825:11;;;;10796:52;;-1:-1:-1;;;10796:52:3;;10808:15;10838:9;10796:52;;23457:25:21;10825:11:3;;;;23527:18:21;;;23520:43;10838:9:3;;;;;;;23579:18:21;;;23572:43;23430:18;;10796:52:3;;;;;;;;10702:146;10862:12;10872:1;41846:7;;;-1:-1:-1;;;41846:7:3;;5082:6;41846:27;:32;;;41761:124;10862:12;10858:37;;;10883:12;;-1:-1:-1;;;10883:12:3;;;;;;;;;;;10858:37;11020:6;;;;-1:-1:-1;;;11020:6:3;;;;-1:-1:-1;;11040:21:3;;11036:121;;11063:19;11077:1;11080;11063:13;:19::i;:::-;11036:121;;;-1:-1:-1;;11101:24:3;;;;11097:60;;11127:30;11152:1;11155;11127:24;:30::i;:::-;11168:28;11185:4;11191:1;11194;11168:16;:28::i;:::-;11281:26;11310:56;11329:6;;;;;;;;:::i;:::-;11337:1;11340:10;;;;;;;;:::i;:::-;11352:13;;;;;;;;:::i;:::-;11310:18;:56::i;:::-;11281:85;;11377:17;11460:15;11527:1;:7;;;11514:9;:20;11510:65;;11567:7;;11543:32;;-1:-1:-1;;;11543:32:3;;11556:9;11543:32;;;23989:25:21;24030:18;;;24023:34;;;;23962:18;;11543:32:3;23815:248:21;11510:65:3;11638:13;;;;11628:7;;11712:10;;-1:-1:-1;;;;;11712:10:3;11628:7;11692:31;;;;;;;;;;:48;;;;;;11628:23;;-1:-1:-1;11800:56:3;11712:1;11826:11;;;;;;;;:::i;:::-;11839:16;;;;:1;:16;:::i;:::-;11800:22;:56::i;:::-;11787:69;;;11783:545;;;11889:14;;;;11876:27;;;;;11953:20;:33;11974:11;;;;;;;;:::i;:::-;-1:-1:-1;;;;;11953:33:3;;;;;;;;;;;;-1:-1:-1;11953:33:3;:51;;;;;;;11783:545;;;12196:1;12173:11;;;;;;;;:::i;:::-;-1:-1:-1;;;;;12173:25:3;;12169:56;;12207:18;;-1:-1:-1;;;12207:18:3;;;;;;;;;;;12169:56;12260:1;12243:14;;;:18;11783:545;12422:23;12464:9;;;;:1;:9;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12422:52:3;;-1:-1:-1;12529:10:3;;;;;;;;:::i;:::-;12516:23;;;;-1:-1:-1;;;;;12565:12:3;;;12586:9;12598:6;;;;;;;;:::i;:::-;12606:4;;;;;;;;:::i;:::-;12612:10;;;;;;;;:::i;:::-;12565:58;;-1:-1:-1;;;;;;12565:58:3;;;;;;;24845:4:21;24833:17;;;12565:58:3;;;24815:36:21;-1:-1:-1;;;;;24887:32:21;;;24867:18;;;24860:60;12565:58:3;24956:23:21;24936:18;;;24929:51;24788:18;;12565:58:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12549:13;;;:74;12649:13;;;;;;;;:::i;:::-;-1:-1:-1;;;;;12633:29:3;:13;;;:29;12696:21;;;;;;;;:::i;:::-;12672:45;;:21;;;:45;12749:19;;;;;;;;:::i;:::-;12727:41;;:19;;;:41;12792:11;;;;;;;;:::i;:::-;-1:-1:-1;;;;;12778:25:3;:11;;;:25;12813;;;:12;;;:25;12871:7;;12848:20;;;;:30;;;;12902:11;;;;12888;;;:25;12939:13;;;;;12923;;;:29;12982:17;;;;;12962;;;:37;13026:14;;;;13009;;;:31;13106:15;;;;;13097:4;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;13056:66:3;13063:9;;;;:1;:9;:::i;:::-;-1:-1:-1;;;;;13056:66:3;;13074:6;;;;;;;;:::i;:::-;13082:13;;;;;;;;:::i;:::-;13103:1;13056:66;;;;;;;;:::i;:::-;;;;;;;;10487:2642;;;;;;;10437:2692;:::o;25860:387::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26032:29:3;;;;4543:10:2;;;4540:37;26012:50:3;;:19;:50;;;;;;25983:79;;;;;;;;-1:-1:-1;;;;;25983:79:3;;;;;-1:-1:-1;;;25983:79:3;;;;;;;;;;;-1:-1:-1;;;25983:79:3;;;;;;;;;;-1:-1:-1;;;25983:79:3;;;;;;;;;;;-1:-1:-1;;26072:90:3;;26091:19;:71;4547:2:2;4543:10;;;5459:3:3;4540:37:2;26091:71:3;;;;;;;;;;;;;;-1:-1:-1;26091:71:3;26087:75;;;;;;;;;-1:-1:-1;;;;;26087:75:3;;;;;-1:-1:-1;;;26087:75:3;;;;;;;;;;-1:-1:-1;;;26087:75:3;;;;;;;;;;;-1:-1:-1;;;26087:75:3;;;;;;;;;;;;-1:-1:-1;26072:90:3;26177:1;:8;;;26172:23;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26172:23:3;26239:1;25860:387;-1:-1:-1;;;25860:387:3:o;28344:121::-;28386:22;28435:23;:21;:23::i;21189:171::-;21240:14;21257:23;:21;:23::i;:::-;-1:-1:-1;;;;;21290:15:3;;;;;;:7;:15;;;;;;;;;:23;;-1:-1:-1;;21290:23:3;-1:-1:-1;;;;;21290:23:3;;;;;;;;21328:25;;17513:58:21;;;21290:15:3;;-1:-1:-1;21290:15:3;;21328:25;;17486:18:21;21328:25:3;17369:208:21;24022:377:3;24230:4;24246:14;24263:41;24277:7;24286:4;24292:11;24263:13;:41::i;:::-;24246:58;;24321:71;24344:20;24357:6;24344:12;:20::i;:::-;24366:9;24377:14;;24321:22;:71::i;:::-;24314:78;24022:377;-1:-1:-1;;;;;;;;24022:377:3:o;24782:544::-;24948:21;24981:14;24998:41;25012:7;25021:4;25027:11;24998:13;:41::i;:::-;25049:31;25083:22;;;:14;:22;;;;;24981:58;;-1:-1:-1;25136:12:3;25125:31;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;25125:31:3;;25115:41;;25195:9;25190:120;25206:24;;;25190:120;;25268:27;25279:12;;25292:1;25279:15;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;25268:27;;:6;:10;;:27;;;;:::i;:::-;25255:7;25263:1;25255:10;;;;;;;;:::i;:::-;:40;;;:10;;;;;;;;;;;:40;25232:3;;25190:120;;;;24971:355;;24782:544;;;;;;;:::o;6926:596:13:-;-1:-1:-1;;;7051:18:13;;7024:13;;;7051:18;7322:23;:21;:23::i;:::-;6926:596;;7304:41;;;-1:-1:-1;7365:13:13;;-1:-1:-1;7416:4:13;;-1:-1:-1;6926:596:13;;-1:-1:-1;6926:596:13;:::o;20171:265:3:-;20238:14;20255:23;:21;:23::i;:::-;20238:40;;20288:38;20316:9;20288:27;:38::i;:::-;-1:-1:-1;;;;;20336:26:3;;;;;;;:18;:26;;;;;;;;;:38;;-1:-1:-1;;;;;;20336:38:3;;;;;;;;;20389:40;;17307:51:21;;;20336:26:3;;20389:40;;17280:18:21;20389:40:3;17161:203:21;20831:304:3;20913:14;20930:23;:21;:23::i;:::-;20913:40;;20963:29;20990:1;20963:26;:29::i;:::-;4547:2:2;4543:10;;;5459:3:3;4540:37:2;21002:69:3;;;;:19;:69;;;;;;;;;:73;;;;;;;;;;;;;;;;;;-1:-1:-1;;;21002:73:3;-1:-1:-1;;;;21002:73:3;;;;-1:-1:-1;;;21002:73:3;;;;;-1:-1:-1;;;;;;;;;21002:73:3;;;-1:-1:-1;;;21002:73:3;-1:-1:-1;;;;;;21002:73:3;;;;;;;;;;;;;;;;;;;;;;;;;;;21090:38;-1:-1:-1;;;;;21090:38:3;;;;;;;21002:73;;21090:38;:::i;17789:502::-;17949:7;29168:40;29200:7;29168:31;:40::i;:::-;17968:14:::1;17985:41;17999:7;18008:4;18014:11;17985:13;:41::i;:::-;17968:58;;18036:18;18057:20;18070:6;18057:12;:20::i;:::-;4032:1;18091:6:::0;;::::1;::::0;18036:41;;-1:-1:-1;;;;18091:6:3;;::::1;:23;:6;:23;18087:53;;18123:17;;-1:-1:-1::0;;;18123:17:3::1;;;;;;;;;;;18087:53;18150:31;18170:10;18150:19;:31::i;:::-;18191:12;::::0;::::1;:25:::0;;;18231:53:::1;::::0;;21783:4:21;21771:17;;;21753:36;;21825:17;;21820:2;21805:18;;21798:45;21859:18;;;21852:34;;;-1:-1:-1;;;;;18231:53:3;::::1;::::0;::::1;::::0;21741:2:21;21726:18;18231:53:3::1;21559:333:21::0;26301:751:3;26361:19;4543:10:2;;;26416:28:3;26447:36;;;:9;:36;;;;;26509:23;;;;;-1:-1:-1;;;26509:23:3;;;;;-1:-1:-1;;;26580:16:3;;;26509:23;26646:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;26642:21;;26834:202;26841:6;;26834:202;;26898:25;;;4547:2:2;4543:10;;;4540:37;26867:18:3;26888:36;;;:9;:36;;;;;26951:42;4543:10:2;26975:6:3;26980:1;26975:6;;;;26898:25;26951:8;:42::i;:::-;26942:1;26944:3;;;;;;;26942:6;;;;;;;;:::i;:::-;;;;;;;;;;:51;27015:6;;;-1:-1:-1;;;27015:6:3;;;;;-1:-1:-1;26834:202:3;;;26392:654;;;26301:751;;;:::o;16423:689::-;16588:7;29168:40;29200:7;29168:31;:40::i;:::-;16607:14:::1;16624:41;16638:7;16647:4;16653:11;16624:13;:41::i;:::-;16607:58;;16675:18;16696:20;16709:6;16696:12;:20::i;:::-;16675:41:::0;-1:-1:-1;16779:15:3::1;::::0;::::1;16775:45;;16803:17;;-1:-1:-1::0;;;16803:17:3::1;;;;;;;;;;;16775:45;16891:6;::::0;::::1;::::0;-1:-1:-1;;;;;16891:6:3;;::::1;:26;:6;:26:::0;16887:56:::1;;16926:17;;-1:-1:-1::0;;;16926:17:3::1;;;;;;;;;;;16887:56;16953:37;16984:5;16953:30;:37::i;:::-;17000:23;::::0;::::1;:31:::0;;-1:-1:-1;;17000:31:3::1;-1:-1:-1::0;;;17000:31:3::1;::::0;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;17046:59:::1;::::0;;22572:4:21;22560:17;;;22542:36;;22614:17;;22609:2;22594:18;;22587:45;22648:18;;;22641:51;;;;-1:-1:-1;;;;;17046:59:3;::::1;::::0;::::1;::::0;22530:2:21;22515:18;17046:59:3::1;22350:348:21::0;15134:296:3;15277:14;15294:41;15308:7;15317:4;15323:11;15294:13;:41::i;:::-;15397:17;;;;:9;:17;;;;;:25;;;:17;;-1:-1:-1;15345:78:3;;15358:7;;15367:4;;15373:11;;15386:9;;15397:25;;;;;15345:12;:78::i;:::-;15267:163;15134:296;;;;:::o;20490:287::-;20577:14;20594:23;:21;:23::i;:::-;20577:40;;20627:29;20654:1;20627:26;:29::i;:::-;4547:2:2;4543:10;;;20686:27:3;;;4540:37:2;20666:48:3;;;;:19;:48;;;;;;;;;:52;;;;;;;;;;;;;;;;;;-1:-1:-1;;;20666:52:3;-1:-1:-1;;;;20666:52:3;;;;-1:-1:-1;;;20666:52:3;;;;;-1:-1:-1;;;;;;;;;20666:52:3;;;-1:-1:-1;;;20666:52:3;-1:-1:-1;;;;;;20666:52:3;;;;;;;;;;;;;;;;;;;;;;;;;;;20733:37;-1:-1:-1;;;;;20733:37:3;;;;;;;20686:27;;20666:52;;20733:37;:::i;:::-;;;;;;;;20567:210;20490:287;;:::o;15484:424::-;15638:7;29168:40;29200:7;29168:31;:40::i;:::-;15657:14:::1;15674:41;15688:7;15697:4;15703:11;15674:13;:41::i;:::-;15657:58;;15725:18;15746:20;15759:6;15746:12;:20::i;:::-;15725:41;;15776:29;15801:3;15776:24;:29::i;:::-;15815:17;::::0;::::1;:23:::0;;-1:-1:-1;;;;15815:23:3::1;-1:-1:-1::0;;;15815:23:3::1;::::0;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;15853:48:::1;::::0;;27536:4:21;27524:17;;;27506:36;;27578:17;;27573:2;27558:18;;27551:45;27612:18;;;27605:47;;;;-1:-1:-1;;;;;15853:48:3;::::1;::::0;::::1;::::0;27494:2:21;27479:18;15853:48:3::1;27314:344:21::0;23682:286:3;23832:6;23850:14;23867:41;23881:7;23890:4;23896:11;23867:13;:41::i;:::-;-1:-1:-1;;;;;23925:24:3;;;;;;:13;:24;;;;;;;;3360:1:16;3351:10;;;3343:19;;;;;;;;23850:58:3;;-1:-1:-1;3367:16:16;3382:1;3367:16;;;;3343:41;23925:36:3;23918:43;23682:286;-1:-1:-1;;;;;;23682:286:3:o;7101:3282::-;7167:17;7196:42;7228:1;:9;;;7196:31;:42::i;:::-;7249:43;7274:1;:17;;;7249:24;:43::i;:::-;7316:6;;;;7337:15;;;7333:464;;7387:1;7368:8;;;:21;;;7403:12;;;:25;7333:464;;;-1:-1:-1;;7449:21:3;;;;7445:352;;7486:33;7506:1;:12;;;7486:19;:33::i;:::-;7552:1;7533:8;;;:21;7445:352;;;-1:-1:-1;;7575:24:3;;;;7571:226;;7615:25;7631:1;:8;;;7615:15;:25::i;:::-;7677:1;7654:12;;;:25;7719:16;7693:23;;;:42;7571:226;;;7773:13;;-1:-1:-1;;;7773:13:3;;;;;;;;;;;7571:226;7876:6;;;;:17;;7872:586;;7921:16;7909:9;;;:28;;;7951:23;;;:42;8266:24;;;4139:1;8266:24;8262:41;;8302:1;8292:7;;;:11;8262:41;8398:15;;;8394:53;;8431:16;8415:13;;;:32;8394:53;8468:42;8487:1;:11;;;8500:1;:9;;;8468:18;:42::i;:::-;8520:55;8551:1;:23;;;8520:30;:55::i;:::-;8585:35;8606:1;:13;;;8585:20;:35::i;:::-;8655:25;8683:9;:46;8693:35;8707:1;:9;;;8718:1;:6;;;8726:1;8693:13;:35::i;:::-;8683:46;;;;;;;;;;;;;;-1:-1:-1;8683:46:3;;;8798:9;;4547:2:2;4543:10;8774:38:3;;:9;:38;;;;8841:24;;;;;-1:-1:-1;;;8841:24:3;;;;;-1:-1:-1;8683:46:3;;-1:-1:-1;8774:38:3;8920:3;;8841:24;8920:13;;8916:42;;8935:23;:21;:23::i;:::-;8972:24;;;;:35;;;;;;-1:-1:-1;;;8972:35:3;-1:-1:-1;;;;8972:35:3;;;;;;;;;;9026:23;;;;;-1:-1:-1;;;9026:23:3;;;;9067:3;9074:7;9067:14;;9063:43;;9083:23;:21;:23::i;:::-;9120;;;:35;;-1:-1:-1;;;;9120:35:3;-1:-1:-1;;;9120:35:3;;;;;;;9201:9;;9120:35;9212:6;;;-1:-1:-1;;9187:45:3;;9220:11;9187:13;:45::i;:::-;9170:62;;9246:22;9291:1;-1:-1:-1;;;;;9271:22:3;:1;:8;;;-1:-1:-1;;;;;9271:22:3;;9246:47;;9308:18;9329:9;:17;9339:6;9329:17;;;;;;;;;;;9308:38;;9373:1;:10;;;9360:1;:10;;;:23;;;;;-1:-1:-1;;;;;9360:23:3;;;;;-1:-1:-1;;;;;9360:23:3;;;;;;9407:1;:7;;;9397:1;:7;;;:17;;;;;-1:-1:-1;;;;;9397:17:3;;;;;-1:-1:-1;;;;;9397:17:3;;;;;;9442:1;:11;;;9428:1;:11;;;:25;;;;;;;;;;;;;;;;;;9479:1;:9;;;9467:1;:9;;;:21;;;;;;;;;;;;;;;;;;9528:1;:23;;;9502:1;:23;;;:49;;;;;;;;;;;;;;;;;;9581:1;:13;;;9565:1;:13;;;:29;;;;;;;;;;;;;;;;;;9628:1;:17;;;9608:1;:17;;;:37;;;;;;;;;;;;;;;;;;9668:1;:6;;;9659:1;:6;;;:15;;;;;;;;;;;;;;;;;;9719:59;9733:17;5240:6;1866:12:2;;1859:20;1855:31;;1736:166;9719:59:3;4949:6;9688:7;;;:90;;-1:-1:-1;;;;9688:90:3;;-1:-1:-1;;;9698:80:3;;;9688:90;;;;;;;;;;;;;9801:16;;;;;-1:-1:-1;;;;9792:25:3;;;-1:-1:-1;;;;9792:25:3;;;;;;;-1:-1:-1;;;9801:16:3;;;;;;-1:-1:-1;;;9792:25:3;;;;;9688:90;9866:6;;;9831:72;;-1:-1:-1;;;;9831:72:3;9882:20;;;9877:1;9858:20;;;;;;9857:45;9831:72;;;;;;;9980:21;;;;:35;9976:86;;10041:21;;;;10017;;;:45;9976:86;10080:12;;;;:26;10076:59;;10123:12;;;;10108;;;:27;10076:59;10153:8;;;;-1:-1:-1;;;;;10153:22:3;;10149:152;;10200:17;10195:43;;10230:8;;;;10219;;;:19;;-1:-1:-1;;;;;;10219:19:3;-1:-1:-1;;;;;10219:19:3;;;;;;;;;10195:43;10332:1;:9;;;-1:-1:-1;;;;;10320:46:3;;10343:1;:6;;;10351:11;10364:1;10320:46;;;;;;;;:::i;:::-;;;;;;;;8631:1746;;;;;;7186:3197;7101:3282;;;:::o;27106:1018::-;27223:20;;:::i;:::-;27255:14;27272:41;27286:7;27295:4;27301:11;27272:13;:41::i;:::-;27255:58;;27323:18;27344:20;27357:6;27344:12;:20::i;:::-;-1:-1:-1;;;;;27374:22:3;;;;;27406:16;;;;:9;;;:16;;;27432:30;;;:16;;;:30;27488:10;;;;;27472:13;;;:26;27323:41;;-1:-1:-1;27521:15:3;:45;;;;-1:-1:-1;27540:6:3;;;;-1:-1:-1;;;27540:6:3;;:26;:6;4139:1;27540:26;;27521:45;:77;;27591:7;;-1:-1:-1;;;27591:7:3;;-1:-1:-1;;;;;27591:7:3;27521:77;;;27577:10;;-1:-1:-1;;;;;27577:10:3;27569:19;;;;:7;:19;;;;;;-1:-1:-1;;;;;27569:19:3;27521:77;-1:-1:-1;;;;;27508:90:3;:10;;;:90;27625:11;;;;;;;;27608:14;;;:28;27661:9;;;;;27646:12;;;:24;-1:-1:-1;;;27709:23:3;;;;27680:26;;;:52;-1:-1:-1;;;27761:13:3;;;;27625:11;27742:16;;:32;-1:-1:-1;;;27798:8:3;;;27784:11;;;:22;-1:-1:-1;;;27839:17:3;;;;27816:20;;;:40;-1:-1:-1;;;27878:6:3;;;;27866:9;;;:18;5082:6;-1:-1:-1;;;41846:7:3;;;:27;;:32;;27894:11;;;:26;27957:21;;;27930:24;;;:48;28006:12;;;;27988:15;;;:30;28042:19;27625:11;28042:16;:19::i;:::-;-1:-1:-1;;;;;28028:33:3;:11;;;:33;28096:21;28115:1;42510:7;;;-1:-1:-1;;;42510:7:3;;5240:6;42510:35;:40;;;42416:141;28096:21;28071:46;;:22;;;:46;-1:-1:-1;28071:4:3;;27106:1018;-1:-1:-1;;;;27106:1018:3:o;13954:416::-;14103:7;29168:40;29200:7;29168:31;:40::i;:::-;14122:14:::1;14139:41;14153:7;14162:4;14168:11;14139:13;:41::i;:::-;14122:58;;14190:18;14211:20;14224:6;14211:12;:20::i;:::-;14268:7;::::0;::::1;::::0;14190:41;;-1:-1:-1;14251:52:3::1;::::0;14268:7:::1;-1:-1:-1::0;;;14268:7:3;;::::1;;5082:6;14296::::0;2304:4:2;2310:16;;;2300:27;2293:35;2330:12;;2289:54;2285:65;2274:77;;2109:258;14251:52:3::1;14241:7;::::0;::::1;:62:::0;;-1:-1:-1;;;;14241:62:3::1;-1:-1:-1::0;;;14241:62:3::1;::::0;;::::1;;;::::0;;14318:45:::1;::::0;;29692:17:21;;;29674:36;;29746:17;;;29741:2;29726:18;;29719:45;29807:14;;29800:22;29780:18;;;29773:50;-1:-1:-1;;;;;14318:45:3;::::1;::::0;::::1;::::0;29662:2:21;29647:18;14318:45:3::1;29486:343:21::0;22151:496:3;22220:7;22285:355;3308:390;22372:9;;;;:1;:9;:::i;:::-;22399:6;;;;;;;;:::i;:::-;22424:13;;;;;;;;:::i;:::-;22455:4;;;;;;;;:::i;:::-;22477:16;;;;;;;;:::i;:::-;22511:19;;;;;;;;:::i;:::-;22548:13;;;;;;;;:::i;:::-;22579:16;;;;;;;;:::i;:::-;22613:11;;;;;;;;:::i;:::-;22310:328;;;;;;30217:25:21;;;;-1:-1:-1;;;;;30316:15:21;;;30296:18;;;30289:43;30380:4;30368:17;;;30348:18;;;30341:45;30422:17;;;;30402:18;;;30395:45;30477:15;;;30456:19;;;30449:44;30512:10;30559:15;;;30538:19;;;30531:44;30612:15;;30591:19;;;30584:44;-1:-1:-1;;;;;30665:39:21;;;30644:19;;;30637:68;30742:15;30721:19;;;30714:44;30795:15;30774:19;;;30767:44;30189:19;;22310:328:3;;;;;;;;;;;;22300:339;;;;;;22285:14;:355::i;19543:438::-;-1:-1:-1;;;;;19627:28:3;;;19607:17;19627:28;;;:18;:28;;;;;;;19665:38;19627:28;19665:27;:38::i;:::-;-1:-1:-1;;;;;19731:29:3;;19713:15;19731:29;;;;;;;;;;;19774:12;;19770:205;;-1:-1:-1;;;;;19802:29:3;;19834:1;19802:29;;;;;;;;;;:33;19849:56;19886:9;19897:7;19849:36;:56::i;:::-;19946:8;-1:-1:-1;;;;;19924:40:3;;19956:7;19924:40;;;;4832:25:21;;4820:2;4805:18;;4686:177;19770:205:3;19597:384;;19543:438;:::o;23029:381::-;23223:24;;:::i;:::-;23259:14;23276:41;23290:7;23299:4;23305:11;23276:13;:41::i;:::-;23259:58;;23334:69;23353:4;23359:20;23372:6;23359:12;:20::i;:::-;23381:8;23391:11;23334:18;:69::i;:::-;23327:76;23029:381;-1:-1:-1;;;;;;;23029:381:3:o;19149:340::-;-1:-1:-1;;;;;19233:31:3;;19215:15;19233:31;;;:20;:31;;;;;;19278:12;;19274:209;;-1:-1:-1;;;;;19306:31:3;;19340:1;19306:31;;;:20;:31;;;;;:35;19355:56;19327:9;19403:7;19355:36;:56::i;:::-;19453:9;-1:-1:-1;;;;;19430:42:3;;19464:7;19430:42;;;;4832:25:21;;4820:2;4805:18;;4686:177;19274:209:3;19205:284;19149:340;:::o;24453:275::-;24609:4;24632:89;24654:7;24663:4;24669:11;24682:9;14093:24:18;24609:4:3;24022:377;:::i;32223:224::-;32395:21;;;;;;;;;;;-1:-1:-1;;;32395:21:3;;;;;;;;32426:14;;;;;;;;;;;-1:-1:-1;;;32426:14:3;;;;32395:21;32223:224::o;29364:289::-;29446:14;29463:23;:21;:23::i;:::-;29446:40;;29523:7;-1:-1:-1;;;;;29510:27:3;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;29500:39:3;:6;-1:-1:-1;;;;;29500:39:3;;29496:150;;29558:59;;-1:-1:-1;;;29558:59:3;;-1:-1:-1;;;;;31270:32:21;;;29558:59:3;;;31252:51:21;1211:6:2;31319:18:21;;;31312:34;29558:32:3;;;;;31225:18:21;;29558:59:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;29553:93;;29619:27;:25;:27::i;4895:317:2:-;5012:14;5082:7;5078:2;5074:16;5068:4;5061:30;5118:4;5112;5104:19;5150:11;5144:4;5136:26;-1:-1:-1;;5191:4:2;5185:11;;4895:317;-1:-1:-1;;4895:317:2:o;41401:193:3:-;41462:18;41496:17;;;:9;:17;;;;;4949:6;41527:7;;;;41496:17;;-1:-1:-1;;;41527:7:3;;;:28;:33;;41523:64;;41569:18;;-1:-1:-1;;;41569:18:3;;;;;;;;;;;41523:64;41401:193;;;:::o;30870:126::-;-1:-1:-1;;;;;30939:20:3;;30935:54;;30968:21;;-1:-1:-1;;;30968:21:3;;;;;;;;;;;30935:54;30870:126;:::o;1961:485:7:-;2002:14;2107:8;2101:4;2094:22;2147:23;2199:10;2189:8;2186:24;2183:213;;2287:4;2281;2275;2269;2257:10;2250:5;2239:53;2229:153;;2329:4;2323;2316:18;2229:153;-1:-1:-1;;2425:4:7;2419:11;;1961:485::o;29830:143:3:-;29932:7;29920:19;;:9;:19;;;29916:50;;;29948:18;;-1:-1:-1;;;29948:18:3;;;;;;;;;;;30378:117;30450:5;:10;;30459:1;30450:10;30446:42;;30469:19;;-1:-1:-1;;;30469:19:3;;;;;;;;;;;34981:1700;35067:26;35096:21;;;;;;;;:::i;:::-;35067:50;-1:-1:-1;35127:19:3;35149:13;;;;;;;;:::i;:::-;35127:35;-1:-1:-1;;;;;;35339:25:3;;35335:58;;35373:20;;-1:-1:-1;;;35373:20:3;;;;;;;;;;;35335:58;-1:-1:-1;;35542:16:3;35519:39;;;35515:782;;35769:65;35801:1;:12;;;35815:18;35821:11;40515:14;40564:25;40628:4;40622;40612:21;;40456:193;35815:18;35769:16;;;;:1;:16;:::i;:::-;:31;;;;;:65::i;:::-;35768:66;:170;;;;;35855:83;35887:1;:12;;;35901:36;35907:11;35920:16;41078:4;41071:33;41022:14;41117:25;41181:4;41175;41165:21;;40935:267;35855:83;35854:84;35768:170;35747:233;;;35960:20;;-1:-1:-1;;;35960:20:3;;;;;;;;;;;35747:233;35515:782;;;36155:86;36187:1;:12;;;36201:39;36207:11;36220:19;41078:4;41071:33;41022:14;41117:25;41181:4;41175;41165:21;;40935:267;36155:86;36150:136;;36266:20;;-1:-1:-1;;;36266:20:3;;;;;;;;;;;36150:136;36384:14;36401:23;:21;:23::i;:::-;36384:40;-1:-1:-1;36439:53:3;-1:-1:-1;;;;;36449:21:3;;;;;;;;;36472:4;;;;;;;;:::i;:::-;-1:-1:-1;;;;;36472:19:3;;3395:9:2;;3388:17;3414:9;;3407:17;3385:40;;3288:153;36439:53:3;36434:241;;36579:56;36615:6;36623:11;36579:35;:56::i;:::-;36574:90;;36644:20;;-1:-1:-1;;;36644:20:3;;;;;;;;;;;34234:601;34343:16;;;;;;;;:::i;:::-;34330:29;;:10;;;;;;;;:::i;:::-;:29;;;34326:65;;;34368:23;;-1:-1:-1;;;34368:23:3;;;;;;;;;;;34326:65;34401:14;34418:19;34435:1;34418:16;:19::i;:::-;34401:36;;34452:92;34500:6;34508:22;34528:1;34508:19;:22::i;:::-;34532:11;;;;:1;:11;:::i;:::-;34452:47;:92::i;:::-;34447:136;;34565:18;;-1:-1:-1;;;34565:18:3;;;;;;;;;;;34447:136;34615:16;;;;;;;;:::i;:::-;34597:34;;:15;:34;34593:65;;;34640:18;;-1:-1:-1;;;34640:18:3;;;;;;;;;;;34593:65;34668:14;34685:47;34699:9;;;;:1;:9;:::i;34685:47::-;34668:64;-1:-1:-1;34747:50:3;34777:19;;;;;;;;:::i;:::-;34747:22;;;;:14;:22;;;;;;:50;;;;;:29;:50;:::i;:::-;34742:86;;34806:22;;-1:-1:-1;;;34806:22:3;;;;;;;;;;;34742:86;34316:519;;34234:601;;:::o;32722:1324::-;32928:9;32968:10;;;;;;;;:::i;:::-;32948:8;;;;32960:19;;;;-1:-1:-1;;;32948:8:3;;;;32940:39;;-1:-1:-1;;;;33023:13:3;;;33019:17;;33015:49;;;33045:19;;-1:-1:-1;;;33045:19:3;;;;;;;;;;;33015:49;33078:8;;;:20;;-1:-1:-1;;;;33078:20:3;-1:-1:-1;;;33078:20:3;;;;;;;-1:-1:-1;33191:47:3;33205:9;;;;;;:::i;33191:47::-;33174:64;-1:-1:-1;;;33256:21:3;;;;33252:778;;33297:26;33326:13;33297:26;33340:13;;;;;;;;:::i;:::-;-1:-1:-1;;;;;33326:28:3;;;;;;;;;;;;-1:-1:-1;33326:28:3;;-1:-1:-1;33409:10:3;;;;;;;;:::i;:::-;33401:19;;33384:13;33390:6;33384:1;:5;;:13;;;;:::i;:::-;33616:23;;;;33376:22;;;;:44;;;;;-1:-1:-1;33602:65:3;;-1:-1:-1;;;33616:23:3;;;33612:27;;33645:21;;;;;;;;:::i;:::-;33641:25;;:1;:25;3395:9:2;;3388:17;3414:9;;3407:17;3385:40;;3288:153;33602:65:3;33598:100;;;33676:22;;-1:-1:-1;;;33676:22:3;;;;;;;;;;;33598:100;3614:4:16;3607:22;;;3659:1;3655:13;;;3649:4;3642:27;;;3707:4;3691:21;;3825:8;;3751:21;3755:1;3751:21;;;;3951:9;;;3947:21;;3878:10;3940:29;3933:37;;3926:45;3916:56;;33279:476:3;33252:778;;;33779:26;33808:13;33779:26;33822:4;;;;;;;;:::i;:::-;-1:-1:-1;;;;;33808:19:3;;;;;;;;;;;;-1:-1:-1;33808:19:3;;-1:-1:-1;33882:10:3;;;;;;;;:::i;:::-;33874:19;;33857:13;33863:6;33857:1;:5;;:13;;;;:::i;:::-;33919:23;;;;33849:22;;;;:44;;;;;-1:-1:-1;;;;33919:23:3;;;;33915:27;;33911:62;;;33951:22;;-1:-1:-1;;;33951:22:3;;;;;;;;;;;33911:62;3614:4:16;3607:22;;;3659:1;3655:13;;;3649:4;3642:27;;;3707:4;3691:21;;3825:8;;3751:21;3755:1;3751:21;;;;3951:9;;;3947:21;;3878:10;3940:29;3933:37;;3926:45;3916:56;;33761:269:3;32848:1192;;32722:1324;;;:::o;37042:2188::-;37200:26;;:::i;:::-;37318:10;;37262:26;;37291:44;;-1:-1:-1;;;;;37318:10:3;37330:4;37291:26;:44::i;:::-;37521:6;;;;37262:73;;-1:-1:-1;37397:17:3;;-1:-1:-1;;;;;37521:6:3;;;:26;:6;:26;37517:407;;37585:7;;-1:-1:-1;;;;;;;;37585:7:3;;;;;37571:21;;;;37567:53;;;37601:19;;-1:-1:-1;;;37601:19:3;;;;;;;;;;;37567:53;-1:-1:-1;;;;;;37666:23:3;;37517:407;;;37714:15;;;37710:214;;-1:-1:-1;37769:10:3;;-1:-1:-1;;;;;37769:10:3;37761:19;;;;:7;:19;;;;;;-1:-1:-1;;;;;37761:19:3;37710:214;;;-1:-1:-1;37876:7:3;;-1:-1:-1;;;37876:7:3;;-1:-1:-1;;;;;37876:7:3;37710:214;37937:11;;;;:23;;;38177:17;;;38165:29;;;38152:10;;;;:42;;;38310:11;;-1:-1:-1;;;;;38288:33:3;;;:19;;;:33;;;38359:13;;;;:33;;;;38335:21;;;:57;;;38426:43;;;38406:17;;;:63;38598:12;;;;38569:59;;38165:29;38569:59;;1495:5:2;3012:9;;3008:17;;2854:187;38569:59:3;38546:20;;;:82;;;38805:17;;;;38782:40;38766:13;;;:56;-1:-1:-1;39017:10:3;;;39029:17;;;;1495:5:2;-1:-1:-1;;;39029:17:3;;;;;3012:9:2;;;3008:17;38983:14:3;;;:81;-1:-1:-1;;39196:17:3;;;;39183:10;;;;:30;39173:40;;38983:1;37042:2188;-1:-1:-1;;;;37042:2188:3:o;39525:700::-;39723:21;;;;39692:4;;39723:21;39815:54;;-1:-1:-1;;;;;;;39846:23:3;;;;39839:30;;39815:54;40128:90;-1:-1:-1;;;;;40139:23:3;;;;40164:53;40194:4;40200:16;40139:9;40515:14;40564:25;40628:4;40622;40612:21;;40456:193;40200:16;40164:14;;;;:29;:53::i;:::-;3999:9:2;3992:17;3980:9;;3973:17;3969:41;;3871:155;1672:479:15;2024:1;2015:10;;;1746;2004:22;;;;;;;;;;;;;2048:1;2039:4;2031:12;;;2004:40;2003:46;;1672:479::o;31914:133:3:-;-1:-1:-1;;;;;31990:15:3;;31986:54;;32014:26;;-1:-1:-1;;;32014:26:3;;;;;;;;;;;31408:365;31513:209;4805:9;-1:-1:-1;;;;;31540:42:3;:1;:11;;;-1:-1:-1;;;;;31540:42:3;;4660:9;-1:-1:-1;;;;;31600:46:3;:1;:13;;;-1:-1:-1;;;;;31600:46:3;;4525:4;31664:44;;:1;:12;;;:44;;;31513:9;:209::i;:::-;31496:270;;;31740:26;;-1:-1:-1;;;31740:26:3;;;;;;;;;;;30616:136;30693:10;30689:56;;30726:19;;-1:-1:-1;;;30726:19:3;;;;;;;;;;;30116:137;30198:5;:10;;30207:1;30198:10;30194:52;;30217:29;;-1:-1:-1;;;30217:29:3;;;;;;;;;;;31143:141;4392:4;31217:27;;;;31213:64;;;31253:24;;-1:-1:-1;;;31253:24:3;;;;;;;;;;;3228:164:16;3360:1;3351:10;;;3302:13;3343:19;;;;;;;;;;;;;3382:1;3367:16;;;;;;3343:41;;3228:164::o;5267:161:2:-;5353:10;5347:4;5340:24;5407:4;5401;5394:18;42040:163:3;42109:7;42135:21;42154:1;42510:7;;;-1:-1:-1;;;42510:7:3;;5240:6;42510:35;:40;;;42416:141;42135:21;:61;;42188:8;;;;-1:-1:-1;;;;;42188:8:3;42135:61;;;-1:-1:-1;42174:10:3;-1:-1:-1;;;;;42174:10:3;;;42159:26;;;;:14;:26;;;;;;;;42040:163::o;5739:840:13:-;5814:14;5997:22;8980:11;9121:9;9118:25;8935:14;9091:9;9088:28;9084:60;6033:76;;-1:-1:-1;8426:4:13;8420:11;;8487:16;8477:27;;8264:15;8531:4;8524:12;;8517:30;8307:18;8567:12;;;8560:33;;;;8627:9;8620:4;8613:12;;8606:31;8671:9;8664:4;8657:12;;8650:31;8720:4;8707:18;;6033:76;6243:18;6237:4;6230:32;6309:9;6303:4;6296:23;6376:10;6370:4;6363:24;6452:4;6446;6436:21;6426:31;;6561:1;6555:4;6548:15;6181:392;5739:840;;;:::o;5578:772:19:-;5742:6;5727:13;5724:25;5721:146;;;5781:10;5775:4;5768:24;5848:4;5842;5835:18;5721:146;5949:4;5942:5;5936:4;5929:5;5921:6;5917:2;5895:20;5890:64;5880:454;;5987:2;5981:4;5974:16;6060:4;6054;6046:19;6116:4;6110;6102:19;6195:4;6189;6181:6;6174:26;6164:156;;6272:5;6268:2;6264:14;6246:16;6239:5;6224:55;5578:772;;:::o;5487:169:2:-;5577:10;5571:4;5564:24;5635:4;5629;5622:18;2397:1407:18;2522:12;2619;2616:1134;;;2759:12;2756:1;2752:20;2738:12;2734:39;2885:12;2983:753;3176:20;;3167:30;;;3164:1;3160:38;3391:21;;;3453:4;3440:18;;;3433:48;3608:4;3602;3592:21;;3644:17;3692:15;;;2983:753;3682:36;2987:2;;2616:1134;-1:-1:-1;3774:14:18;;2397:1407;-1:-1:-1;;2397:1407:18:o;176:956:5:-;261:11;368:4;362:11;493:10;487:4;480:24;567:8;561:4;554:22;636:5;630:4;623:19;1020:4;1014;1008;1002;989:11;982:5;971:54;902:1;895:4;889:11;886:18;795:244;785:254;;1114:1;1108:4;1101:15;;176:956;;;;:::o;4820:3036:20:-;-1:-1:-1;;;;;5145:24:20;;;;4960:12;5172:6;5129:2711;;;5215:4;5209:11;5261:2;5243:16;5240:24;5237:1102;;5300:4;5294;5287:18;5382:4;5364:16;5360:27;5347:41;5344:1;5339:50;5333:4;5326:64;5456:4;5438:16;5432:4;5419:42;5863:4;5809;5757;5704;5646:1;5568:5;5528:384;6083:1;6077:8;6069:6;6065:21;6046:16;6039:24;6036:51;6026:295;;-1:-1:-1;6165:1:20;6159:4;6152:15;6225:4;6218:15;-1:-1:-1;6126:1:20;6294:5;;6026:295;;5237:1102;6369:1;6363:4;6356:15;6427:1;6421:4;6414:15;6501:10;6496:3;6492:20;6539:1;6536;6529:12;6638:4;6631;6628:1;6624:12;6617:26;6676:4;6673:1;6669:12;6708:4;6705:1;6698:15;6801:16;6794:4;6791:1;6787:12;6780:38;6926:16;6908;6901:4;6898:1;6894:12;6881:62;7726:4;7674:1;7610:4;7592:16;7588:27;7528:1;7471:6;7422:5;7386:400;7140:8;;7137:15;;;7018:786;;-1:-1:-1;;4820:3036:20;;;;;;:::o;2649:841:15:-;2829:1;2825:13;;;2721;2812:27;;;2859:4;2852:25;;;;2925:4;2909:21;;;3005:18;;3060:1;2967:4;2956:16;;;3049:13;;;;3091:23;;;3441:33;;;;3403:23;3396:31;3389:39;;2649:841::o;3488:133:2:-;3577:6;3395:9;;3388:17;3395:9;;3388:17;3414:9;;3407:17;3385:40;3414:9;3407:17;3385:40;3599:15;3288:153;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:286:21:-;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;167:23;;-1:-1:-1;;;;;;219:32:21;;209:43;;199:71;;266:1;263;256:12;593:423;635:3;673:5;667:12;700:6;695:3;688:19;725:1;735:162;749:6;746:1;743:13;735:162;;;811:4;867:13;;;863:22;;857:29;839:11;;;835:20;;828:59;764:12;735:162;;;739:3;942:1;935:4;926:6;921:3;917:16;913:27;906:38;1005:4;998:2;994:7;989:2;981:6;977:15;973:29;968:3;964:39;960:50;953:57;;;593:423;;;;:::o;1021:220::-;1170:2;1159:9;1152:21;1133:4;1190:45;1231:2;1220:9;1216:18;1208:6;1190:45;:::i;1515:131::-;-1:-1:-1;;;;;1590:31:21;;1580:42;;1570:70;;1636:1;1633;1626:12;1651:134;1719:20;;1748:31;1719:20;1748:31;:::i;1790:156::-;1856:20;;1916:4;1905:16;;1895:27;;1885:55;;1936:1;1933;1926:12;1951:529;2033:6;2041;2049;2057;2110:3;2098:9;2089:7;2085:23;2081:33;2078:53;;;2127:1;2124;2117:12;2078:53;2166:9;2153:23;2185:31;2210:5;2185:31;:::i;:::-;2235:5;-1:-1:-1;2259:36:21;2291:2;2276:18;;2259:36;:::i;:::-;2249:46;;2314:36;2346:2;2335:9;2331:18;2314:36;:::i;:::-;2304:46;;2402:2;2391:9;2387:18;2374:32;2415:33;2440:7;2415:33;:::i;:::-;1951:529;;;;-1:-1:-1;1951:529:21;;-1:-1:-1;;1951:529:21:o;2485:456::-;2567:6;2575;2583;2591;2644:3;2632:9;2623:7;2619:23;2615:33;2612:53;;;2661:1;2658;2651:12;2612:53;2700:9;2687:23;2719:31;2744:5;2719:31;:::i;:::-;2769:5;-1:-1:-1;2793:36:21;2825:2;2810:18;;2793:36;:::i;:::-;2783:46;;2848:36;2880:2;2869:9;2865:18;2848:36;:::i;:::-;2485:456;;;;-1:-1:-1;2838:46:21;;2931:2;2916:18;2903:32;;-1:-1:-1;;2485:456:21:o;2946:317::-;3012:6;3020;3073:2;3061:9;3052:7;3048:23;3044:32;3041:52;;;3089:1;3086;3079:12;3041:52;3128:9;3115:23;3147:31;3172:5;3147:31;:::i;:::-;3197:5;-1:-1:-1;3221:36:21;3253:2;3238:18;;3221:36;:::i;:::-;3211:46;;2946:317;;;;;:::o;3268:163::-;3335:20;;3395:10;3384:22;;3374:33;;3364:61;;3421:1;3418;3411:12;3436:460;3517:6;3525;3533;3541;3594:3;3582:9;3573:7;3569:23;3565:33;3562:53;;;3611:1;3608;3601:12;3562:53;3650:9;3637:23;3669:31;3694:5;3669:31;:::i;:::-;3719:5;-1:-1:-1;3743:36:21;3775:2;3760:18;;3743:36;:::i;:::-;3733:46;;3798:36;3830:2;3819:9;3815:18;3798:36;:::i;:::-;3788:46;;3853:37;3886:2;3875:9;3871:18;3853:37;:::i;:::-;3843:47;;3436:460;;;;;;;:::o;4868:247::-;4927:6;4980:2;4968:9;4959:7;4955:23;4951:32;4948:52;;;4996:1;4993;4986:12;4948:52;5035:9;5022:23;5054:31;5079:5;5054:31;:::i;5120:533::-;5209:6;5217;5225;5233;5241;5294:3;5282:9;5273:7;5269:23;5265:33;5262:53;;;5311:1;5308;5301:12;5262:53;5350:9;5337:23;5369:31;5394:5;5369:31;:::i;:::-;5419:5;-1:-1:-1;5443:36:21;5475:2;5460:18;;5443:36;:::i;:::-;5433:46;;5498:36;5530:2;5519:9;5515:18;5498:36;:::i;:::-;5488:46;;5553:37;5586:2;5575:9;5571:18;5553:37;:::i;:::-;5543:47;;5609:38;5642:3;5631:9;5627:19;5609:38;:::i;:::-;5599:48;;5120:533;;;;;;;;:::o;5658:179::-;5725:20;;-1:-1:-1;;;;;5774:38:21;;5764:49;;5754:77;;5827:1;5824;5817:12;5842:460;5923:6;5931;5939;5947;6000:3;5988:9;5979:7;5975:23;5971:33;5968:53;;;6017:1;6014;6007:12;5968:53;6056:9;6043:23;6075:31;6100:5;6075:31;:::i;:::-;6125:5;-1:-1:-1;6149:36:21;6181:2;6166:18;;6149:36;:::i;:::-;6139:46;;6204:36;6236:2;6225:9;6221:18;6204:36;:::i;:::-;6194:46;;6259:37;6292:2;6281:9;6277:18;6259:37;:::i;6307:386::-;6392:6;6445:2;6433:9;6424:7;6420:23;6416:32;6413:52;;;6461:1;6458;6451:12;6413:52;6501:9;6488:23;6534:18;6526:6;6523:30;6520:50;;;6566:1;6563;6556:12;6520:50;6589:22;;6645:3;6627:16;;;6623:26;6620:46;;;6662:1;6659;6652:12;7275:277;7479:3;7464:19;;7492:54;7468:9;7528:6;-1:-1:-1;;;;;7054:2:21;7046:5;7040:12;7036:21;7031:3;7024:34;7119:2;7111:4;7104:5;7100:16;7094:23;7090:32;7083:4;7078:3;7074:14;7067:56;;7184:6;7176:4;7169:5;7165:16;7159:23;7155:36;7148:4;7143:3;7139:14;7132:60;7255:4;7248:5;7244:16;7238:23;7231:31;7224:39;7217:4;7212:3;7208:14;7201:63;6908:362;;;7557:184;7615:6;7668:2;7656:9;7647:7;7643:23;7639:32;7636:52;;;7684:1;7681;7674:12;7636:52;7707:28;7725:9;7707:28;:::i;7746:367::-;7809:8;7819:6;7873:3;7866:4;7858:6;7854:17;7850:27;7840:55;;7891:1;7888;7881:12;7840:55;-1:-1:-1;7914:20:21;;7957:18;7946:30;;7943:50;;;7989:1;7986;7979:12;7943:50;8026:4;8018:6;8014:17;8002:29;;8086:3;8079:4;8069:6;8066:1;8062:14;8054:6;8050:27;8046:38;8043:47;8040:67;;;8103:1;8100;8093:12;8040:67;7746:367;;;;;:::o;8118:855::-;8236:6;8244;8252;8260;8268;8276;8329:3;8317:9;8308:7;8304:23;8300:33;8297:53;;;8346:1;8343;8336:12;8297:53;8385:9;8372:23;8404:31;8429:5;8404:31;:::i;:::-;8454:5;-1:-1:-1;8478:36:21;8510:2;8495:18;;8478:36;:::i;:::-;8468:46;;8533:36;8565:2;8554:9;8550:18;8533:36;:::i;:::-;8523:46;;8621:2;8610:9;8606:18;8593:32;8634:33;8659:7;8634:33;:::i;:::-;8686:7;-1:-1:-1;8744:3:21;8729:19;;8716:33;8772:18;8761:30;;8758:50;;;8804:1;8801;8794:12;8758:50;8843:70;8905:7;8896:6;8885:9;8881:22;8843:70;:::i;:::-;8118:855;;;;-1:-1:-1;8118:855:21;;-1:-1:-1;8118:855:21;;8932:8;;8118:855;-1:-1:-1;;;8118:855:21:o;9171:712::-;9279:6;9287;9295;9303;9311;9364:3;9352:9;9343:7;9339:23;9335:33;9332:53;;;9381:1;9378;9371:12;9332:53;9420:9;9407:23;9439:31;9464:5;9439:31;:::i;:::-;9489:5;-1:-1:-1;9513:36:21;9545:2;9530:18;;9513:36;:::i;:::-;9503:46;;9568:36;9600:2;9589:9;9585:18;9568:36;:::i;:::-;9558:46;;9655:2;9644:9;9640:18;9627:32;9682:18;9674:6;9671:30;9668:50;;;9714:1;9711;9704:12;9668:50;9753:70;9815:7;9806:6;9795:9;9791:22;9753:70;:::i;:::-;9171:712;;;;-1:-1:-1;9171:712:21;;-1:-1:-1;9842:8:21;;9727:96;9171:712;-1:-1:-1;;;9171:712:21:o;9888:642::-;10053:2;10105:21;;;10175:13;;10078:18;;;10197:22;;;10024:4;;10053:2;10276:15;;;;10250:2;10235:18;;;10024:4;10319:185;10333:6;10330:1;10327:13;10319:185;;;10408:13;;10401:21;10394:29;10382:42;;10479:15;;;;10444:12;;;;10355:1;10348:9;10319:185;;;-1:-1:-1;10521:3:21;;9888:642;-1:-1:-1;;;;;;9888:642:21:o;10644:1259::-;11050:3;11045;11041:13;11033:6;11029:26;11018:9;11011:45;10992:4;11075:2;11113:3;11108:2;11097:9;11093:18;11086:31;11140:46;11181:3;11170:9;11166:19;11158:6;11140:46;:::i;:::-;11234:9;11226:6;11222:22;11217:2;11206:9;11202:18;11195:50;11268:33;11294:6;11286;11268:33;:::i;:::-;11332:2;11317:18;;11310:34;;;-1:-1:-1;;;;;11381:32:21;;11375:3;11360:19;;11353:61;11401:3;11430:19;;11423:35;;;11495:22;;;11489:3;11474:19;;11467:51;11567:13;;11589:22;;;11665:15;;;;-1:-1:-1;11627:15:21;;;;-1:-1:-1;11708:169:21;11722:6;11719:1;11716:13;11708:169;;;11783:13;;11771:26;;11852:15;;;;11817:12;;;;11744:1;11737:9;11708:169;;;-1:-1:-1;11894:3:21;;10644:1259;-1:-1:-1;;;;;;;;;;;;10644:1259:21:o;12090:127::-;12151:10;12146:3;12142:20;12139:1;12132:31;12182:4;12179:1;12172:15;12206:4;12203:1;12196:15;12222:344;12289:2;12283:9;12331:3;12319:16;;12365:18;12350:34;;12386:22;;;12347:62;12344:185;;;12451:10;12446:3;12442:20;12439:1;12432:31;12486:4;12483:1;12476:15;12514:4;12511:1;12504:15;12344:185;12545:2;12538:22;12222:344;:::o;12571:159::-;12638:20;;12698:6;12687:18;;12677:29;;12667:57;;12720:1;12717;12710:12;12735:118;12821:5;12814:13;12807:21;12800:5;12797:32;12787:60;;12843:1;12840;12833:12;12858:796;12922:5;12970:4;12958:9;12953:3;12949:19;12945:30;12942:50;;;12988:1;12985;12978:12;12942:50;13021:2;13015:9;13063:4;13055:6;13051:17;13134:6;13122:10;13119:22;13098:18;13086:10;13083:34;13080:62;13077:185;;;13184:10;13179:3;13175:20;13172:1;13165:31;13219:4;13216:1;13209:15;13247:4;13244:1;13237:15;13077:185;13278:2;13271:22;13311:6;-1:-1:-1;13311:6:21;13341:28;13359:9;13341:28;:::i;:::-;13333:6;13326:44;13403:37;13436:2;13425:9;13421:18;13403:37;:::i;:::-;13398:2;13390:6;13386:15;13379:62;13474:37;13507:2;13496:9;13492:18;13474:37;:::i;:::-;13469:2;13461:6;13457:15;13450:62;13564:2;13553:9;13549:18;13536:32;13577:30;13599:7;13577:30;:::i;:::-;13635:2;13623:15;;;;13616:32;12858:796;;-1:-1:-1;;12858:796:21:o;13659:248::-;13753:6;13806:3;13794:9;13785:7;13781:23;13777:33;13774:53;;;13823:1;13820;13813:12;13774:53;13846:55;13893:7;13882:9;13846:55;:::i;14011:2109::-;14092:12;;-1:-1:-1;;;;;10601:31:21;10589:44;;14156:4;14149:5;14145:16;14139:23;14171:46;14211:4;14206:3;14202:14;14188:12;1313:4;1302:16;1290:29;;1246:75;14171:46;;14265:4;14258:5;14254:16;14248:23;14280:48;14322:4;14317:3;14313:14;14297;1313:4;1302:16;1290:29;;1246:75;14280:48;;14376:4;14369:5;14365:16;14359:23;14391:50;14435:4;14430:3;14426:14;14410;-1:-1:-1;;;;;10601:31:21;10589:44;;10535:104;14391:50;;14489:4;14482:5;14478:16;14472:23;14504:49;14547:4;14542:3;14538:14;14522;-1:-1:-1;;;;;6763:38:21;6751:51;;6698:110;14504:49;;14601:4;14594:5;14590:16;14584:23;14616:49;14659:4;14654:3;14650:14;14634;13988:10;13977:22;13965:35;;13912:94;14616:49;;14713:4;14706:5;14702:16;14696:23;14728:49;14771:4;14766:3;14762:14;14746;13988:10;13977:22;13965:35;;13912:94;14728:49;;14825:4;14818:5;14814:16;14808:23;14840:49;14883:4;14878:3;14874:14;14858;13988:10;13977:22;13965:35;;13912:94;14840:49;-1:-1:-1;14908:6:21;14951:14;;;14945:21;13988:10;13977:22;;;15009:12;;;13965:35;;;;15041:6;15084:14;;;15078:21;13977:22;;;15142:12;;;13965:35;15174:6;15217:14;;;15211:21;6889:6;6878:18;15275:12;;;6866:31;15307:6;15351:14;;;15345:21;1313:4;1302:16;15409:12;;;1290:29;15441:6;15485:14;;;15479:21;375:13;368:21;15542:12;;;356:34;15574:6;15618:14;;;15612:21;375:13;368:21;15675:12;;;356:34;15707:6;15749:14;;;15743:21;15729:12;;;15722:43;15784:6;15826:14;;;15820:21;15806:12;;;15799:43;15861:6;15905:14;;;15899:21;-1:-1:-1;;;;;10601:31:21;15965:12;;;10589:44;15998:6;16042:15;;;16036:22;375:13;;368:21;16100:13;;;356:34;16067:47;305:91;16125:708;16348:2;16400:21;;;16470:13;;16373:18;;;16492:22;;;16319:4;;16348:2;16571:15;;;;16545:2;16530:18;;;16319:4;16614:193;16628:6;16625:1;16622:13;16614:193;;;16677:46;16719:3;16710:6;16704:13;16677:46;:::i;:::-;16782:15;;;;16752:6;16743:16;;;;;16650:1;16643:9;16614:193;;16838:318;16939:6;16947;17000:3;16988:9;16979:7;16975:23;16971:33;16968:53;;;17017:1;17014;17007:12;16968:53;17040:27;17057:9;17040:27;:::i;:::-;17030:37;;17086:64;17142:7;17137:2;17126:9;17122:18;17086:64;:::i;17582:460::-;17663:6;17671;17679;17687;17740:3;17728:9;17719:7;17715:23;17711:33;17708:53;;;17757:1;17754;17747:12;17708:53;17796:9;17783:23;17815:31;17840:5;17815:31;:::i;:::-;17865:5;-1:-1:-1;17889:36:21;17921:2;17906:18;;17889:36;:::i;:::-;17879:46;;17944:36;17976:2;17965:9;17961:18;17944:36;:::i;:::-;17934:46;;17999:37;18032:2;18021:9;18017:18;17999:37;:::i;18244:1233::-;18333:6;18386:3;18374:9;18365:7;18361:23;18357:33;18354:53;;;18403:1;18400;18393:12;18354:53;18429:17;;:::i;:::-;18469:29;18488:9;18469:29;:::i;:::-;18462:5;18455:44;18531:37;18564:2;18553:9;18549:18;18531:37;:::i;:::-;18526:2;18519:5;18515:14;18508:61;18601:37;18634:2;18623:9;18619:18;18601:37;:::i;:::-;18596:2;18589:5;18585:14;18578:61;18671:37;18704:2;18693:9;18689:18;18671:37;:::i;:::-;18666:2;18659:5;18655:14;18648:61;18742:38;18775:3;18764:9;18760:19;18742:38;:::i;:::-;18736:3;18729:5;18725:15;18718:63;18814:38;18847:3;18836:9;18832:19;18814:38;:::i;:::-;18808:3;18801:5;18797:15;18790:63;18886:38;18919:3;18908:9;18904:19;18886:38;:::i;:::-;18880:3;18873:5;18869:15;18862:63;18986:3;18975:9;18971:19;18958:33;18952:3;18945:5;18941:15;18934:58;19011:3;19046:36;19078:2;19067:9;19063:18;19046:36;:::i;:::-;19030:14;;;19023:60;19102:3;19137:38;19156:18;;;19137:38;:::i;:::-;19121:14;;;19114:62;19195:3;19230:36;19247:18;;;19230:36;:::i;:::-;19214:14;;;19207:60;19286:3;19321:38;19340:18;;;19321:38;:::i;:::-;19305:14;;;19298:62;19379:3;19427:18;;;19414:32;19398:14;;;19391:56;;;;-1:-1:-1;19309:5:21;18244:1233;-1:-1:-1;18244:1233:21:o;19482:387::-;19555:6;19563;19571;19624:2;19612:9;19603:7;19599:23;19595:32;19592:52;;;19640:1;19637;19630:12;19592:52;19679:9;19666:23;19698:31;19723:5;19698:31;:::i;:::-;19748:5;-1:-1:-1;19772:36:21;19804:2;19789:18;;19772:36;:::i;:::-;19762:46;;19827:36;19859:2;19848:9;19844:18;19827:36;:::i;:::-;19817:46;;19482:387;;;;;:::o;19874:250::-;20060:3;20045:19;;20073:45;20049:9;20100:6;20073:45;:::i;20129:523::-;20208:6;20216;20224;20232;20285:3;20273:9;20264:7;20260:23;20256:33;20253:53;;;20302:1;20299;20292:12;20253:53;20341:9;20328:23;20360:31;20385:5;20360:31;:::i;:::-;20410:5;-1:-1:-1;20434:36:21;20466:2;20451:18;;20434:36;:::i;:::-;20424:46;;20489:36;20521:2;20510:9;20506:18;20489:36;:::i;:::-;20479:46;;20577:2;20566:9;20562:18;20549:32;20590:30;20612:7;20590:30;:::i;20657:533::-;20746:6;20754;20762;20770;20778;20831:3;20819:9;20810:7;20806:23;20802:33;20799:53;;;20848:1;20845;20838:12;20799:53;20887:9;20874:23;20906:31;20931:5;20906:31;:::i;:::-;20956:5;-1:-1:-1;20980:36:21;21012:2;20997:18;;20980:36;:::i;:::-;20970:46;;21035:36;21067:2;21056:9;21052:18;21035:36;:::i;:::-;21025:46;;21090:37;21123:2;21112:9;21108:18;21090:37;:::i;:::-;21080:47;;21146:38;21179:3;21168:9;21164:19;21146:38;:::i;23072:182::-;23129:6;23182:2;23170:9;23161:7;23157:23;23153:32;23150:52;;;23198:1;23195;23188:12;23150:52;23221:27;23238:9;23221:27;:::i;23626:184::-;23684:6;23737:2;23725:9;23716:7;23712:23;23708:32;23705:52;;;23753:1;23750;23743:12;23705:52;23776:28;23794:9;23776:28;:::i;24068:545::-;24161:4;24167:6;24227:11;24214:25;24321:2;24317:7;24306:8;24290:14;24286:29;24282:43;24262:18;24258:68;24248:96;;24340:1;24337;24330:12;24248:96;24367:33;;24419:20;;;-1:-1:-1;24462:18:21;24451:30;;24448:50;;;24494:1;24491;24484:12;24448:50;24527:4;24515:17;;-1:-1:-1;24578:1:21;24574:14;;;24558;24554:35;24544:46;;24541:66;;;24603:1;24600;24593:12;24991:184;25061:6;25114:2;25102:9;25093:7;25089:23;25085:32;25082:52;;;25130:1;25127;25120:12;25082:52;-1:-1:-1;25153:16:21;;24991:184;-1:-1:-1;24991:184:21:o;25180:1637::-;25467:4;25455:17;;;25437:36;;25509:17;;25504:2;25489:18;;25482:45;25554:13;;13988:10;13977:22;25584:2;25569:18;;13965:35;25424:3;25409:19;;25642:2;25630:15;;25624:22;25619:2;25604:18;;25597:50;25694:2;25682:15;;25676:22;-1:-1:-1;;;;;10601:31:21;;25755:3;25740:19;;10589:44;-1:-1:-1;25809:2:21;25797:15;;25791:22;13988:10;13977:22;;25871:3;25856:19;;13965:35;-1:-1:-1;25925:3:21;25913:16;;25907:23;13988:10;13977:22;;25988:3;25973:19;;13965:35;-1:-1:-1;26042:3:21;26030:16;;26024:23;13988:10;13977:22;;26105:3;26090:19;;13965:35;26056:54;26159:3;26151:6;26147:16;26141:23;26183:3;26195:54;26245:2;26234:9;26230:18;26214:14;-1:-1:-1;;;;;10601:31:21;10589:44;;10535:104;26195:54;26298:3;26290:6;26286:16;26280:23;26258:45;;26322:3;26334:51;26381:2;26370:9;26366:18;26350:14;375:13;368:21;356:34;;305:91;26334:51;26410:15;;;26404:22;26445:3;26464:18;;;26457:30;;;;26512:15;;;26506:22;26547:3;26566:18;;;26559:30;;;;26614:15;;;26608:22;26649:3;26668:18;;;26661:30;;;;26734:15;;;26728:22;26722:3;26707:19;;26700:51;26794:15;;;26788:22;26782:3;26767:19;;;26760:51;;;;25180:1637;;-1:-1:-1;;;25180:1637:21:o;26822:127::-;26883:10;26878:3;26874:20;26871:1;26864:31;26914:4;26911:1;26904:15;26938:4;26935:1;26928:15;26954:355;27225:4;27213:17;;27195:36;;27182:3;27167:19;;27240:63;27299:2;27284:18;;27276:6;-1:-1:-1;;;;;7054:2:21;7046:5;7040:12;7036:21;7031:3;7024:34;7119:2;7111:4;7104:5;7100:16;7094:23;7090:32;7083:4;7078:3;7074:14;7067:56;;7184:6;7176:4;7169:5;7165:16;7159:23;7155:36;7148:4;7143:3;7139:14;7132:60;7255:4;7248:5;7244:16;7238:23;7231:31;7224:39;7217:4;7212:3;7208:14;7201:63;6908:362;;;27663:1818;27948:4;27936:17;;;27918:36;;27990:17;;27985:2;27970:18;;27963:45;28036:13;;-1:-1:-1;;;;;10601:31:21;28066:2;28051:18;;10589:44;27905:3;27890:19;;28117:2;28105:15;;28099:22;-1:-1:-1;;;;;6763:38:21;;28177:2;28162:18;;6751:51;-1:-1:-1;28230:2:21;28218:15;;28212:22;13988:10;13977:22;;28292:3;28277:19;;13965:35;-1:-1:-1;28346:2:21;28334:15;;28328:22;13988:10;13977:22;;28408:3;28393:19;;13965:35;-1:-1:-1;28462:3:21;28450:16;;28444:23;13988:10;13977:22;;28525:3;28510:19;;13965:35;-1:-1:-1;28579:3:21;28567:16;;28561:23;13988:10;13977:22;;28642:3;28627:19;;13965:35;28593:54;28696:3;28688:6;28684:16;28678:23;28720:3;28732:53;28781:2;28770:9;28766:18;28750:14;6889:6;6878:18;6866:31;;6813:90;28732:53;28822:3;28810:16;;28804:23;28846:3;28865:18;;;28858:30;;;;28925:15;;;28919:22;;-1:-1:-1;28960:3:21;;28972:52;29005:18;;;28919:22;1313:4;1302:16;1290:29;;1246:75;28972:52;29061:15;;29055:22;;-1:-1:-1;29096:3:21;29108:54;29143:18;;;29055:22;-1:-1:-1;;;;;10601:31:21;10589:44;;10535:104;29108:54;29199:15;;;29193:22;;-1:-1:-1;29234:3:21;;29246:52;29279:18;;;29193:22;1313:4;1302:16;1290:29;;1246:75;29246:52;29335:15;;29329:22;-1:-1:-1;;;;;10601:31:21;29410:3;29395:19;;10589:44;29458:15;;;29452:22;29446:3;29431:19;;;29424:51;;;;27663:1818;;-1:-1:-1;;;27663:1818:21:o;30822:251::-;30892:6;30945:2;30933:9;30924:7;30920:23;30916:32;30913:52;;;30961:1;30958;30951:12;30913:52;30993:9;30987:16;31012:31;31037:5;31012:31;:::i;31357:245::-;31424:6;31477:2;31465:9;31456:7;31452:23;31448:32;31445:52;;;31493:1;31490;31483:12;31445:52;31525:9;31519:16;31544:28;31566:5;31544:28;:::i;31607:521::-;31684:4;31690:6;31750:11;31737:25;31844:2;31840:7;31829:8;31813:14;31809:29;31805:43;31785:18;31781:68;31771:96;;31863:1;31860;31853:12;31771:96;31890:33;;31942:20;;;-1:-1:-1;31985:18:21;31974:30;;31971:50;;;32017:1;32014;32007:12;31971:50;32050:4;32038:17;;-1:-1:-1;32081:14:21;32077:27;;;32067:38;;32064:58;;;32118:1;32115;32108:12

Swarm Source

ipfs://82a9fe6d3c01d9f8932f133836ed974fec48211730542b3dc9d954d491f40651

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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

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