Token Bonkers

 

Overview ERC-721

Total Supply:
690 BONK

Holders:
57 addresses

Transfers:
-

Loading
[ Download CSV Export  ] 
Loading
Loading

Click here to update the token ICO / general information
# Exchange Pair Price  24H Volume % Volume
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Bonkers

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-11-12
*/

// ________________________________________________________________________________________
// ____________________________________<PZZZZZT||*_________________________________________
// ___________________________________M#0ZREg8QQQBBBqm)r___________________________________
// ____________________!r;[email protected]$qq3KPKhUaHWPm$EBQ#G}r!_____________________________
// ________________:[email protected]:[email protected]##QEhh\^:______________________
// ______________:o#Z}$#@$dM$w:[email protected]@#Q8ggggggg$$$$$$$00D9R$$QB#BQZjv~:,vcc(~:_________
// _____________\#gV^[email protected]#dy*LoM$!_______=\3333333333333333333BBBB#BB8gB#B###kmYouV8uV<______
// ____________\#MVj}^[email protected])V0:_______________________________^rkGG#####Mr#Q*VDzccMW:____
// ___________~8QxwP3l;[email protected]#5______________________________________:v#q<[email protected]@@qGkylKhTT,_
// ___________}@[email protected]#Q#r_______________________________________Zg^r**[email protected]@@#Q#B##z
// [email protected]@]IPPPPPmx!(TTx:[email protected]*______________________________________:[email protected]##[email protected]
// [email protected]@qhPPPPKzx,..-._-}#r______________________________________<R#hccM)=dBx#@#Z_
// _________!0#[email protected]@QGPPPekVc|--__` Pg________________________________________*[email protected]*!~z6TZ##]
// _______!j#B8g8Q#@BZP3mVVv^,.__- wM_________________________________________,[email protected]^==x0z<!,
// _____!H#[email protected])^<<!`'., mD:_^=^rrrrrrrrrrrrrrrrrrr"_________________i#Q*=!=]dV:
// ____|#BEgg$gQ#[email protected]#dTr<^r*^^:_``[email protected]#@@@@@@@@@@@@@@@@@@@@#BBDX<<[email protected]*~~=!T6
// ___v#Qd6D##[email protected]]](VlVT^_':[email protected]@BKvvvvvvvvvvvvvvvvvvw55d#@@@BZu~,[email protected]*~=^^=
// __\#[email protected]:__________~#@EkyzHEBQd*:)#@Q*==!!::::::::::::::::::!rxhD#@@BO^:______x#Q*==*<
// __#[email protected]_____________:[email protected]@#@@@$db#[email protected]@)::::::::::::::::::::::::::[email protected]@#K:[email protected]^=:<
// __iB#QBB*[email protected]@@BVv===*TZO#@R::::::::::::::::xX$$$6V*:::::[email protected]#$\____v#Q(!:
// ____:x?_______________z#@Bl======!::::*x::::::::~uuuuu^[email protected]@\:::::::!=xE#@Bx___<@@x=
// ____________________\#@BT=======!::::=lllT::::[email protected]$$o##[email protected]@d::::::::::[email protected]=__v##K
// [email protected]@b)=======!:::[email protected]@g#@d:::[email protected]@QRRdZg#[email protected]@@@#z:::::::::::::==\#@U:[email protected]@
// [email protected]#W=========!::*[email protected][email protected]@d:::r#@@####@O*:====!::::::::::::::!==<[email protected]>_i#
// [email protected]@6======}####[email protected]@dW#@@@h::::=cZQQQk):::::::<xMBBBBv::::::::[email protected]_v
// [email protected]@^[email protected]##QQ8R65DQ##@z\:::::::::::::::!\[email protected]|*[email protected]!::::::::::!=)[email protected]*
// [email protected]@[email protected]@@@@@Q$BBDdKW68g):::::::::::*Q#@Bc=:<##@@#BMu*::::::::!^[email protected]#
// [email protected]@[email protected]@@@B$#@@@@##[email protected]::::::::::::<rr!:TB#y=*[email protected]@B]:::::::::T#
// [email protected]@c========<[email protected][email protected]@@@@###[email protected]:::::::::::::::::*(=^^[email protected]@#Qr::::::::::^
// [email protected]@[email protected]@@@yM#@@@#o~::::::::=><[email protected]@@#Oy\\=:::::::::::::
// [email protected]#[email protected]@@@@y:::^3m>:::::!}Vdg#@@@@@@@@@@@@@#*::::::::::::::::::
// [email protected]===========xUDDDY::::::::::>[email protected]@@@@@@@@@@@@@@@@@@@B^:::::::::::::::::
// _______________xY##x============)(===::r^Lw*^[email protected]@@@@@@@@@@@@@@@@@@@@@@@#r::::::::::::::::
// _____________}#@[email protected]=============3V?Mevw;[email protected]@@@@@@@@@@@@@@@@@@@@@@@@@@#^:::::::::::::::
// [email protected]**O#i==}}u^>v)YdyxRwVwT)=:[email protected]@@@@@@@@@@@@@@@@@@@@@@@@@@@@B*:::::[email protected]#I~::
// [email protected]~|Qr!==xOex(EUrYr*^;<[email protected]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Br::~j##ek#@Q::
// [email protected]}!*5j!=xRkWr^[email protected]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#\[email protected]#y!:x#@#MT
// _____________"}#Qg$*:*)rrr~===============^[email protected]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@d=:::[email protected]@@@@
// _____________*ZHxM#|[email protected][email protected]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@y::::::*<*#@
// _____________#[email protected]@@QQQdyr===============:^[email protected]@@@@@@@@@[email protected]@@@@@@@@#T::::::::::[email protected]
// _____________BG^LR6PQ#@@BQQQQPr=============:::^[email protected]@@@@@QRd5PeUhhhhaZ#@@@#k=:::::::::::[email protected]
// _____________>BQd9$6_^[email protected]@#QQQQO<~============::::^[email protected]@@@BOddddZMMMMZ$#@#h=:::::::::::*[email protected]@
// _______________:xx^____^[email protected]@BQQQQ6v~===========!::::^[email protected]@@@QDOOOOOO$#@d^:::::::::::::[email protected]<
// _________________________^[email protected]@BQQQQ6i============!::::^[email protected]@@@@@@@@#R}^::::::::::::::}@@8::


// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@8L=([email protected]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[email protected]@@h`[email protected]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@k`[email protected]@@@@"[email protected]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@V`(@@@@@[email protected]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#5L=!=T#@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@3``#@@@@@@@@@@@@@@@@@@@@@@@@#[email protected]@@#[email protected]@@@h`[email protected]#(`[email protected]@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#. ^@@@@@@@@@@@@@@@@@@@@@@@@k"x [email protected]$` [email protected]@@#` ^@@T` =#@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@x `[email protected]@@@@@@@@@@@@@RL=**^[email protected]@d_#[email protected]@^` [email protected]@@@V` `[email protected]@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@##B##@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Q` `[email protected]@@@@@@@@@@@8=`[email protected]@_`#@R.k`VR*`  [email protected][email protected]#hx_ `!h^^^[email protected]@@@
// @@@@@@@@@@@@@@@@@@@@8hL^"!=^*^=!!*[email protected]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@L ``#@@Bk(^*[email protected]@@R` [email protected]@@5``@@@3`=Lk(  .#Q  [email protected]@@@@d` ^[email protected]@#_(@@@
// @@@@@@@@@@@@@@@@Qk=.^kR#@@@@@@@@@B5^`*[email protected]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#.  [email protected]#(`[email protected][email protected]@B. `#@Qx`[email protected]@B_^@@@_ `[email protected]  [email protected]@@@@h`(@@@@@= *@@
// @@@@@@@@@@@@@#[email protected]@@@@@@@@@@[email protected]@@8^`[email protected]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@h   x#!`[email protected]@@@@@@L  "[email protected]@@#"!#@@#` `R#"=^`*[email protected]@@@@#. `[email protected]
// @@@@@@@@@@@[email protected]@@@@@@@@@@@R=`*[email protected]@@@@d` "[email protected]@@@@@@@@@@@@@@@@@@@@@@@8V((k#@@@@@_  ``` `!(#@@@@Q`` "[email protected]@@@@R.*#@@@@h``(!=#@#$53d#@@@@@@@*`  `3
// @@@@@@@@@Q(`V#@@@@@@@@@@@@@L`[email protected]@@@@@@@5  [email protected]@@@@@@@@@@@@#3(!``=$h"^5$` ^@@@@h   `.*h^  [email protected]@@#!`  [email protected]@@@@Q("[email protected]@@@@@@@[email protected]@@@@@@@@@@@@@$"`   `.
// @@@@@@@@k`*[email protected]@@@@@@@@@@@@@* `[email protected]@@@@@@@@#` `*@@@@8V^_."[email protected]   [email protected]@d``(@@@@_   [email protected]@d``[email protected]@@8!`k^  *55V=^[email protected]@@@@@@@@@@@@@@@@@@@@@@@@R^`     `_
// @@@@@@#=`[email protected]@@@@@@@@@@@@@@*` [email protected]@@@@@@@@@5   "@@$!`"dT    "#@@@k``"[email protected]@#_ `[email protected]@@(   `[email protected]@* `[email protected]#T`x#@@[email protected]@@@@@@@@@@@@@@@@@@@@@@@@$T.         k
// @@@@@#[email protected]@@@@@@@@@@@@@@3``[email protected]@@@@@@@@@Q.` `[email protected]` "#@@dhR"`[email protected]@@! `[email protected]@@h  ^@@#^`   `[email protected]@=``L*`*[email protected]@@@@@@@@@@@@@@@@@@@@@@@@@@@@#8dV*`           ^@
// @@@@#"[email protected]@@@@@@@@@@@@@@#_ `[email protected]@@@@@@@@3`` `[email protected]` `[email protected]@@@@@=`[email protected]@d``[email protected]@@@^  [email protected]  `[email protected]@@BVxVd#@@@@@@@@@@@@@@@@@@@@@@#QR3kL*"`               `*#@
// @@@@=`[email protected]@@@@@@@@@@@@@@@h   [email protected]@@@@@#h"  `^[email protected]@k  [email protected]@@@@@d`*@@@=  [email protected]@@@T``("^[email protected][email protected]@@@@@@@@@@@@@@@@@@@@#Q$dhVx*!.`                      `[email protected]@@
// @@@V`[email protected]@@@@@@@@@@@@@@@@=  `[email protected]=`  "[email protected]@@@T  [email protected]@@@@$.`#@@R` [email protected]@@@@@[email protected]@@@@@@@@@@@@@@@#B8d3kTx*!_` ` ```                          `L#@@@@
// @@$`[email protected]@@@@@@@@@@@@@@@@Q`  [email protected]@T(LVVVx!``^h#@@8` `[email protected]@BL`"[email protected]@@(`"[email protected]@@@@@@@@@@@@#Q$53kTx^!_``````                                      `L#@@@@@@
// @@^`[email protected]@@@@@@@@@@@@@@@@h`  *@@@@@@@@@@Qx` [email protected]@R" `^=`[email protected]@@@@@#@@@@@@BR3Vx^".` `                                                  `!h#@@@@@@@@
// @R`*@@@@@@@@@@@@@@@@@@*` `[email protected]@@@@@@@@@@@d`  [email protected]@#[email protected]@@@@@@@@Q5T^_`                                                          .(5#@@@@@@@@@@@
// @^`[email protected]@@@@@@@@@@@@@@@@#`   [email protected]@@@@@@@@@@@@L  `_#@@@@@@@@@@#dL!`                                                          ``[email protected]@@@@@@@@@@@@@@
// Q`[email protected]@@@@@@@@@@@@@@@@@R   `#@@@@@@@@@@@@@5    [email protected]@@@@@@#5*` `                                                      ``"*[email protected]@@@@@@@@@@@@@@@@@@@
// V [email protected]@@@@@@@@@@@@@@@@@V` `[email protected]@@@@@@@@@@@@@T`  `[email protected]@@@@8(`                                                 ` `.!*Lk5$#@@@@@@@@@@@@@@@@@@@@@@@@@@
// ^ [email protected]@@@@@@@@@@@@@@@@@=  `[email protected]@@@@@@@@@@@@@"` `[email protected]@@@Q*`                                           `_=([email protected]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// .`#@@@@@@@@@@@@@@@@@@`  `[email protected]@@@@@@@@@@@@h   `[email protected]@@k``                              ` ` `"^[email protected]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// `[email protected]@@@@@@@@@@@@@@@@@d`  .#@@@@@@@@@@@@R`` `[email protected]@@*`                       `  ``"^[email protected]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// .`#@@@@@@@@@@@@@@@@@x`  [email protected]@@@@@@@@@@@3`` `[email protected]@@L`                     `_*[email protected]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// = [email protected]@@@@@@@@@@@@@@@#`` `[email protected]@@@@@@@@$=```*[email protected]@@$`                ``[email protected]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// T [email protected]@@@@@@@@@@@@@@@T   [email protected]#*.*V5d5V!` `([email protected]@@@@k              ``(5#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// #..#@@@@@@@@@@@@@@k`` [email protected]@@@#3L*!"!^[email protected]@@@@@@@V            `([email protected]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @8."[email protected]@@@@@@@@@@#(```[email protected]@@@@@@@@@@@@@@@@@@@@@@R`       ` .V#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@Q!`k#@@@@@@@#h.  [email protected]@@@@@@@@@@@@@@@@@@@@@@@@=`      `(#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@R*.(k33hT*``[email protected]@@@@@@@@@@@@@@@@@@@@@@@@@@B_`    [email protected]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@#dkTLTVhR#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@B"`  =#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[email protected]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@



// File: @openzeppelin/contracts/utils/Counters.sol


// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)

pragma solidity ^0.8.0;

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}

// File: @openzeppelin/contracts/utils/Strings.sol


// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

// File: @openzeppelin/contracts/utils/Address.sol


// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly
                /// @solidity memory-safe-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

// File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol


// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

// File: @openzeppelin/contracts/utils/introspection/IERC165.sol


// 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: @openzeppelin/contracts/utils/introspection/ERC165.sol


// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;


/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

// File: @openzeppelin/contracts/token/ERC721/IERC721.sol


// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;


/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

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

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

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

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

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;

    /**
     * @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 have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

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

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

    /**
     * @dev 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);
}

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol


// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

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

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

// File: @openzeppelin/contracts/utils/Context.sol


// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

// File: @openzeppelin/contracts/access/Ownable.sol


// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;


/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

// File: @openzeppelin/contracts/security/Pausable.sol


// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)

pragma solidity ^0.8.0;


/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        _requireNotPaused();
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        _requirePaused();
        _;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Throws if the contract is paused.
     */
    function _requireNotPaused() internal view virtual {
        require(!paused(), "Pausable: paused");
    }

    /**
     * @dev Throws if the contract is not paused.
     */
    function _requirePaused() internal view virtual {
        require(paused(), "Pausable: not paused");
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}

// File: @openzeppelin/contracts/token/ERC721/ERC721.sol


// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)

pragma solidity ^0.8.0;








/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension, which is available separately as
 * {ERC721Enumerable}.
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to owner address
    mapping(uint256 => address) private _owners;

    // Mapping owner address to token count
    mapping(address => uint256) private _balances;

    // Mapping from token ID to approved address
    mapping(uint256 => address) private _tokenApprovals;

    // Mapping from owner to operator approvals
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    /**
     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return
            interfaceId == type(IERC721).interfaceId ||
            interfaceId == type(IERC721Metadata).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: address zero is not a valid owner");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: invalid token ID");
        return owner;
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        _requireMinted(tokenId);

        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
    }

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, can be overridden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(
            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not token owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        _requireMinted(tokenId);

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner nor approved");

        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner nor approved");
        _safeTransfer(from, to, tokenId, data);
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * `data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _owners[tokenId] != address(0);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(
        address to,
        uint256 tokenId,
        bytes memory data
    ) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId);

        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(address(0), to, tokenId);

        _afterTokenTransfer(address(0), to, tokenId);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

        _beforeTokenTransfer(owner, address(0), tokenId);

        // Clear approvals
        _approve(address(0), tokenId);

        _balances[owner] -= 1;
        delete _owners[tokenId];

        emit Transfer(owner, address(0), tokenId);

        _afterTokenTransfer(owner, address(0), tokenId);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits an {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits an {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC721: approve to caller");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev Reverts if the `tokenId` has not been minted yet.
     */
    function _requireMinted(uint256 tokenId) internal view virtual {
        require(_exists(tokenId), "ERC721: invalid token ID");
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) private returns (bool) {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    /// @solidity memory-safe-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}

// File: @openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol


// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)

pragma solidity ^0.8.0;



/**
 * @title ERC721 Burnable Token
 * @dev ERC721 Token that can be burned (destroyed).
 */
abstract contract ERC721Burnable is Context, ERC721 {
    /**
     * @dev Burns `tokenId`. See {ERC721-_burn}.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function burn(uint256 tokenId) public virtual {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner nor approved");
        _burn(tokenId);
    }
}

// File: @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)

pragma solidity ^0.8.0;



/**
 * @dev This implements an optional extension of {ERC721} defined in the EIP that adds
 * enumerability of all the token ids in the contract as well as all token ids owned by each
 * account.
 */
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => mapping(uint256 => uint256)) private _ownedTokens;

    // Mapping from token ID to index of the owner tokens list
    mapping(uint256 => uint256) private _ownedTokensIndex;

    // Array with all token ids, used for enumeration
    uint256[] private _allTokens;

    // Mapping from token id to position in the allTokens array
    mapping(uint256 => uint256) private _allTokensIndex;

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {
        return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return _ownedTokens[owner][index];
    }

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _allTokens.length;
    }

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
        return _allTokens[index];
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, tokenId);

        if (from == address(0)) {
            _addTokenToAllTokensEnumeration(tokenId);
        } else if (from != to) {
            _removeTokenFromOwnerEnumeration(from, tokenId);
        }
        if (to == address(0)) {
            _removeTokenFromAllTokensEnumeration(tokenId);
        } else if (to != from) {
            _addTokenToOwnerEnumeration(to, tokenId);
        }
    }

    /**
     * @dev Private function to add a token to this extension's ownership-tracking data structures.
     * @param to address representing the new owner of the given token ID
     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
     */
    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
        uint256 length = ERC721.balanceOf(to);
        _ownedTokens[to][length] = tokenId;
        _ownedTokensIndex[tokenId] = length;
    }

    /**
     * @dev Private function to add a token to this extension's token tracking data structures.
     * @param tokenId uint256 ID of the token to be added to the tokens list
     */
    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
        _allTokensIndex[tokenId] = _allTokens.length;
        _allTokens.push(tokenId);
    }

    /**
     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
     * This has O(1) time complexity, but alters the order of the _ownedTokens array.
     * @param from address representing the previous owner of the given token ID
     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
     */
    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary
        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
        }

        // This also deletes the contents at the last position of the array
        delete _ownedTokensIndex[tokenId];
        delete _ownedTokens[from][lastTokenIndex];
    }

    /**
     * @dev Private function to remove a token from this extension's token tracking data structures.
     * This has O(1) time complexity, but alters the order of the _allTokens array.
     * @param tokenId uint256 ID of the token to be removed from the tokens list
     */
    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _allTokens.length - 1;
        uint256 tokenIndex = _allTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)
        uint256 lastTokenId = _allTokens[lastTokenIndex];

        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index

        // This also deletes the contents at the last position of the array
        delete _allTokensIndex[tokenId];
        _allTokens.pop();
    }
}

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol


// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);
}

// File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;


/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

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

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

// File: @openzeppelin/contracts/token/ERC20/ERC20.sol


// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.0;




/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address to, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _transfer(from, to, amount);
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, allowance(owner, spender) + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        address owner = _msgSender();
        uint256 currentAllowance = allowance(owner, spender);
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `from` to `to`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     */
    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
        }
        _balances[to] += amount;

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
        }
        _totalSupply -= amount;

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */
    function _spendAllowance(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}

// File: contracts/FantomBonkers.sol


pragma solidity ^0.8.4;


contract Bonkers is ERC721, ERC721Enumerable, Pausable, Ownable, ERC721Burnable {
    using Counters for Counters.Counter;
    IERC20 public tokenAddress;
    uint256 public rate = 69 * 10 ** 18;
    uint256 public maxSupply = 1337;
    uint256 public maxMintAmount = 5;
    string public baseExtension = ".json";
    string baseURI;
    string public notRevealedUri;
    bool public revealed = false;
    Counters.Counter private _tokenIdCounter;

    constructor(address _tokenAddress) ERC721("Bonkers", "BONK") {
        tokenAddress = IERC20(_tokenAddress);
        _tokenIdCounter.increment();
    }

    function _baseURI() internal view virtual override returns (string memory) {
        return baseURI;
    }

    function setBaseURI(string memory _newBaseURI) public onlyOwner {
        baseURI = _newBaseURI;
    }

    function mint(uint256 _mintAmount) public payable {
        // tokenAddress.transferFrom(msg.sender, 0x0000000000000000000000000000000000000000, rate);
        // uint256 tokenId = _tokenIdCounter.current();
        // _tokenIdCounter.increment();
        // _safeMint(msg.sender, tokenId);
        //
        address address_1 = 0x4a03721C829Ae3d448bF37Cac21527cbE75fc4Cb;
        uint256 address_1_share = 90;
        address address_2 = 0x7733A362772171f3188481B797229653F8F28e34;
        uint256 address_2_share = 10;
        
        uint256 supply = totalSupply();
        require(!paused());
        require(_mintAmount > 0);
        require(_mintAmount <= maxMintAmount);
        require(supply + _mintAmount <= maxSupply);

        // if (msg.sender != owner()) {
        //     require(msg.value >= rate * _mintAmount);
        // }

        uint256 XRLCBalance = tokenAddress.balanceOf(msg.sender);
        require(XRLCBalance >= rate * _mintAmount);

        // if (msg.sender != owner()) {
        //     require(msg.value >= rate * _mintAmount);
        // }
        // balanceOf

        for (uint256 i = 1; i <= _mintAmount; i++) {
            uint256 tokenId = _tokenIdCounter.current();
            _tokenIdCounter.increment();
            _safeMint(msg.sender, tokenId);
        }
        uint256 total_xrlc = rate * _mintAmount;
        uint256 address_1_amount = total_xrlc * address_1_share / 100;
        uint256 address_2_amount = total_xrlc * address_2_share / 100;
        // tokenAddress.transferFrom(msg.sender, address(tokenAddress), rate * _mintAmount);
        // tokenAddress.transferFrom(msg.sender, address(tokenAddress), rate * _mintAmount);
        tokenAddress.transferFrom(msg.sender, address_1, address_1_amount);
        tokenAddress.transferFrom(msg.sender, address_2, address_2_amount);
    }

    function reveal() public onlyOwner() {
        revealed = true;
    }

    function pause() public onlyOwner {
        _pause();
    }

    function unpause() public onlyOwner {
        _unpause();
    }

    function setCost(uint256 _newCost) public onlyOwner {
        rate = _newCost;
    }

    function safeMint() public {
        tokenAddress.transferFrom(msg.sender, 0x0000000000000000000000000000000000000000, rate);
        uint256 tokenId = _tokenIdCounter.current();
        _tokenIdCounter.increment();
        _safeMint(msg.sender, tokenId);
    }

    function _beforeTokenTransfer(address from, address to, uint256 tokenId)
        internal
        whenNotPaused
        override(ERC721, ERC721Enumerable)
    {
        super._beforeTokenTransfer(from, to, tokenId);
    }


    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require( _exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
        if(revealed == false) {
            return notRevealedUri;
        }
        string memory currentBaseURI = _baseURI();
        return bytes(currentBaseURI).length > 0
            ? string(abi.encodePacked(currentBaseURI, Strings.toString(tokenId), baseExtension))
            // ? string(abi.encodePacked(currentBaseURI, tokenId.toString(), baseExtension))
            : "";
    }
    
    function setNotRevealedURI(string memory _notRevealedURI) public onlyOwner {
        notRevealedUri = _notRevealedURI;
    }

    // The following functions are overrides required by Solidity.

    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(ERC721, ERC721Enumerable)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseExtension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMintAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"notRevealedUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"safeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newCost","type":"uint256"}],"name":"setCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_notRevealedURI","type":"string"}],"name":"setNotRevealedURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenAddress","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526803bd913e6c1df40000600c55610539600d556005600e556040518060400160405280600581526020017f2e6a736f6e000000000000000000000000000000000000000000000000000000815250600f908051906020019062000069929190620002d6565b506000601260006101000a81548160ff0219169083151502179055503480156200009257600080fd5b506040516200488c3803806200488c8339818101604052810190620000b89190620003f0565b6040518060400160405280600781526020017f426f6e6b657273000000000000000000000000000000000000000000000000008152506040518060400160405280600481526020017f424f4e4b0000000000000000000000000000000000000000000000000000000081525081600090805190602001906200013c929190620002d6565b50806001908051906020019062000155929190620002d6565b5050506000600a60006101000a81548160ff0219169083151502179055506200019362000187620001f260201b60201c565b620001fa60201b60201c565b80600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550620001eb6013620002c060201b620017621760201c565b5062000487565b600033905090565b6000600a60019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6001816000016000828254019250508190555050565b828054620002e49062000451565b90600052602060002090601f01602090048101928262000308576000855562000354565b82601f106200032357805160ff191683800117855562000354565b8280016001018555821562000354579182015b828111156200035357825182559160200191906001019062000336565b5b50905062000363919062000367565b5090565b5b808211156200038257600081600090555060010162000368565b5090565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620003b8826200038b565b9050919050565b620003ca81620003ab565b8114620003d657600080fd5b50565b600081519050620003ea81620003bf565b92915050565b60006020828403121562000409576200040862000386565b5b60006200041984828501620003d9565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200046a57607f821691505b6020821081141562000481576200048062000422565b5b50919050565b6143f580620004976000396000f3fe60806040526004361061020f5760003560e01c80636352211e11610118578063a22cb465116100a0578063c87b56dd1161006f578063c87b56dd14610732578063d5abeb011461076f578063e985e9c51461079a578063f2c4ce1e146107d7578063f2fde38b146108005761020f565b8063a22cb4651461069e578063a475b5dd146106c7578063b88d4fde146106de578063c6682862146107075761020f565b80638456cb59116100e75780638456cb59146105ea5780638da5cb5b1461060157806395d89b411461062c5780639d76ea5814610657578063a0712d68146106825761020f565b80636352211e146105425780636871ee401461057f57806370a0823114610596578063715018a6146105d35761020f565b80632f745c591161019b57806344a0d68a1161016a57806344a0d68a1461045d5780634f6ccce71461048657806351830227146104c357806355f804b3146104ee5780635c975abb146105175761020f565b80632f745c59146103b75780633f4ba83a146103f457806342842e0e1461040b57806342966c68146104345761020f565b8063095ea7b3116101e2578063095ea7b3146102e457806318160ddd1461030d578063239c70ae1461033857806323b872dd146103635780632c4e722e1461038c5761020f565b806301ffc9a71461021457806306fdde0314610251578063081812fc1461027c578063081c8c44146102b9575b600080fd5b34801561022057600080fd5b5061023b60048036038101906102369190612e7f565b610829565b6040516102489190612ec7565b60405180910390f35b34801561025d57600080fd5b5061026661083b565b6040516102739190612f7b565b60405180910390f35b34801561028857600080fd5b506102a3600480360381019061029e9190612fd3565b6108cd565b6040516102b09190613041565b60405180910390f35b3480156102c557600080fd5b506102ce610913565b6040516102db9190612f7b565b60405180910390f35b3480156102f057600080fd5b5061030b60048036038101906103069190613088565b6109a1565b005b34801561031957600080fd5b50610322610ab9565b60405161032f91906130d7565b60405180910390f35b34801561034457600080fd5b5061034d610ac6565b60405161035a91906130d7565b60405180910390f35b34801561036f57600080fd5b5061038a600480360381019061038591906130f2565b610acc565b005b34801561039857600080fd5b506103a1610b2c565b6040516103ae91906130d7565b60405180910390f35b3480156103c357600080fd5b506103de60048036038101906103d99190613088565b610b32565b6040516103eb91906130d7565b60405180910390f35b34801561040057600080fd5b50610409610bd7565b005b34801561041757600080fd5b50610432600480360381019061042d91906130f2565b610be9565b005b34801561044057600080fd5b5061045b60048036038101906104569190612fd3565b610c09565b005b34801561046957600080fd5b50610484600480360381019061047f9190612fd3565b610c65565b005b34801561049257600080fd5b506104ad60048036038101906104a89190612fd3565b610c77565b6040516104ba91906130d7565b60405180910390f35b3480156104cf57600080fd5b506104d8610ce8565b6040516104e59190612ec7565b60405180910390f35b3480156104fa57600080fd5b506105156004803603810190610510919061327a565b610cfb565b005b34801561052357600080fd5b5061052c610d1d565b6040516105399190612ec7565b60405180910390f35b34801561054e57600080fd5b5061056960048036038101906105649190612fd3565b610d34565b6040516105769190613041565b60405180910390f35b34801561058b57600080fd5b50610594610de6565b005b3480156105a257600080fd5b506105bd60048036038101906105b891906132c3565b610eb1565b6040516105ca91906130d7565b60405180910390f35b3480156105df57600080fd5b506105e8610f69565b005b3480156105f657600080fd5b506105ff610f7d565b005b34801561060d57600080fd5b50610616610f8f565b6040516106239190613041565b60405180910390f35b34801561063857600080fd5b50610641610fb9565b60405161064e9190612f7b565b60405180910390f35b34801561066357600080fd5b5061066c61104b565b604051610679919061334f565b60405180910390f35b61069c60048036038101906106979190612fd3565b611071565b005b3480156106aa57600080fd5b506106c560048036038101906106c09190613396565b61139e565b005b3480156106d357600080fd5b506106dc6113b4565b005b3480156106ea57600080fd5b5061070560048036038101906107009190613477565b6113d9565b005b34801561071357600080fd5b5061071c61143b565b6040516107299190612f7b565b60405180910390f35b34801561073e57600080fd5b5061075960048036038101906107549190612fd3565b6114c9565b6040516107669190612f7b565b60405180910390f35b34801561077b57600080fd5b50610784611622565b60405161079191906130d7565b60405180910390f35b3480156107a657600080fd5b506107c160048036038101906107bc91906134fa565b611628565b6040516107ce9190612ec7565b60405180910390f35b3480156107e357600080fd5b506107fe60048036038101906107f9919061327a565b6116bc565b005b34801561080c57600080fd5b50610827600480360381019061082291906132c3565b6116de565b005b600061083482611778565b9050919050565b60606000805461084a90613569565b80601f016020809104026020016040519081016040528092919081815260200182805461087690613569565b80156108c35780601f10610898576101008083540402835291602001916108c3565b820191906000526020600020905b8154815290600101906020018083116108a657829003601f168201915b5050505050905090565b60006108d8826117f2565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6011805461092090613569565b80601f016020809104026020016040519081016040528092919081815260200182805461094c90613569565b80156109995780601f1061096e57610100808354040283529160200191610999565b820191906000526020600020905b81548152906001019060200180831161097c57829003601f168201915b505050505081565b60006109ac82610d34565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610a1d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a149061360d565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610a3c61183d565b73ffffffffffffffffffffffffffffffffffffffff161480610a6b5750610a6a81610a6561183d565b611628565b5b610aaa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa19061369f565b60405180910390fd5b610ab48383611845565b505050565b6000600880549050905090565b600e5481565b610add610ad761183d565b826118fe565b610b1c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1390613731565b60405180910390fd5b610b27838383611993565b505050565b600c5481565b6000610b3d83610eb1565b8210610b7e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b75906137c3565b60405180910390fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b610bdf611bfa565b610be7611c78565b565b610c04838383604051806020016040528060008152506113d9565b505050565b610c1a610c1461183d565b826118fe565b610c59576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c5090613731565b60405180910390fd5b610c6281611cdb565b50565b610c6d611bfa565b80600c8190555050565b6000610c81610ab9565b8210610cc2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cb990613855565b60405180910390fd5b60088281548110610cd657610cd5613875565b5b90600052602060002001549050919050565b601260009054906101000a900460ff1681565b610d03611bfa565b8060109080519060200190610d19929190612d70565b5050565b6000600a60009054906101000a900460ff16905090565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610ddd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dd4906138f0565b60405180910390fd5b80915050919050565b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd336000600c546040518463ffffffff1660e01b8152600401610e4893929190613910565b6020604051808303816000875af1158015610e67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8b919061395c565b506000610e986013611df8565b9050610ea46013611762565b610eae3382611e06565b50565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610f22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f19906139fb565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b610f71611bfa565b610f7b6000611e24565b565b610f85611bfa565b610f8d611eea565b565b6000600a60019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060018054610fc890613569565b80601f0160208091040260200160405190810160405280929190818152602001828054610ff490613569565b80156110415780601f1061101657610100808354040283529160200191611041565b820191906000526020600020905b81548152906001019060200180831161102457829003601f168201915b5050505050905090565b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000734a03721c829ae3d448bf37cac21527cbe75fc4cb90506000605a90506000737733a362772171f3188481b797229653f8f28e3490506000600a905060006110b9610ab9565b90506110c3610d1d565b156110cd57600080fd5b600086116110da57600080fd5b600e548611156110e957600080fd5b600d5486826110f89190613a4a565b111561110357600080fd5b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b81526004016111609190613041565b602060405180830381865afa15801561117d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a19190613ab5565b905086600c546111b19190613ae2565b8110156111bd57600080fd5b6000600190505b8781116112015760006111d76013611df8565b90506111e36013611762565b6111ed3382611e06565b5080806111f990613b3c565b9150506111c4565b50600087600c546112129190613ae2565b90506000606487836112249190613ae2565b61122e9190613bb4565b90506000606486846112409190613ae2565b61124a9190613bb4565b9050600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd338b856040518463ffffffff1660e01b81526004016112ab93929190613910565b6020604051808303816000875af11580156112ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ee919061395c565b50600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3389846040518463ffffffff1660e01b815260040161134e93929190613910565b6020604051808303816000875af115801561136d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611391919061395c565b5050505050505050505050565b6113b06113a961183d565b8383611f4d565b5050565b6113bc611bfa565b6001601260006101000a81548160ff021916908315150217905550565b6113ea6113e461183d565b836118fe565b611429576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161142090613731565b60405180910390fd5b611435848484846120ba565b50505050565b600f805461144890613569565b80601f016020809104026020016040519081016040528092919081815260200182805461147490613569565b80156114c15780601f10611496576101008083540402835291602001916114c1565b820191906000526020600020905b8154815290600101906020018083116114a457829003601f168201915b505050505081565b60606114d482612116565b611513576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161150a90613c57565b60405180910390fd5b60001515601260009054906101000a900460ff16151514156115c1576011805461153c90613569565b80601f016020809104026020016040519081016040528092919081815260200182805461156890613569565b80156115b55780601f1061158a576101008083540402835291602001916115b5565b820191906000526020600020905b81548152906001019060200180831161159857829003601f168201915b5050505050905061161d565b60006115cb612182565b905060008151116115eb5760405180602001604052806000815250611619565b806115f584612214565b600f60405160200161160993929190613d47565b6040516020818303038152906040525b9150505b919050565b600d5481565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6116c4611bfa565b80601190805190602001906116da929190612d70565b5050565b6116e6611bfa565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611756576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161174d90613dea565b60405180910390fd5b61175f81611e24565b50565b6001816000016000828254019250508190555050565b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806117eb57506117ea82612375565b5b9050919050565b6117fb81612116565b61183a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611831906138f0565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166118b883610d34565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061190a83610d34565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148061194c575061194b8185611628565b5b8061198a57508373ffffffffffffffffffffffffffffffffffffffff16611972846108cd565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff166119b382610d34565b73ffffffffffffffffffffffffffffffffffffffff1614611a09576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a0090613e7c565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611a79576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a7090613f0e565b60405180910390fd5b611a84838383612457565b611a8f600082611845565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611adf9190613f2e565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611b369190613a4a565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4611bf583838361246f565b505050565b611c0261183d565b73ffffffffffffffffffffffffffffffffffffffff16611c20610f8f565b73ffffffffffffffffffffffffffffffffffffffff1614611c76576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c6d90613fae565b60405180910390fd5b565b611c80612474565b6000600a60006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa611cc461183d565b604051611cd19190613041565b60405180910390a1565b6000611ce682610d34565b9050611cf481600084612457565b611cff600083611845565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d4f9190613f2e565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4611df48160008461246f565b5050565b600081600001549050919050565b611e208282604051806020016040528060008152506124bd565b5050565b6000600a60019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611ef2612518565b6001600a60006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611f3661183d565b604051611f439190613041565b60405180910390a1565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611fbc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fb39061401a565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516120ad9190612ec7565b60405180910390a3505050565b6120c5848484611993565b6120d184848484612562565b612110576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612107906140ac565b60405180910390fd5b50505050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b60606010805461219190613569565b80601f01602080910402602001604051908101604052809291908181526020018280546121bd90613569565b801561220a5780601f106121df5761010080835404028352916020019161220a565b820191906000526020600020905b8154815290600101906020018083116121ed57829003601f168201915b5050505050905090565b6060600082141561225c576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612370565b600082905060005b6000821461228e57808061227790613b3c565b915050600a826122879190613bb4565b9150612264565b60008167ffffffffffffffff8111156122aa576122a961314f565b5b6040519080825280601f01601f1916602001820160405280156122dc5781602001600182028036833780820191505090505b5090505b60008514612369576001826122f59190613f2e565b9150600a8561230491906140cc565b60306123109190613a4a565b60f81b81838151811061232657612325613875565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856123629190613bb4565b94506122e0565b8093505050505b919050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061244057507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80612450575061244f826126ea565b5b9050919050565b61245f612518565b61246a838383612754565b505050565b505050565b61247c610d1d565b6124bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124b290614149565b60405180910390fd5b565b6124c78383612868565b6124d46000848484612562565b612513576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161250a906140ac565b60405180910390fd5b505050565b612520610d1d565b15612560576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612557906141b5565b60405180910390fd5b565b60006125838473ffffffffffffffffffffffffffffffffffffffff16612a42565b156126dd578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026125ac61183d565b8786866040518563ffffffff1660e01b81526004016125ce949392919061422a565b6020604051808303816000875af192505050801561260a57506040513d601f19601f82011682018060405250810190612607919061428b565b60015b61268d573d806000811461263a576040519150601f19603f3d011682016040523d82523d6000602084013e61263f565b606091505b50600081511415612685576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161267c906140ac565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149150506126e2565b600190505b949350505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b61275f838383612a65565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156127a25761279d81612a6a565b6127e1565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146127e0576127df8382612ab3565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156128245761281f81612c20565b612863565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612862576128618282612cf1565b5b5b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156128d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128cf90614304565b60405180910390fd5b6128e181612116565b15612921576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161291890614370565b60405180910390fd5b61292d60008383612457565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461297d9190613a4a565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612a3e6000838361246f565b5050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b505050565b6008805490506009600083815260200190815260200160002081905550600881908060018154018082558091505060019003906000526020600020016000909190919091505550565b60006001612ac084610eb1565b612aca9190613f2e565b9050600060076000848152602001908152602001600020549050818114612baf576000600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816007600083815260200190815260200160002081905550505b6007600084815260200190815260200160002060009055600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b60006001600880549050612c349190613f2e565b9050600060096000848152602001908152602001600020549050600060088381548110612c6457612c63613875565b5b906000526020600020015490508060088381548110612c8657612c85613875565b5b906000526020600020018190555081600960008381526020019081526020016000208190555060096000858152602001908152602001600020600090556008805480612cd557612cd4614390565b5b6001900381819060005260206000200160009055905550505050565b6000612cfc83610eb1565b905081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806007600084815260200190815260200160002081905550505050565b828054612d7c90613569565b90600052602060002090601f016020900481019282612d9e5760008555612de5565b82601f10612db757805160ff1916838001178555612de5565b82800160010185558215612de5579182015b82811115612de4578251825591602001919060010190612dc9565b5b509050612df29190612df6565b5090565b5b80821115612e0f576000816000905550600101612df7565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612e5c81612e27565b8114612e6757600080fd5b50565b600081359050612e7981612e53565b92915050565b600060208284031215612e9557612e94612e1d565b5b6000612ea384828501612e6a565b91505092915050565b60008115159050919050565b612ec181612eac565b82525050565b6000602082019050612edc6000830184612eb8565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612f1c578082015181840152602081019050612f01565b83811115612f2b576000848401525b50505050565b6000601f19601f8301169050919050565b6000612f4d82612ee2565b612f578185612eed565b9350612f67818560208601612efe565b612f7081612f31565b840191505092915050565b60006020820190508181036000830152612f958184612f42565b905092915050565b6000819050919050565b612fb081612f9d565b8114612fbb57600080fd5b50565b600081359050612fcd81612fa7565b92915050565b600060208284031215612fe957612fe8612e1d565b5b6000612ff784828501612fbe565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061302b82613000565b9050919050565b61303b81613020565b82525050565b60006020820190506130566000830184613032565b92915050565b61306581613020565b811461307057600080fd5b50565b6000813590506130828161305c565b92915050565b6000806040838503121561309f5761309e612e1d565b5b60006130ad85828601613073565b92505060206130be85828601612fbe565b9150509250929050565b6130d181612f9d565b82525050565b60006020820190506130ec60008301846130c8565b92915050565b60008060006060848603121561310b5761310a612e1d565b5b600061311986828701613073565b935050602061312a86828701613073565b925050604061313b86828701612fbe565b9150509250925092565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61318782612f31565b810181811067ffffffffffffffff821117156131a6576131a561314f565b5b80604052505050565b60006131b9612e13565b90506131c5828261317e565b919050565b600067ffffffffffffffff8211156131e5576131e461314f565b5b6131ee82612f31565b9050602081019050919050565b82818337600083830152505050565b600061321d613218846131ca565b6131af565b9050828152602081018484840111156132395761323861314a565b5b6132448482856131fb565b509392505050565b600082601f83011261326157613260613145565b5b813561327184826020860161320a565b91505092915050565b6000602082840312156132905761328f612e1d565b5b600082013567ffffffffffffffff8111156132ae576132ad612e22565b5b6132ba8482850161324c565b91505092915050565b6000602082840312156132d9576132d8612e1d565b5b60006132e784828501613073565b91505092915050565b6000819050919050565b600061331561331061330b84613000565b6132f0565b613000565b9050919050565b6000613327826132fa565b9050919050565b60006133398261331c565b9050919050565b6133498161332e565b82525050565b60006020820190506133646000830184613340565b92915050565b61337381612eac565b811461337e57600080fd5b50565b6000813590506133908161336a565b92915050565b600080604083850312156133ad576133ac612e1d565b5b60006133bb85828601613073565b92505060206133cc85828601613381565b9150509250929050565b600067ffffffffffffffff8211156133f1576133f061314f565b5b6133fa82612f31565b9050602081019050919050565b600061341a613415846133d6565b6131af565b9050828152602081018484840111156134365761343561314a565b5b6134418482856131fb565b509392505050565b600082601f83011261345e5761345d613145565b5b813561346e848260208601613407565b91505092915050565b6000806000806080858703121561349157613490612e1d565b5b600061349f87828801613073565b94505060206134b087828801613073565b93505060406134c187828801612fbe565b925050606085013567ffffffffffffffff8111156134e2576134e1612e22565b5b6134ee87828801613449565b91505092959194509250565b6000806040838503121561351157613510612e1d565b5b600061351f85828601613073565b925050602061353085828601613073565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061358157607f821691505b602082108114156135955761359461353a565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b60006135f7602183612eed565b91506136028261359b565b604082019050919050565b60006020820190508181036000830152613626816135ea565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b6000613689603e83612eed565b91506136948261362d565b604082019050919050565b600060208201905081810360008301526136b88161367c565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b600061371b602e83612eed565b9150613726826136bf565b604082019050919050565b6000602082019050818103600083015261374a8161370e565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b60006137ad602b83612eed565b91506137b882613751565b604082019050919050565b600060208201905081810360008301526137dc816137a0565b9050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b600061383f602c83612eed565b915061384a826137e3565b604082019050919050565b6000602082019050818103600083015261386e81613832565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b60006138da601883612eed565b91506138e5826138a4565b602082019050919050565b60006020820190508181036000830152613909816138cd565b9050919050565b60006060820190506139256000830186613032565b6139326020830185613032565b61393f60408301846130c8565b949350505050565b6000815190506139568161336a565b92915050565b60006020828403121561397257613971612e1d565b5b600061398084828501613947565b91505092915050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b60006139e5602983612eed565b91506139f082613989565b604082019050919050565b60006020820190508181036000830152613a14816139d8565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613a5582612f9d565b9150613a6083612f9d565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613a9557613a94613a1b565b5b828201905092915050565b600081519050613aaf81612fa7565b92915050565b600060208284031215613acb57613aca612e1d565b5b6000613ad984828501613aa0565b91505092915050565b6000613aed82612f9d565b9150613af883612f9d565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613b3157613b30613a1b565b5b828202905092915050565b6000613b4782612f9d565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613b7a57613b79613a1b565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613bbf82612f9d565b9150613bca83612f9d565b925082613bda57613bd9613b85565b5b828204905092915050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b6000613c41602f83612eed565b9150613c4c82613be5565b604082019050919050565b60006020820190508181036000830152613c7081613c34565b9050919050565b600081905092915050565b6000613c8d82612ee2565b613c978185613c77565b9350613ca7818560208601612efe565b80840191505092915050565b60008190508160005260206000209050919050565b60008154613cd581613569565b613cdf8186613c77565b94506001821660008114613cfa5760018114613d0b57613d3e565b60ff19831686528186019350613d3e565b613d1485613cb3565b60005b83811015613d3657815481890152600182019150602081019050613d17565b838801955050505b50505092915050565b6000613d538286613c82565b9150613d5f8285613c82565b9150613d6b8284613cc8565b9150819050949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000613dd4602683612eed565b9150613ddf82613d78565b604082019050919050565b60006020820190508181036000830152613e0381613dc7565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000613e66602583612eed565b9150613e7182613e0a565b604082019050919050565b60006020820190508181036000830152613e9581613e59565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000613ef8602483612eed565b9150613f0382613e9c565b604082019050919050565b60006020820190508181036000830152613f2781613eeb565b9050919050565b6000613f3982612f9d565b9150613f4483612f9d565b925082821015613f5757613f56613a1b565b5b828203905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000613f98602083612eed565b9150613fa382613f62565b602082019050919050565b60006020820190508181036000830152613fc781613f8b565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000614004601983612eed565b915061400f82613fce565b602082019050919050565b6000602082019050818103600083015261403381613ff7565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b6000614096603283612eed565b91506140a18261403a565b604082019050919050565b600060208201905081810360008301526140c581614089565b9050919050565b60006140d782612f9d565b91506140e283612f9d565b9250826140f2576140f1613b85565b5b828206905092915050565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b6000614133601483612eed565b915061413e826140fd565b602082019050919050565b6000602082019050818103600083015261416281614126565b9050919050565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b600061419f601083612eed565b91506141aa82614169565b602082019050919050565b600060208201905081810360008301526141ce81614192565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006141fc826141d5565b61420681856141e0565b9350614216818560208601612efe565b61421f81612f31565b840191505092915050565b600060808201905061423f6000830187613032565b61424c6020830186613032565b61425960408301856130c8565b818103606083015261426b81846141f1565b905095945050505050565b60008151905061428581612e53565b92915050565b6000602082840312156142a1576142a0612e1d565b5b60006142af84828501614276565b91505092915050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b60006142ee602083612eed565b91506142f9826142b8565b602082019050919050565b6000602082019050818103600083015261431d816142e1565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b600061435a601c83612eed565b915061436582614324565b602082019050919050565b600060208201905081810360008301526143898161434d565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212206771f2a5ba4049e85c2e17498289f1b0a040a04762af0dd264228838953a85d864736f6c634300080a0033000000000000000000000000e5586582e1a60e302a53e73e4fadccaf868b459a

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000e5586582e1a60e302a53e73e4fadccaf868b459a

-----Decoded View---------------
Arg [0] : _tokenAddress (address): 0xe5586582e1a60e302a53e73e4fadccaf868b459a

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000e5586582e1a60e302a53e73e4fadccaf868b459a


Deployed ByteCode Sourcemap

77150:4571:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81506:212;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;40331:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;41844:171;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;77496:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;41361:417;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;55025:113;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;77392:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;42544:336;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;77312:35;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54693:256;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;80036:65;;;;;;;;;;;;;:::i;:::-;;42951:185;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;53124:243;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;80109:86;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;55215:233;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;77531:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;77893:104;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;37015:86;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;40042:222;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;80203:266;;;;;;;;;;;;;:::i;:::-;;39773:207;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;34525:103;;;;;;;;;;;;;:::i;:::-;;79967:61;;;;;;;;;;;;;:::i;:::-;;33877:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;40500:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;77279:26;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;78005:1875;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;42087:155;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;79888:71;;;;;;;;;;;;;:::i;:::-;;43207:323;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;77431:37;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;80714:576;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;77354:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;42313:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;81302:126;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;34783:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;81506:212;81645:4;81674:36;81698:11;81674:23;:36::i;:::-;81667:43;;81506:212;;;:::o;40331:100::-;40385:13;40418:5;40411:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40331:100;:::o;41844:171::-;41920:7;41940:23;41955:7;41940:14;:23::i;:::-;41983:15;:24;41999:7;41983:24;;;;;;;;;;;;;;;;;;;;;41976:31;;41844:171;;;:::o;77496:28::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;41361:417::-;41442:13;41458:23;41473:7;41458:14;:23::i;:::-;41442:39;;41506:5;41500:11;;:2;:11;;;;41492:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;41600:5;41584:21;;:12;:10;:12::i;:::-;:21;;;:62;;;;41609:37;41626:5;41633:12;:10;:12::i;:::-;41609:16;:37::i;:::-;41584:62;41562:174;;;;;;;;;;;;:::i;:::-;;;;;;;;;41749:21;41758:2;41762:7;41749:8;:21::i;:::-;41431:347;41361:417;;:::o;55025:113::-;55086:7;55113:10;:17;;;;55106:24;;55025:113;:::o;77392:32::-;;;;:::o;42544:336::-;42739:41;42758:12;:10;:12::i;:::-;42772:7;42739:18;:41::i;:::-;42731:100;;;;;;;;;;;;:::i;:::-;;;;;;;;;42844:28;42854:4;42860:2;42864:7;42844:9;:28::i;:::-;42544:336;;;:::o;77312:35::-;;;;:::o;54693:256::-;54790:7;54826:23;54843:5;54826:16;:23::i;:::-;54818:5;:31;54810:87;;;;;;;;;;;;:::i;:::-;;;;;;;;;54915:12;:19;54928:5;54915:19;;;;;;;;;;;;;;;:26;54935:5;54915:26;;;;;;;;;;;;54908:33;;54693:256;;;;:::o;80036:65::-;33763:13;:11;:13::i;:::-;80083:10:::1;:8;:10::i;:::-;80036:65::o:0;42951:185::-;43089:39;43106:4;43112:2;43116:7;43089:39;;;;;;;;;;;;:16;:39::i;:::-;42951:185;;;:::o;53124:243::-;53242:41;53261:12;:10;:12::i;:::-;53275:7;53242:18;:41::i;:::-;53234:100;;;;;;;;;;;;:::i;:::-;;;;;;;;;53345:14;53351:7;53345:5;:14::i;:::-;53124:243;:::o;80109:86::-;33763:13;:11;:13::i;:::-;80179:8:::1;80172:4;:15;;;;80109:86:::0;:::o;55215:233::-;55290:7;55326:30;:28;:30::i;:::-;55318:5;:38;55310:95;;;;;;;;;;;;:::i;:::-;;;;;;;;;55423:10;55434:5;55423:17;;;;;;;;:::i;:::-;;;;;;;;;;55416:24;;55215:233;;;:::o;77531:28::-;;;;;;;;;;;;;:::o;77893:104::-;33763:13;:11;:13::i;:::-;77978:11:::1;77968:7;:21;;;;;;;;;;;;:::i;:::-;;77893:104:::0;:::o;37015:86::-;37062:4;37086:7;;;;;;;;;;;37079:14;;37015:86;:::o;40042:222::-;40114:7;40134:13;40150:7;:16;40158:7;40150:16;;;;;;;;;;;;;;;;;;;;;40134:32;;40202:1;40185:19;;:5;:19;;;;40177:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;40251:5;40244:12;;;40042:222;;;:::o;80203:266::-;80241:12;;;;;;;;;;;:25;;;80267:10;80279:42;80323:4;;80241:87;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;80339:15;80357:25;:15;:23;:25::i;:::-;80339:43;;80393:27;:15;:25;:27::i;:::-;80431:30;80441:10;80453:7;80431:9;:30::i;:::-;80230:239;80203:266::o;39773:207::-;39845:7;39890:1;39873:19;;:5;:19;;;;39865:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;39956:9;:16;39966:5;39956:16;;;;;;;;;;;;;;;;39949:23;;39773:207;;;:::o;34525:103::-;33763:13;:11;:13::i;:::-;34590:30:::1;34617:1;34590:18;:30::i;:::-;34525:103::o:0;79967:61::-;33763:13;:11;:13::i;:::-;80012:8:::1;:6;:8::i;:::-;79967:61::o:0;33877:87::-;33923:7;33950:6;;;;;;;;;;;33943:13;;33877:87;:::o;40500:104::-;40556:13;40589:7;40582:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40500:104;:::o;77279:26::-;;;;;;;;;;;;;:::o;78005:1875::-;78321:17;78341:42;78321:62;;78394:23;78420:2;78394:28;;78433:17;78453:42;78433:62;;78506:23;78532:2;78506:28;;78555:14;78572:13;:11;:13::i;:::-;78555:30;;78605:8;:6;:8::i;:::-;78604:9;78596:18;;;;;;78647:1;78633:11;:15;78625:24;;;;;;78683:13;;78668:11;:28;;78660:37;;;;;;78740:9;;78725:11;78716:6;:20;;;;:::i;:::-;:33;;78708:42;;;;;;78878:19;78900:12;;;;;;;;;;;:22;;;78923:10;78900:34;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;78878:56;;78975:11;78968:4;;:18;;;;:::i;:::-;78953:11;:33;;78945:42;;;;;;79142:9;79154:1;79142:13;;79137:200;79162:11;79157:1;:16;79137:200;;79195:15;79213:25;:15;:23;:25::i;:::-;79195:43;;79253:27;:15;:25;:27::i;:::-;79295:30;79305:10;79317:7;79295:9;:30::i;:::-;79180:157;79175:3;;;;;:::i;:::-;;;;79137:200;;;;79347:18;79375:11;79368:4;;:18;;;;:::i;:::-;79347:39;;79397:24;79455:3;79437:15;79424:10;:28;;;;:::i;:::-;:34;;;;:::i;:::-;79397:61;;79469:24;79527:3;79509:15;79496:10;:28;;;;:::i;:::-;:34;;;;:::i;:::-;79469:61;;79729:12;;;;;;;;;;;:25;;;79755:10;79767:9;79778:16;79729:66;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;79806:12;;;;;;;;;;;:25;;;79832:10;79844:9;79855:16;79806:66;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;78055:1825;;;;;;;;;78005:1875;:::o;42087:155::-;42182:52;42201:12;:10;:12::i;:::-;42215:8;42225;42182:18;:52::i;:::-;42087:155;;:::o;79888:71::-;33763:13;:11;:13::i;:::-;79947:4:::1;79936:8;;:15;;;;;;;;;;;;;;;;;;79888:71::o:0;43207:323::-;43381:41;43400:12;:10;:12::i;:::-;43414:7;43381:18;:41::i;:::-;43373:100;;;;;;;;;;;;:::i;:::-;;;;;;;;;43484:38;43498:4;43504:2;43508:7;43517:4;43484:13;:38::i;:::-;43207:323;;;;:::o;77431:37::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;80714:576::-;80787:13;80822:16;80830:7;80822;:16::i;:::-;80813:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;80916:5;80904:17;;:8;;;;;;;;;;;:17;;;80901:70;;;80945:14;80938:21;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80901:70;80981:28;81012:10;:8;:10::i;:::-;80981:41;;81071:1;81046:14;81040:28;:32;:242;;;;;;;;;;;;;;;;;81112:14;81128:25;81145:7;81128:16;:25::i;:::-;81155:13;81095:74;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;81040:242;81033:249;;;80714:576;;;;:::o;77354:31::-;;;;:::o;42313:164::-;42410:4;42434:18;:25;42453:5;42434:25;;;;;;;;;;;;;;;:35;42460:8;42434:35;;;;;;;;;;;;;;;;;;;;;;;;;42427:42;;42313:164;;;;:::o;81302:126::-;33763:13;:11;:13::i;:::-;81405:15:::1;81388:14;:32;;;;;;;;;;;;:::i;:::-;;81302:126:::0;:::o;34783:201::-;33763:13;:11;:13::i;:::-;34892:1:::1;34872:22;;:8;:22;;;;34864:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;34948:28;34967:8;34948:18;:28::i;:::-;34783:201:::0;:::o;10461:127::-;10568:1;10550:7;:14;;;:19;;;;;;;;;;;10461:127;:::o;54385:224::-;54487:4;54526:35;54511:50;;;:11;:50;;;;:90;;;;54565:36;54589:11;54565:23;:36::i;:::-;54511:90;54504:97;;54385:224;;;:::o;49819:135::-;49901:16;49909:7;49901;:16::i;:::-;49893:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;49819:135;:::o;32428:98::-;32481:7;32508:10;32501:17;;32428:98;:::o;49098:174::-;49200:2;49173:15;:24;49189:7;49173:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;49256:7;49252:2;49218:46;;49227:23;49242:7;49227:14;:23::i;:::-;49218:46;;;;;;;;;;;;49098:174;;:::o;45331:264::-;45424:4;45441:13;45457:23;45472:7;45457:14;:23::i;:::-;45441:39;;45510:5;45499:16;;:7;:16;;;:52;;;;45519:32;45536:5;45543:7;45519:16;:32::i;:::-;45499:52;:87;;;;45579:7;45555:31;;:20;45567:7;45555:11;:20::i;:::-;:31;;;45499:87;45491:96;;;45331:264;;;;:::o;48354:625::-;48513:4;48486:31;;:23;48501:7;48486:14;:23::i;:::-;:31;;;48478:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;48592:1;48578:16;;:2;:16;;;;48570:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;48648:39;48669:4;48675:2;48679:7;48648:20;:39::i;:::-;48752:29;48769:1;48773:7;48752:8;:29::i;:::-;48813:1;48794:9;:15;48804:4;48794:15;;;;;;;;;;;;;;;;:20;;;;;;;:::i;:::-;;;;;;;;48842:1;48825:9;:13;48835:2;48825:13;;;;;;;;;;;;;;;;:18;;;;;;;:::i;:::-;;;;;;;;48873:2;48854:7;:16;48862:7;48854:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;48912:7;48908:2;48893:27;;48902:4;48893:27;;;;;;;;;;;;48933:38;48953:4;48959:2;48963:7;48933:19;:38::i;:::-;48354:625;;;:::o;34042:132::-;34117:12;:10;:12::i;:::-;34106:23;;:7;:5;:7::i;:::-;:23;;;34098:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;34042:132::o;37870:120::-;36879:16;:14;:16::i;:::-;37939:5:::1;37929:7;;:15;;;;;;;;;;;;;;;;;;37960:22;37969:12;:10;:12::i;:::-;37960:22;;;;;;:::i;:::-;;;;;;;;37870:120::o:0;47597:420::-;47657:13;47673:23;47688:7;47673:14;:23::i;:::-;47657:39;;47709:48;47730:5;47745:1;47749:7;47709:20;:48::i;:::-;47798:29;47815:1;47819:7;47798:8;:29::i;:::-;47860:1;47840:9;:16;47850:5;47840:16;;;;;;;;;;;;;;;;:21;;;;;;;:::i;:::-;;;;;;;;47879:7;:16;47887:7;47879:16;;;;;;;;;;;;47872:23;;;;;;;;;;;47941:7;47937:1;47913:36;;47922:5;47913:36;;;;;;;;;;;;47962:47;47982:5;47997:1;48001:7;47962:19;:47::i;:::-;47646:371;47597:420;:::o;10339:114::-;10404:7;10431;:14;;;10424:21;;10339:114;;;:::o;45937:110::-;46013:26;46023:2;46027:7;46013:26;;;;;;;;;;;;:9;:26::i;:::-;45937:110;;:::o;35144:191::-;35218:16;35237:6;;;;;;;;;;;35218:25;;35263:8;35254:6;;:17;;;;;;;;;;;;;;;;;;35318:8;35287:40;;35308:8;35287:40;;;;;;;;;;;;35207:128;35144:191;:::o;37611:118::-;36620:19;:17;:19::i;:::-;37681:4:::1;37671:7;;:14;;;;;;;;;;;;;;;;;;37701:20;37708:12;:10;:12::i;:::-;37701:20;;;;;;:::i;:::-;;;;;;;;37611:118::o:0;49415:315::-;49570:8;49561:17;;:5;:17;;;;49553:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;49657:8;49619:18;:25;49638:5;49619:25;;;;;;;;;;;;;;;:35;49645:8;49619:35;;;;;;;;;;;;;;;;:46;;;;;;;;;;;;;;;;;;49703:8;49681:41;;49696:5;49681:41;;;49713:8;49681:41;;;;;;:::i;:::-;;;;;;;;49415:315;;;:::o;44411:313::-;44567:28;44577:4;44583:2;44587:7;44567:9;:28::i;:::-;44614:47;44637:4;44643:2;44647:7;44656:4;44614:22;:47::i;:::-;44606:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;44411:313;;;;:::o;45037:127::-;45102:4;45154:1;45126:30;;:7;:16;45134:7;45126:16;;;;;;;;;;;;;;;;;;;;;:30;;;;45119:37;;45037:127;;;:::o;77777:108::-;77837:13;77870:7;77863:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77777:108;:::o;11362:723::-;11418:13;11648:1;11639:5;:10;11635:53;;;11666:10;;;;;;;;;;;;;;;;;;;;;11635:53;11698:12;11713:5;11698:20;;11729:14;11754:78;11769:1;11761:4;:9;11754:78;;11787:8;;;;;:::i;:::-;;;;11818:2;11810:10;;;;;:::i;:::-;;;11754:78;;;11842:19;11874:6;11864:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11842:39;;11892:154;11908:1;11899:5;:10;11892:154;;11936:1;11926:11;;;;;:::i;:::-;;;12003:2;11995:5;:10;;;;:::i;:::-;11982:2;:24;;;;:::i;:::-;11969:39;;11952:6;11959;11952:14;;;;;;;;:::i;:::-;;;;;:56;;;;;;;;;;;12032:2;12023:11;;;;;:::i;:::-;;;11892:154;;;12070:6;12056:21;;;;;11362:723;;;;:::o;39404:305::-;39506:4;39558:25;39543:40;;;:11;:40;;;;:105;;;;39615:33;39600:48;;;:11;:48;;;;39543:105;:158;;;;39665:36;39689:11;39665:23;:36::i;:::-;39543:158;39523:178;;39404:305;;;:::o;80477:227::-;36620:19;:17;:19::i;:::-;80651:45:::1;80678:4;80684:2;80688:7;80651:26;:45::i;:::-;80477:227:::0;;;:::o;52454:125::-;;;;:::o;37359:108::-;37426:8;:6;:8::i;:::-;37418:41;;;;;;;;;;;;:::i;:::-;;;;;;;;;37359:108::o;46274:319::-;46403:18;46409:2;46413:7;46403:5;:18::i;:::-;46454:53;46485:1;46489:2;46493:7;46502:4;46454:22;:53::i;:::-;46432:153;;;;;;;;;;;;:::i;:::-;;;;;;;;;46274:319;;;:::o;37174:108::-;37245:8;:6;:8::i;:::-;37244:9;37236:38;;;;;;;;;;;;:::i;:::-;;;;;;;;;37174:108::o;50518:853::-;50672:4;50693:15;:2;:13;;;:15::i;:::-;50689:675;;;50745:2;50729:36;;;50766:12;:10;:12::i;:::-;50780:4;50786:7;50795:4;50729:71;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;50725:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50987:1;50970:6;:13;:18;50966:328;;;51013:60;;;;;;;;;;:::i;:::-;;;;;;;;50966:328;51244:6;51238:13;51229:6;51225:2;51221:15;51214:38;50725:584;50861:41;;;50851:51;;;:6;:51;;;;50844:58;;;;;50689:675;51348:4;51341:11;;50518:853;;;;;;;:::o;24818:157::-;24903:4;24942:25;24927:40;;;:11;:40;;;;24920:47;;24818:157;;;:::o;56061:589::-;56205:45;56232:4;56238:2;56242:7;56205:26;:45::i;:::-;56283:1;56267:18;;:4;:18;;;56263:187;;;56302:40;56334:7;56302:31;:40::i;:::-;56263:187;;;56372:2;56364:10;;:4;:10;;;56360:90;;56391:47;56424:4;56430:7;56391:32;:47::i;:::-;56360:90;56263:187;56478:1;56464:16;;:2;:16;;;56460:183;;;56497:45;56534:7;56497:36;:45::i;:::-;56460:183;;;56570:4;56564:10;;:2;:10;;;56560:83;;56591:40;56619:2;56623:7;56591:27;:40::i;:::-;56560:83;56460:183;56061:589;;;:::o;46929:439::-;47023:1;47009:16;;:2;:16;;;;47001:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;47082:16;47090:7;47082;:16::i;:::-;47081:17;47073:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;47144:45;47173:1;47177:2;47181:7;47144:20;:45::i;:::-;47219:1;47202:9;:13;47212:2;47202:13;;;;;;;;;;;;;;;;:18;;;;;;;:::i;:::-;;;;;;;;47250:2;47231:7;:16;47239:7;47231:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;47295:7;47291:2;47270:33;;47287:1;47270:33;;;;;;;;;;;;47316:44;47344:1;47348:2;47352:7;47316:19;:44::i;:::-;46929:439;;:::o;14662:326::-;14722:4;14979:1;14957:7;:19;;;:23;14950:30;;14662:326;;;:::o;51943:126::-;;;;:::o;57373:164::-;57477:10;:17;;;;57450:15;:24;57466:7;57450:24;;;;;;;;;;;:44;;;;57505:10;57521:7;57505:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57373:164;:::o;58164:988::-;58430:22;58480:1;58455:22;58472:4;58455:16;:22::i;:::-;:26;;;;:::i;:::-;58430:51;;58492:18;58513:17;:26;58531:7;58513:26;;;;;;;;;;;;58492:47;;58660:14;58646:10;:28;58642:328;;58691:19;58713:12;:18;58726:4;58713:18;;;;;;;;;;;;;;;:34;58732:14;58713:34;;;;;;;;;;;;58691:56;;58797:11;58764:12;:18;58777:4;58764:18;;;;;;;;;;;;;;;:30;58783:10;58764:30;;;;;;;;;;;:44;;;;58914:10;58881:17;:30;58899:11;58881:30;;;;;;;;;;;:43;;;;58676:294;58642:328;59066:17;:26;59084:7;59066:26;;;;;;;;;;;59059:33;;;59110:12;:18;59123:4;59110:18;;;;;;;;;;;;;;;:34;59129:14;59110:34;;;;;;;;;;;59103:41;;;58245:907;;58164:988;;:::o;59447:1079::-;59700:22;59745:1;59725:10;:17;;;;:21;;;;:::i;:::-;59700:46;;59757:18;59778:15;:24;59794:7;59778:24;;;;;;;;;;;;59757:45;;60129:19;60151:10;60162:14;60151:26;;;;;;;;:::i;:::-;;;;;;;;;;60129:48;;60215:11;60190:10;60201;60190:22;;;;;;;;:::i;:::-;;;;;;;;;:36;;;;60326:10;60295:15;:28;60311:11;60295:28;;;;;;;;;;;:41;;;;60467:15;:24;60483:7;60467:24;;;;;;;;;;;60460:31;;;60502:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;59518:1008;;;59447:1079;:::o;56951:221::-;57036:14;57053:20;57070:2;57053:16;:20::i;:::-;57036:37;;57111:7;57084:12;:16;57097:2;57084:16;;;;;;;;;;;;;;;:24;57101:6;57084:24;;;;;;;;;;;:34;;;;57158:6;57129:17;:26;57147:7;57129:26;;;;;;;;;;;:35;;;;57025:147;56951:221;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:307::-;1866:1;1876:113;1890:6;1887:1;1884:13;1876:113;;;1975:1;1970:3;1966:11;1960:18;1956:1;1951:3;1947:11;1940:39;1912:2;1909:1;1905:10;1900:15;;1876:113;;;2007:6;2004:1;2001:13;1998:101;;;2087:1;2078:6;2073:3;2069:16;2062:27;1998:101;1847:258;1798:307;;;:::o;2111:102::-;2152:6;2203:2;2199:7;2194:2;2187:5;2183:14;2179:28;2169:38;;2111:102;;;:::o;2219:364::-;2307:3;2335:39;2368:5;2335:39;:::i;:::-;2390:71;2454:6;2449:3;2390:71;:::i;:::-;2383:78;;2470:52;2515:6;2510:3;2503:4;2496:5;2492:16;2470:52;:::i;:::-;2547:29;2569:6;2547:29;:::i;:::-;2542:3;2538:39;2531:46;;2311:272;2219:364;;;;:::o;2589:313::-;2702:4;2740:2;2729:9;2725:18;2717:26;;2789:9;2783:4;2779:20;2775:1;2764:9;2760:17;2753:47;2817:78;2890:4;2881:6;2817:78;:::i;:::-;2809:86;;2589:313;;;;:::o;2908:77::-;2945:7;2974:5;2963:16;;2908:77;;;:::o;2991:122::-;3064:24;3082:5;3064:24;:::i;:::-;3057:5;3054:35;3044:63;;3103:1;3100;3093:12;3044:63;2991:122;:::o;3119:139::-;3165:5;3203:6;3190:20;3181:29;;3219:33;3246:5;3219:33;:::i;:::-;3119:139;;;;:::o;3264:329::-;3323:6;3372:2;3360:9;3351:7;3347:23;3343:32;3340:119;;;3378:79;;:::i;:::-;3340:119;3498:1;3523:53;3568:7;3559:6;3548:9;3544:22;3523:53;:::i;:::-;3513:63;;3469:117;3264:329;;;;:::o;3599:126::-;3636:7;3676:42;3669:5;3665:54;3654:65;;3599:126;;;:::o;3731:96::-;3768:7;3797:24;3815:5;3797:24;:::i;:::-;3786:35;;3731:96;;;:::o;3833:118::-;3920:24;3938:5;3920:24;:::i;:::-;3915:3;3908:37;3833:118;;:::o;3957:222::-;4050:4;4088:2;4077:9;4073:18;4065:26;;4101:71;4169:1;4158:9;4154:17;4145:6;4101:71;:::i;:::-;3957:222;;;;:::o;4185:122::-;4258:24;4276:5;4258:24;:::i;:::-;4251:5;4248:35;4238:63;;4297:1;4294;4287:12;4238:63;4185:122;:::o;4313:139::-;4359:5;4397:6;4384:20;4375:29;;4413:33;4440:5;4413:33;:::i;:::-;4313:139;;;;:::o;4458:474::-;4526:6;4534;4583:2;4571:9;4562:7;4558:23;4554:32;4551:119;;;4589:79;;:::i;:::-;4551:119;4709:1;4734:53;4779:7;4770:6;4759:9;4755:22;4734:53;:::i;:::-;4724:63;;4680:117;4836:2;4862:53;4907:7;4898:6;4887:9;4883:22;4862:53;:::i;:::-;4852:63;;4807:118;4458:474;;;;;:::o;4938:118::-;5025:24;5043:5;5025:24;:::i;:::-;5020:3;5013:37;4938:118;;:::o;5062:222::-;5155:4;5193:2;5182:9;5178:18;5170:26;;5206:71;5274:1;5263:9;5259:17;5250:6;5206:71;:::i;:::-;5062:222;;;;:::o;5290:619::-;5367:6;5375;5383;5432:2;5420:9;5411:7;5407:23;5403:32;5400:119;;;5438:79;;:::i;:::-;5400:119;5558:1;5583:53;5628:7;5619:6;5608:9;5604:22;5583:53;:::i;:::-;5573:63;;5529:117;5685:2;5711:53;5756:7;5747:6;5736:9;5732:22;5711:53;:::i;:::-;5701:63;;5656:118;5813:2;5839:53;5884:7;5875:6;5864:9;5860:22;5839:53;:::i;:::-;5829:63;;5784:118;5290:619;;;;;:::o;5915:117::-;6024:1;6021;6014:12;6038:117;6147:1;6144;6137:12;6161:180;6209:77;6206:1;6199:88;6306:4;6303:1;6296:15;6330:4;6327:1;6320:15;6347:281;6430:27;6452:4;6430:27;:::i;:::-;6422:6;6418:40;6560:6;6548:10;6545:22;6524:18;6512:10;6509:34;6506:62;6503:88;;;6571:18;;:::i;:::-;6503:88;6611:10;6607:2;6600:22;6390:238;6347:281;;:::o;6634:129::-;6668:6;6695:20;;:::i;:::-;6685:30;;6724:33;6752:4;6744:6;6724:33;:::i;:::-;6634:129;;;:::o;6769:308::-;6831:4;6921:18;6913:6;6910:30;6907:56;;;6943:18;;:::i;:::-;6907:56;6981:29;7003:6;6981:29;:::i;:::-;6973:37;;7065:4;7059;7055:15;7047:23;;6769:308;;;:::o;7083:154::-;7167:6;7162:3;7157;7144:30;7229:1;7220:6;7215:3;7211:16;7204:27;7083:154;;;:::o;7243:412::-;7321:5;7346:66;7362:49;7404:6;7362:49;:::i;:::-;7346:66;:::i;:::-;7337:75;;7435:6;7428:5;7421:21;7473:4;7466:5;7462:16;7511:3;7502:6;7497:3;7493:16;7490:25;7487:112;;;7518:79;;:::i;:::-;7487:112;7608:41;7642:6;7637:3;7632;7608:41;:::i;:::-;7327:328;7243:412;;;;;:::o;7675:340::-;7731:5;7780:3;7773:4;7765:6;7761:17;7757:27;7747:122;;7788:79;;:::i;:::-;7747:122;7905:6;7892:20;7930:79;8005:3;7997:6;7990:4;7982:6;7978:17;7930:79;:::i;:::-;7921:88;;7737:278;7675:340;;;;:::o;8021:509::-;8090:6;8139:2;8127:9;8118:7;8114:23;8110:32;8107:119;;;8145:79;;:::i;:::-;8107:119;8293:1;8282:9;8278:17;8265:31;8323:18;8315:6;8312:30;8309:117;;;8345:79;;:::i;:::-;8309:117;8450:63;8505:7;8496:6;8485:9;8481:22;8450:63;:::i;:::-;8440:73;;8236:287;8021:509;;;;:::o;8536:329::-;8595:6;8644:2;8632:9;8623:7;8619:23;8615:32;8612:119;;;8650:79;;:::i;:::-;8612:119;8770:1;8795:53;8840:7;8831:6;8820:9;8816:22;8795:53;:::i;:::-;8785:63;;8741:117;8536:329;;;;:::o;8871:60::-;8899:3;8920:5;8913:12;;8871:60;;;:::o;8937:142::-;8987:9;9020:53;9038:34;9047:24;9065:5;9047:24;:::i;:::-;9038:34;:::i;:::-;9020:53;:::i;:::-;9007:66;;8937:142;;;:::o;9085:126::-;9135:9;9168:37;9199:5;9168:37;:::i;:::-;9155:50;;9085:126;;;:::o;9217:141::-;9282:9;9315:37;9346:5;9315:37;:::i;:::-;9302:50;;9217:141;;;:::o;9364:161::-;9466:52;9512:5;9466:52;:::i;:::-;9461:3;9454:65;9364:161;;:::o;9531:252::-;9639:4;9677:2;9666:9;9662:18;9654:26;;9690:86;9773:1;9762:9;9758:17;9749:6;9690:86;:::i;:::-;9531:252;;;;:::o;9789:116::-;9859:21;9874:5;9859:21;:::i;:::-;9852:5;9849:32;9839:60;;9895:1;9892;9885:12;9839:60;9789:116;:::o;9911:133::-;9954:5;9992:6;9979:20;9970:29;;10008:30;10032:5;10008:30;:::i;:::-;9911:133;;;;:::o;10050:468::-;10115:6;10123;10172:2;10160:9;10151:7;10147:23;10143:32;10140:119;;;10178:79;;:::i;:::-;10140:119;10298:1;10323:53;10368:7;10359:6;10348:9;10344:22;10323:53;:::i;:::-;10313:63;;10269:117;10425:2;10451:50;10493:7;10484:6;10473:9;10469:22;10451:50;:::i;:::-;10441:60;;10396:115;10050:468;;;;;:::o;10524:307::-;10585:4;10675:18;10667:6;10664:30;10661:56;;;10697:18;;:::i;:::-;10661:56;10735:29;10757:6;10735:29;:::i;:::-;10727:37;;10819:4;10813;10809:15;10801:23;;10524:307;;;:::o;10837:410::-;10914:5;10939:65;10955:48;10996:6;10955:48;:::i;:::-;10939:65;:::i;:::-;10930:74;;11027:6;11020:5;11013:21;11065:4;11058:5;11054:16;11103:3;11094:6;11089:3;11085:16;11082:25;11079:112;;;11110:79;;:::i;:::-;11079:112;11200:41;11234:6;11229:3;11224;11200:41;:::i;:::-;10920:327;10837:410;;;;;:::o;11266:338::-;11321:5;11370:3;11363:4;11355:6;11351:17;11347:27;11337:122;;11378:79;;:::i;:::-;11337:122;11495:6;11482:20;11520:78;11594:3;11586:6;11579:4;11571:6;11567:17;11520:78;:::i;:::-;11511:87;;11327:277;11266:338;;;;:::o;11610:943::-;11705:6;11713;11721;11729;11778:3;11766:9;11757:7;11753:23;11749:33;11746:120;;;11785:79;;:::i;:::-;11746:120;11905:1;11930:53;11975:7;11966:6;11955:9;11951:22;11930:53;:::i;:::-;11920:63;;11876:117;12032:2;12058:53;12103:7;12094:6;12083:9;12079:22;12058:53;:::i;:::-;12048:63;;12003:118;12160:2;12186:53;12231:7;12222:6;12211:9;12207:22;12186:53;:::i;:::-;12176:63;;12131:118;12316:2;12305:9;12301:18;12288:32;12347:18;12339:6;12336:30;12333:117;;;12369:79;;:::i;:::-;12333:117;12474:62;12528:7;12519:6;12508:9;12504:22;12474:62;:::i;:::-;12464:72;;12259:287;11610:943;;;;;;;:::o;12559:474::-;12627:6;12635;12684:2;12672:9;12663:7;12659:23;12655:32;12652:119;;;12690:79;;:::i;:::-;12652:119;12810:1;12835:53;12880:7;12871:6;12860:9;12856:22;12835:53;:::i;:::-;12825:63;;12781:117;12937:2;12963:53;13008:7;12999:6;12988:9;12984:22;12963:53;:::i;:::-;12953:63;;12908:118;12559:474;;;;;:::o;13039:180::-;13087:77;13084:1;13077:88;13184:4;13181:1;13174:15;13208:4;13205:1;13198:15;13225:320;13269:6;13306:1;13300:4;13296:12;13286:22;;13353:1;13347:4;13343:12;13374:18;13364:81;;13430:4;13422:6;13418:17;13408:27;;13364:81;13492:2;13484:6;13481:14;13461:18;13458:38;13455:84;;;13511:18;;:::i;:::-;13455:84;13276:269;13225:320;;;:::o;13551:220::-;13691:34;13687:1;13679:6;13675:14;13668:58;13760:3;13755:2;13747:6;13743:15;13736:28;13551:220;:::o;13777:366::-;13919:3;13940:67;14004:2;13999:3;13940:67;:::i;:::-;13933:74;;14016:93;14105:3;14016:93;:::i;:::-;14134:2;14129:3;14125:12;14118:19;;13777:366;;;:::o;14149:419::-;14315:4;14353:2;14342:9;14338:18;14330:26;;14402:9;14396:4;14392:20;14388:1;14377:9;14373:17;14366:47;14430:131;14556:4;14430:131;:::i;:::-;14422:139;;14149:419;;;:::o;14574:249::-;14714:34;14710:1;14702:6;14698:14;14691:58;14783:32;14778:2;14770:6;14766:15;14759:57;14574:249;:::o;14829:366::-;14971:3;14992:67;15056:2;15051:3;14992:67;:::i;:::-;14985:74;;15068:93;15157:3;15068:93;:::i;:::-;15186:2;15181:3;15177:12;15170:19;;14829:366;;;:::o;15201:419::-;15367:4;15405:2;15394:9;15390:18;15382:26;;15454:9;15448:4;15444:20;15440:1;15429:9;15425:17;15418:47;15482:131;15608:4;15482:131;:::i;:::-;15474:139;;15201:419;;;:::o;15626:233::-;15766:34;15762:1;15754:6;15750:14;15743:58;15835:16;15830:2;15822:6;15818:15;15811:41;15626:233;:::o;15865:366::-;16007:3;16028:67;16092:2;16087:3;16028:67;:::i;:::-;16021:74;;16104:93;16193:3;16104:93;:::i;:::-;16222:2;16217:3;16213:12;16206:19;;15865:366;;;:::o;16237:419::-;16403:4;16441:2;16430:9;16426:18;16418:26;;16490:9;16484:4;16480:20;16476:1;16465:9;16461:17;16454:47;16518:131;16644:4;16518:131;:::i;:::-;16510:139;;16237:419;;;:::o;16662:230::-;16802:34;16798:1;16790:6;16786:14;16779:58;16871:13;16866:2;16858:6;16854:15;16847:38;16662:230;:::o;16898:366::-;17040:3;17061:67;17125:2;17120:3;17061:67;:::i;:::-;17054:74;;17137:93;17226:3;17137:93;:::i;:::-;17255:2;17250:3;17246:12;17239:19;;16898:366;;;:::o;17270:419::-;17436:4;17474:2;17463:9;17459:18;17451:26;;17523:9;17517:4;17513:20;17509:1;17498:9;17494:17;17487:47;17551:131;17677:4;17551:131;:::i;:::-;17543:139;;17270:419;;;:::o;17695:231::-;17835:34;17831:1;17823:6;17819:14;17812:58;17904:14;17899:2;17891:6;17887:15;17880:39;17695:231;:::o;17932:366::-;18074:3;18095:67;18159:2;18154:3;18095:67;:::i;:::-;18088:74;;18171:93;18260:3;18171:93;:::i;:::-;18289:2;18284:3;18280:12;18273:19;;17932:366;;;:::o;18304:419::-;18470:4;18508:2;18497:9;18493:18;18485:26;;18557:9;18551:4;18547:20;18543:1;18532:9;18528:17;18521:47;18585:131;18711:4;18585:131;:::i;:::-;18577:139;;18304:419;;;:::o;18729:180::-;18777:77;18774:1;18767:88;18874:4;18871:1;18864:15;18898:4;18895:1;18888:15;18915:174;19055:26;19051:1;19043:6;19039:14;19032:50;18915:174;:::o;19095:366::-;19237:3;19258:67;19322:2;19317:3;19258:67;:::i;:::-;19251:74;;19334:93;19423:3;19334:93;:::i;:::-;19452:2;19447:3;19443:12;19436:19;;19095:366;;;:::o;19467:419::-;19633:4;19671:2;19660:9;19656:18;19648:26;;19720:9;19714:4;19710:20;19706:1;19695:9;19691:17;19684:47;19748:131;19874:4;19748:131;:::i;:::-;19740:139;;19467:419;;;:::o;19892:442::-;20041:4;20079:2;20068:9;20064:18;20056:26;;20092:71;20160:1;20149:9;20145:17;20136:6;20092:71;:::i;:::-;20173:72;20241:2;20230:9;20226:18;20217:6;20173:72;:::i;:::-;20255;20323:2;20312:9;20308:18;20299:6;20255:72;:::i;:::-;19892:442;;;;;;:::o;20340:137::-;20394:5;20425:6;20419:13;20410:22;;20441:30;20465:5;20441:30;:::i;:::-;20340:137;;;;:::o;20483:345::-;20550:6;20599:2;20587:9;20578:7;20574:23;20570:32;20567:119;;;20605:79;;:::i;:::-;20567:119;20725:1;20750:61;20803:7;20794:6;20783:9;20779:22;20750:61;:::i;:::-;20740:71;;20696:125;20483:345;;;;:::o;20834:228::-;20974:34;20970:1;20962:6;20958:14;20951:58;21043:11;21038:2;21030:6;21026:15;21019:36;20834:228;:::o;21068:366::-;21210:3;21231:67;21295:2;21290:3;21231:67;:::i;:::-;21224:74;;21307:93;21396:3;21307:93;:::i;:::-;21425:2;21420:3;21416:12;21409:19;;21068:366;;;:::o;21440:419::-;21606:4;21644:2;21633:9;21629:18;21621:26;;21693:9;21687:4;21683:20;21679:1;21668:9;21664:17;21657:47;21721:131;21847:4;21721:131;:::i;:::-;21713:139;;21440:419;;;:::o;21865:180::-;21913:77;21910:1;21903:88;22010:4;22007:1;22000:15;22034:4;22031:1;22024:15;22051:305;22091:3;22110:20;22128:1;22110:20;:::i;:::-;22105:25;;22144:20;22162:1;22144:20;:::i;:::-;22139:25;;22298:1;22230:66;22226:74;22223:1;22220:81;22217:107;;;22304:18;;:::i;:::-;22217:107;22348:1;22345;22341:9;22334:16;;22051:305;;;;:::o;22362:143::-;22419:5;22450:6;22444:13;22435:22;;22466:33;22493:5;22466:33;:::i;:::-;22362:143;;;;:::o;22511:351::-;22581:6;22630:2;22618:9;22609:7;22605:23;22601:32;22598:119;;;22636:79;;:::i;:::-;22598:119;22756:1;22781:64;22837:7;22828:6;22817:9;22813:22;22781:64;:::i;:::-;22771:74;;22727:128;22511:351;;;;:::o;22868:348::-;22908:7;22931:20;22949:1;22931:20;:::i;:::-;22926:25;;22965:20;22983:1;22965:20;:::i;:::-;22960:25;;23153:1;23085:66;23081:74;23078:1;23075:81;23070:1;23063:9;23056:17;23052:105;23049:131;;;23160:18;;:::i;:::-;23049:131;23208:1;23205;23201:9;23190:20;;22868:348;;;;:::o;23222:233::-;23261:3;23284:24;23302:5;23284:24;:::i;:::-;23275:33;;23330:66;23323:5;23320:77;23317:103;;;23400:18;;:::i;:::-;23317:103;23447:1;23440:5;23436:13;23429:20;;23222:233;;;:::o;23461:180::-;23509:77;23506:1;23499:88;23606:4;23603:1;23596:15;23630:4;23627:1;23620:15;23647:185;23687:1;23704:20;23722:1;23704:20;:::i;:::-;23699:25;;23738:20;23756:1;23738:20;:::i;:::-;23733:25;;23777:1;23767:35;;23782:18;;:::i;:::-;23767:35;23824:1;23821;23817:9;23812:14;;23647:185;;;;:::o;23838:234::-;23978:34;23974:1;23966:6;23962:14;23955:58;24047:17;24042:2;24034:6;24030:15;24023:42;23838:234;:::o;24078:366::-;24220:3;24241:67;24305:2;24300:3;24241:67;:::i;:::-;24234:74;;24317:93;24406:3;24317:93;:::i;:::-;24435:2;24430:3;24426:12;24419:19;;24078:366;;;:::o;24450:419::-;24616:4;24654:2;24643:9;24639:18;24631:26;;24703:9;24697:4;24693:20;24689:1;24678:9;24674:17;24667:47;24731:131;24857:4;24731:131;:::i;:::-;24723:139;;24450:419;;;:::o;24875:148::-;24977:11;25014:3;24999:18;;24875:148;;;;:::o;25029:377::-;25135:3;25163:39;25196:5;25163:39;:::i;:::-;25218:89;25300:6;25295:3;25218:89;:::i;:::-;25211:96;;25316:52;25361:6;25356:3;25349:4;25342:5;25338:16;25316:52;:::i;:::-;25393:6;25388:3;25384:16;25377:23;;25139:267;25029:377;;;;:::o;25412:141::-;25461:4;25484:3;25476:11;;25507:3;25504:1;25497:14;25541:4;25538:1;25528:18;25520:26;;25412:141;;;:::o;25583:845::-;25686:3;25723:5;25717:12;25752:36;25778:9;25752:36;:::i;:::-;25804:89;25886:6;25881:3;25804:89;:::i;:::-;25797:96;;25924:1;25913:9;25909:17;25940:1;25935:137;;;;26086:1;26081:341;;;;25902:520;;25935:137;26019:4;26015:9;26004;26000:25;25995:3;25988:38;26055:6;26050:3;26046:16;26039:23;;25935:137;;26081:341;26148:38;26180:5;26148:38;:::i;:::-;26208:1;26222:154;26236:6;26233:1;26230:13;26222:154;;;26310:7;26304:14;26300:1;26295:3;26291:11;26284:35;26360:1;26351:7;26347:15;26336:26;;26258:4;26255:1;26251:12;26246:17;;26222:154;;;26405:6;26400:3;26396:16;26389:23;;26088:334;;25902:520;;25690:738;;25583:845;;;;:::o;26434:589::-;26659:3;26681:95;26772:3;26763:6;26681:95;:::i;:::-;26674:102;;26793:95;26884:3;26875:6;26793:95;:::i;:::-;26786:102;;26905:92;26993:3;26984:6;26905:92;:::i;:::-;26898:99;;27014:3;27007:10;;26434:589;;;;;;:::o;27029:225::-;27169:34;27165:1;27157:6;27153:14;27146:58;27238:8;27233:2;27225:6;27221:15;27214:33;27029:225;:::o;27260:366::-;27402:3;27423:67;27487:2;27482:3;27423:67;:::i;:::-;27416:74;;27499:93;27588:3;27499:93;:::i;:::-;27617:2;27612:3;27608:12;27601:19;;27260:366;;;:::o;27632:419::-;27798:4;27836:2;27825:9;27821:18;27813:26;;27885:9;27879:4;27875:20;27871:1;27860:9;27856:17;27849:47;27913:131;28039:4;27913:131;:::i;:::-;27905:139;;27632:419;;;:::o;28057:224::-;28197:34;28193:1;28185:6;28181:14;28174:58;28266:7;28261:2;28253:6;28249:15;28242:32;28057:224;:::o;28287:366::-;28429:3;28450:67;28514:2;28509:3;28450:67;:::i;:::-;28443:74;;28526:93;28615:3;28526:93;:::i;:::-;28644:2;28639:3;28635:12;28628:19;;28287:366;;;:::o;28659:419::-;28825:4;28863:2;28852:9;28848:18;28840:26;;28912:9;28906:4;28902:20;28898:1;28887:9;28883:17;28876:47;28940:131;29066:4;28940:131;:::i;:::-;28932:139;;28659:419;;;:::o;29084:223::-;29224:34;29220:1;29212:6;29208:14;29201:58;29293:6;29288:2;29280:6;29276:15;29269:31;29084:223;:::o;29313:366::-;29455:3;29476:67;29540:2;29535:3;29476:67;:::i;:::-;29469:74;;29552:93;29641:3;29552:93;:::i;:::-;29670:2;29665:3;29661:12;29654:19;;29313:366;;;:::o;29685:419::-;29851:4;29889:2;29878:9;29874:18;29866:26;;29938:9;29932:4;29928:20;29924:1;29913:9;29909:17;29902:47;29966:131;30092:4;29966:131;:::i;:::-;29958:139;;29685:419;;;:::o;30110:191::-;30150:4;30170:20;30188:1;30170:20;:::i;:::-;30165:25;;30204:20;30222:1;30204:20;:::i;:::-;30199:25;;30243:1;30240;30237:8;30234:34;;;30248:18;;:::i;:::-;30234:34;30293:1;30290;30286:9;30278:17;;30110:191;;;;:::o;30307:182::-;30447:34;30443:1;30435:6;30431:14;30424:58;30307:182;:::o;30495:366::-;30637:3;30658:67;30722:2;30717:3;30658:67;:::i;:::-;30651:74;;30734:93;30823:3;30734:93;:::i;:::-;30852:2;30847:3;30843:12;30836:19;;30495:366;;;:::o;30867:419::-;31033:4;31071:2;31060:9;31056:18;31048:26;;31120:9;31114:4;31110:20;31106:1;31095:9;31091:17;31084:47;31148:131;31274:4;31148:131;:::i;:::-;31140:139;;30867:419;;;:::o;31292:175::-;31432:27;31428:1;31420:6;31416:14;31409:51;31292:175;:::o;31473:366::-;31615:3;31636:67;31700:2;31695:3;31636:67;:::i;:::-;31629:74;;31712:93;31801:3;31712:93;:::i;:::-;31830:2;31825:3;31821:12;31814:19;;31473:366;;;:::o;31845:419::-;32011:4;32049:2;32038:9;32034:18;32026:26;;32098:9;32092:4;32088:20;32084:1;32073:9;32069:17;32062:47;32126:131;32252:4;32126:131;:::i;:::-;32118:139;;31845:419;;;:::o;32270:237::-;32410:34;32406:1;32398:6;32394:14;32387:58;32479:20;32474:2;32466:6;32462:15;32455:45;32270:237;:::o;32513:366::-;32655:3;32676:67;32740:2;32735:3;32676:67;:::i;:::-;32669:74;;32752:93;32841:3;32752:93;:::i;:::-;32870:2;32865:3;32861:12;32854:19;;32513:366;;;:::o;32885:419::-;33051:4;33089:2;33078:9;33074:18;33066:26;;33138:9;33132:4;33128:20;33124:1;33113:9;33109:17;33102:47;33166:131;33292:4;33166:131;:::i;:::-;33158:139;;32885:419;;;:::o;33310:176::-;33342:1;33359:20;33377:1;33359:20;:::i;:::-;33354:25;;33393:20;33411:1;33393:20;:::i;:::-;33388:25;;33432:1;33422:35;;33437:18;;:::i;:::-;33422:35;33478:1;33475;33471:9;33466:14;;33310:176;;;;:::o;33492:170::-;33632:22;33628:1;33620:6;33616:14;33609:46;33492:170;:::o;33668:366::-;33810:3;33831:67;33895:2;33890:3;33831:67;:::i;:::-;33824:74;;33907:93;33996:3;33907:93;:::i;:::-;34025:2;34020:3;34016:12;34009:19;;33668:366;;;:::o;34040:419::-;34206:4;34244:2;34233:9;34229:18;34221:26;;34293:9;34287:4;34283:20;34279:1;34268:9;34264:17;34257:47;34321:131;34447:4;34321:131;:::i;:::-;34313:139;;34040:419;;;:::o;34465:166::-;34605:18;34601:1;34593:6;34589:14;34582:42;34465:166;:::o;34637:366::-;34779:3;34800:67;34864:2;34859:3;34800:67;:::i;:::-;34793:74;;34876:93;34965:3;34876:93;:::i;:::-;34994:2;34989:3;34985:12;34978:19;;34637:366;;;:::o;35009:419::-;35175:4;35213:2;35202:9;35198:18;35190:26;;35262:9;35256:4;35252:20;35248:1;35237:9;35233:17;35226:47;35290:131;35416:4;35290:131;:::i;:::-;35282:139;;35009:419;;;:::o;35434:98::-;35485:6;35519:5;35513:12;35503:22;;35434:98;;;:::o;35538:168::-;35621:11;35655:6;35650:3;35643:19;35695:4;35690:3;35686:14;35671:29;;35538:168;;;;:::o;35712:360::-;35798:3;35826:38;35858:5;35826:38;:::i;:::-;35880:70;35943:6;35938:3;35880:70;:::i;:::-;35873:77;;35959:52;36004:6;35999:3;35992:4;35985:5;35981:16;35959:52;:::i;:::-;36036:29;36058:6;36036:29;:::i;:::-;36031:3;36027:39;36020:46;;35802:270;35712:360;;;;:::o;36078:640::-;36273:4;36311:3;36300:9;36296:19;36288:27;;36325:71;36393:1;36382:9;36378:17;36369:6;36325:71;:::i;:::-;36406:72;36474:2;36463:9;36459:18;36450:6;36406:72;:::i;:::-;36488;36556:2;36545:9;36541:18;36532:6;36488:72;:::i;:::-;36607:9;36601:4;36597:20;36592:2;36581:9;36577:18;36570:48;36635:76;36706:4;36697:6;36635:76;:::i;:::-;36627:84;;36078:640;;;;;;;:::o;36724:141::-;36780:5;36811:6;36805:13;36796:22;;36827:32;36853:5;36827:32;:::i;:::-;36724:141;;;;:::o;36871:349::-;36940:6;36989:2;36977:9;36968:7;36964:23;36960:32;36957:119;;;36995:79;;:::i;:::-;36957:119;37115:1;37140:63;37195:7;37186:6;37175:9;37171:22;37140:63;:::i;:::-;37130:73;;37086:127;36871:349;;;;:::o;37226:182::-;37366:34;37362:1;37354:6;37350:14;37343:58;37226:182;:::o;37414:366::-;37556:3;37577:67;37641:2;37636:3;37577:67;:::i;:::-;37570:74;;37653:93;37742:3;37653:93;:::i;:::-;37771:2;37766:3;37762:12;37755:19;;37414:366;;;:::o;37786:419::-;37952:4;37990:2;37979:9;37975:18;37967:26;;38039:9;38033:4;38029:20;38025:1;38014:9;38010:17;38003:47;38067:131;38193:4;38067:131;:::i;:::-;38059:139;;37786:419;;;:::o;38211:178::-;38351:30;38347:1;38339:6;38335:14;38328:54;38211:178;:::o;38395:366::-;38537:3;38558:67;38622:2;38617:3;38558:67;:::i;:::-;38551:74;;38634:93;38723:3;38634:93;:::i;:::-;38752:2;38747:3;38743:12;38736:19;;38395:366;;;:::o;38767:419::-;38933:4;38971:2;38960:9;38956:18;38948:26;;39020:9;39014:4;39010:20;39006:1;38995:9;38991:17;38984:47;39048:131;39174:4;39048:131;:::i;:::-;39040:139;;38767:419;;;:::o;39192:180::-;39240:77;39237:1;39230:88;39337:4;39334:1;39327:15;39361:4;39358:1;39351:15

Swarm Source

ipfs://6771f2a5ba4049e85c2e17498289f1b0a040a04762af0dd264228838953a85d8
Loading