S Price: $0.429154 (+0.49%)

Contract

0xB73693f6b87A81628AD26Bd9275A9B28084dc634

Overview

S Balance

Sonic LogoSonic LogoSonic Logo0 S

S Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

Parent Transaction Hash Block From To
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
MowseDungeonPlayerClassAttackFacet

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 10 : MowseDungeonPlayerClassAttackFacet.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.12;
import "hardhat/console.sol";
/*************************************************************************
___  ___                       
|  \/  |                                          ___
| .  . | _____      _____  ___           _  _  .-'   '-.
| |\/| |/ _ \ \ /\ / / __|/ _ \         (.)(.)/         \   
| |  | | (_) \ V  V /\__ \  __/          /@@             ;
\_|  |_/\___/ \_/\_/ |___/\___|         o_\\-mm-......-mm`~~~~~~~~~~~~~~~~` 
                               
/*************************************************************************/

import "@openzeppelin/contracts/utils/Strings.sol";
import {GameStorage, MowseDungeonClassEnum, MowseDungeonActionTypeEnum, MowseDungeonSimpleMonster, MowseDungeonBattleSimulation, STAT_DEXTERITY, STAT_STRENGTH, STAT_INTELLIGENCE, STAT_CONSTITUTION, STAT_CHARISMA, STAT_LUCK, STAT_WISDOM, MowseDungeonBattleLog, MowseDungeonBattleLogSourceEnum, MowseDungeonBattleLogTypeEnum} from "../../libraries/LibStorage.sol";
import {LibDiamond} from "../../libraries/LibDiamond.sol";
import "../../libraries/Base64.sol";
import "../../libraries/LibDungeon.sol";

contract MowseDungeonPlayerClassAttackFacet {
    using Strings for uint256;
    GameStorage internal gs;

    function playerClassAttack(
        MowseDungeonBattleSimulation memory _battleSimulation,
        MowseDungeonSimpleMonster memory _monster
    ) external pure returns (MowseDungeonBattleSimulation memory, MowseDungeonSimpleMonster memory) {
        MowseDungeonSimpleMonster memory updatedMonster;
        // Calculate damage of player attack to monster
        _battleSimulation.player.tempAttack = (_battleSimulation.player.tempAttack * _classBasicAttackRatio(_battleSimulation.player.class)) / 100;
        // Slingshot only for max health damage
        if (_battleSimulation.player.trinkets.slingshot > 0) {
            if (_monster.currentHealth == _monster.maxHealth) {
                _battleSimulation.player.damageMultiplier = 110 + 10 * _battleSimulation.player.trinkets.slingshot;
            }
        }
        if (_monster.statusEffects.bulk > 0) {
            _battleSimulation.player.damageMultiplier -= 30;
        }
        if (_monster.statusEffects.frail > 0) {
            _battleSimulation.player.damageMultiplier += 30;
        }
        if (_monster.statusEffects.sleep > 0) {
            _battleSimulation.player.damageMultiplier += 50;
            _monster.statusEffects.sleep = 0;
        }
        _battleSimulation.player.tempAttack = (_battleSimulation.player.tempAttack * _battleSimulation.player.damageMultiplier) / 100;
        _battleSimulation.player.numberOfHits = 1;
        if (_battleSimulation.player.class == MowseDungeonClassEnum.WARRIOR && _battleSimulation.actionType == MowseDungeonActionTypeEnum.SPECIAL_ABILITY) {
            // Warrior
            if (_battleSimulation.monster1.currentHealth > 0) {
              (_battleSimulation, updatedMonster) = LibDungeon._dealPlayerDamageToMonster(_battleSimulation, _battleSimulation.monster1, 0);
              _battleSimulation.monster1 = updatedMonster;
              if (_battleSimulation.targetIndex == 0) {
                _monster = updatedMonster;
              }
            }
            if (_battleSimulation.monster2.currentHealth > 0) {
              (_battleSimulation, updatedMonster) = LibDungeon._dealPlayerDamageToMonster(_battleSimulation, _battleSimulation.monster2, 1);
              _battleSimulation.monster2 = updatedMonster;
              if (_battleSimulation.targetIndex == 1) {
                _monster = updatedMonster;
              }
            }
            if (_battleSimulation.monster3.currentHealth > 0) {
              (_battleSimulation, updatedMonster) = LibDungeon._dealPlayerDamageToMonster(_battleSimulation, _battleSimulation.monster3, 2);
              _battleSimulation.monster3 = updatedMonster;
              if (_battleSimulation.targetIndex == 2) {
                _monster = updatedMonster;
              }
            }
        } else if (
            // Mage
            _battleSimulation.player.class == MowseDungeonClassEnum.MAGE &&
            _battleSimulation.actionType == MowseDungeonActionTypeEnum.SPECIAL_ABILITY
        ) {
            // Deal damage based off base attack
            _battleSimulation.player.tempAttack = _battleSimulation.player.attack * 2;
            (_battleSimulation, updatedMonster) = LibDungeon._dealPlayerDamageToMonster(_battleSimulation, _monster, _battleSimulation.targetIndex);

            // Apply burn stack
            if (updatedMonster.statusEffects.fireResist == 0) {
                _battleSimulation = LibDungeon._addToBattleLogForMonsterIndex(_battleSimulation, 0, MowseDungeonBattleLogTypeEnum.APPLY_STATUS_EFFECT, MowseDungeonBattleLogSourceEnum.STATUS_EFFECT_BURN, 1);    
                updatedMonster.statusEffects.burn++;
            }
            _monster = updatedMonster;
        } else if (
            // Archer
            _battleSimulation.player.class == MowseDungeonClassEnum.ARCHER &&
            _battleSimulation.actionType == MowseDungeonActionTypeEnum.SPECIAL_ABILITY
        ) {
            _battleSimulation = LibDungeon._addStatusEffectToBattleLogForPlayer(_battleSimulation, MowseDungeonBattleLogSourceEnum.STATUS_EFFECT_EAGLE_EYE, 2);
            _battleSimulation.player.statusEffects.eagleEye += 2;
            // First do a basic attack            
            (_battleSimulation, updatedMonster) = LibDungeon._dealPlayerDamageToMonster(_battleSimulation, _monster, _battleSimulation.targetIndex);
            // Then do while loop for every 20 dex, 50% chance to hit again
            if (_battleSimulation.player.stats[STAT_DEXTERITY] > 0) {
              uint256 numberOfTries = LibDungeon._int32ToUint256(_battleSimulation.player.stats[STAT_DEXTERITY]) / 20 + 1;
              while(numberOfTries > 0) {
                _battleSimulation.seed = LibDungeon.updateNewSeed(_battleSimulation.dungeonId, _battleSimulation.seed);
                if (_battleSimulation.seed % 2 == 0) {
                  console.log('Hit again!');
                  (_battleSimulation, updatedMonster) = LibDungeon._dealPlayerDamageToMonster(_battleSimulation, updatedMonster, _battleSimulation.targetIndex);
                  _battleSimulation.player.numberOfHits++;
                }
                numberOfTries--;
              }
            } else {
              // Else only one chance of an additional hit
              _battleSimulation.seed = LibDungeon.updateNewSeed(_battleSimulation.dungeonId, _battleSimulation.seed);
              if (_battleSimulation.seed % 2 == 0) {
                console.log('Hit Again!');
                (_battleSimulation, updatedMonster) = LibDungeon._dealPlayerDamageToMonster(_battleSimulation, _monster, _battleSimulation.targetIndex);
                _battleSimulation.player.numberOfHits++;
              }
            }
            _monster = updatedMonster;
        } else if (_battleSimulation.player.class == MowseDungeonClassEnum.ROGUE) {
            // Rogue
            if (_battleSimulation.actionType == MowseDungeonActionTypeEnum.SPECIAL_ABILITY) {
                _battleSimulation = LibDungeon._addStatusEffectToBattleLogForPlayer(_battleSimulation, MowseDungeonBattleLogSourceEnum.STATUS_EFFECT_DODGE, 2);
                _battleSimulation.player.statusEffects.dodge += 2;
            }
            _battleSimulation.player.numberOfHits = 2;

            for (uint256 i = 0; i < 2; i++) {
                (_battleSimulation, updatedMonster) = LibDungeon._dealPlayerDamageToMonster(_battleSimulation, _monster, _battleSimulation.targetIndex);

                // Apply POISON stack
                if (updatedMonster.statusEffects.poisonResist == 0) {
                    _battleSimulation = LibDungeon._addToBattleLogForMonsterIndex(_battleSimulation, 0, MowseDungeonBattleLogTypeEnum.APPLY_STATUS_EFFECT, MowseDungeonBattleLogSourceEnum.STATUS_EFFECT_POISON, 1);    
                    updatedMonster.statusEffects.poison++;
                }
            }
            _monster = updatedMonster;
        } else if (_battleSimulation.player.class == MowseDungeonClassEnum.PALADIN && _battleSimulation.actionType == MowseDungeonActionTypeEnum.SPECIAL_ABILITY) {
            // Paladin
            (_battleSimulation, updatedMonster) = LibDungeon._dealPlayerDamageToMonster(_battleSimulation, _monster, _battleSimulation.targetIndex);
            // Try to heal
            if (_battleSimulation.player.statusEffects.healBlock == 0) {
              uint256 maxHealthToRestore = 30;
              if (_battleSimulation.player.stats[STAT_STRENGTH] > 0) {
                  maxHealthToRestore += LibDungeon._int32ToUint256(_battleSimulation.player.stats[STAT_STRENGTH]) / 10 + 1;
              }
              if (_battleSimulation.player.stats[STAT_INTELLIGENCE] > 0) {
                  maxHealthToRestore += LibDungeon._int32ToUint256(_battleSimulation.player.stats[STAT_INTELLIGENCE]) / 10 + 1;
              }
              _battleSimulation = LibDungeon._addToBattleLog(_battleSimulation, MowseDungeonBattleLogTypeEnum.HEAL, MowseDungeonBattleLogSourceEnum.PLAYER, MowseDungeonBattleLogSourceEnum.PLAYER, maxHealthToRestore * _battleSimulation.player.maxHealth / 100);
              _battleSimulation.player.currentHealth += maxHealthToRestore * _battleSimulation.player.maxHealth / 100;
              // Make sure health doesn't exceed maxHealth
              if (_battleSimulation.player.currentHealth > _battleSimulation.player.maxHealth) {
                  _battleSimulation.player.currentHealth = _battleSimulation.player.maxHealth;
              }
              _battleSimulation.achievementProgress.healthHealed += maxHealthToRestore * _battleSimulation.player.maxHealth / 100;
            } else {
                _battleSimulation.player.statusEffects.healBlock--;
            }
            _monster = updatedMonster;
        } else if (_battleSimulation.player.class == MowseDungeonClassEnum.GUARDIAN) {
          if (_battleSimulation.actionType == MowseDungeonActionTypeEnum.SPECIAL_ABILITY) {
            // Guardian Shield Bash
            // Double shield, then deal damage based on shield value
            _battleSimulation.player.shield *= 2;
            _battleSimulation.player.tempAttack += _battleSimulation.player.shield;
          } else {
            // Guardian basic attack
            // Gain small shield on attack
            uint256 shieldToGain = _battleSimulation.player.attack / 10;
            if (_battleSimulation.player.stats[STAT_STRENGTH] > 0) {
                shieldToGain += LibDungeon._int32ToUint256(_battleSimulation.player.stats[STAT_STRENGTH]) / 10 + 1;
            }
            if (_battleSimulation.player.stats[STAT_CONSTITUTION] > 0) {
                shieldToGain += LibDungeon._int32ToUint256(_battleSimulation.player.stats[STAT_CONSTITUTION]) / 5 + 1;
            }
          }
          (_battleSimulation, updatedMonster) = LibDungeon._dealPlayerDamageToMonster(_battleSimulation, _monster, _battleSimulation.targetIndex);
          _monster = updatedMonster;
        } else if (_battleSimulation.player.class == MowseDungeonClassEnum.BERSERKER) {
          if (_battleSimulation.actionType == MowseDungeonActionTypeEnum.SPECIAL_ABILITY) {
            // Berserker RAGE
            _battleSimulation.player.statusEffects.strengthen += 2;
            _battleSimulation.player.statusEffects.frail++;
            _battleSimulation.player.statusEffects.lastHope++;
            _battleSimulation.player.statusEffects.silence += 2;
            _battleSimulation = LibDungeon._addStatusEffectToBattleLogForPlayer(_battleSimulation, MowseDungeonBattleLogSourceEnum.STATUS_EFFECT_STRENGTHEN, 2);
            _battleSimulation = LibDungeon._addStatusEffectToBattleLogForPlayer(_battleSimulation, MowseDungeonBattleLogSourceEnum.STATUS_EFFECT_FRAIL, 1);
            _battleSimulation = LibDungeon._addStatusEffectToBattleLogForPlayer(_battleSimulation, MowseDungeonBattleLogSourceEnum.STATUS_EFFECT_LAST_HOPE, 1);
            _battleSimulation = LibDungeon._addStatusEffectToBattleLogForPlayer(_battleSimulation, MowseDungeonBattleLogSourceEnum.STATUS_EFFECT_SILENCE, 2);
          }
          (_battleSimulation, updatedMonster) = LibDungeon._dealPlayerDamageToMonster(_battleSimulation, _monster, _battleSimulation.targetIndex);
          _monster = updatedMonster;
        } else if (_battleSimulation.player.class == MowseDungeonClassEnum.CLERIC && _battleSimulation.actionType == MowseDungeonActionTypeEnum.SPECIAL_ABILITY) {
            // Cleric Heal
            // Heal based on intelligence & wisdom
            uint256 healthToRestore = _battleSimulation.player.attack;
            if (_battleSimulation.player.stats[STAT_INTELLIGENCE] > 0) {
                healthToRestore += LibDungeon._int32ToUint256(_battleSimulation.player.stats[STAT_INTELLIGENCE]) / 10 + 1;
            }
            if (_battleSimulation.player.stats[STAT_WISDOM] > 0) {
                healthToRestore += LibDungeon._int32ToUint256(_battleSimulation.player.stats[STAT_WISDOM]) / 5 + 1;
            }
            _battleSimulation = LibDungeon._addToBattleLog(_battleSimulation, MowseDungeonBattleLogTypeEnum.HEAL, MowseDungeonBattleLogSourceEnum.PLAYER, MowseDungeonBattleLogSourceEnum.PLAYER, healthToRestore);
            _battleSimulation.player.currentHealth += healthToRestore;
            // Make sure health doesn't exceed maxHealth
            if (_battleSimulation.player.currentHealth > _battleSimulation.player.maxHealth) {
                _battleSimulation.player.currentHealth = _battleSimulation.player.maxHealth;
            }
            _battleSimulation.achievementProgress.healthHealed += healthToRestore;
        } else if (_battleSimulation.player.class == MowseDungeonClassEnum.NECROMANCER) {
          if (_battleSimulation.actionType == MowseDungeonActionTypeEnum.SPECIAL_ABILITY) {
            // Necromancer Life tap
            // Deal damage to monster, if monster dies, then permanently gain attack
            (_battleSimulation, updatedMonster) = LibDungeon._dealPlayerDamageToMonster(_battleSimulation, _monster, _battleSimulation.targetIndex);
            if (updatedMonster.currentHealth == 0) {
              _battleSimulation.player.attack += _battleSimulation.player.attack / 10;
            }
          } else {
            (_battleSimulation, updatedMonster) = LibDungeon._dealPlayerDamageToMonster(_battleSimulation, _monster, _battleSimulation.targetIndex);
            // Life Steal on basic attack
            uint256 healthToRestore = _battleSimulation.player.attack / 10;
            if (_battleSimulation.player.stats[STAT_INTELLIGENCE] > 0) {
                healthToRestore += LibDungeon._int32ToUint256(_battleSimulation.player.stats[STAT_INTELLIGENCE]) / 10 + 1;
            }
            if (_battleSimulation.player.stats[STAT_WISDOM] > 0) {
                healthToRestore += LibDungeon._int32ToUint256(_battleSimulation.player.stats[STAT_WISDOM]) / 10 + 1;
            }
            _battleSimulation = LibDungeon._addToBattleLog(_battleSimulation, MowseDungeonBattleLogTypeEnum.HEAL, MowseDungeonBattleLogSourceEnum.PLAYER, MowseDungeonBattleLogSourceEnum.PLAYER, healthToRestore);
            _battleSimulation.player.currentHealth += healthToRestore;
            // Make sure health doesn't exceed maxHealth
            if (_battleSimulation.player.currentHealth > _battleSimulation.player.maxHealth) {
                _battleSimulation.player.currentHealth = _battleSimulation.player.maxHealth;
            }
            _battleSimulation.achievementProgress.healthHealed += healthToRestore;
            _monster = updatedMonster;
          }
        } else if (_battleSimulation.player.class == MowseDungeonClassEnum.BARD && _battleSimulation.actionType == MowseDungeonActionTypeEnum.SPECIAL_ABILITY) {
            // Bard CHARM all monsters
            _battleSimulation.player.tempAttack = _battleSimulation.player.attack;
            if (_battleSimulation.player.stats[STAT_CHARISMA] > 0) {
                _battleSimulation.player.tempAttack += LibDungeon._int32ToUint256(_battleSimulation.player.stats[STAT_CHARISMA]) / 5 + 1;
            }
            // Deal damage to all monsters
            if (_battleSimulation.monster1.currentHealth > 0) {
              (_battleSimulation, updatedMonster) = LibDungeon._dealPlayerDamageToMonster(_battleSimulation, _battleSimulation.monster1, 0);
              _battleSimulation = LibDungeon._addToBattleLogForMonsterIndex(_battleSimulation, 0, MowseDungeonBattleLogTypeEnum.APPLY_STATUS_EFFECT, MowseDungeonBattleLogSourceEnum.STATUS_EFFECT_CHARM, 2);    
              updatedMonster.statusEffects.charm += 2;
              _battleSimulation.monster1 = updatedMonster;
              if (_battleSimulation.targetIndex == 0) {
                _monster = updatedMonster;
              }
            }
            if (_battleSimulation.monster2.currentHealth > 0) {
              (_battleSimulation, updatedMonster) = LibDungeon._dealPlayerDamageToMonster(_battleSimulation, _battleSimulation.monster2, 1);
              _battleSimulation = LibDungeon._addToBattleLogForMonsterIndex(_battleSimulation, 1, MowseDungeonBattleLogTypeEnum.APPLY_STATUS_EFFECT, MowseDungeonBattleLogSourceEnum.STATUS_EFFECT_CHARM, 2);    
              updatedMonster.statusEffects.charm += 2;
              _battleSimulation.monster2 = updatedMonster;
              if (_battleSimulation.targetIndex == 1) {
                _monster = updatedMonster;
              }
            }
            if (_battleSimulation.monster3.currentHealth > 0) {
              (_battleSimulation, updatedMonster) = LibDungeon._dealPlayerDamageToMonster(_battleSimulation, _battleSimulation.monster3, 2);
              _battleSimulation = LibDungeon._addToBattleLogForMonsterIndex(_battleSimulation, 2, MowseDungeonBattleLogTypeEnum.APPLY_STATUS_EFFECT, MowseDungeonBattleLogSourceEnum.STATUS_EFFECT_CHARM, 2);    
              updatedMonster.statusEffects.charm += 2;
              _battleSimulation.monster3 = updatedMonster;
              if (_battleSimulation.targetIndex == 2) {
                _monster = updatedMonster;
              }
            }
        } else {
            // Default
            (_battleSimulation, updatedMonster) = LibDungeon._dealPlayerDamageToMonster(_battleSimulation, _monster, _battleSimulation.targetIndex);
            _monster = updatedMonster;
        }

        return (_battleSimulation, _monster);
    }

    function _classBasicAttackRatio(MowseDungeonClassEnum _class) internal pure returns (uint256) {
        if (_class == MowseDungeonClassEnum.WARRIOR) {
            return 100;
        } else if (_class == MowseDungeonClassEnum.MAGE) {
            return 60;
        } else if (_class == MowseDungeonClassEnum.ARCHER) {
            return 80;
        } else if (_class == MowseDungeonClassEnum.ROGUE) {
            return 50;
        } else if (_class == MowseDungeonClassEnum.PALADIN) {
            return 70;
        } else if (_class == MowseDungeonClassEnum.GUARDIAN) {
            return 50;
        } else if (_class == MowseDungeonClassEnum.BERSERKER) {
            return 120;
        } else if (_class == MowseDungeonClassEnum.CLERIC) {
            return 40;
        } else if (_class == MowseDungeonClassEnum.NECROMANCER) {
            return 55;
        } else if (_class == MowseDungeonClassEnum.BARD) {
            return 60;
        } else {
            return 50;
        }
    }
}

File 2 of 10 : Math.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1, "Math: mulDiv overflow");

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10 ** 64) {
                value /= 10 ** 64;
                result += 64;
            }
            if (value >= 10 ** 32) {
                value /= 10 ** 32;
                result += 32;
            }
            if (value >= 10 ** 16) {
                value /= 10 ** 16;
                result += 16;
            }
            if (value >= 10 ** 8) {
                value /= 10 ** 8;
                result += 8;
            }
            if (value >= 10 ** 4) {
                value /= 10 ** 4;
                result += 4;
            }
            if (value >= 10 ** 2) {
                value /= 10 ** 2;
                result += 2;
            }
            if (value >= 10 ** 1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
        }
    }
}

File 3 of 10 : SignedMath.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard signed math utilities missing in the Solidity language.
 */
library SignedMath {
    /**
     * @dev Returns the largest of two signed numbers.
     */
    function max(int256 a, int256 b) internal pure returns (int256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two signed numbers.
     */
    function min(int256 a, int256 b) internal pure returns (int256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two signed numbers without overflow.
     * The result is rounded towards zero.
     */
    function average(int256 a, int256 b) internal pure returns (int256) {
        // Formula from the book "Hacker's Delight"
        int256 x = (a & b) + ((a ^ b) >> 1);
        return x + (int256(uint256(x) >> 255) & (a ^ b));
    }

    /**
     * @dev Returns the absolute unsigned value of a signed value.
     */
    function abs(int256 n) internal pure returns (uint256) {
        unchecked {
            // must be unchecked in order to support `n = type(int256).min`
            return uint256(n >= 0 ? n : -n);
        }
    }
}

File 4 of 10 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

import "./math/Math.sol";
import "./math/SignedMath.sol";

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _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) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `int256` to its ASCII `string` decimal representation.
     */
    function toString(int256 value) internal pure returns (string memory) {
        return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value))));
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

    /**
     * @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] = _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);
    }

    /**
     * @dev Returns true if the two strings are equal.
     */
    function equal(string memory a, string memory b) internal pure returns (bool) {
        return keccak256(bytes(a)) == keccak256(bytes(b));
    }
}

File 5 of 10 : IDiamondCut.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/******************************************************************************\
* Author: Nick Mudge <[email protected]> (https://twitter.com/mudgen)
* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535
/******************************************************************************/

interface IDiamondCut {
    enum FacetCutAction {Add, Replace, Remove}
    // Add=0, Replace=1, Remove=2

    struct FacetCut {
        address facetAddress;
        FacetCutAction action;
        bytes4[] functionSelectors;
    }

    /// @notice Add/replace/remove any number of functions and optionally execute
    ///         a function with delegatecall
    /// @param _diamondCut Contains the facet addresses and function selectors
    /// @param _init The address of the contract or facet to execute _calldata
    /// @param _calldata A function call, including function selector and arguments
    ///                  _calldata is executed with delegatecall on _init
    function diamondCut(
        FacetCut[] calldata _diamondCut,
        address _init,
        bytes calldata _calldata
    ) external;

    event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);
}

File 6 of 10 : Base64.sol
// SPDX-License-Identifier: MIT

// Credit https://github.com/derekchiang/loot-name/blob/main/contracts/LootName.sol

pragma solidity ^0.8.12;

/// [MIT License]
/// @title Base64
/// @notice Provides a function for encoding some bytes in base64
/// @author Brecht Devos <[email protected]>
library Base64 {
    bytes internal constant TABLE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';

    /// @notice Encodes some bytes to the base64 representation
    function encode(bytes memory data) internal pure returns (string memory) {
        uint256 len = data.length;
        if (len == 0) return '';

        // multiply by 4/3 rounded up
        uint256 encodedLen = 4 * ((len + 2) / 3);

        // Add some extra buffer at the end
        bytes memory result = new bytes(encodedLen + 32);

        bytes memory table = TABLE;

        assembly {
            let tablePtr := add(table, 1)
            let resultPtr := add(result, 32)

            for {
                let i := 0
            } lt(i, len) {

            } {
                i := add(i, 3)
                let input := and(mload(add(data, i)), 0xffffff)

                let out := mload(add(tablePtr, and(shr(18, input), 0x3F)))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(input, 0x3F))), 0xFF))
                out := shl(224, out)

                mstore(resultPtr, out)

                resultPtr := add(resultPtr, 4)
            }

            switch mod(len, 3)
            case 1 {
                mstore(sub(resultPtr, 2), shl(240, 0x3d3d))
            }
            case 2 {
                mstore(sub(resultPtr, 1), shl(248, 0x3d))
            }

            mstore(result, encodedLen)
        }

        return string(result);
    }
}

File 7 of 10 : LibDiamond.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/******************************************************************************\
* Author: Nick Mudge <[email protected]> (https://twitter.com/mudgen)
* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535
/******************************************************************************/
import { IDiamondCut } from "../interfaces/IDiamondCut.sol";

// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.
// The loupe functions are required by the EIP2535 Diamonds standard

error InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);

library LibDiamond {
    bytes32 constant DIAMOND_STORAGE_POSITION = keccak256("diamond.standard.diamond.storage");

    struct FacetAddressAndPosition {
        address facetAddress;
        uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array
    }

    struct FacetFunctionSelectors {
        bytes4[] functionSelectors;
        uint256 facetAddressPosition; // position of facetAddress in facetAddresses array
    }

    struct DiamondStorage {
        // maps function selector to the facet address and
        // the position of the selector in the facetFunctionSelectors.selectors array
        mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;
        // maps facet addresses to function selectors
        mapping(address => FacetFunctionSelectors) facetFunctionSelectors;
        // facet addresses
        address[] facetAddresses;
        // Used to query if a contract implements an interface.
        // Used to implement ERC-165.
        mapping(bytes4 => bool) supportedInterfaces;
        // owner of the contract
        address contractOwner;
    }

    function diamondStorage() internal pure returns (DiamondStorage storage ds) {
        bytes32 position = DIAMOND_STORAGE_POSITION;
        assembly {
            ds.slot := position
        }
    }

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

    function setContractOwner(address _newOwner) internal {
        DiamondStorage storage ds = diamondStorage();
        address previousOwner = ds.contractOwner;
        ds.contractOwner = _newOwner;
        emit OwnershipTransferred(previousOwner, _newOwner);
    }

    function contractOwner() internal view returns (address contractOwner_) {
        contractOwner_ = diamondStorage().contractOwner;
    }

    function enforceIsContractOwner() internal view {
        require(msg.sender == diamondStorage().contractOwner, "LibDiamond: Must be contract owner");
    }

    event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);

    // Internal function version of diamondCut
    function diamondCut(
        IDiamondCut.FacetCut[] memory _diamondCut,
        address _init,
        bytes memory _calldata
    ) internal {
        for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {
            IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;
            if (action == IDiamondCut.FacetCutAction.Add) {
                addFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);
            } else if (action == IDiamondCut.FacetCutAction.Replace) {
                replaceFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);
            } else if (action == IDiamondCut.FacetCutAction.Remove) {
                removeFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);
            } else {
                revert("LibDiamondCut: Incorrect FacetCutAction");
            }
        }
        emit DiamondCut(_diamondCut, _init, _calldata);
        initializeDiamondCut(_init, _calldata);
    }

    function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
        require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
        DiamondStorage storage ds = diamondStorage();        
        require(_facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)");
        uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);
        // add new facet address if it does not exist
        if (selectorPosition == 0) {
            addFacet(ds, _facetAddress);            
        }
        for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
            bytes4 selector = _functionSelectors[selectorIndex];
            address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;
            require(oldFacetAddress == address(0), "LibDiamondCut: Can't add function that already exists");
            addFunction(ds, selector, selectorPosition, _facetAddress);
            selectorPosition++;
        }
    }

    function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
        require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
        DiamondStorage storage ds = diamondStorage();
        require(_facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)");
        uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);
        // add new facet address if it does not exist
        if (selectorPosition == 0) {
            addFacet(ds, _facetAddress);
        }
        for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
            bytes4 selector = _functionSelectors[selectorIndex];
            address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;
            require(oldFacetAddress != _facetAddress, "LibDiamondCut: Can't replace function with same function");
            removeFunction(ds, oldFacetAddress, selector);
            addFunction(ds, selector, selectorPosition, _facetAddress);
            selectorPosition++;
        }
    }

    function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
        require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
        DiamondStorage storage ds = diamondStorage();
        // if function does not exist then do nothing and return
        require(_facetAddress == address(0), "LibDiamondCut: Remove facet address must be address(0)");
        for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
            bytes4 selector = _functionSelectors[selectorIndex];
            address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;
            removeFunction(ds, oldFacetAddress, selector);
        }
    }

    function addFacet(DiamondStorage storage ds, address _facetAddress) internal {
        enforceHasContractCode(_facetAddress, "LibDiamondCut: New facet has no code");
        ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;
        ds.facetAddresses.push(_facetAddress);
    }    


    function addFunction(DiamondStorage storage ds, bytes4 _selector, uint96 _selectorPosition, address _facetAddress) internal {
        ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;
        ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);
        ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;
    }

    function removeFunction(DiamondStorage storage ds, address _facetAddress, bytes4 _selector) internal {        
        require(_facetAddress != address(0), "LibDiamondCut: Can't remove function that doesn't exist");
        // an immutable function is a function defined directly in a diamond
        require(_facetAddress != address(this), "LibDiamondCut: Can't remove immutable function");
        // replace selector with last selector, then delete last selector
        uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;
        uint256 lastSelectorPosition = ds.facetFunctionSelectors[_facetAddress].functionSelectors.length - 1;
        // if not the same then replace _selector with lastSelector
        if (selectorPosition != lastSelectorPosition) {
            bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[lastSelectorPosition];
            ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;
            ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(selectorPosition);
        }
        // delete the last selector
        ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();
        delete ds.selectorToFacetAndPosition[_selector];

        // if no more selectors for facet address then delete the facet address
        if (lastSelectorPosition == 0) {
            // replace facet address with last facet address and delete last facet address
            uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;
            uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;
            if (facetAddressPosition != lastFacetAddressPosition) {
                address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];
                ds.facetAddresses[facetAddressPosition] = lastFacetAddress;
                ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;
            }
            ds.facetAddresses.pop();
            delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;
        }
    }

    function initializeDiamondCut(address _init, bytes memory _calldata) internal {
        if (_init == address(0)) {
            return;
        }
        enforceHasContractCode(_init, "LibDiamondCut: _init address has no code");        
        (bool success, bytes memory error) = _init.delegatecall(_calldata);
        if (!success) {
            if (error.length > 0) {
                // bubble up error
                /// @solidity memory-safe-assembly
                assembly {
                    let returndata_size := mload(error)
                    revert(add(32, error), returndata_size)
                }
            } else {
                revert InitializationFunctionReverted(_init, _calldata);
            }
        }
    }

    function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {
        uint256 contractSize;
        assembly {
            contractSize := extcodesize(_contract)
        }
        require(contractSize > 0, _errorMessage);
    }
}

File 8 of 10 : LibDungeon.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;
import "hardhat/console.sol";
import {
    MowseDungeonSimplePlayer, 
    MowseDungeonSimpleMonster, 
    MowseDungeonBattleSimulation, 
    MowseDungeonBattleLog, 
    MowseDungeonBattleLogTypeEnum, 
    MowseDungeonBattleLogSourceEnum
} from "../libraries/LibStorage.sol";

library LibDungeon {
    function _int32ToUint256(int32 _stat) internal pure returns (uint256) {
        return uint256(int256(_stat));
    }
    function getNewSeed(uint256 seed, uint256 newSeed) internal pure returns (uint256) {
        return uint256(keccak256(abi.encodePacked(seed, newSeed)));
    }
    function updateNewSeed(uint256 seed, uint256 newSeed) internal pure returns (uint256) {
        if (newSeed >> 2 == 0) {
            newSeed = getNewSeed(seed, newSeed);
        } else {
            newSeed >>= 2;
        }
        return newSeed;
    }

    function _damageShieldAndHealth(uint256 _damage, uint256 _enemyHealth, uint256 _enemyShield) internal pure returns (uint256, uint256) {
        if (_damage > _enemyShield) {
            if (_damage - _enemyShield > _enemyHealth) {
                _enemyHealth = 0;
            } else {
                _enemyHealth = _enemyHealth - (_damage - _enemyShield);
            }
            _enemyShield = 0;
        } else {
            _enemyShield = _enemyShield - _damage;
        }
        return (_enemyHealth, _enemyShield);
    }
    // For true damage/pierce attacks
    function _damageHealth(uint256 _damage, uint256 _enemyHealth) internal pure returns (uint256) {
        if (_damage > _enemyHealth) {
            return 0;
        } else {
            return _enemyHealth - _damage;
        }
    }
    function _checkPlayerRevive(MowseDungeonSimplePlayer memory _player) internal pure returns (MowseDungeonSimplePlayer memory) {
        // Check if player has died
        if (_player.currentHealth == 0) {
            // Revive
            if (_player.statusEffects.revive > 0) {
                _player.currentHealth = _player.maxHealth;
                _player.statusEffects.revive = 0;
            }
            // LAST_HOPE
            if (_player.statusEffects.lastHope > 0) {
                _player.currentHealth = 1;
                _player.statusEffects.lastHope = 0;
            }
        }
        return _player;
    }

    function _checkMonsterRevive(MowseDungeonSimpleMonster memory _monster) internal pure returns (MowseDungeonSimpleMonster memory) {
        // Check if monster has died
        if (_monster.currentHealth == 0) {
            // Revive
            if (_monster.statusEffects.revive > 0) {
                _monster.currentHealth = _monster.maxHealth;
                _monster.statusEffects.revive = 0;
            }
            // LAST_HOPE
            if (_monster.statusEffects.lastHope > 0) {
                _monster.currentHealth = 1;
                _monster.statusEffects.lastHope = 0;
            }
        }
        return _monster;
    }

function _applyStatusEffectsFromTrinketsToMonster(
        MowseDungeonBattleSimulation memory _battleSimulation,
        MowseDungeonSimpleMonster memory _monster,
        uint256 _monsterIndex
    ) internal pure returns (MowseDungeonBattleSimulation memory, MowseDungeonSimpleMonster memory) {
        if (_battleSimulation.player.trinkets.poisonDab > 0) {
            if (_monster.statusEffects.poisonResist == 0) {
                _monster.statusEffects.poison += _battleSimulation.player.trinkets.poisonDab * (_battleSimulation.player.statusEffects.doubleUp + 1);
                _battleSimulation = _addToBattleLogForMonsterIndex(_battleSimulation, _monsterIndex, MowseDungeonBattleLogTypeEnum.APPLY_STATUS_EFFECT, MowseDungeonBattleLogSourceEnum.STATUS_EFFECT_POISON, _battleSimulation.player.trinkets.poisonDab * (_battleSimulation.player.statusEffects.doubleUp + 1));
            }
        }
        if (_battleSimulation.player.trinkets.kindle > 0) {
            if (_monster.statusEffects.fireResist == 0) {
                _monster.statusEffects.burn += _battleSimulation.player.trinkets.kindle * (_battleSimulation.player.statusEffects.doubleUp + 1);
                _battleSimulation = _addToBattleLogForMonsterIndex(_battleSimulation, _monsterIndex, MowseDungeonBattleLogTypeEnum.APPLY_STATUS_EFFECT, MowseDungeonBattleLogSourceEnum.STATUS_EFFECT_BURN, _battleSimulation.player.trinkets.kindle * (_battleSimulation.player.statusEffects.doubleUp + 1));
            }
        }
        if (_battleSimulation.player.trinkets.bloodLetter > 0) {
            _monster.statusEffects.bleed += _battleSimulation.player.trinkets.bloodLetter * (_battleSimulation.player.statusEffects.doubleUp + 1);
            _battleSimulation = _addToBattleLogForMonsterIndex(_battleSimulation, _monsterIndex, MowseDungeonBattleLogTypeEnum.APPLY_STATUS_EFFECT, MowseDungeonBattleLogSourceEnum.STATUS_EFFECT_BLEED, _battleSimulation.player.trinkets.bloodLetter * (_battleSimulation.player.statusEffects.doubleUp + 1));
        }
        if (_battleSimulation.player.trinkets.cursedRing > 0) {
            _monster.statusEffects.curse += _battleSimulation.player.trinkets.cursedRing * (_battleSimulation.player.statusEffects.doubleUp + 1);
            _battleSimulation = _addToBattleLogForMonsterIndex(_battleSimulation, _monsterIndex, MowseDungeonBattleLogTypeEnum.APPLY_STATUS_EFFECT, MowseDungeonBattleLogSourceEnum.STATUS_EFFECT_CURSE, _battleSimulation.player.trinkets.cursedRing * (_battleSimulation.player.statusEffects.doubleUp + 1));
        }
        if (_battleSimulation.player.trinkets.stunRod > 0) {
            if (_monster.statusEffects.stunResist == 0 && _monster.statusEffects.unstoppable == 0 && _monster.isBoss == false) {
                _battleSimulation.seed = updateNewSeed(_battleSimulation.dungeonId, _battleSimulation.seed);
                if (_battleSimulation.seed % 100 < 20 + _battleSimulation.player.trinkets.stunRod * 20) {
                    _monster.statusEffects.stun++;
                    _battleSimulation = _addToBattleLogForMonsterIndex(_battleSimulation, _monsterIndex, MowseDungeonBattleLogTypeEnum.APPLY_STATUS_EFFECT, MowseDungeonBattleLogSourceEnum.STATUS_EFFECT_STUN, 1);
                }
            }
        }
        if (_battleSimulation.player.trinkets.silenceBell > 0) {
            if (_monster.statusEffects.unstoppable == 0 && _monster.isBoss == false) {
                _battleSimulation.seed = updateNewSeed(_battleSimulation.dungeonId, _battleSimulation.seed);
                if (_battleSimulation.seed % 100 < 20 + _battleSimulation.player.trinkets.silenceBell * 20) {
                    _monster.statusEffects.silence++;
                    _battleSimulation = _addToBattleLogForMonsterIndex(_battleSimulation, _monsterIndex, MowseDungeonBattleLogTypeEnum.APPLY_STATUS_EFFECT, MowseDungeonBattleLogSourceEnum.STATUS_EFFECT_SILENCE, 1);
                }
            }
        }
        if (_battleSimulation.player.trinkets.strengthBelt > 0) {
            _battleSimulation.player.statusEffects.strengthen +=
                _battleSimulation.player.trinkets.strengthBelt *
                (_battleSimulation.player.statusEffects.doubleUp + 1);
                _battleSimulation = _addToBattleLogForMonsterIndex(_battleSimulation, _monsterIndex, MowseDungeonBattleLogTypeEnum.APPLY_STATUS_EFFECT, MowseDungeonBattleLogSourceEnum.STATUS_EFFECT_STRENGTHEN, _battleSimulation.player.trinkets.strengthBelt * (_battleSimulation.player.statusEffects.doubleUp + 1));
        }
        if (_battleSimulation.player.trinkets.weakenedChain > 0) {
            _monster.statusEffects.weaken += _battleSimulation.player.trinkets.weakenedChain * (_battleSimulation.player.statusEffects.doubleUp + 1);
            _battleSimulation = _addToBattleLogForMonsterIndex(_battleSimulation, _monsterIndex, MowseDungeonBattleLogTypeEnum.APPLY_STATUS_EFFECT, MowseDungeonBattleLogSourceEnum.STATUS_EFFECT_WEAKEN, _battleSimulation.player.trinkets.weakenedChain * (_battleSimulation.player.statusEffects.doubleUp + 1));
        }
        if (_battleSimulation.player.trinkets.leech > 0) {
            _battleSimulation.player.currentHealth +=
                ((_battleSimulation.player.tempAttack * (10 * _battleSimulation.player.trinkets.leech)) / 100) *
                (_battleSimulation.player.statusEffects.doubleUp + 1);
            _battleSimulation = _addToBattleLog(_battleSimulation, MowseDungeonBattleLogTypeEnum.HEAL, MowseDungeonBattleLogSourceEnum.TRINKET_LEECH, MowseDungeonBattleLogSourceEnum.PLAYER, ((_battleSimulation.player.tempAttack * (10 * _battleSimulation.player.trinkets.leech)) / 100) * (_battleSimulation.player.statusEffects.doubleUp + 1));

            // Make sure health doesn't exceed maxHealth
            if (_battleSimulation.player.currentHealth > _battleSimulation.player.maxHealth) {
                _battleSimulation.player.currentHealth = _battleSimulation.player.maxHealth;
            }
            _battleSimulation.achievementProgress.healthHealed +=
                ((_battleSimulation.player.tempAttack * (10 * _battleSimulation.player.trinkets.leech)) / 100) *
                (_battleSimulation.player.statusEffects.doubleUp + 1);
        }

        return (_battleSimulation, _monster);
    }
    function _monsterRetaliate(
        MowseDungeonBattleSimulation memory _battleSimulation,
        MowseDungeonSimpleMonster memory _monster,
        uint256 _monsterIndex
    ) internal pure returns (MowseDungeonBattleSimulation memory) {
        if (_monster.statusEffects.counter > 0) {
            (_battleSimulation.player.currentHealth, _battleSimulation.player.shield) = _damageShieldAndHealth(
                _monster.attack,
                _battleSimulation.player.currentHealth,
                _battleSimulation.player.shield
            );
            _battleSimulation.achievementProgress.damageTaken += _monster.attack;
            _battleSimulation = _addToBattleLogForPlayerFromMonsterIndex(_battleSimulation, _monsterIndex, MowseDungeonBattleLogTypeEnum.DAMAGE, _monster.attack);
            _battleSimulation.player = _checkPlayerRevive(_battleSimulation.player);
        }
        if (_monster.statusEffects.thorns > 0) {
            (_battleSimulation.player.currentHealth, _battleSimulation.player.shield) = _damageShieldAndHealth(
                5 * _monster.statusEffects.thorns,
                _battleSimulation.player.currentHealth,
                _battleSimulation.player.shield
            );
            _battleSimulation.achievementProgress.damageTaken += 5 * _monster.statusEffects.thorns;
            _battleSimulation = _addToBattleLog(_battleSimulation, MowseDungeonBattleLogTypeEnum.DAMAGE, MowseDungeonBattleLogSourceEnum.STATUS_EFFECT_THORNS, MowseDungeonBattleLogSourceEnum.PLAYER, 5 * _monster.statusEffects.thorns);
            _battleSimulation.player = _checkPlayerRevive(_battleSimulation.player);
        }
        if (_monster.statusEffects.wrathfulReprisal > 0) {
            (_battleSimulation.player.currentHealth, _battleSimulation.player.shield) = _damageShieldAndHealth(
                _battleSimulation.player.attack,
                _battleSimulation.player.currentHealth,
                _battleSimulation.player.shield
            );
            _battleSimulation = _addToBattleLog(_battleSimulation, MowseDungeonBattleLogTypeEnum.DAMAGE, MowseDungeonBattleLogSourceEnum.STATUS_EFFECT_WRATHFUL_REPRISAL, MowseDungeonBattleLogSourceEnum.PLAYER, _battleSimulation.player.attack);
            _battleSimulation.achievementProgress.damageTaken += _battleSimulation.player.attack;
            _battleSimulation.player = _checkPlayerRevive(_battleSimulation.player);
        }
        return _battleSimulation;
    }
    function _dealPlayerDamageToMonster(MowseDungeonBattleSimulation memory _battleSimulation, MowseDungeonSimpleMonster memory _monster, uint256 _monsterIndex) internal pure returns (MowseDungeonBattleSimulation memory, MowseDungeonSimpleMonster memory) {
        if (_monster.statusEffects.invincible == 0) {
            if (_battleSimulation.player.statusEffects.pierce > 0) {
                _monster.currentHealth = _damageHealth(_battleSimulation.player.tempAttack, _monster.currentHealth);
            } else {
                (_monster.currentHealth, _monster.shield) = _damageShieldAndHealth(
                    _battleSimulation.player.tempAttack,
                    _monster.currentHealth,
                    _monster.shield
                );
            }
            _battleSimulation = _addToBattleLogForMonsterIndex(_battleSimulation, _monsterIndex, MowseDungeonBattleLogTypeEnum.DAMAGE, MowseDungeonBattleLogSourceEnum.PLAYER, _battleSimulation.player.tempAttack);
            _battleSimulation.achievementProgress.damageDealt += _battleSimulation.player.tempAttack;
            _monster = _checkMonsterRevive(_monster);
        }
        (_battleSimulation, _monster) = _applyStatusEffectsFromTrinketsToMonster(_battleSimulation, _monster, _monsterIndex);
        if (_monster.currentHealth > 0) {
            _battleSimulation = _monsterRetaliate(_battleSimulation, _monster, _monsterIndex);
        }
        return (_battleSimulation, _monster);
    }

    function _addToBattleLogForMonsterIndex(MowseDungeonBattleSimulation memory _battleSimulation, uint256 _monsterIndex, MowseDungeonBattleLogTypeEnum _logType, MowseDungeonBattleLogSourceEnum _source, uint256 _amount) internal pure returns (MowseDungeonBattleSimulation memory) {
        if (_monsterIndex == 0) {
            _battleSimulation = _addToBattleLog(_battleSimulation, _logType, _source, MowseDungeonBattleLogSourceEnum.MONSTER_1, _amount);
        } else if (_monsterIndex == 1) {
            _battleSimulation = _addToBattleLog(_battleSimulation, _logType, _source, MowseDungeonBattleLogSourceEnum.MONSTER_2, _amount);
        } else {
            _battleSimulation = _addToBattleLog(_battleSimulation, _logType, _source, MowseDungeonBattleLogSourceEnum.MONSTER_3, _amount);
        }
        return _battleSimulation;
    }
    function _addToBattleLogForPlayerFromMonsterIndex(MowseDungeonBattleSimulation memory _battleSimulation, uint256 _monsterIndex, MowseDungeonBattleLogTypeEnum _logType, uint256 _amount) internal pure returns (MowseDungeonBattleSimulation memory) {
        if (_monsterIndex == 0) {
            _battleSimulation = _addToBattleLog(_battleSimulation, _logType, MowseDungeonBattleLogSourceEnum.MONSTER_1, MowseDungeonBattleLogSourceEnum.PLAYER, _amount);
        } else if (_monsterIndex == 1) {
            _battleSimulation = _addToBattleLog(_battleSimulation, _logType, MowseDungeonBattleLogSourceEnum.MONSTER_2, MowseDungeonBattleLogSourceEnum.PLAYER, _amount);
        } else {
            _battleSimulation = _addToBattleLog(_battleSimulation, _logType, MowseDungeonBattleLogSourceEnum.MONSTER_3, MowseDungeonBattleLogSourceEnum.PLAYER, _amount);
        }
        return _battleSimulation;
    }
    function _addStatusEffectToBattleLogForPlayer(MowseDungeonBattleSimulation memory _battleSimulation, MowseDungeonBattleLogSourceEnum _source, uint256 _amount) internal pure returns (MowseDungeonBattleSimulation memory) {
        _battleSimulation = _addToBattleLog(_battleSimulation, MowseDungeonBattleLogTypeEnum.APPLY_STATUS_EFFECT, _source, MowseDungeonBattleLogSourceEnum.PLAYER, _amount);
        return _battleSimulation;
    }
    function _addToBattleLog(MowseDungeonBattleSimulation memory _battleSimulation, MowseDungeonBattleLogTypeEnum _logType, MowseDungeonBattleLogSourceEnum _source, MowseDungeonBattleLogSourceEnum _target, uint256 _amount) internal pure returns (MowseDungeonBattleSimulation memory) {
        if (_battleSimulation.battleLogCount >= 100) return _battleSimulation;
        _battleSimulation.battleLog[_battleSimulation.battleLogCount++] = (MowseDungeonBattleLog({logType: _logType, source: _source, target: _target, amount: _amount}));
        return _battleSimulation;
    }
}

File 9 of 10 : LibStorage.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

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

uint256 constant SKILL_TYPE_NUM = 7;
uint256 constant STAT_CHARISMA = 0;
uint256 constant STAT_CONSTITUTION = 1;
uint256 constant STAT_DEXTERITY = 2;
uint256 constant STAT_INTELLIGENCE = 3;
uint256 constant STAT_LUCK = 4;
uint256 constant STAT_STRENGTH = 5;
uint256 constant STAT_WISDOM = 6;
uint256 constant EQUIPPED_WEARABLE_SLOTS = 12;
bytes32 constant MOWSE_ADMIN_ROLE = keccak256('MOWSE_ADMIN_ROLE');
bytes32 constant MOWSEWEAR_MINTER_ROLE = keccak256('MOWSEWEAR_MINTER_ROLE');
bytes32 constant MOWSE_MINTER_ROLE = keccak256('MOWSE_MINTER_ROLE');
bytes32 constant MOWSEWEAR_ADMIN_ROLE = keccak256('MOWSEWEAR_ADMIN_ROLE');
bytes32 constant MOWSEGAME_ADMIN_ROLE = keccak256('MOWSEGAME_ADMIN_ROLE');
bytes32 constant MOWSEBANK_CREATE2_SALT = keccak256('MOWSEBANK_CREATE2_SALT');
bytes32 constant MOWSELOOTBOX_MINTER_ROLE = keccak256('MOWSELOOTBOX_MINTER_ROLE');
bytes32 constant MOWSEJOB_ADMIN_ROLE = keccak256('MOWSEJOB_ADMIN_ROLE');

struct GameStorage {
  address diamondAddress;
  address mowseAvatarContractAddress;
  address mowseGoldContractAddress;
  address mowseBankContractAddress;
  address mowseLootboxContractAddress;

  bool paused;
  // Mowse = id > 10,000
  uint256 mowseMintPrice;
  uint256 mowseTokenIdCounter; // Current tokenId of Mowse for minting purposes
  uint256 mowseWearTotalCount;  // Total Count of MowseWear minted
  uint256 mowseWearTokenIdCounter; // Current tokenId of MowseWear for minting purposes
  mapping(address => bool) isMowse; // maps Mowse address to bool if it is a mowse address or not
  mapping(address => uint256) mainMowse; // map address to mowseTokenId
  mapping(uint256 => Mowse) mowses; // map mowseAvatar tokenId to Mowse struct
  mapping(uint256 => MowseWear) mowsewears; // map mowsewear tokenId to MowseWear struct
  // mapping(uint256 => MowseLineage) mowselineages;
  mapping(uint8 => mapping(uint16 => MowseWearMetadata)) mowseWearDictionary; // map equippable wearable slot index to dictionary index to get unique mowsewear
  mapping(uint256 => MowseWearMetadata) mowseWearDictionaryByDictionaryIndex; // map dictionary index to mowsewear (for lootbox)
  uint256 mowseWearDictionaryCount; // Counts how many items are in the mowseWearDictionary (for lootbox)
  uint16[EQUIPPED_WEARABLE_SLOTS] mowseWearDictionaryTraitCount; // count of each trait (11 shirts, 10 eyeWear, etc), used for incrementing next traitIndex
  mapping(uint8 => mapping(uint16 => uint256)) mowseWearCountByTraitIndex;  // Counts how many mowsewear are minted per traitIndex (3 Blue Headbands)
  mapping(uint8 => uint256) mowseWearCountByTraitType;  // Counts how many shirts were minted
  mapping(uint16 => string) possibleTraitTypes; // mapping of all possible traitTypes to strings
  string[] initTraitNames;  // used in DiamondInit

  // MowseWear
  uint256 mowseWearHemPrice;

  // Initial merkel MGOLD aidrop
  // mapping(address => uint256) initialMowseGoldClaimList;  // Used for merkel airdrop

  // MowseLootbox
  // lootbox index is the loot pool index; [0-11] are trait type specific, [12] is general pool, 13+ are any other specific pools (weekly chests or seasonal chests)
  mapping(uint64 => MowseLootboxPool) mowselootboxes;  // map lootbox index (traitType + a few more) to MowseLootbox
  // count of current lootbox index
  uint64 mowseLootboxIndexCount;
  // Current tokenId of MowseLootbox for minting purposes
  uint256 mowseLootboxTokenIdCounter;
  // map tokenId to LootboxIndex to get the lootbox data
  mapping(uint256 => uint64) mowseLootboxIndexByTokenId;
  // large prime used for VDF
  uint256 mowseLootboxPrime;
  // iterations for VDF
  uint256 mowseLootboxIterations;
  // nonce for VDF
  uint256 mowseLootboxNonce;
  // mapping to get seed from tokenId if minted through mowseLootbox
  mapping(uint256 => uint256) mowseLootboxTokenIdToSeed;

  // random seed for pseudo-rng
  uint256 mowsePrngSeed;
  uint256 mowseJobPrngSeed;
  uint256 mowseWearPrngSeed;
  uint256 prngNonce;
  
  // DonationTree
  uint256 totalWishCount;
  uint256 donationTreePrime;
  uint256 donationTreeIterations;
  uint256 donationTreeNonce;
  mapping(uint256 => uint256) donationTreeWishCountToSeed;
  mapping(uint256 => uint256) mowseNextWish;
  mapping(address => uint256) nextWish;
  mapping(address => uint256) wishCount;

  // MowseGame
  mapping(uint256 => MowseGames) mowsegames;
  uint256 mowseGamesCount;
  uint256 activeMowseGamesCount;  // Needed 
  mapping(string => uint256) getMowseGameByName;
  uint8 maxFreeGameSubmits;
  // Normal base token payout
  uint256 baseGamePayout;
  // Pay for users' gas but it ain't free yo. After x number of submits, purchase MowseGold to continue forever
  mapping(address => uint256) freeMowseGameSubmits;
  mapping(address => bool) hasPurchasedMowseGold;
  // For suspicious gaming activity, temporary ban
  mapping(address => bool) mowseGameUserBanned;

  // MowseBank and MowseWallet
  address mowseBankWalletImplementation;
  mapping(address => uint256) mowseBankBalances;
  mapping(address => uint256) mowseBankTokenIdForWallet;

  // Withdrawal
  address payable devRoyaltyAddress;
  address payable teamAddress;
  address payable backendAddress;
  address payable treasuryAddress;
  uint256 devRoyaltyTaxBasisPoints;
  uint256 teamTaxBasisPoints;
  uint256 backendTaxBasisPoints;
  uint256 developerTaxBasisPoints;

  // For testnet purposes and rewarding testers
  uint256 testPatchCount;
  mapping(uint256 => TestPatch) testPatches;  // Maps patchVersion to testPatch  

  // GatherAndGarnishFacet
  uint256 gatherGarnishPrngSeed;
  uint256 gatherGarnishSeasonStart;
  uint256 gatherGarnishSeasonEnd;
  uint256 gatherGarnishSeasonCount;
  // Maps season count -> season reward (mowse wear dictionary index)
  mapping(uint256 => uint256) gatherGarnishSeasonReward;  // MowseWearDictionaryIndex
  // Maps player address -> season count -> stats
  mapping(address => mapping(uint256 => GatherAndGarnishPlayerStats)) gatherGarnishPlayerStats;
  // What day index did the first winner win
  uint256 gatherGarnishDayOfFirstWinner;
  // Maps season count -> first winners count index -> player address for season first winners
  mapping(uint256 => mapping(uint256 => address)) gatherGarnishSeasonFirstWinners;
  uint256 gatherGarnishSeasonFirstWinnersCount;
  // Maps season count -> winners count index -> player address for season winners
  mapping(uint256 => mapping(uint256 => address)) gatherGarnishSeasonWinners;
  uint256 gatherGarnishSeasonWinnersCount;
  // Maps season count -> winners address -> bool if they have won and claimed their rewards
  mapping(uint256 => mapping(address => bool)) gatherGarnishClaimedRewards;
  // Maps season count -> mainMowseId -> bool if the mowseId has received rewards for this season (to prevent transferring main mowse and claiming multiple exp rewards)
  mapping(uint256 => mapping(uint256 => bool)) gatherGarnishMainMowseClaimedRewards;
  // Maps season count -> winners address -> bool if they have won
  mapping(uint256 => mapping(address => bool)) gatherGarnishHasPlayerWon;
  // Maps season count -> day index -> scavenge hunt count
  mapping(uint256 => mapping(uint256 => GatherAndGarnishScavenge)) gatherGarnishScavenge;
  // Maps season count -> day index -> resource type [1-4, wood/rock/gem/food]
  mapping(uint256 => mapping(uint256 => uint256)) gatherGarnishDailyResource;
  // Maps season count -> day index -> investment resource type [1-4]
  mapping(uint256 => mapping(uint256 => uint256)) gatherGarnishInvestmentResource;
  // Maps season count -> pointsStructureCost
  mapping(uint256 => uint256[4]) gatherGarnishFirstPointsStructureCost;
  mapping(uint256 => uint256[4]) gatherGarnishSecondPointsStructureCost;
  mapping(uint256 => uint256[4]) gatherGarnishThirdPointsStructureCost;

  // MowseDungeonFacet
  uint256 statusEffectCount;
  // VDF for initial dungeon hash
  uint256 mowseDungeonPrime;
  uint256 mowseDungeonIterations;
  uint256 mowseDungeonNonce;
  // pRNG for smaller pseudo random actions
  uint256 mowseDungeonPrngSeed;
  // Maps mowseTokenId -> dungeonRunCount -> MowseDungeon
  mapping(uint256 => mapping(uint256 => MowseDungeon)) mowsedungeons;
  // Maps monsterIdCount -> mapping of statusEffects
  mapping(uint256 => mapping(MowseDungeonStatusEffectEnum => uint256)) mowseDungeonMonsterStatusEffects;
  // Count of Monster Ids
  // uint256 mowseDungeonMonsterIdCount;
  // Maps roomId -> MowseDungeonRoom
  // mapping(uint256 => MowseDungeonRoom) mowseDungeonRoom;
  // Count of rooms
  // uint256 mowseDungeonRoomCount;
  // Maps mowseTokenId -> Current Player stats
  mapping(uint256 => MowseDungeonPlayer) mowseDungeonPlayer;
  // Maps mowseTokenId -> AchievementEnum -> threshold
  mapping(uint256 => mapping(MowseDungeonAchievementsEnum => uint256)) mowseDungeonAchievementProgress;
  // Maps mowseTokenId -> Companion Enum -> Companion
  mapping(uint256 => mapping(MowseDungeonCompanionEnum => MowseDungeonCompanion)) mowseDungeonPlayerCompanion;
  // Maps mowseTokenId -> dungeonRunCount -> DungeonRewards
  mapping(uint256 => mapping(uint256 => MowseDungeonDungeonRewards)) mowseDungeonDungeonRewards;
  
  // Maps Monster Enum -> Monster for default values
  mapping(MowseDungeonMonsterEnum => MowseDungeonMonsterAttributes) mowseDungeonMonsterDefaults;
  uint256 mowseDungeonMonsterDefaultsCount;
  // Maps Room Enum -> Room for default values
  mapping(MowseDungeonRoomEnum => MowseDungeonRoom) mowseDungeonRoomDefaults;
  uint256 mowseDungeonRoomDefaultsCount;
  mapping(MowseDungeonTrinketEnum => MowseDungeonTrinket) mowseDungeonTrinketDefaults;
  // Keeps track of number of different trinkets exist
  uint256 mowseDungeonTrinketDefaultsCount;
  
  // Maps mowseTokenId to dungeon run count to vdf seed
  mapping(uint256 => mapping(uint256 => uint256)) mowseDungeonRunCountToSeed;
  // Maps mowseTokenId to dungeon run count
  mapping(uint256 => uint256) mowseDungeonRunCount;

  // RandomFortuneFacet
  mapping(address => uint256) randomFortuneCount;
  // large prime used for VDF
  uint256 randomFortunePrime;
  // iterations for VDF
  uint256 randomFortuneIterations;
  // nonce for VDF
  uint256 randomFortuneNonce;
  // mapping to get seed from timestamp
  mapping(address => mapping(uint256 => uint256)) randomFortuneTimestampToSeed;

  // MowseSpin
  // uint256 mowseSpinPrime;
  // uint256 mowseSpinIterations;
  // uint256 mowseSpinNonce;
  // // Maps mowseTokenId to current mowse spin game
  // mapping(uint256 => MowseSpinStorage) mowseSpinStorage;
  // // Maps mowseTokenId to player stats
  // mapping(uint256 => MowseSpinPlayer) mowseSpinPlayer;
}

// MowseSpin
// struct MowseSpinStorage {
//   uint256 mowseId;
//   uint256 stageCount;
//   uint256 spinCount;
//   uint256 mowseSpinId;
//   uint256 seed;
//   uint256 recountTokens;
//   uint256 trashTokens;
//   uint256 coins;
//   MowseSpinSimplePlayer player;
//   MowseSpinPlayerAchievementsProgress achievementProgress;
//   MowseSpinLog[] spinLog;
//   uint256 spinLogCount;
//   uint256 grid;
// }

// struct MowseSpinPlayer {
//   uint256 mowseId;
//   // Number of times a player has created a game
//   uint256 spinRunCount;
//   // MowseDungeonSimplePlayerAchievementsUnlocked achievements;
//   // // Used for quickly checking if an achievement is unlocked
//   // mapping(MowseDungeonAchievementsEnum => bool) achievementsUnlocked;
//   // mapping(MowseDungeonAchievementsEnum => bool) achievementsClaimed;
//   // MowseDungeonSimplePlayerAchievementsProgress achievementsProgress;
// }

enum MowseDungeonStatusEffectEnum {
  NONE,
  BLIND,      // 1/2 chance of missing attack
  EAGLE_EYE,   // double chance of hitting atttack
  POISON,     // Damage per turn, pre attack
  BURN,       // Damage per turn, post attack
  BLEED,      // Damage per turn, post attack
  CURSE,      // % Damage per turn, pre attack
  STUN,       // Skip damage step
  SILENCE,    // Disable special ability
  FREEZE,     // Skip damage step, +50% damage taken from fire damage
  STRENGTHEN, // Damage Up
  WEAKEN,     // Damage Down
  BULK,       // Defense Up
  FRAIL,      // Defense Down
  THORNS,     // Return damage on hit
  REGEN,      // Heal, pre attack
  SLEEP,      // Skip damage step, +150% damage taken, wakes up after damage taken
  DEATH,      // Kill player after x turns
  INVINCIBLE, // Player does not receive damage 
  LAST_HOPE,   // If player would die, set health to 1
  DODGE,      // Increase dodge chance
  HEAL_BLOCK,  // Disable healing
  CHARM,      // Skip damage step
  COUNTER,    // Basic attack after getting hit by a basic/special attack
  PIERCE,     // Attack through shield
  CLEAVE,     // Every attack hits all monsters
  REVIVE,     // After dying, revive with full health
  UNSTOPPABLE,// Debuffs cannot be applied (existing ones still damage)
  PETRIFY,    // Skip damage step, can't receive damage from enemy attack
  FIRE_RESIST, // Resist application of burn
  POISON_RESIST,
  FREEZE_RESIST,
  STUN_RESIST,
  SLEEP_RESIST,
  CHARGED,    // Used for boss abilities that take wind up time
  DOUBLE_UP,   // Apply double status effects
  RAMPAGE,    // Increase monster damage per turn
  LONE_SURVIVOR,// If all other monsters are dead, increase damage
  ROYAL_DECREE,// Cannot be directly targeted until all other monsters are dead
  WRATHFUL_REPRISAL// Counter attack based off player attack
}
enum MowseDungeonSpecialAbilityEnum {
  DEFEND,         // Apply thorns/counter/shield+5 to self
  POISON_GAS,      // Apply poison to enemy
  BOULDER_TOSS,    // Charge up and deal 3x damage + stun
  RAGE,           // Apply STRENGTHEN to self
  SUMMON_CLUCKO,   // Summon a Clucko in an empty monster slot
  THIN_STICK,      // 80% dodge chance
  BADMOUTH,       // Apply SILENCE, WEAKEN, FRAIL to enemy
  SUMMON_PUNK,     // Summon up to 2 WRAT_PUNK in empty monster slots
  CURSED_SLIME,    // Apply CURSE to enemy
  BLEEDING_SLIME,  // Apply BLEED to enemy
  IRON_GRASP,      // Charge up and double shield. Next turn add shield to damage
  IRON_PRAYER,     // Grant shield to monsters other than self
  JESTER_DANCE,    // Apply CURSE/BLEED/BURN/POISON/STUN/SLEEP/CHARM/freeze to enemy
  KNIGHTS_HONOR,   // Apply STRENGTHEN to self and shield to self
  QUEENS_GRACE,    // Apply REGEN,STRENGTHEN,BULK to all monsters
  KINGS_AUTHORITY, // Apply stun and charge up 2 turns, at end, deal damage equal to players coins
  ROYAL_DECREE,    // Summon up to 2 copper squire, then charge for 2 turns
  HOARDERS_STASH,  // Steal 25% of player's coins, add amount to current & max health
  WRATHFUL_REPRISAL,// Apply WRATHFUL_REPRISAL to self
  DESTRUCTIVE_ENVY,// Charge up 1 turn, copy player's attack
  SEDUCTIVE_GAZE,  // Apply CHARM +2 to player
  INSATIABLE_FEAST,// Charge 1 turn, Consume all debuffs from self and all buffs from player, heal for 10% per debuff
  ANTI_SONIC_SPEED,// Apply SLEEP to all players for 2 turns
  NONE
}
enum MowseDungeonCompanionEnum {
  NONE,
  DIAMOND_BACK,
  DEVILISH,       // Get Copper Squire Achievement
  WONDER_CHILD,     // Get Novice Achievement
  INVALID_COMPANION
}
enum MowseDungeonTrinketEnum {
  DAGGER,         // +10% attack
  SLINGSHOT,      // increase damage when enemy at max health
  PENDANT_OF_LIFE,  // +5 health pre attack
  LEECH,          // +10% lifesteal per stack
  POISON_DAB,      // +1 apply poison stack after attack
  KINDLE,         // +1 burn stack
  BLOOD_LETTER,    // +1 bleed stack
  CURSED_RING,     // +1 curse stack
  STUN_ROD,        // chance to apply +1 stun stack
  SILENCE_BELL,    // chance to apply +1 silence stack
  STRENGTH_BELT,   // +1 strengthen stack (2x damage)
  WEAKENED_CHAIN,  // +1 weaken stack (1/2 damage)
  EMBLEM_OF_INITIATIVE, // +1 action
  GOLD_RING,       // increase coin drop 10% + 10% per stack
  NONE
}
enum MowseDungeonRoomEnum {
  MERCHANT,             // Merchant
  COIN_LOOT_ROOM,
  TRINKET_LOOT_ROOM,
  FOREST_SLIME_1,       // 1 Green Slime
  FOREST_SLIME_2,       // 2 Green Slime
  FOREST_SLIME_3,       // 3 Green Slime
  FOREST_MUSHY,   // 2 Red Mushy
  FOREST_PEBBLE,   // 1 Pebble Golem 1 DUCKY
  FOREST_TOAD,   // 3 Spiny Toad
  FOREST_ROOSTA,         // 1 Roosta 2 Clucko
  FOREST_STICK,         // 3 Stick Bug
  FOREST_WRAT_PUNK,         // 2 WRAT_PUNK
  FOREST_WRAT_GANG_LEADER,           // 1 Wrat Gang Leader
  RAIN_OF_FROGS,          // 3 Spiny Toad
  STICKY_SITUATION,       // 2 Green Slime 1 Stick Bug
  MEDIEVAL_SLIME_INTRO,   // 1 Helmet Slime
  MEDIEVAL_SQUIRE_INTRO,  // 1 Copper Squire
  MEDIEVAL_PRIEST_INTRO,  // 2 Iron Priest
  MEDIEVAL_SLIME,        // 3 Helmet Slime
  MEDIEVAL_SQUIRE,       // 2 Copper Squire
  MEDIEVAL_JESTER,       // 2 Pyrite Jester
  MEDIEVAL_KNIGHT,       // 2 Steel Knight
  MEDIEVAL_KNIGHT_PRIEST, // 1 Steel Knight 1 Iron Priest
  MEDIEVAL_KNIGHT_SQUIRE,       // 1 Steel Knight 1 CopperSquire
  MEDIEVAL_MAIDEN,       // 1 Iron Maiden 2 Iron Priest
  MEDIEVAL_QUEEN,        // 1 Silver Queen 1 SteelKnight
  MEDIEVAL_KING,         // 1 Gold King 1 SteelKnight
  MEDIEVAL_ROYAL,        // 1 Silver Queen 1 Gold King
  BOSS_LIONS_PRIDE,
  BOSS_GOBLINS_GREED,
  BOSS_LICHS_WRATH,
  BOSS_WRATS_ENVY,
  BOSS_LUSTFUL_HEIRESS,
  BOSS_GLUTTONOUS_PIG,
  BOSS_SLOTHFUL_HEDGEHOG
}
enum MowseDungeonMonsterEnum {
  // Forest
  SPINY_TOAD,
  GREEN_SLIME,
  RED_MUSHY,
  PEBBLE_GOLEM,
  CLUCKO,
  ROOSTA,
  STICK_BUG,
  DUCKY,
  WRAT_PUNK,
  WRAT_GANG_LEADER,
  BLUE_SLIME,
  RED_SLIME,
  // Metal Medieval theme
  HELMET_SLIME,
  COPPER_SQUIRE,
  IRON_MAIDEN,
  IRON_PRIEST,
  PYRITE_JESTER,
  STEEL_KNIGHT,
  SILVER_QUEEN,
  GOLD_KING,
  // Bosses
  // 7 Deadly Sins
  LIONS_PRIDE,
  GOBLINS_GREED,
  LICHS_WRATH,
  WRATS_ENVY,
  LUSTFUL_HEIRESS,
  GLUTTONOUS_PIG,
  SLOTHFUL_HEDGEHOG,
  NONE
}
enum MowseDungeonClassEnum {
  // Base Classes
  WARRIOR,  // Basic 100% damage Special ability whirlwind (apply cleave to self)
  MAGE,     // Basic 60% Special ability fireball (2x base attack, apply burn to enemy)
  ARCHER,   // Basic 80% damage, Special ability Hawkshot (apply eagle eye, deal damage x # of times)
  ROGUE,    // Basic 50% x 2 apply poison Special ability backstab (apply dodge 2x)
  // Advanced Classes
  PALADIN,  // Basic 70% damage, Special ability Judgement Of Light (heal 30% max health + 1% per 10 int + 1% per 10 str)
  GUARDIAN,  // Basic 50% damage, gain shield Special ability shieldbash (gain extra shield, damage equal to shield)
  BERSERKER,// Basic 120% Special ability rage (deal basic attack damage, apply strengthen, lastHope, silence to self)
  CLERIC,   // Basic 40% Special ability heal (apply regen to self)
  NECROMANCER,// Basic 55% Special ability life tap (deal basic attack damage, if monster dies, permanently gain 10% attack)
  BARD,     // Basic 60% Special ability charm (apply charm to enemy)
  // T2 Classes
  INVALID_CLASS
}
enum MowseDungeonRoomTypeEnum {
  MONSTER,
  COIN_LOOT,
  TRINKET_LOOT,
  BOSS,
  MERCHANT,
  INVALID_ROOM
}
// Complete Achievements to unlock Companions
enum MowseDungeonAchievementsEnum {
  NOVICE,           // Complete the forest-0 dungeon
  FOREST_MASTER,     // Complete the forest-10 dungeon
  COPPER_SQUIRE,   // Complete the medieval-0 dungeon
  IRON_MAIDEN,   // Complete the medieval-3 dungeon
  STEEL_KNIGHT,    // Complete the medieval-6 dungeon
  GOLD_KING,     // Complete the medieval-9 dungeon
  MASTER_OF_DEADLY_SINS,// Complete the medieval-10 dungeon
  UNTOUCHABLE,      // Defeat a boss without taking damage
  POISON_MASTER,      // Apply 99 stacks of poison in one dungeon
  LOOT_GOBLIN,       // Steal successfully more than 5 times in a single run
  COIN_GOBLIN,       // Have at least 500 coins in inventory
  ONE_MAN_ARMY,       // Deal 1000 damage in a single run
  LEARN_THE_ROPES,  // Complete any dungeon with all 4 base classes
  WARRIOR,          // Complete any dungeon with Warrior
  MAGE,             // Complete any dungeon with Mage
  ARCHER,           // Complete any dungeon with Archer
  ROGUE,            // Complete any dungeon with Rogue
  PALADIN,          // Complete any dungeon with Paladin
  GUARDIAN,         // Complete any dungeon with Guardian
  BERSERKER,        // Complete any dungeon with Berserker
  CLERIC,           // Complete any dungeon with Cleric
  NECROMANCER,      // Complete any dungeon with Necromancer
  BARD,             // Complete any dungeon with Bard
  INVALID_ACHIEVEMENT
}
enum MowseDungeonActionTypeEnum {
  BASIC_ATTACK,
  SPECIAL_ABILITY,
  STEAL,
  DEFEND,
  INVALID_ACTION
}
enum MowseDungeonBattleStatusEnum {
  VICTORY,
  DEFEAT,
  ONGOING
}
enum MowseDungeonDungeonTypeEnum {
  FOREST,
  MEDIEVAL
}
enum MowseDungeonBattleLogTypeEnum {
  INVALID_LOG_TYPE,
  DAMAGE,
  APPLY_STATUS_EFFECT,
  HEAL,
  SUMMON,
  STEAL_SUCCESS,
  STEAL_FAILURE
}
enum MowseDungeonBattleLogSourceEnum {
  PLAYER,
  MONSTER_1,
  MONSTER_2,
  MONSTER_3,
  TARGET_INDEX_MONSTER,  // Target a Monster according to targetIndex
  COMPANION,
  TRINKET_PENDANT_OF_LIFE,
  TRINKET_LEECH,
  STATUS_EFFECT_BLIND,
  STATUS_EFFECT_EAGLE_EYE,
  STATUS_EFFECT_POISON,
  STATUS_EFFECT_BURN,
  STATUS_EFFECT_BLEED,
  STATUS_EFFECT_CURSE,
  STATUS_EFFECT_STUN,
  STATUS_EFFECT_SILENCE,
  STATUS_EFFECT_FREEZE,
  STATUS_EFFECT_STRENGTHEN,
  STATUS_EFFECT_WEAKEN,
  STATUS_EFFECT_BULK,
  STATUS_EFFECT_FRAIL,
  STATUS_EFFECT_THORNS,
  STATUS_EFFECT_REGEN,
  STATUS_EFFECT_SLEEP,
  STATUS_EFFECT_DEATH,
  STATUS_EFFECT_INVINCIBLE,
  STATUS_EFFECT_LAST_HOPE,
  STATUS_EFFECT_DODGE,
  STATUS_EFFECT_HEAL_BLOCK,
  STATUS_EFFECT_CHARM,
  STATUS_EFFECT_COUNTER,
  STATUS_EFFECT_PIERCE,
  STATUS_EFFECT_CLEAVE,
  STATUS_EFFECT_REVIVE,
  STATUS_EFFECT_UNSTOPPABLE,
  STATUS_EFFECT_PETRIFY,
  STATUS_EFFECT_FIRE_RESIST,
  STATUS_EFFECT_POISON_RESIST,
  STATUS_EFFECT_FREEZE_RESIST,
  STATUS_EFFECT_STUN_RESIST,
  STATUS_EFFECT_SLEEP_RESIST,
  STATUS_EFFECT_CHARGED,
  STATUS_EFFECT_DOUBLE_UP,
  STATUS_EFFECT_RAMPAGE,
  STATUS_EFFECT_LONE_SURVIVOR,
  STATUS_EFFECT_ROYAL_DECREE,
  STATUS_EFFECT_WRATHFUL_REPRISAL
}
struct MowseDungeonSimpleTrinkets {
  uint256 dagger;
  uint256 slingshot;
  uint256 pendantOfLife;
  uint256 leech;
  uint256 poisonDab;
  uint256 kindle;
  uint256 bloodLetter;
  uint256 cursedRing;
  uint256 stunRod;
  uint256 silenceBell;
  uint256 strengthBelt;
  uint256 weakenedChain;
  uint256 emblemOfInitiative;
  uint256 goldRing;
}
struct MowseDungeonSimpleStatusEffect {
  uint256 blind;
  uint256 eagleEye;
  uint256 poison;
  uint256 burn;
  uint256 bleed;
  uint256 curse;
  uint256 stun;
  uint256 silence;
  uint256 freeze;
  uint256 strengthen;
  uint256 weaken;
  uint256 bulk;
  uint256 frail;
  uint256 thorns;
  uint256 regen;
  uint256 sleep;
  uint256 death;
  uint256 invincible;
  uint256 lastHope;
  uint256 dodge;
  uint256 healBlock;
  uint256 charm;
  uint256 counter;
  uint256 pierce;
  uint256 cleave;
  uint256 revive;
  uint256 unstoppable;
  uint256 petrify;
  uint256 fireResist;
  uint256 poisonResist;
  uint256 freezeResist;
  uint256 stunResist;
  uint256 sleepResist;
  uint256 charged;
  uint256 doubleUp;
  uint256 rampage;
  uint256 loneSurvivor;
  uint256 royalDecree;
  uint256 wrathfulReprisal;
}
struct MowseDungeonSimplePlayerAchievementsUnlocked {
  bool novice;
  bool forestMaster;
  bool copperSquire;
  bool ironMaiden;
  bool steelKnight;
  bool goldKing;
  bool masterOfDeadlySins;
  bool untouchable;
  bool poisonMaster;
  bool lootGoblin;
  bool coinGoblin;
  bool oneManArmy;
  bool learnTheRopes;
  bool warrior;
  bool mage;
  bool archer;
  bool rogue;
  bool paladin;
  bool guardian;
  bool berserker;
  bool cleric;
  bool necromancer;
  bool bard;
}
struct MowseDungeonSimplePlayerAchievementsProgress {
  uint256 damageDealt;
  uint256 damageTaken;
  uint256 healthHealed;
  uint256 burnDamageDealt;
  uint256 poisonDamageDealt;
  uint256 bleedDamageDealt;
  uint256 curseDamageDealt;
  uint256 trinketsStolen;
}
struct MowseDungeonBattleLog {
  MowseDungeonBattleLogTypeEnum logType;
  MowseDungeonBattleLogSourceEnum source;
  MowseDungeonBattleLogSourceEnum target;
  uint256 amount;
}
struct MowseDungeonBattleSimulation {
  MowseDungeonSimplePlayer player;
  MowseDungeonSimpleMonster monster1;
  MowseDungeonSimpleMonster monster2;
  MowseDungeonSimpleMonster monster3;
  uint256 dungeonId;
  uint256 seed;
  MowseDungeonActionTypeEnum actionType;
  uint8 targetIndex;
  uint256 actionsRun;
  MowseDungeonTrinketEnum[] stolenTrinkets;
  uint256 stolenTrinketCount;
  bool isStealSuccessful;
  MowseDungeonBattleStatusEnum status;
  MowseDungeonSimplePlayerAchievementsProgress achievementProgress;
  uint256 descentLevel;
  MowseDungeonBattleLog[] battleLog;
  uint256 battleLogCount;
}
struct MowseDungeonBattleResults {
  MowseDungeonBattleSimulation simulation;
  MowseDungeonPostBattleResults postBattleResults;
  bytes32 actionsRunHash;
  bytes32 postBattleResultsHash;
}
struct MowseDungeonPostBattleResults {
  uint256 mowseId;
  uint256 coins;
  MowseDungeonMonsterEnum monster1;
  MowseDungeonMonsterEnum monster2;
  MowseDungeonMonsterEnum monster3;
  MowseDungeonTrinketEnum[] stolenTrinkets;
  uint256 stolenTrinketCount;
  MowseDungeonBattleStatusEnum status;
  MowseDungeonSimplePlayerAchievementsProgress achievementProgress;
  uint256 descentLevel;
}
struct MowseDungeonDungeonRewards {
  bool hasRewards;
  uint256 mgoldMintAmount;
  uint256 xpGainedAmount;
  uint256 companionXpGained;
  uint256 completionPercentage;
  uint256 additionalFactor;
}
// Used for _performAction to calculate damage
struct MowseDungeonSimplePlayer {
  uint256 mowseId;
  int32[SKILL_TYPE_NUM] stats;
  uint256 maxHealth;
  uint256 currentHealth;
  uint256 shield;
  uint256 attack;
  bool canHit;
  uint256 accuracy;
  uint256 tempAttack;
  uint256 damageMultiplier;
  uint256 action;
  uint256 numberOfHits;
  MowseDungeonClassEnum class;
  MowseDungeonSimpleStatusEffect statusEffects;
  MowseDungeonSimpleTrinkets trinkets;
  MowseDungeonCompanion companion;
  MowseDungeonDescentLevel descentLevel;
  // MowseDungeonSimplePlayerAchievementsUnlocked achievements;
  uint256 coins;
  uint256 currentDungeonRunCount;
  uint256 currentRoomIndex;
}
struct MowseDungeonPlayer {
  uint256 mowseId;
  int32[SKILL_TYPE_NUM] stats;
  uint256 maxHealth;
  uint256 currentHealth;
  uint256 shield;
  uint256 attack;
  // uint256 maxAction;  // Special Ability points
  uint256 action;
  // Maps StatusEffect to statusEffect value (ex: 1 (poison) => 2 is equal to 2 stacks of poison)
  mapping(MowseDungeonStatusEffectEnum => uint256) statusEffects;
  // Maps trinketIndex to MowseDungeonTrinketEnum
  mapping(MowseDungeonTrinketEnum => MowseDungeonTrinket) trinkets;
  // uint256 trinketCount;
  mapping(MowseDungeonCompanionEnum => MowseDungeonCompanion) companions;
  MowseDungeonCompanion currentCompanion;
  uint256 coins;
  MowseDungeonClassEnum class;
  // Number of times a player has run a dungeon
  uint256 dungeonRunCount;
  MowseDungeonSimplePlayerAchievementsUnlocked achievements;
  // Used for quickly checking if an achievement is unlocked
  mapping(MowseDungeonAchievementsEnum => bool) achievementsUnlocked;
  mapping(MowseDungeonAchievementsEnum => bool) achievementsClaimed;
  MowseDungeonSimplePlayerAchievementsProgress achievementsProgress;
  MowseDungeonDescentLevel descentLevel;
}
struct MowseDungeonPerformAction {
  MowseDungeonActionTypeEnum actionType;
  uint256 targetIndex;
}
// Used for _performAction to calculate damage
struct MowseDungeonSimpleMonster {
  MowseDungeonMonsterEnum monsterType;
  uint256 monsterId;
  uint256 maxHealth;
  uint256 currentHealth;
  uint256 shield;
  uint256 attack;
  bool canHit;
  uint256 accuracy;
  uint256 tempAttack;
  uint256 damageMultiplier;
  MowseDungeonSpecialAbilityEnum specialAbility;
  bool isBoss;
  bool hasBeenStolen;
  bool usedSpecialAbility;
  MowseDungeonSimpleStatusEffect statusEffects;
  string image;
}
// Used for setting default monster values 
struct MowseDungeonMonsterAttributes {
  bool isActive;
  MowseDungeonMonsterEnum monsterType;
  uint256 monsterId;
  uint256 maxHealth;
  uint256 shield;
  uint256 attack;
  MowseDungeonSpecialAbilityEnum specialAbility;
  MowseDungeonSimpleStatusEffect statusEffects;
  bool isBoss;
  uint256 coins;
  string name;
  string image;
}
struct MowseDungeonMonster {
  MowseDungeonMonsterEnum monsterType;
  uint256 monsterId;
  uint256 maxHealth;
  uint256 currentHealth;
  uint256 shield;
  uint256 attack;
  MowseDungeonSpecialAbilityEnum specialAbility;
  mapping(MowseDungeonStatusEffectEnum => uint256) statusEffects;
  // Bosses cannot be stunned, slept, etc.
  bool isBoss;
  // Maps monsterDropIndex to MowseDungeonTrinket
  mapping(uint256 => MowseDungeonTrinket) monsterDrops;
  uint256 monsterDropCount;
  uint256 coins;
  // Players can only use steal once per monster
  bool hasBeenStolen;
  string name;
}
// Trinkets are passive boosts to the player they can select after battle
// Trinkets do not carry over between dungeon run, however, you can enhance trinkets so they are stronger the next run
// Use MowseDungeonTrinketEnum id to conditionally apply statusEffects
struct MowseDungeonTrinket {
  MowseDungeonTrinketEnum trinketId;
  uint256 level;
  // mapping(MowseDungeonStatusEffectEnum => uint256) statusEffects;
  uint256 health;
  uint256 shield;
  uint256 attack;
}
// Should always have 5 items
struct MowseDungeonMerchantRoom {
  MowseDungeonMerchantItem[] items;
}
struct MowseDungeonMerchantItem {
  MowseDungeonTrinketEnum trinketId;
  MowseDungeonTrinket trinket;
  uint256 cost;
  bool hasPurchased;
}
// Unlike Trinkets, Companions carry over between dungeon runs
// Companions can level up before a dungeon run
struct MowseDungeonCompanion {
  MowseDungeonCompanionEnum companionId;
  bool isUnlocked;
  uint256 level;
  uint256 experience;
}
struct MowseDungeonRoom {
  MowseDungeonRoomEnum id;
  MowseDungeonRoomTypeEnum roomType;
  MowseDungeonMonsterEnum[] monsters;
}
struct MowseDungeon {
  uint256 id;   // Should be the VDF hash
  MowseDungeonRoom[] rooms;
  uint256 currentRoomIndex;
  bool active;
  MowseDungeonDungeonTypeEnum dungeonType;
  MowseDungeonMerchantRoom merchantRoom;
  uint256 descentLevel;
}
// 0 - normal
// 1 - +25% hp/shield
// 2 - +25% attack
// 3 - +25% attack, -25% coin
// 4 - +25% attack/hp/shield
// 5 - +25% attack/hp/shield, items cost 10% more
// 6 - +25% attack, +50% hp/shield
// 7 - +25% attack, +50% hp/shield, -25% coins
// 8 - +25% attack, +50% hp/shield, -25% coins, items cost 10% more
// 9 - +100% hp/shield, rampage
// 10 - +100% hp/shield, rampage, -25% coins, items cost 10% more
struct MowseDungeonDescentLevel {
  uint256 forestDungeon;
  uint256 medievalDungeon;
}

// Gather and Garnish
struct GatherAndGarnishScavenge {
  uint256 woodCount;
  uint256 rockCount;
  uint256 gemCount;
  uint256 foodCount;
}
struct GatherAndGarnishPlayerStats {
  // Maps season day index -> action index taken [1 - gather, 2 - predict, 3 - build, 4 - invest]
  mapping(uint256 => uint256) dailyAction;
  uint256 woodStorage;
  uint256 woodStorageLevel;
  uint256 rockStorage;
  uint256 rockStorageLevel;
  uint256 gemStorage;
  uint256 gemStorageLevel;
  uint256 foodStorage;
  uint256 foodStorageLevel;
  uint256 investmentCount;
  // Maps whether the player has built the first/second/third points structure
  mapping(uint256 => bool) hasBuiltPointsStructure;
  // Maps season day index -> resource type prediction [1-4, wood/rock/gem/food]
  mapping(uint256 => uint256) prediction;
  uint256 latestPredictionDay;
  uint256 seasonFirstWinnerIndex;
}

struct TestPatch {
  uint256 testPatchVersion;
  uint256 uniqueInteractionCount; // Unique address interactions
  address[] interactedAddresses;  // Addresses that interacted
  mapping(address => uint256) numberOfInteractions; // maps addresses -> number of times interacted
}

struct Mowse {
  uint256 tokenId; // Mowse asset tokenId counter, also used to check if exists
  address ownerAddress; // Owner Address
  // BaseTraits required on all Mowse
  uint16 generation;
  MowseWearMetadata baseBackgroundColor; // Index 0
  MowseWearMetadata baseSkinColor;       // Index 2
  MowseWearMetadata baseEarType;         // Index 3
  MowseWearMetadata baseBodyType;        // Index 5
  MowseWearMetadata baseMouth;           // Index 6
  MowseWearMetadata baseEyeType;         // Index 8
  // MowseJob
  int32[SKILL_TYPE_NUM] skillLevelBoosts;  // Additional Skill LEVEL modifiers
  int32[SKILL_TYPE_NUM] skillLevel; // Base Skill LEVEL, increases as ExperiencePoints caps [charisma, constitution, dexterity, intelligence, luck, strength, wisdom]
  // uint32[SKILL_TYPE_NUM] skillExperiencePoints; // Skill EXPERIENCE points
  // uint16[SKILL_TYPE_NUM] skillExperiencePointsBoosts; // Additional Skill EXPERIENCE points boosts
  uint8 primarySkillType;  // Primary skill preference from birth (should be 0-6), cannot change
  uint8 secondarySkillType;  // Secondary skill preference from birth (should be 0-6, can be the same as primary skill), cannot change
  uint8 profession; // Career (should be 0-7), can change. 
  // 0 = no profession
  // 1 = Agriculture and Food
  // 2 = Finance and Marketing
  // 3 = Art and Manufacturing
  // 4 = Science and Medicine
  // 5 = Military
  // 6 = Politics (Law and Government)
  // 7 = Nursing and Childcare (Family-focused)
  // MowseLife
  uint16 lifeLevel; // LIFE Experience level
  uint256 lifeExperiencePoints;  // Life Experience points (as life level goes up, skill level can be increased)
  uint256 prngNonce;  // Used in Mowse PRNG (level up to randomly distribute stat points and onMint)

  // MowseWear
  uint256[EQUIPPED_WEARABLE_SLOTS] equippedMowseWearByTokenIds;  // Currently equipped mowsewear tokenIds
  // [backgroundColor, backgroundFeature, skinColor, earType, shirt, bodyType, mouth, eyeBrow, eyeType, eyeWear, headWear, jewelry]

}

// 1 Background Color
// 2 Background Feature
// 3 Skin Color
// 4 Ear Type
// 5 Shirt
// 6 Body Type
// 7 Mouth
// 8 Eye Brow Type
// 9 Eye Type
// 10 Eye Wear
// 11 Head Wear
// 12 Jewelry

struct MowseWear {
  uint256 tokenId;  // MowseWear asset tokenId counter, also used to check if exists
  bool isEquipped;  // Quick way to know if a MowseWear is equipped
  uint256 equippedBy; // track which Mowse tokenId is equipped by
  uint256 durability;  // Durability time after stitching
  uint256 alterCount;  // Number of times a MowseWear has been altered (stitched or hemmed)
  uint256 maxAlterCount;  // Max number of times a MowseWear can be altered (stitched or hemmed)
  MowseWearMetadata metadata;
  MowseWearDimensions dimensions;
  MowseWearBonuses bonuses;
}

struct MowseWearMetadata {
  uint8 traitType;  // Type of MowseWear (backgroundColor, shirt, eyeWear, etc) (should be 0-11)
  string traitName; // MowseWear item name ("Blue Headband")
  uint16 traitIndex;  // MowseWear trait index (12th headband)
  uint256 dictionaryIndex;  // MowseWear dictionary index (12th item in dictionary)
  bool nonTransferrable;  // MowseWear can be traded or not (soulbound)
  string svgFilter; // Any overrides on the svgFilter
  MowseWearDimensions baseDimensions; // Base SVG Dimensions
}

struct MowseWearBonuses {
  uint256 randomness; // Random seed for MowseWear
  uint256 itemRarityIV;  // Item Rarity inherent value (pseudorandom number between 0-4294967294)
  uint8 itemRarity; // Item Rarity (common, uncommon, rare, epic, legendary, unique) (should be 0-5)
  int32[SKILL_TYPE_NUM] baseSkillLevelBoosts; // Base Skill LEVEL modifiers from IV
  int32[SKILL_TYPE_NUM] additionalSkillLevelBoosts;  // Additional Skill LEVEL modifiers from other factors (set bonuses?)
}

struct MowseSkillTypes {
  int32 charisma;
  int32 constitution;
  int32 dexterity;
  int32 intelligence;
  int32 luck;
  int32 strength;
  int32 wisdom;
}

struct MowseWearDimensions {
  uint16 width;
  uint16 height;
  string transform;
  string style;
  string image;
  uint16 weight;
}

struct MowseLootboxPool {
  bool active;  // Is lootbox active and can be minted from?
  uint256 price;  // Price per MowseGold (generic loot pool cheapest -> specific trait type more expensive -> event specific)
  string name;
  uint16 width; // Goes with image to create on-chain SVG
  uint16 height;  // Goes with image to create on-chain SVG
  string image;
  mapping(uint16 => uint256) lootPool;  // TraitTypes & TraitIndexes in the lootPool for minting
  uint16 itemCount; // Number of items in lootpool
  uint256 dateAdded;  // When the lootbox was added; Ex: Earlier lootboxes might have rarer items
  uint256 index;  // Index of the lootbox
}
// This struct is used by MowseLootboxFacet.getMowseLootboxData to return the lootPool mapping as well
struct MowseLootboxPoolData {
  bool active;
  uint256 price;
  string name;
  string image;
  SimpleMowseLootboxPoolItem[] lootPool;
  uint16 itemCount;
  uint256 dateAdded;
  uint64 index;
}
struct SimpleMowseLootboxPoolItem {
  uint16 traitType;
  uint16 traitIndex;
  string traitName;
  string image;
}

struct MowseLineage {
  uint16 generation;
  uint256 parent1;
  uint256 parent2;
  uint256[] children;
}

struct MowseBankStruct {
  address _walletImplementation;
  mapping(address => uint256) balances;
  mapping(address => uint256) getTokenIdForWallet;
}
struct MowseGames {
  string name;
  bool active;  // Game is active or disabled (disable if game updates or something. idk. Bad developer)
  bytes32 gameHash;
  uint256 totalNumberOfSubmits;
  mapping(address => uint256) uniqueSubmitsByAddress;
  address[] uniqueAddressesList;
  uint256 uniqueAddressesCount;
  mapping(address => uint256[3]) dailySubmits;
  // Minimum score to pass to get the max payout MGOLD
  uint256 minScoreForMaxPayout;
  // For granting additional bonuses for special event days
  bool rewardBonus;
  // For paying game developers
  address payable developerAddress;
}


library LibStorage {
  function gameStorage() internal pure returns (GameStorage storage gs) {
    assembly {
      gs.slot := 0
    }
  }
  function skillTypeToString(uint16 x) internal pure returns (string memory skillTypeString) {
    require(x < SKILL_TYPE_NUM, "LibStorage: Invalid Skill Type");

    if (x == 0) return "charisma";
    if (x == 1) return "constitution";
    if (x == 2) return "dexterity";
    if (x == 3) return "intelligence";
    if (x == 4) return "luck";
    if (x == 5) return "strength";
    if (x == 6) return "wisdom";
  }
  function equippableWearableSlotToString(uint8 traitType) internal pure returns (string memory wearableSlotString) {
    require(traitType < EQUIPPED_WEARABLE_SLOTS, "LibStorage: Invalid Trait Type");

    if (traitType == 0) return "backgroundColor"; 
    if (traitType == 1) return "backgroundFeature"; 
    if (traitType == 2) return "skinColor"; 
    if (traitType == 3) return "earType"; 
    if (traitType == 4) return "shirt"; 
    if (traitType == 5) return "bodyType"; 
    if (traitType == 6) return "mouth"; 
    if (traitType == 7) return "eyeBrow"; 
    if (traitType == 8) return "eyeType"; 
    if (traitType == 9) return "eyeWear"; 
    if (traitType == 10) return "headWear"; 
    if (traitType == 11) return "jewelry";
  }
  function itemRarityToString(uint8 itemRarity) internal pure returns (string memory itemRarityString) {
    if (itemRarity == 0) return "common";
    if (itemRarity == 1) return "uncommon";
    if (itemRarity == 2) return "rare";
    if (itemRarity == 3) return "epic";
    if (itemRarity == 4) return "legendary";
    if (itemRarity == 5) return "unique";
  }
}
contract WithStorage {
  function skillTypeToString(uint16 skillType) internal pure returns (string memory) {
    return LibStorage.skillTypeToString(skillType);
  }
  function equippedWearableSlotToString(uint8 traitType) internal pure returns (string memory) {
    return LibStorage.equippableWearableSlotToString(traitType);
  }
  function itemRarityToString(uint8 itemRarity) internal pure returns (string memory) {
    return LibStorage.itemRarityToString(itemRarity);
  }
}

File 10 of 10 : console.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;

library console {
    address constant CONSOLE_ADDRESS =
        0x000000000000000000636F6e736F6c652e6c6f67;

    function _sendLogPayloadImplementation(bytes memory payload) internal view {
        address consoleAddress = CONSOLE_ADDRESS;
        /// @solidity memory-safe-assembly
        assembly {
            pop(
                staticcall(
                    gas(),
                    consoleAddress,
                    add(payload, 32),
                    mload(payload),
                    0,
                    0
                )
            )
        }
    }

    function _castToPure(
      function(bytes memory) internal view fnIn
    ) internal pure returns (function(bytes memory) pure fnOut) {
        assembly {
            fnOut := fnIn
        }
    }

    function _sendLogPayload(bytes memory payload) internal pure {
        _castToPure(_sendLogPayloadImplementation)(payload);
    }

    function log() internal pure {
        _sendLogPayload(abi.encodeWithSignature("log()"));
    }

    function logInt(int256 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(int256)", p0));
    }

    function logUint(uint256 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0));
    }

    function logString(string memory p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string)", p0));
    }

    function logBool(bool p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
    }

    function logAddress(address p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address)", p0));
    }

    function logBytes(bytes memory p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0));
    }

    function logBytes1(bytes1 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0));
    }

    function logBytes2(bytes2 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0));
    }

    function logBytes3(bytes3 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0));
    }

    function logBytes4(bytes4 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0));
    }

    function logBytes5(bytes5 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0));
    }

    function logBytes6(bytes6 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0));
    }

    function logBytes7(bytes7 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0));
    }

    function logBytes8(bytes8 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0));
    }

    function logBytes9(bytes9 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0));
    }

    function logBytes10(bytes10 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0));
    }

    function logBytes11(bytes11 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0));
    }

    function logBytes12(bytes12 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0));
    }

    function logBytes13(bytes13 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0));
    }

    function logBytes14(bytes14 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0));
    }

    function logBytes15(bytes15 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0));
    }

    function logBytes16(bytes16 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0));
    }

    function logBytes17(bytes17 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0));
    }

    function logBytes18(bytes18 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0));
    }

    function logBytes19(bytes19 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0));
    }

    function logBytes20(bytes20 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0));
    }

    function logBytes21(bytes21 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0));
    }

    function logBytes22(bytes22 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0));
    }

    function logBytes23(bytes23 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0));
    }

    function logBytes24(bytes24 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0));
    }

    function logBytes25(bytes25 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0));
    }

    function logBytes26(bytes26 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0));
    }

    function logBytes27(bytes27 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0));
    }

    function logBytes28(bytes28 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0));
    }

    function logBytes29(bytes29 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0));
    }

    function logBytes30(bytes30 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0));
    }

    function logBytes31(bytes31 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0));
    }

    function logBytes32(bytes32 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0));
    }

    function log(uint256 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0));
    }

    function log(string memory p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string)", p0));
    }

    function log(bool p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
    }

    function log(address p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address)", p0));
    }

    function log(uint256 p0, uint256 p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256)", p0, p1));
    }

    function log(uint256 p0, string memory p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string)", p0, p1));
    }

    function log(uint256 p0, bool p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool)", p0, p1));
    }

    function log(uint256 p0, address p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address)", p0, p1));
    }

    function log(string memory p0, uint256 p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1));
    }

    function log(string memory p0, string memory p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1));
    }

    function log(string memory p0, bool p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1));
    }

    function log(string memory p0, address p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1));
    }

    function log(bool p0, uint256 p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256)", p0, p1));
    }

    function log(bool p0, string memory p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1));
    }

    function log(bool p0, bool p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1));
    }

    function log(bool p0, address p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1));
    }

    function log(address p0, uint256 p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256)", p0, p1));
    }

    function log(address p0, string memory p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1));
    }

    function log(address p0, bool p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1));
    }

    function log(address p0, address p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1));
    }

    function log(uint256 p0, uint256 p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256)", p0, p1, p2));
    }

    function log(uint256 p0, uint256 p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string)", p0, p1, p2));
    }

    function log(uint256 p0, uint256 p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool)", p0, p1, p2));
    }

    function log(uint256 p0, uint256 p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address)", p0, p1, p2));
    }

    function log(uint256 p0, string memory p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256)", p0, p1, p2));
    }

    function log(uint256 p0, string memory p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string)", p0, p1, p2));
    }

    function log(uint256 p0, string memory p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool)", p0, p1, p2));
    }

    function log(uint256 p0, string memory p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address)", p0, p1, p2));
    }

    function log(uint256 p0, bool p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256)", p0, p1, p2));
    }

    function log(uint256 p0, bool p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string)", p0, p1, p2));
    }

    function log(uint256 p0, bool p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool)", p0, p1, p2));
    }

    function log(uint256 p0, bool p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address)", p0, p1, p2));
    }

    function log(uint256 p0, address p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256)", p0, p1, p2));
    }

    function log(uint256 p0, address p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string)", p0, p1, p2));
    }

    function log(uint256 p0, address p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool)", p0, p1, p2));
    }

    function log(uint256 p0, address p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address)", p0, p1, p2));
    }

    function log(string memory p0, uint256 p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256)", p0, p1, p2));
    }

    function log(string memory p0, uint256 p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string)", p0, p1, p2));
    }

    function log(string memory p0, uint256 p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool)", p0, p1, p2));
    }

    function log(string memory p0, uint256 p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address)", p0, p1, p2));
    }

    function log(string memory p0, string memory p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256)", p0, p1, p2));
    }

    function log(string memory p0, string memory p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2));
    }

    function log(string memory p0, string memory p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2));
    }

    function log(string memory p0, string memory p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2));
    }

    function log(string memory p0, bool p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256)", p0, p1, p2));
    }

    function log(string memory p0, bool p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2));
    }

    function log(string memory p0, bool p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2));
    }

    function log(string memory p0, bool p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2));
    }

    function log(string memory p0, address p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256)", p0, p1, p2));
    }

    function log(string memory p0, address p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2));
    }

    function log(string memory p0, address p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2));
    }

    function log(string memory p0, address p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2));
    }

    function log(bool p0, uint256 p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256)", p0, p1, p2));
    }

    function log(bool p0, uint256 p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string)", p0, p1, p2));
    }

    function log(bool p0, uint256 p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool)", p0, p1, p2));
    }

    function log(bool p0, uint256 p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address)", p0, p1, p2));
    }

    function log(bool p0, string memory p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256)", p0, p1, p2));
    }

    function log(bool p0, string memory p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2));
    }

    function log(bool p0, string memory p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2));
    }

    function log(bool p0, string memory p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2));
    }

    function log(bool p0, bool p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256)", p0, p1, p2));
    }

    function log(bool p0, bool p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2));
    }

    function log(bool p0, bool p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2));
    }

    function log(bool p0, bool p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2));
    }

    function log(bool p0, address p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256)", p0, p1, p2));
    }

    function log(bool p0, address p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2));
    }

    function log(bool p0, address p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2));
    }

    function log(bool p0, address p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2));
    }

    function log(address p0, uint256 p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256)", p0, p1, p2));
    }

    function log(address p0, uint256 p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string)", p0, p1, p2));
    }

    function log(address p0, uint256 p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool)", p0, p1, p2));
    }

    function log(address p0, uint256 p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address)", p0, p1, p2));
    }

    function log(address p0, string memory p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256)", p0, p1, p2));
    }

    function log(address p0, string memory p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2));
    }

    function log(address p0, string memory p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2));
    }

    function log(address p0, string memory p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2));
    }

    function log(address p0, bool p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256)", p0, p1, p2));
    }

    function log(address p0, bool p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2));
    }

    function log(address p0, bool p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2));
    }

    function log(address p0, bool p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2));
    }

    function log(address p0, address p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256)", p0, p1, p2));
    }

    function log(address p0, address p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2));
    }

    function log(address p0, address p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2));
    }

    function log(address p0, address p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2));
    }

    function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,string)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,address)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,string)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,address)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,string)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,address)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,string)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,address)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,string)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,address)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,string)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,address)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,string)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,address)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,string)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,bool)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,address)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,string)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,bool)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,address)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,string)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,bool)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,address)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,string)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,bool)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,address)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,string)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,bool)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,address)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,string)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,bool)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,address)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,string)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,bool)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,address)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3));
    }
}

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

Contract Security Audit

Contract ABI

API
[{"inputs":[{"components":[{"components":[{"internalType":"uint256","name":"mowseId","type":"uint256"},{"internalType":"int32[7]","name":"stats","type":"int32[7]"},{"internalType":"uint256","name":"maxHealth","type":"uint256"},{"internalType":"uint256","name":"currentHealth","type":"uint256"},{"internalType":"uint256","name":"shield","type":"uint256"},{"internalType":"uint256","name":"attack","type":"uint256"},{"internalType":"bool","name":"canHit","type":"bool"},{"internalType":"uint256","name":"accuracy","type":"uint256"},{"internalType":"uint256","name":"tempAttack","type":"uint256"},{"internalType":"uint256","name":"damageMultiplier","type":"uint256"},{"internalType":"uint256","name":"action","type":"uint256"},{"internalType":"uint256","name":"numberOfHits","type":"uint256"},{"internalType":"enum MowseDungeonClassEnum","name":"class","type":"uint8"},{"components":[{"internalType":"uint256","name":"blind","type":"uint256"},{"internalType":"uint256","name":"eagleEye","type":"uint256"},{"internalType":"uint256","name":"poison","type":"uint256"},{"internalType":"uint256","name":"burn","type":"uint256"},{"internalType":"uint256","name":"bleed","type":"uint256"},{"internalType":"uint256","name":"curse","type":"uint256"},{"internalType":"uint256","name":"stun","type":"uint256"},{"internalType":"uint256","name":"silence","type":"uint256"},{"internalType":"uint256","name":"freeze","type":"uint256"},{"internalType":"uint256","name":"strengthen","type":"uint256"},{"internalType":"uint256","name":"weaken","type":"uint256"},{"internalType":"uint256","name":"bulk","type":"uint256"},{"internalType":"uint256","name":"frail","type":"uint256"},{"internalType":"uint256","name":"thorns","type":"uint256"},{"internalType":"uint256","name":"regen","type":"uint256"},{"internalType":"uint256","name":"sleep","type":"uint256"},{"internalType":"uint256","name":"death","type":"uint256"},{"internalType":"uint256","name":"invincible","type":"uint256"},{"internalType":"uint256","name":"lastHope","type":"uint256"},{"internalType":"uint256","name":"dodge","type":"uint256"},{"internalType":"uint256","name":"healBlock","type":"uint256"},{"internalType":"uint256","name":"charm","type":"uint256"},{"internalType":"uint256","name":"counter","type":"uint256"},{"internalType":"uint256","name":"pierce","type":"uint256"},{"internalType":"uint256","name":"cleave","type":"uint256"},{"internalType":"uint256","name":"revive","type":"uint256"},{"internalType":"uint256","name":"unstoppable","type":"uint256"},{"internalType":"uint256","name":"petrify","type":"uint256"},{"internalType":"uint256","name":"fireResist","type":"uint256"},{"internalType":"uint256","name":"poisonResist","type":"uint256"},{"internalType":"uint256","name":"freezeResist","type":"uint256"},{"internalType":"uint256","name":"stunResist","type":"uint256"},{"internalType":"uint256","name":"sleepResist","type":"uint256"},{"internalType":"uint256","name":"charged","type":"uint256"},{"internalType":"uint256","name":"doubleUp","type":"uint256"},{"internalType":"uint256","name":"rampage","type":"uint256"},{"internalType":"uint256","name":"loneSurvivor","type":"uint256"},{"internalType":"uint256","name":"royalDecree","type":"uint256"},{"internalType":"uint256","name":"wrathfulReprisal","type":"uint256"}],"internalType":"struct MowseDungeonSimpleStatusEffect","name":"statusEffects","type":"tuple"},{"components":[{"internalType":"uint256","name":"dagger","type":"uint256"},{"internalType":"uint256","name":"slingshot","type":"uint256"},{"internalType":"uint256","name":"pendantOfLife","type":"uint256"},{"internalType":"uint256","name":"leech","type":"uint256"},{"internalType":"uint256","name":"poisonDab","type":"uint256"},{"internalType":"uint256","name":"kindle","type":"uint256"},{"internalType":"uint256","name":"bloodLetter","type":"uint256"},{"internalType":"uint256","name":"cursedRing","type":"uint256"},{"internalType":"uint256","name":"stunRod","type":"uint256"},{"internalType":"uint256","name":"silenceBell","type":"uint256"},{"internalType":"uint256","name":"strengthBelt","type":"uint256"},{"internalType":"uint256","name":"weakenedChain","type":"uint256"},{"internalType":"uint256","name":"emblemOfInitiative","type":"uint256"},{"internalType":"uint256","name":"goldRing","type":"uint256"}],"internalType":"struct MowseDungeonSimpleTrinkets","name":"trinkets","type":"tuple"},{"components":[{"internalType":"enum MowseDungeonCompanionEnum","name":"companionId","type":"uint8"},{"internalType":"bool","name":"isUnlocked","type":"bool"},{"internalType":"uint256","name":"level","type":"uint256"},{"internalType":"uint256","name":"experience","type":"uint256"}],"internalType":"struct MowseDungeonCompanion","name":"companion","type":"tuple"},{"components":[{"internalType":"uint256","name":"forestDungeon","type":"uint256"},{"internalType":"uint256","name":"medievalDungeon","type":"uint256"}],"internalType":"struct MowseDungeonDescentLevel","name":"descentLevel","type":"tuple"},{"internalType":"uint256","name":"coins","type":"uint256"},{"internalType":"uint256","name":"currentDungeonRunCount","type":"uint256"},{"internalType":"uint256","name":"currentRoomIndex","type":"uint256"}],"internalType":"struct MowseDungeonSimplePlayer","name":"player","type":"tuple"},{"components":[{"internalType":"enum MowseDungeonMonsterEnum","name":"monsterType","type":"uint8"},{"internalType":"uint256","name":"monsterId","type":"uint256"},{"internalType":"uint256","name":"maxHealth","type":"uint256"},{"internalType":"uint256","name":"currentHealth","type":"uint256"},{"internalType":"uint256","name":"shield","type":"uint256"},{"internalType":"uint256","name":"attack","type":"uint256"},{"internalType":"bool","name":"canHit","type":"bool"},{"internalType":"uint256","name":"accuracy","type":"uint256"},{"internalType":"uint256","name":"tempAttack","type":"uint256"},{"internalType":"uint256","name":"damageMultiplier","type":"uint256"},{"internalType":"enum MowseDungeonSpecialAbilityEnum","name":"specialAbility","type":"uint8"},{"internalType":"bool","name":"isBoss","type":"bool"},{"internalType":"bool","name":"hasBeenStolen","type":"bool"},{"internalType":"bool","name":"usedSpecialAbility","type":"bool"},{"components":[{"internalType":"uint256","name":"blind","type":"uint256"},{"internalType":"uint256","name":"eagleEye","type":"uint256"},{"internalType":"uint256","name":"poison","type":"uint256"},{"internalType":"uint256","name":"burn","type":"uint256"},{"internalType":"uint256","name":"bleed","type":"uint256"},{"internalType":"uint256","name":"curse","type":"uint256"},{"internalType":"uint256","name":"stun","type":"uint256"},{"internalType":"uint256","name":"silence","type":"uint256"},{"internalType":"uint256","name":"freeze","type":"uint256"},{"internalType":"uint256","name":"strengthen","type":"uint256"},{"internalType":"uint256","name":"weaken","type":"uint256"},{"internalType":"uint256","name":"bulk","type":"uint256"},{"internalType":"uint256","name":"frail","type":"uint256"},{"internalType":"uint256","name":"thorns","type":"uint256"},{"internalType":"uint256","name":"regen","type":"uint256"},{"internalType":"uint256","name":"sleep","type":"uint256"},{"internalType":"uint256","name":"death","type":"uint256"},{"internalType":"uint256","name":"invincible","type":"uint256"},{"internalType":"uint256","name":"lastHope","type":"uint256"},{"internalType":"uint256","name":"dodge","type":"uint256"},{"internalType":"uint256","name":"healBlock","type":"uint256"},{"internalType":"uint256","name":"charm","type":"uint256"},{"internalType":"uint256","name":"counter","type":"uint256"},{"internalType":"uint256","name":"pierce","type":"uint256"},{"internalType":"uint256","name":"cleave","type":"uint256"},{"internalType":"uint256","name":"revive","type":"uint256"},{"internalType":"uint256","name":"unstoppable","type":"uint256"},{"internalType":"uint256","name":"petrify","type":"uint256"},{"internalType":"uint256","name":"fireResist","type":"uint256"},{"internalType":"uint256","name":"poisonResist","type":"uint256"},{"internalType":"uint256","name":"freezeResist","type":"uint256"},{"internalType":"uint256","name":"stunResist","type":"uint256"},{"internalType":"uint256","name":"sleepResist","type":"uint256"},{"internalType":"uint256","name":"charged","type":"uint256"},{"internalType":"uint256","name":"doubleUp","type":"uint256"},{"internalType":"uint256","name":"rampage","type":"uint256"},{"internalType":"uint256","name":"loneSurvivor","type":"uint256"},{"internalType":"uint256","name":"royalDecree","type":"uint256"},{"internalType":"uint256","name":"wrathfulReprisal","type":"uint256"}],"internalType":"struct MowseDungeonSimpleStatusEffect","name":"statusEffects","type":"tuple"},{"internalType":"string","name":"image","type":"string"}],"internalType":"struct MowseDungeonSimpleMonster","name":"monster1","type":"tuple"},{"components":[{"internalType":"enum MowseDungeonMonsterEnum","name":"monsterType","type":"uint8"},{"internalType":"uint256","name":"monsterId","type":"uint256"},{"internalType":"uint256","name":"maxHealth","type":"uint256"},{"internalType":"uint256","name":"currentHealth","type":"uint256"},{"internalType":"uint256","name":"shield","type":"uint256"},{"internalType":"uint256","name":"attack","type":"uint256"},{"internalType":"bool","name":"canHit","type":"bool"},{"internalType":"uint256","name":"accuracy","type":"uint256"},{"internalType":"uint256","name":"tempAttack","type":"uint256"},{"internalType":"uint256","name":"damageMultiplier","type":"uint256"},{"internalType":"enum MowseDungeonSpecialAbilityEnum","name":"specialAbility","type":"uint8"},{"internalType":"bool","name":"isBoss","type":"bool"},{"internalType":"bool","name":"hasBeenStolen","type":"bool"},{"internalType":"bool","name":"usedSpecialAbility","type":"bool"},{"components":[{"internalType":"uint256","name":"blind","type":"uint256"},{"internalType":"uint256","name":"eagleEye","type":"uint256"},{"internalType":"uint256","name":"poison","type":"uint256"},{"internalType":"uint256","name":"burn","type":"uint256"},{"internalType":"uint256","name":"bleed","type":"uint256"},{"internalType":"uint256","name":"curse","type":"uint256"},{"internalType":"uint256","name":"stun","type":"uint256"},{"internalType":"uint256","name":"silence","type":"uint256"},{"internalType":"uint256","name":"freeze","type":"uint256"},{"internalType":"uint256","name":"strengthen","type":"uint256"},{"internalType":"uint256","name":"weaken","type":"uint256"},{"internalType":"uint256","name":"bulk","type":"uint256"},{"internalType":"uint256","name":"frail","type":"uint256"},{"internalType":"uint256","name":"thorns","type":"uint256"},{"internalType":"uint256","name":"regen","type":"uint256"},{"internalType":"uint256","name":"sleep","type":"uint256"},{"internalType":"uint256","name":"death","type":"uint256"},{"internalType":"uint256","name":"invincible","type":"uint256"},{"internalType":"uint256","name":"lastHope","type":"uint256"},{"internalType":"uint256","name":"dodge","type":"uint256"},{"internalType":"uint256","name":"healBlock","type":"uint256"},{"internalType":"uint256","name":"charm","type":"uint256"},{"internalType":"uint256","name":"counter","type":"uint256"},{"internalType":"uint256","name":"pierce","type":"uint256"},{"internalType":"uint256","name":"cleave","type":"uint256"},{"internalType":"uint256","name":"revive","type":"uint256"},{"internalType":"uint256","name":"unstoppable","type":"uint256"},{"internalType":"uint256","name":"petrify","type":"uint256"},{"internalType":"uint256","name":"fireResist","type":"uint256"},{"internalType":"uint256","name":"poisonResist","type":"uint256"},{"internalType":"uint256","name":"freezeResist","type":"uint256"},{"internalType":"uint256","name":"stunResist","type":"uint256"},{"internalType":"uint256","name":"sleepResist","type":"uint256"},{"internalType":"uint256","name":"charged","type":"uint256"},{"internalType":"uint256","name":"doubleUp","type":"uint256"},{"internalType":"uint256","name":"rampage","type":"uint256"},{"internalType":"uint256","name":"loneSurvivor","type":"uint256"},{"internalType":"uint256","name":"royalDecree","type":"uint256"},{"internalType":"uint256","name":"wrathfulReprisal","type":"uint256"}],"internalType":"struct MowseDungeonSimpleStatusEffect","name":"statusEffects","type":"tuple"},{"internalType":"string","name":"image","type":"string"}],"internalType":"struct MowseDungeonSimpleMonster","name":"monster2","type":"tuple"},{"components":[{"internalType":"enum MowseDungeonMonsterEnum","name":"monsterType","type":"uint8"},{"internalType":"uint256","name":"monsterId","type":"uint256"},{"internalType":"uint256","name":"maxHealth","type":"uint256"},{"internalType":"uint256","name":"currentHealth","type":"uint256"},{"internalType":"uint256","name":"shield","type":"uint256"},{"internalType":"uint256","name":"attack","type":"uint256"},{"internalType":"bool","name":"canHit","type":"bool"},{"internalType":"uint256","name":"accuracy","type":"uint256"},{"internalType":"uint256","name":"tempAttack","type":"uint256"},{"internalType":"uint256","name":"damageMultiplier","type":"uint256"},{"internalType":"enum MowseDungeonSpecialAbilityEnum","name":"specialAbility","type":"uint8"},{"internalType":"bool","name":"isBoss","type":"bool"},{"internalType":"bool","name":"hasBeenStolen","type":"bool"},{"internalType":"bool","name":"usedSpecialAbility","type":"bool"},{"components":[{"internalType":"uint256","name":"blind","type":"uint256"},{"internalType":"uint256","name":"eagleEye","type":"uint256"},{"internalType":"uint256","name":"poison","type":"uint256"},{"internalType":"uint256","name":"burn","type":"uint256"},{"internalType":"uint256","name":"bleed","type":"uint256"},{"internalType":"uint256","name":"curse","type":"uint256"},{"internalType":"uint256","name":"stun","type":"uint256"},{"internalType":"uint256","name":"silence","type":"uint256"},{"internalType":"uint256","name":"freeze","type":"uint256"},{"internalType":"uint256","name":"strengthen","type":"uint256"},{"internalType":"uint256","name":"weaken","type":"uint256"},{"internalType":"uint256","name":"bulk","type":"uint256"},{"internalType":"uint256","name":"frail","type":"uint256"},{"internalType":"uint256","name":"thorns","type":"uint256"},{"internalType":"uint256","name":"regen","type":"uint256"},{"internalType":"uint256","name":"sleep","type":"uint256"},{"internalType":"uint256","name":"death","type":"uint256"},{"internalType":"uint256","name":"invincible","type":"uint256"},{"internalType":"uint256","name":"lastHope","type":"uint256"},{"internalType":"uint256","name":"dodge","type":"uint256"},{"internalType":"uint256","name":"healBlock","type":"uint256"},{"internalType":"uint256","name":"charm","type":"uint256"},{"internalType":"uint256","name":"counter","type":"uint256"},{"internalType":"uint256","name":"pierce","type":"uint256"},{"internalType":"uint256","name":"cleave","type":"uint256"},{"internalType":"uint256","name":"revive","type":"uint256"},{"internalType":"uint256","name":"unstoppable","type":"uint256"},{"internalType":"uint256","name":"petrify","type":"uint256"},{"internalType":"uint256","name":"fireResist","type":"uint256"},{"internalType":"uint256","name":"poisonResist","type":"uint256"},{"internalType":"uint256","name":"freezeResist","type":"uint256"},{"internalType":"uint256","name":"stunResist","type":"uint256"},{"internalType":"uint256","name":"sleepResist","type":"uint256"},{"internalType":"uint256","name":"charged","type":"uint256"},{"internalType":"uint256","name":"doubleUp","type":"uint256"},{"internalType":"uint256","name":"rampage","type":"uint256"},{"internalType":"uint256","name":"loneSurvivor","type":"uint256"},{"internalType":"uint256","name":"royalDecree","type":"uint256"},{"internalType":"uint256","name":"wrathfulReprisal","type":"uint256"}],"internalType":"struct MowseDungeonSimpleStatusEffect","name":"statusEffects","type":"tuple"},{"internalType":"string","name":"image","type":"string"}],"internalType":"struct MowseDungeonSimpleMonster","name":"monster3","type":"tuple"},{"internalType":"uint256","name":"dungeonId","type":"uint256"},{"internalType":"uint256","name":"seed","type":"uint256"},{"internalType":"enum MowseDungeonActionTypeEnum","name":"actionType","type":"uint8"},{"internalType":"uint8","name":"targetIndex","type":"uint8"},{"internalType":"uint256","name":"actionsRun","type":"uint256"},{"internalType":"enum MowseDungeonTrinketEnum[]","name":"stolenTrinkets","type":"uint8[]"},{"internalType":"uint256","name":"stolenTrinketCount","type":"uint256"},{"internalType":"bool","name":"isStealSuccessful","type":"bool"},{"internalType":"enum MowseDungeonBattleStatusEnum","name":"status","type":"uint8"},{"components":[{"internalType":"uint256","name":"damageDealt","type":"uint256"},{"internalType":"uint256","name":"damageTaken","type":"uint256"},{"internalType":"uint256","name":"healthHealed","type":"uint256"},{"internalType":"uint256","name":"burnDamageDealt","type":"uint256"},{"internalType":"uint256","name":"poisonDamageDealt","type":"uint256"},{"internalType":"uint256","name":"bleedDamageDealt","type":"uint256"},{"internalType":"uint256","name":"curseDamageDealt","type":"uint256"},{"internalType":"uint256","name":"trinketsStolen","type":"uint256"}],"internalType":"struct MowseDungeonSimplePlayerAchievementsProgress","name":"achievementProgress","type":"tuple"},{"internalType":"uint256","name":"descentLevel","type":"uint256"},{"components":[{"internalType":"enum MowseDungeonBattleLogTypeEnum","name":"logType","type":"uint8"},{"internalType":"enum MowseDungeonBattleLogSourceEnum","name":"source","type":"uint8"},{"internalType":"enum MowseDungeonBattleLogSourceEnum","name":"target","type":"uint8"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct MowseDungeonBattleLog[]","name":"battleLog","type":"tuple[]"},{"internalType":"uint256","name":"battleLogCount","type":"uint256"}],"internalType":"struct MowseDungeonBattleSimulation","name":"_battleSimulation","type":"tuple"},{"components":[{"internalType":"enum MowseDungeonMonsterEnum","name":"monsterType","type":"uint8"},{"internalType":"uint256","name":"monsterId","type":"uint256"},{"internalType":"uint256","name":"maxHealth","type":"uint256"},{"internalType":"uint256","name":"currentHealth","type":"uint256"},{"internalType":"uint256","name":"shield","type":"uint256"},{"internalType":"uint256","name":"attack","type":"uint256"},{"internalType":"bool","name":"canHit","type":"bool"},{"internalType":"uint256","name":"accuracy","type":"uint256"},{"internalType":"uint256","name":"tempAttack","type":"uint256"},{"internalType":"uint256","name":"damageMultiplier","type":"uint256"},{"internalType":"enum MowseDungeonSpecialAbilityEnum","name":"specialAbility","type":"uint8"},{"internalType":"bool","name":"isBoss","type":"bool"},{"internalType":"bool","name":"hasBeenStolen","type":"bool"},{"internalType":"bool","name":"usedSpecialAbility","type":"bool"},{"components":[{"internalType":"uint256","name":"blind","type":"uint256"},{"internalType":"uint256","name":"eagleEye","type":"uint256"},{"internalType":"uint256","name":"poison","type":"uint256"},{"internalType":"uint256","name":"burn","type":"uint256"},{"internalType":"uint256","name":"bleed","type":"uint256"},{"internalType":"uint256","name":"curse","type":"uint256"},{"internalType":"uint256","name":"stun","type":"uint256"},{"internalType":"uint256","name":"silence","type":"uint256"},{"internalType":"uint256","name":"freeze","type":"uint256"},{"internalType":"uint256","name":"strengthen","type":"uint256"},{"internalType":"uint256","name":"weaken","type":"uint256"},{"internalType":"uint256","name":"bulk","type":"uint256"},{"internalType":"uint256","name":"frail","type":"uint256"},{"internalType":"uint256","name":"thorns","type":"uint256"},{"internalType":"uint256","name":"regen","type":"uint256"},{"internalType":"uint256","name":"sleep","type":"uint256"},{"internalType":"uint256","name":"death","type":"uint256"},{"internalType":"uint256","name":"invincible","type":"uint256"},{"internalType":"uint256","name":"lastHope","type":"uint256"},{"internalType":"uint256","name":"dodge","type":"uint256"},{"internalType":"uint256","name":"healBlock","type":"uint256"},{"internalType":"uint256","name":"charm","type":"uint256"},{"internalType":"uint256","name":"counter","type":"uint256"},{"internalType":"uint256","name":"pierce","type":"uint256"},{"internalType":"uint256","name":"cleave","type":"uint256"},{"internalType":"uint256","name":"revive","type":"uint256"},{"internalType":"uint256","name":"unstoppable","type":"uint256"},{"internalType":"uint256","name":"petrify","type":"uint256"},{"internalType":"uint256","name":"fireResist","type":"uint256"},{"internalType":"uint256","name":"poisonResist","type":"uint256"},{"internalType":"uint256","name":"freezeResist","type":"uint256"},{"internalType":"uint256","name":"stunResist","type":"uint256"},{"internalType":"uint256","name":"sleepResist","type":"uint256"},{"internalType":"uint256","name":"charged","type":"uint256"},{"internalType":"uint256","name":"doubleUp","type":"uint256"},{"internalType":"uint256","name":"rampage","type":"uint256"},{"internalType":"uint256","name":"loneSurvivor","type":"uint256"},{"internalType":"uint256","name":"royalDecree","type":"uint256"},{"internalType":"uint256","name":"wrathfulReprisal","type":"uint256"}],"internalType":"struct MowseDungeonSimpleStatusEffect","name":"statusEffects","type":"tuple"},{"internalType":"string","name":"image","type":"string"}],"internalType":"struct MowseDungeonSimpleMonster","name":"_monster","type":"tuple"}],"name":"playerClassAttack","outputs":[{"components":[{"components":[{"internalType":"uint256","name":"mowseId","type":"uint256"},{"internalType":"int32[7]","name":"stats","type":"int32[7]"},{"internalType":"uint256","name":"maxHealth","type":"uint256"},{"internalType":"uint256","name":"currentHealth","type":"uint256"},{"internalType":"uint256","name":"shield","type":"uint256"},{"internalType":"uint256","name":"attack","type":"uint256"},{"internalType":"bool","name":"canHit","type":"bool"},{"internalType":"uint256","name":"accuracy","type":"uint256"},{"internalType":"uint256","name":"tempAttack","type":"uint256"},{"internalType":"uint256","name":"damageMultiplier","type":"uint256"},{"internalType":"uint256","name":"action","type":"uint256"},{"internalType":"uint256","name":"numberOfHits","type":"uint256"},{"internalType":"enum MowseDungeonClassEnum","name":"class","type":"uint8"},{"components":[{"internalType":"uint256","name":"blind","type":"uint256"},{"internalType":"uint256","name":"eagleEye","type":"uint256"},{"internalType":"uint256","name":"poison","type":"uint256"},{"internalType":"uint256","name":"burn","type":"uint256"},{"internalType":"uint256","name":"bleed","type":"uint256"},{"internalType":"uint256","name":"curse","type":"uint256"},{"internalType":"uint256","name":"stun","type":"uint256"},{"internalType":"uint256","name":"silence","type":"uint256"},{"internalType":"uint256","name":"freeze","type":"uint256"},{"internalType":"uint256","name":"strengthen","type":"uint256"},{"internalType":"uint256","name":"weaken","type":"uint256"},{"internalType":"uint256","name":"bulk","type":"uint256"},{"internalType":"uint256","name":"frail","type":"uint256"},{"internalType":"uint256","name":"thorns","type":"uint256"},{"internalType":"uint256","name":"regen","type":"uint256"},{"internalType":"uint256","name":"sleep","type":"uint256"},{"internalType":"uint256","name":"death","type":"uint256"},{"internalType":"uint256","name":"invincible","type":"uint256"},{"internalType":"uint256","name":"lastHope","type":"uint256"},{"internalType":"uint256","name":"dodge","type":"uint256"},{"internalType":"uint256","name":"healBlock","type":"uint256"},{"internalType":"uint256","name":"charm","type":"uint256"},{"internalType":"uint256","name":"counter","type":"uint256"},{"internalType":"uint256","name":"pierce","type":"uint256"},{"internalType":"uint256","name":"cleave","type":"uint256"},{"internalType":"uint256","name":"revive","type":"uint256"},{"internalType":"uint256","name":"unstoppable","type":"uint256"},{"internalType":"uint256","name":"petrify","type":"uint256"},{"internalType":"uint256","name":"fireResist","type":"uint256"},{"internalType":"uint256","name":"poisonResist","type":"uint256"},{"internalType":"uint256","name":"freezeResist","type":"uint256"},{"internalType":"uint256","name":"stunResist","type":"uint256"},{"internalType":"uint256","name":"sleepResist","type":"uint256"},{"internalType":"uint256","name":"charged","type":"uint256"},{"internalType":"uint256","name":"doubleUp","type":"uint256"},{"internalType":"uint256","name":"rampage","type":"uint256"},{"internalType":"uint256","name":"loneSurvivor","type":"uint256"},{"internalType":"uint256","name":"royalDecree","type":"uint256"},{"internalType":"uint256","name":"wrathfulReprisal","type":"uint256"}],"internalType":"struct MowseDungeonSimpleStatusEffect","name":"statusEffects","type":"tuple"},{"components":[{"internalType":"uint256","name":"dagger","type":"uint256"},{"internalType":"uint256","name":"slingshot","type":"uint256"},{"internalType":"uint256","name":"pendantOfLife","type":"uint256"},{"internalType":"uint256","name":"leech","type":"uint256"},{"internalType":"uint256","name":"poisonDab","type":"uint256"},{"internalType":"uint256","name":"kindle","type":"uint256"},{"internalType":"uint256","name":"bloodLetter","type":"uint256"},{"internalType":"uint256","name":"cursedRing","type":"uint256"},{"internalType":"uint256","name":"stunRod","type":"uint256"},{"internalType":"uint256","name":"silenceBell","type":"uint256"},{"internalType":"uint256","name":"strengthBelt","type":"uint256"},{"internalType":"uint256","name":"weakenedChain","type":"uint256"},{"internalType":"uint256","name":"emblemOfInitiative","type":"uint256"},{"internalType":"uint256","name":"goldRing","type":"uint256"}],"internalType":"struct MowseDungeonSimpleTrinkets","name":"trinkets","type":"tuple"},{"components":[{"internalType":"enum MowseDungeonCompanionEnum","name":"companionId","type":"uint8"},{"internalType":"bool","name":"isUnlocked","type":"bool"},{"internalType":"uint256","name":"level","type":"uint256"},{"internalType":"uint256","name":"experience","type":"uint256"}],"internalType":"struct MowseDungeonCompanion","name":"companion","type":"tuple"},{"components":[{"internalType":"uint256","name":"forestDungeon","type":"uint256"},{"internalType":"uint256","name":"medievalDungeon","type":"uint256"}],"internalType":"struct MowseDungeonDescentLevel","name":"descentLevel","type":"tuple"},{"internalType":"uint256","name":"coins","type":"uint256"},{"internalType":"uint256","name":"currentDungeonRunCount","type":"uint256"},{"internalType":"uint256","name":"currentRoomIndex","type":"uint256"}],"internalType":"struct MowseDungeonSimplePlayer","name":"player","type":"tuple"},{"components":[{"internalType":"enum MowseDungeonMonsterEnum","name":"monsterType","type":"uint8"},{"internalType":"uint256","name":"monsterId","type":"uint256"},{"internalType":"uint256","name":"maxHealth","type":"uint256"},{"internalType":"uint256","name":"currentHealth","type":"uint256"},{"internalType":"uint256","name":"shield","type":"uint256"},{"internalType":"uint256","name":"attack","type":"uint256"},{"internalType":"bool","name":"canHit","type":"bool"},{"internalType":"uint256","name":"accuracy","type":"uint256"},{"internalType":"uint256","name":"tempAttack","type":"uint256"},{"internalType":"uint256","name":"damageMultiplier","type":"uint256"},{"internalType":"enum MowseDungeonSpecialAbilityEnum","name":"specialAbility","type":"uint8"},{"internalType":"bool","name":"isBoss","type":"bool"},{"internalType":"bool","name":"hasBeenStolen","type":"bool"},{"internalType":"bool","name":"usedSpecialAbility","type":"bool"},{"components":[{"internalType":"uint256","name":"blind","type":"uint256"},{"internalType":"uint256","name":"eagleEye","type":"uint256"},{"internalType":"uint256","name":"poison","type":"uint256"},{"internalType":"uint256","name":"burn","type":"uint256"},{"internalType":"uint256","name":"bleed","type":"uint256"},{"internalType":"uint256","name":"curse","type":"uint256"},{"internalType":"uint256","name":"stun","type":"uint256"},{"internalType":"uint256","name":"silence","type":"uint256"},{"internalType":"uint256","name":"freeze","type":"uint256"},{"internalType":"uint256","name":"strengthen","type":"uint256"},{"internalType":"uint256","name":"weaken","type":"uint256"},{"internalType":"uint256","name":"bulk","type":"uint256"},{"internalType":"uint256","name":"frail","type":"uint256"},{"internalType":"uint256","name":"thorns","type":"uint256"},{"internalType":"uint256","name":"regen","type":"uint256"},{"internalType":"uint256","name":"sleep","type":"uint256"},{"internalType":"uint256","name":"death","type":"uint256"},{"internalType":"uint256","name":"invincible","type":"uint256"},{"internalType":"uint256","name":"lastHope","type":"uint256"},{"internalType":"uint256","name":"dodge","type":"uint256"},{"internalType":"uint256","name":"healBlock","type":"uint256"},{"internalType":"uint256","name":"charm","type":"uint256"},{"internalType":"uint256","name":"counter","type":"uint256"},{"internalType":"uint256","name":"pierce","type":"uint256"},{"internalType":"uint256","name":"cleave","type":"uint256"},{"internalType":"uint256","name":"revive","type":"uint256"},{"internalType":"uint256","name":"unstoppable","type":"uint256"},{"internalType":"uint256","name":"petrify","type":"uint256"},{"internalType":"uint256","name":"fireResist","type":"uint256"},{"internalType":"uint256","name":"poisonResist","type":"uint256"},{"internalType":"uint256","name":"freezeResist","type":"uint256"},{"internalType":"uint256","name":"stunResist","type":"uint256"},{"internalType":"uint256","name":"sleepResist","type":"uint256"},{"internalType":"uint256","name":"charged","type":"uint256"},{"internalType":"uint256","name":"doubleUp","type":"uint256"},{"internalType":"uint256","name":"rampage","type":"uint256"},{"internalType":"uint256","name":"loneSurvivor","type":"uint256"},{"internalType":"uint256","name":"royalDecree","type":"uint256"},{"internalType":"uint256","name":"wrathfulReprisal","type":"uint256"}],"internalType":"struct MowseDungeonSimpleStatusEffect","name":"statusEffects","type":"tuple"},{"internalType":"string","name":"image","type":"string"}],"internalType":"struct MowseDungeonSimpleMonster","name":"monster1","type":"tuple"},{"components":[{"internalType":"enum MowseDungeonMonsterEnum","name":"monsterType","type":"uint8"},{"internalType":"uint256","name":"monsterId","type":"uint256"},{"internalType":"uint256","name":"maxHealth","type":"uint256"},{"internalType":"uint256","name":"currentHealth","type":"uint256"},{"internalType":"uint256","name":"shield","type":"uint256"},{"internalType":"uint256","name":"attack","type":"uint256"},{"internalType":"bool","name":"canHit","type":"bool"},{"internalType":"uint256","name":"accuracy","type":"uint256"},{"internalType":"uint256","name":"tempAttack","type":"uint256"},{"internalType":"uint256","name":"damageMultiplier","type":"uint256"},{"internalType":"enum MowseDungeonSpecialAbilityEnum","name":"specialAbility","type":"uint8"},{"internalType":"bool","name":"isBoss","type":"bool"},{"internalType":"bool","name":"hasBeenStolen","type":"bool"},{"internalType":"bool","name":"usedSpecialAbility","type":"bool"},{"components":[{"internalType":"uint256","name":"blind","type":"uint256"},{"internalType":"uint256","name":"eagleEye","type":"uint256"},{"internalType":"uint256","name":"poison","type":"uint256"},{"internalType":"uint256","name":"burn","type":"uint256"},{"internalType":"uint256","name":"bleed","type":"uint256"},{"internalType":"uint256","name":"curse","type":"uint256"},{"internalType":"uint256","name":"stun","type":"uint256"},{"internalType":"uint256","name":"silence","type":"uint256"},{"internalType":"uint256","name":"freeze","type":"uint256"},{"internalType":"uint256","name":"strengthen","type":"uint256"},{"internalType":"uint256","name":"weaken","type":"uint256"},{"internalType":"uint256","name":"bulk","type":"uint256"},{"internalType":"uint256","name":"frail","type":"uint256"},{"internalType":"uint256","name":"thorns","type":"uint256"},{"internalType":"uint256","name":"regen","type":"uint256"},{"internalType":"uint256","name":"sleep","type":"uint256"},{"internalType":"uint256","name":"death","type":"uint256"},{"internalType":"uint256","name":"invincible","type":"uint256"},{"internalType":"uint256","name":"lastHope","type":"uint256"},{"internalType":"uint256","name":"dodge","type":"uint256"},{"internalType":"uint256","name":"healBlock","type":"uint256"},{"internalType":"uint256","name":"charm","type":"uint256"},{"internalType":"uint256","name":"counter","type":"uint256"},{"internalType":"uint256","name":"pierce","type":"uint256"},{"internalType":"uint256","name":"cleave","type":"uint256"},{"internalType":"uint256","name":"revive","type":"uint256"},{"internalType":"uint256","name":"unstoppable","type":"uint256"},{"internalType":"uint256","name":"petrify","type":"uint256"},{"internalType":"uint256","name":"fireResist","type":"uint256"},{"internalType":"uint256","name":"poisonResist","type":"uint256"},{"internalType":"uint256","name":"freezeResist","type":"uint256"},{"internalType":"uint256","name":"stunResist","type":"uint256"},{"internalType":"uint256","name":"sleepResist","type":"uint256"},{"internalType":"uint256","name":"charged","type":"uint256"},{"internalType":"uint256","name":"doubleUp","type":"uint256"},{"internalType":"uint256","name":"rampage","type":"uint256"},{"internalType":"uint256","name":"loneSurvivor","type":"uint256"},{"internalType":"uint256","name":"royalDecree","type":"uint256"},{"internalType":"uint256","name":"wrathfulReprisal","type":"uint256"}],"internalType":"struct MowseDungeonSimpleStatusEffect","name":"statusEffects","type":"tuple"},{"internalType":"string","name":"image","type":"string"}],"internalType":"struct MowseDungeonSimpleMonster","name":"monster2","type":"tuple"},{"components":[{"internalType":"enum MowseDungeonMonsterEnum","name":"monsterType","type":"uint8"},{"internalType":"uint256","name":"monsterId","type":"uint256"},{"internalType":"uint256","name":"maxHealth","type":"uint256"},{"internalType":"uint256","name":"currentHealth","type":"uint256"},{"internalType":"uint256","name":"shield","type":"uint256"},{"internalType":"uint256","name":"attack","type":"uint256"},{"internalType":"bool","name":"canHit","type":"bool"},{"internalType":"uint256","name":"accuracy","type":"uint256"},{"internalType":"uint256","name":"tempAttack","type":"uint256"},{"internalType":"uint256","name":"damageMultiplier","type":"uint256"},{"internalType":"enum MowseDungeonSpecialAbilityEnum","name":"specialAbility","type":"uint8"},{"internalType":"bool","name":"isBoss","type":"bool"},{"internalType":"bool","name":"hasBeenStolen","type":"bool"},{"internalType":"bool","name":"usedSpecialAbility","type":"bool"},{"components":[{"internalType":"uint256","name":"blind","type":"uint256"},{"internalType":"uint256","name":"eagleEye","type":"uint256"},{"internalType":"uint256","name":"poison","type":"uint256"},{"internalType":"uint256","name":"burn","type":"uint256"},{"internalType":"uint256","name":"bleed","type":"uint256"},{"internalType":"uint256","name":"curse","type":"uint256"},{"internalType":"uint256","name":"stun","type":"uint256"},{"internalType":"uint256","name":"silence","type":"uint256"},{"internalType":"uint256","name":"freeze","type":"uint256"},{"internalType":"uint256","name":"strengthen","type":"uint256"},{"internalType":"uint256","name":"weaken","type":"uint256"},{"internalType":"uint256","name":"bulk","type":"uint256"},{"internalType":"uint256","name":"frail","type":"uint256"},{"internalType":"uint256","name":"thorns","type":"uint256"},{"internalType":"uint256","name":"regen","type":"uint256"},{"internalType":"uint256","name":"sleep","type":"uint256"},{"internalType":"uint256","name":"death","type":"uint256"},{"internalType":"uint256","name":"invincible","type":"uint256"},{"internalType":"uint256","name":"lastHope","type":"uint256"},{"internalType":"uint256","name":"dodge","type":"uint256"},{"internalType":"uint256","name":"healBlock","type":"uint256"},{"internalType":"uint256","name":"charm","type":"uint256"},{"internalType":"uint256","name":"counter","type":"uint256"},{"internalType":"uint256","name":"pierce","type":"uint256"},{"internalType":"uint256","name":"cleave","type":"uint256"},{"internalType":"uint256","name":"revive","type":"uint256"},{"internalType":"uint256","name":"unstoppable","type":"uint256"},{"internalType":"uint256","name":"petrify","type":"uint256"},{"internalType":"uint256","name":"fireResist","type":"uint256"},{"internalType":"uint256","name":"poisonResist","type":"uint256"},{"internalType":"uint256","name":"freezeResist","type":"uint256"},{"internalType":"uint256","name":"stunResist","type":"uint256"},{"internalType":"uint256","name":"sleepResist","type":"uint256"},{"internalType":"uint256","name":"charged","type":"uint256"},{"internalType":"uint256","name":"doubleUp","type":"uint256"},{"internalType":"uint256","name":"rampage","type":"uint256"},{"internalType":"uint256","name":"loneSurvivor","type":"uint256"},{"internalType":"uint256","name":"royalDecree","type":"uint256"},{"internalType":"uint256","name":"wrathfulReprisal","type":"uint256"}],"internalType":"struct MowseDungeonSimpleStatusEffect","name":"statusEffects","type":"tuple"},{"internalType":"string","name":"image","type":"string"}],"internalType":"struct MowseDungeonSimpleMonster","name":"monster3","type":"tuple"},{"internalType":"uint256","name":"dungeonId","type":"uint256"},{"internalType":"uint256","name":"seed","type":"uint256"},{"internalType":"enum MowseDungeonActionTypeEnum","name":"actionType","type":"uint8"},{"internalType":"uint8","name":"targetIndex","type":"uint8"},{"internalType":"uint256","name":"actionsRun","type":"uint256"},{"internalType":"enum MowseDungeonTrinketEnum[]","name":"stolenTrinkets","type":"uint8[]"},{"internalType":"uint256","name":"stolenTrinketCount","type":"uint256"},{"internalType":"bool","name":"isStealSuccessful","type":"bool"},{"internalType":"enum MowseDungeonBattleStatusEnum","name":"status","type":"uint8"},{"components":[{"internalType":"uint256","name":"damageDealt","type":"uint256"},{"internalType":"uint256","name":"damageTaken","type":"uint256"},{"internalType":"uint256","name":"healthHealed","type":"uint256"},{"internalType":"uint256","name":"burnDamageDealt","type":"uint256"},{"internalType":"uint256","name":"poisonDamageDealt","type":"uint256"},{"internalType":"uint256","name":"bleedDamageDealt","type":"uint256"},{"internalType":"uint256","name":"curseDamageDealt","type":"uint256"},{"internalType":"uint256","name":"trinketsStolen","type":"uint256"}],"internalType":"struct MowseDungeonSimplePlayerAchievementsProgress","name":"achievementProgress","type":"tuple"},{"internalType":"uint256","name":"descentLevel","type":"uint256"},{"components":[{"internalType":"enum MowseDungeonBattleLogTypeEnum","name":"logType","type":"uint8"},{"internalType":"enum MowseDungeonBattleLogSourceEnum","name":"source","type":"uint8"},{"internalType":"enum MowseDungeonBattleLogSourceEnum","name":"target","type":"uint8"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct MowseDungeonBattleLog[]","name":"battleLog","type":"tuple[]"},{"internalType":"uint256","name":"battleLogCount","type":"uint256"}],"internalType":"struct MowseDungeonBattleSimulation","name":"","type":"tuple"},{"components":[{"internalType":"enum MowseDungeonMonsterEnum","name":"monsterType","type":"uint8"},{"internalType":"uint256","name":"monsterId","type":"uint256"},{"internalType":"uint256","name":"maxHealth","type":"uint256"},{"internalType":"uint256","name":"currentHealth","type":"uint256"},{"internalType":"uint256","name":"shield","type":"uint256"},{"internalType":"uint256","name":"attack","type":"uint256"},{"internalType":"bool","name":"canHit","type":"bool"},{"internalType":"uint256","name":"accuracy","type":"uint256"},{"internalType":"uint256","name":"tempAttack","type":"uint256"},{"internalType":"uint256","name":"damageMultiplier","type":"uint256"},{"internalType":"enum MowseDungeonSpecialAbilityEnum","name":"specialAbility","type":"uint8"},{"internalType":"bool","name":"isBoss","type":"bool"},{"internalType":"bool","name":"hasBeenStolen","type":"bool"},{"internalType":"bool","name":"usedSpecialAbility","type":"bool"},{"components":[{"internalType":"uint256","name":"blind","type":"uint256"},{"internalType":"uint256","name":"eagleEye","type":"uint256"},{"internalType":"uint256","name":"poison","type":"uint256"},{"internalType":"uint256","name":"burn","type":"uint256"},{"internalType":"uint256","name":"bleed","type":"uint256"},{"internalType":"uint256","name":"curse","type":"uint256"},{"internalType":"uint256","name":"stun","type":"uint256"},{"internalType":"uint256","name":"silence","type":"uint256"},{"internalType":"uint256","name":"freeze","type":"uint256"},{"internalType":"uint256","name":"strengthen","type":"uint256"},{"internalType":"uint256","name":"weaken","type":"uint256"},{"internalType":"uint256","name":"bulk","type":"uint256"},{"internalType":"uint256","name":"frail","type":"uint256"},{"internalType":"uint256","name":"thorns","type":"uint256"},{"internalType":"uint256","name":"regen","type":"uint256"},{"internalType":"uint256","name":"sleep","type":"uint256"},{"internalType":"uint256","name":"death","type":"uint256"},{"internalType":"uint256","name":"invincible","type":"uint256"},{"internalType":"uint256","name":"lastHope","type":"uint256"},{"internalType":"uint256","name":"dodge","type":"uint256"},{"internalType":"uint256","name":"healBlock","type":"uint256"},{"internalType":"uint256","name":"charm","type":"uint256"},{"internalType":"uint256","name":"counter","type":"uint256"},{"internalType":"uint256","name":"pierce","type":"uint256"},{"internalType":"uint256","name":"cleave","type":"uint256"},{"internalType":"uint256","name":"revive","type":"uint256"},{"internalType":"uint256","name":"unstoppable","type":"uint256"},{"internalType":"uint256","name":"petrify","type":"uint256"},{"internalType":"uint256","name":"fireResist","type":"uint256"},{"internalType":"uint256","name":"poisonResist","type":"uint256"},{"internalType":"uint256","name":"freezeResist","type":"uint256"},{"internalType":"uint256","name":"stunResist","type":"uint256"},{"internalType":"uint256","name":"sleepResist","type":"uint256"},{"internalType":"uint256","name":"charged","type":"uint256"},{"internalType":"uint256","name":"doubleUp","type":"uint256"},{"internalType":"uint256","name":"rampage","type":"uint256"},{"internalType":"uint256","name":"loneSurvivor","type":"uint256"},{"internalType":"uint256","name":"royalDecree","type":"uint256"},{"internalType":"uint256","name":"wrathfulReprisal","type":"uint256"}],"internalType":"struct MowseDungeonSimpleStatusEffect","name":"statusEffects","type":"tuple"},{"internalType":"string","name":"image","type":"string"}],"internalType":"struct MowseDungeonSimpleMonster","name":"","type":"tuple"}],"stateMutability":"pure","type":"function"}]

608060405234801561001057600080fd5b506136d3806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f7debabb14610030575b600080fd5b61004361003e366004612bea565b61005a565b6040516100519291906133fb565b60405180910390f35b610062611ddc565b61006a611ed1565b610072611ed1565b606461008686600001516101800151610fb0565b8651610100015161009791906135c2565b6100a191906135ef565b8551610100015284516101c0015160200151156100f05783604001518460600151036100f05784516101c00151602001516100dd90600a6135c2565b6100e890606e613603565b855161012001525b6101c084015161016001511561011c57601e8560000151610120018181516101189190613616565b9052505b6101c084015161018001511561014857601e8560000151610120018181516101449190613603565b9052505b6101c08401516101e00151156101835760328560000151610120018181516101709190613603565b9052506101c084015160006101e0909101525b84516101208101516101009091015160649161019e916135c2565b6101a891906135ef565b855161010001528451600161016090910152600085516101800151600a8111156101d4576101d4612df7565b1480156101f6575060018560c0015160048111156101f4576101f4612df7565b145b156102b65760208501516060015115610238576102198586602001516000611108565b6020820181905260e0820151919650915060ff16600003610238578093505b60408501516060015115610275576102568586604001516001611108565b6040820181905260e0820151919650915060ff16600103610275578093505b6060808601510151156102b1576102928586606001516002611108565b6060820181905260e0820151919650915060ff166002036102b1578093505b610fa7565b600185516101800151600a8111156102d0576102d0612df7565b1480156102f2575060018560c0015160048111156102f0576102f0612df7565b145b1561036f57845160a001516103089060026135c2565b8551610100015260e0850151610324908690869060ff16611108565b6101c0810151610380015191965091506000036103675761034c8560006002600b60016111f7565b6101c0820151606001805191965061036382613629565b9052505b809350610fa7565b600285516101800151600a81111561038957610389612df7565b1480156103ab575060018560c0015160048111156103a9576103a9612df7565b145b15610569576103bd856009600261124f565b9450600285600001516101a001516020018181516103db9190613603565b90525060e08501516103f3908690869060ff16611108565b81516020015191965091506000906002602002015160030b13156104e95784516020015160009060149061042f9060025b602002015160030b90565b61043991906135ef565b610444906001613603565b90505b80156104e35761045f86608001518760a0015161126e565b60a0870181905261047290600290613658565b6000036104d1576104a46040518060400160405280600a81526020016948697420616761696e2160b01b8152506112bc565b6104b686838860e0015160ff16611108565b81516101600180519298509093506104cd82613629565b9052505b806104db8161366c565b915050610447565b50610367565b6104fb85608001518660a0015161126e565b60a0860181905261050e90600290613658565b600003610367576105406040518060400160405280600a81526020016948697420416761696e2160b01b8152506112bc565b61055285858760e0015160ff16611108565b815161016001805192975090925061036382613629565b600385516101800151600a81111561058357610583612df7565b0361065c5760018560c0015160048111156105a0576105a0612df7565b036105d5576105b285601b600261124f565b9450600285600001516101a00151610260018181516105d19190613603565b9052505b845160026101609091015260005b6002811015610653576105fe86868860e0015160ff16611108565b6101c08101516103a001519197509250600003610641576106268660006002600a60016111f7565b6101c0830151604001805191975061063d82613629565b9052505b8061064b81613629565b9150506105e3565b50809350610fa7565b600485516101800151600a81111561067657610676612df7565b148015610698575060018560c00151600481111561069657610696612df7565b145b15610840576106af85858760e0015160ff16611108565b81516101a001516102800151919650915060000361082957845160200151601e906000906005602002015160030b131561071957855160200151600a906106f7906005610424565b61070191906135ef565b61070c906001613603565b6107169082613603565b90505b8551602001516000906003602002015160030b131561076857855160200151600a90610746906003610424565b61075091906135ef565b61075b906001613603565b6107659082613603565b90505b61079686600360008060648b60000151604001518761078791906135c2565b61079191906135ef565b611302565b8051604001519096506064906107ac90836135c2565b6107b691906135ef565b865160600180516107c8908390613603565b9052508551604081015160609091015111156107ec57855160408101516060909101525b8551604001516064906107ff90836135c2565b61080991906135ef565b866101a0015160400181815161081f9190613603565b9052506103679050565b84516101a00151610280018051906103638261366c565b600585516101800151600a81111561085a5761085a612df7565b0361098f5760018560c00151600481111561087757610877612df7565b036108b8576002856000015160800181815161089391906135c2565b9052508451608081015161010090910180516108b0908390613603565b905250610970565b845160a001516000906108cd90600a906135ef565b8651602001519091506000906005602002015160030b131561091f57855160200151600a906108fd906005610424565b61090791906135ef565b610912906001613603565b61091c9082613603565b90505b8551602001516000906001602002015160030b131561096e5785516020015160059061094c906001610424565b61095691906135ef565b610961906001613603565b61096b9082613603565b90505b505b61098285858760e0015160ff16611108565b9095509350839050610fa7565b600685516101800151600a8111156109a9576109a9612df7565b03610a8b5760018560c0015160048111156109c6576109c6612df7565b0361097057600285600001516101a00151610120018181516109e89190613603565b90525084516101a0015161018001805190610a0282613629565b90525084516101a0015161024001805190610a1c82613629565b90525084516101a0015160e001805160029190610a3a908390613603565b905250610a4a856011600261124f565b9450610a59856014600161124f565b9450610a6885601a600161124f565b9450610a7785600f600261124f565b945061098285858760e0015160ff16611108565b600785516101800151600a811115610aa557610aa5612df7565b148015610ac7575060018560c001516004811115610ac557610ac5612df7565b145b15610bdd57845160a08101516020909101516000906003602002015160030b1315610b2257855160200151600a90610b00906003610424565b610b0a91906135ef565b610b15906001613603565b610b1f9082613603565b90505b8551602001516000906006602002015160030b1315610b7157855160200151600590610b4f906006610424565b610b5991906135ef565b610b64906001613603565b610b6e9082613603565b90505b610b8086600360008085611302565b9550808660000151606001818151610b989190613603565b905250855160408101516060909101511115610bbc57855160408101516060909101525b80866101a00151604001818151610bd39190613603565b905250610fa79050565b600885516101800151600a811115610bf757610bf7612df7565b03610da55760018560c001516004811115610c1457610c14612df7565b03610c6857610c2b85858760e0015160ff16611108565b606081015191965091506000036102b157845160a00151610c4e90600a906135ef565b855160a0018051610c60908390613603565b905250610fa7565b610c7a85858760e0015160ff16611108565b815160a001519196509150600090610c9490600a906135ef565b8651602001519091506000906003602002015160030b1315610ce657855160200151600a90610cc4906003610424565b610cce91906135ef565b610cd9906001613603565b610ce39082613603565b90505b8551602001516000906006602002015160030b1315610d3557855160200151600a90610d13906006610424565b610d1d91906135ef565b610d28906001613603565b610d329082613603565b90505b610d4486600360008085611302565b9550808660000151606001818151610d5c9190613603565b905250855160408101516060909101511115610d8057855160408101516060909101525b80866101a00151604001818151610d979190613603565b905250909350839050610fa7565b600985516101800151600a811115610dbf57610dbf612df7565b148015610de1575060018560c001516004811115610ddf57610ddf612df7565b145b15610f8c57845160a08101516101009091015284516020015151600060039190910b1315610e4957845160200151600590610e1d906000610424565b610e2791906135ef565b610e32906001613603565b8551610100018051610e45908390613603565b9052505b60208501516060015115610eb457610e678586602001516000611108565b9095509050610e7c8560006002601d816111f7565b94506002816101c001516102a001818151610e979190613603565b9052506020850181905260e085015160ff16600003610eb4578093505b60408501516060015115610f1f57610ed28586604001516001611108565b9095509050610ee78560016002601d816111f7565b94506002816101c001516102a001818151610f029190613603565b9052506040850181905260e085015160ff16600103610f1f578093505b6060808601510151156102b157610f3c8586606001516002611108565b9095509050610f5085600280601d816111f7565b94506002816101c001516102a001818151610f6b9190613603565b9052506060850181905260e085015160ff166002036102b157809350610fa7565b610f9e85858760e0015160ff16611108565b90955093508390505b50929391925050565b60008082600a811115610fc557610fc5612df7565b03610fd257506064919050565b600182600a811115610fe657610fe6612df7565b03610ff35750603c919050565b600282600a81111561100757611007612df7565b0361101457506050919050565b600382600a81111561102857611028612df7565b0361103557506032919050565b600482600a81111561104957611049612df7565b0361105657506046919050565b600582600a81111561106a5761106a612df7565b0361107757506032919050565b600682600a81111561108b5761108b612df7565b0361109857506078919050565b600782600a8111156110ac576110ac612df7565b036110b957506028919050565b600882600a8111156110cd576110cd612df7565b036110da57506037919050565b600982600a8111156110ee576110ee612df7565b036110fb5750603c919050565b506032919050565b919050565b611110611ddc565b611118611ed1565b836101c0015161022001516000036111c95784516101a001516102e001511561115c576111528560000151610100015185606001516113af565b6060850152611183565b61117885600001516101000151856060015186608001516113d2565b608086015260608501525b61119b858460016000896000015161010001516111f7565b805161010001516101a0820151805192975090916111ba908390613603565b9052506111c68461142e565b93505b6111d4858585611497565b6060810151919650945015610fa7576111ee858585611b2a565b95939450505050565b6111ff611ddc565b8460000361121c57611215868585600186611302565b9550611243565b8460010361123257611215868585600286611302565b611240868585600386611302565b95505b50845b95945050505050565b611257611ddc565b61126684600285600086611302565b949350505050565b6000600282901c6000036112ab576040805160208082018690528183018590528251808303840181526060909201909252805191012091506112b3565b600282901c91505b50805b92915050565b6112ff816040516024016112d09190613683565b60408051601f198184030181529190526020810180516001600160e01b031663104c13eb60e21b179052611cf2565b50565b61130a611ddc565b60648661020001511061131e575084611246565b604051806080016040528086600681111561133b5761133b612df7565b815260200185602e81111561135257611352612df7565b815260200184602e81111561136957611369612df7565b81526020018390526101e0870151610200880180519061138882613629565b90528151811061139a5761139a613642565b60209081029190910101525093949350505050565b6000818311156113c1575060006112b6565b6113cb8383613616565b90506112b6565b6000808285111561141757836113e88487613616565b11156113f7576000935061140e565b6114018386613616565b61140b9085613616565b93505b60009250611424565b6114218584613616565b92505b5091939092509050565b611436611ed1565b8160600151600003611493576101c082015161032001511561146c57604082015160608301526101c08201516000610320909101525b6101c082015161024001511561149357600160608301526101c08201516000610240909101525b5090565b61149f611ddc565b6114a7611ed1565b84516101c00151608001511561155057836101c001516103a001516000036115505784516101a0015161044001516114e0906001613603565b85516101c00151608001516114f591906135c2565b846101c0015160400181815161150b9190613603565b90525084516101a00151610440015161154d9086908590600290600a90611533906001613603565b8a516101c001516080015161154891906135c2565b6111f7565b94505b84516101c0015160a00151156115f457836101c0015161038001516000036115f45784516101a001516104400151611589906001613603565b85516101c0015160a0015161159e91906135c2565b846101c001516060018181516115b49190613603565b90525084516101a0015161044001516115f19086908590600290600b906115dc906001613603565b8a516101c0015160a0015161154891906135c2565b94505b84516101c0015160c00151156116865784516101a00151610440015161161b906001613603565b85516101c0015160c0015161163091906135c2565b846101c001516080018181516116469190613603565b90525084516101a0015161044001516116839086908590600290600c9061166e906001613603565b8a516101c0015160c0015161154891906135c2565b94505b84516101c0015160e00151156117185784516101a0015161044001516116ad906001613603565b85516101c0015160e001516116c291906135c2565b846101c0015160a0018181516116d89190613603565b90525084516101a0015161044001516117159086908590600290600d90611700906001613603565b8a516101c0015160e0015161154891906135c2565b94505b84516101c001516101000151156117d8576101c08401516103e0015115801561174957506101c08401516103400151155b80156117585750610160840151155b156117d85761176f85608001518660a0015161126e565b60a086015284516101c00151610100015161178b9060146135c2565b611796906014613603565b60648660a001516117a79190613658565b10156117d8576101c084015160c0018051906117c282613629565b9052506117d585846002600e60016111f7565b94505b84516101c00151610120015115611884576101c084015161034001511580156118045750610160840151155b156118845761181b85608001518660a0015161126e565b60a086015284516101c0015161012001516118379060146135c2565b611842906014613603565b60648660a001516118539190613658565b1015611884576101c084015160e00180519061186e82613629565b90525061188185846002600f60016111f7565b94505b84516101c0015161014001511561191b5784516101a0015161044001516118ac906001613603565b85516101c0015161014001516118c291906135c2565b85516101a001516101200180516118da908390613603565b90525084516101a0015161044001516119189086908590600290601190611902906001613603565b8a516101c00151610140015161154891906135c2565b94505b84516101c001516101600151156119b15784516101a001516104400151611943906001613603565b85516101c00151610160015161195991906135c2565b846101c00151610140018181516119709190613603565b90525084516101a0015161044001516119ae9086908590600290601290611998906001613603565b8a516101c00151610160015161154891906135c2565b94505b84516101c001516060015115610fa75784516101a0015161044001516119d8906001613603565b85516101c00151606001516064906119f190600a6135c2565b87516101000151611a0291906135c2565b611a0c91906135ef565b611a1691906135c2565b85516060018051611a28908390613603565b90525084516101a001516104400151611a8f908690600390600790600090611a51906001613603565b8a516101c0015160600151606490611a6a90600a6135c2565b8c516101000151611a7b91906135c2565b611a8591906135ef565b61079191906135c2565b805160408101516060909101519196501015611ab357845160408101516060909101525b84516101a001516104400151611aca906001613603565b85516101c0015160600151606490611ae390600a6135c2565b87516101000151611af491906135c2565b611afe91906135ef565b611b0891906135c2565b856101a00151604001818151611b1e9190613603565b90525093949293505050565b611b32611ddc565b6101c08301516102c0015115611bb457611b618360a001518560000151606001518660000151608001516113d2565b855160808101919091526060015260a08301516101a08501516020018051611b8a908390613603565b91508181525050611ba2848360018660a00151611cfb565b9350611bb18460000151611d53565b84525b6101c08301516101a0015115611c6457611bf0836101c001516101a001516005611bde91906135c2565b855160608101516080909101516113d2565b85516080810191909152606001526101c08301516101a00151611c149060056135c2565b846101a00151602001818151611c2a9190613603565b91508181525050611c5284600160156000876101c001516101a00151600561079191906135c2565b9350611c618460000151611d53565b84525b6101c08301516104c0015115611cea57835160a08101516060820151608090920151611c9092906113d2565b8551608081019190915260600152835160a00151611cb8908590600190602e90600090611302565b9350836000015160a00151846101a00151602001818151611cd99190613603565b9052508351611ce790611d53565b84525b509192915050565b6112ff81611dbb565b611d03611ddc565b83600003611d2157611d1a85846001600086611302565b9450611d4a565b83600103611d3857611d1a85846002600086611302565b611d4785846003600086611302565b94505b50929392505050565b611d5b611f68565b8160600151600003611493576101a0820151610320015115611d9157604082015160608301526101a08201516000610320909101525b6101a082015161024001511561149357600160608301526101a08201516000610240909101525090565b60006a636f6e736f6c652e6c6f679050600080835160208501845afa505050565b604051806102200160405280611df0611f68565b8152602001611dfd611ed1565b8152602001611e0a611ed1565b8152602001611e17611ed1565b8152602001600081526020016000815260200160006004811115611e3d57611e3d612df7565b8152600060208201819052604082018190526060808301526080820181905260a0820181905260c0909101908152602001611eb660405180610100016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b81526020016000815260200160608152602001600081525090565b6040805161020081019091528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160001515815260200160008152602001600081526020016000815260200160006017811115611f3957611f39612df7565b8152600060208201819052604082018190526060820152608001611f5b6120cb565b8152602001606081525090565b60405180610280016040528060008152602001611f836121e9565b81526020016000815260200160008152602001600081526020016000815260200160001515815260200160008152602001600081526020016000815260200160008152602001600081526020016000600a811115611fe357611fe3612df7565b8152602001611ff06120cb565b8152602001612067604051806101c0016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b81526040805160808101825260008082526020828101829052928201819052606082015291019081526020016120b0604051806040016040528060008152602001600081525090565b81526020016000815260200160008152602001600081525090565b604051806104e001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b600052604160045260246000fd5b6040516104e081016001600160401b038111828210171561224057612240612207565b60405290565b6040516101c081016001600160401b038111828210171561224057612240612207565b604051608081016001600160401b038111828210171561224057612240612207565b60405161028081016001600160401b038111828210171561224057612240612207565b60405161020081016001600160401b038111828210171561224057612240612207565b60405161022081016001600160401b038111828210171561224057612240612207565b604051601f8201601f191681016001600160401b038111828210171561231c5761231c612207565b604052919050565b600082601f83011261233557600080fd5b60405160e081018181106001600160401b038211171561235757612357612207565b6040528060e084018581111561236c57600080fd5b845b818110156123965780358060030b81146123885760008081fd5b83526020928301920161236e565b509195945050505050565b8035801515811461110357600080fd5b8035600b811061110357600080fd5b60006104e082840312156123d357600080fd5b6123db61221d565b823581526020808401359082015260408084013590820152606080840135908201526080808401359082015260a0808401359082015260c0808401359082015260e08084013590820152610100808401359082015261012080840135908201526101408084013590820152610160808401359082015261018080840135908201526101a080840135908201526101c080840135908201526101e08084013590820152610200808401359082015261022080840135908201526102408084013590820152610260808401359082015261028080840135908201526102a080840135908201526102c080840135908201526102e08084013590820152610300808401359082015261032080840135908201526103408084013590820152610360808401359082015261038080840135908201526103a080840135908201526103c080840135908201526103e08084013590820152610400808401359082015261042080840135908201526104408084013590820152610460808401359082015261048080840135908201526104a080840135908201526104c0928301359281019290925250919050565b60006101c0828403121561259657600080fd5b61259e612246565b9050813581526020820135602082015260408201356040820152606082013560608201526080820135608082015260a082013560a082015260c082013560c082015260e082013560e08201526101008083013581830152506101208083013581830152506101408083013581830152506101608083013581830152506101808083013581830152506101a080830135818301525092915050565b600581106112ff57600080fd5b803561110381612638565b60006080828403121561266257600080fd5b61266a612269565b9050813561267781612638565b8152612685602083016123a1565b6020820152604082013560408201526060820135606082015292915050565b6000604082840312156126b657600080fd5b604051604081018181106001600160401b03821117156126d8576126d8612207565b604052823581526020928301359281019290925250919050565b6000610a20828403121561270557600080fd5b61270d61228b565b9050813581526127208360208401612324565b60208201526101008083013560408301526101208084013560608401526101408085013560808501526101608086013560a08601526101806127638188016123a1565b60c08701526101a08088013560e08801526101c080890135878901526101e096508689013586890152610200955085890135858901526102209450848901358489015261024093506127b6848a016123b1565b8389015261026092506127cb8a848b016123c0565b828901526127dd8a6107408b01612583565b90880152506127f0886109008901612650565b858701526128028861098089016126a4565b848701526109c0870135838701526109e087013582870152610a0087013581870152505050505092915050565b8035601c811061110357600080fd5b80356018811061110357600080fd5b600082601f83011261285e57600080fd5b81356001600160401b0381111561287757612877612207565b61288a601f8201601f19166020016122f4565b81815284602083860101111561289f57600080fd5b816020850160208301376000918101602001919091529392505050565b60006106c082840312156128cf57600080fd5b6128d76122ae565b90506128e28261282f565b81526020820135602082015260408201356040820152606082013560608201526080820135608082015260a082013560a082015261292260c083016123a1565b60c082015260e082810135908201526101008083013590820152610120808301359082015261014061295581840161283e565b908201526101606129678382016123a1565b908201526101806129798382016123a1565b908201526101a061298b8382016123a1565b908201526101c061299e848483016123c0565b908201526106a08201356001600160401b038111156129bc57600080fd5b6129c88482850161284d565b6101e08301525092915050565b803560ff8116811461110357600080fd5b60006001600160401b038211156129ff576129ff612207565b5060051b60200190565b600082601f830112612a1a57600080fd5b81356020612a2f612a2a836129e6565b6122f4565b82815260059290921b84018101918181019086841115612a4e57600080fd5b8286015b84811015612a77578035600f8110612a6a5760008081fd5b8352918301918301612a52565b509695505050505050565b80356003811061110357600080fd5b6000610100808385031215612aa557600080fd5b604051908101906001600160401b0382118183101715612ac757612ac7612207565b81604052809250833581526020840135602082015260408401356040820152606084013560608201526080840135608082015260a084013560a082015260c084013560c082015260e084013560e0820152505092915050565b8035602f811061110357600080fd5b600082601f830112612b4057600080fd5b81356020612b50612a2a836129e6565b828152600792831b8501820192828201919087851115612b6f57600080fd5b8387015b85811015612bdd576080818a031215612b8c5760008081fd5b612b94612269565b8135838110612ba35760008081fd5b8152612bb0828701612b20565b868201526040612bc1818401612b20565b9082015260608281013590820152845292840192608001612b73565b5090979650505050505050565b60008060408385031215612bfd57600080fd5b82356001600160401b0380821115612c1457600080fd5b90840190610d008287031215612c2957600080fd5b612c316122d1565b612c3b87846126f2565b8152610a2083013582811115612c5057600080fd5b612c5c888286016128bc565b602083015250610a4083013582811115612c7557600080fd5b612c81888286016128bc565b604083015250610a6083013582811115612c9a57600080fd5b612ca6888286016128bc565b606083015250610a808301356080820152610aa083013560a0820152612ccf610ac08401612645565b60c0820152612ce1610ae084016129d5565b60e0820152610b00830135610100820152610b2083013582811115612d0557600080fd5b612d1188828601612a09565b61012083015250610b40830135610140820152612d31610b6084016123a1565b610160820152612d44610b808401612a82565b610180820152612d5887610ba08501612a91565b6101a0820152610ca08301356101c0820152610cc083013582811115612d7d57600080fd5b612d8988828601612b2f565b6101e083015250610ce0830135610200820152809450506020850135915080821115612db457600080fd5b50612dc1858286016128bc565b9150509250929050565b8060005b6007811015612df157815160030b845260209384019390910190600101612dcf565b50505050565b634e487b7160e01b600052602160045260246000fd5b600b8110612e1d57612e1d612df7565b9052565b805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a0808201519083015260c0808201519083015260e08082015190830152610100808201519083015261012080820151908301526101408082015190830152610160808201519083015261018080820151908301526101a080820151908301526101c080820151908301526101e08082015190830152610200808201519083015261022080820151908301526102408082015190830152610260808201519083015261028080820151908301526102a080820151908301526102c080820151908301526102e08082015190830152610300808201519083015261032080820151908301526103408082015190830152610360808201519083015261038080820151908301526103a080820151908301526103c080820151908301526103e08082015190830152610400808201519083015261042080820151908301526104408082015190830152610460808201519083015261048080820151908301526104a080820151908301526104c090810151910152565b600581106112ff576112ff612df7565b8051612fdc81612fc1565b825260208181015115159083015260408082015190830152606090810151910152565b8051825260208101516130156020840182612dcb565b506040810151610100818185015260608301519150610120828186015260808401519250610140838187015260a08501519350610160848188015260c086015194506101806130678189018715159052565b60e08701516101a089810191909152948701516101c0808a0191909152938701516101e0808a019190915292870151610200808a019190915291870151610220808a0191909152908701519550929391929091610240906130ca828a0188612e0d565b87015195506102606130de89820188612e21565b8588015180516107408b015260208101516107608b015260408101516107808b015260608101516107a08b015260808101516107c08b015260a08101516107e08b015260c08101516108008b015260e08101516108208b01526101008101516108408b01526101208101516108608b01526101408101516108808b01526101608101516108a08b01526101808101516108c08b01526101a001516108e08a01528488015196506131926109008a0188612fd1565b9287015180516109808a0152602001516109a0890152908601516109c08801528501516109e087015290930151610a0090940193909352505050565b601c8110612e1d57612e1d612df7565b60188110612e1d57612e1d612df7565b6000815180845260005b81811015613214576020818501810151868301820152016131f8565b506000602082860101526020601f19601f83011685010191505092915050565b60006106c06132448484516131ce565b6020830151602085015260408301516040850152606083015160608501526080830151608085015260a083015160a085015260c083015161328960c086018215159052565b5060e0838101519085015261010080840151908501526101208084015190850152610140808401516132bd828701826131de565b505061016083810151151590850152610180808401511515908501526101a0808401511515908501526101c0808401516132f982870182612e21565b50506101e0830151816106a0860152611246828601826131ee565b612e1d81612fc1565b600081518084526020808501945080840160005b8381101561335d578151600f811061334b5761334b612df7565b87529582019590820190600101613331565b509495945050505050565b60038110612e1d57612e1d612df7565b602f8110612e1d57612e1d612df7565b600081518084526020808501945080840160005b8381101561335d5781518051600781106133b8576133b8612df7565b8852808401516133ca858a0182613378565b506040808201516133dd828b0182613378565b5050606090810151908801526080909601959082019060010161339c565b6040815261340d604082018451612fff565b60006020840151610d0080610a6085015261342c610d40850183613234565b91506040860151603f198086850301610a8087015261344b8483613234565b9350606088015191508086850301610aa08701526134698483613234565b93506080880151610ac087015260a0880151610ae087015260c08801519150613496610b00870183613314565b60e088015160ff16610b20870152610100880151610b408701526101208801518685038201610b6088015291506134cd848361331d565b9350610140880151610b8087015261016088015191506134f2610ba087018315159052565b6101808801519150613508610bc0870183613368565b6101a08801518051610be08801526020810151610c008801526040810151610c208801526060810151610c408801526080810151610c6088015260a0810151610c8088015260c0810151610ca088015260e00151610cc08701526101c0880151610ce08701526101e088015186850390910183870152905061358a8382613388565b92505050610200850151610d2084015282810360208401526112468185613234565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176112b6576112b66135ac565b634e487b7160e01b600052601260045260246000fd5b6000826135fe576135fe6135d9565b500490565b808201808211156112b6576112b66135ac565b818103818111156112b6576112b66135ac565b60006001820161363b5761363b6135ac565b5060010190565b634e487b7160e01b600052603260045260246000fd5b600082613667576136676135d9565b500690565b60008161367b5761367b6135ac565b506000190190565b60208152600061369660208301846131ee565b939250505056fea26469706673582212206b4539fd0915402706c010916c7d9fb68eeb79290fa4bf9a64f39460f5e3430264736f6c63430008130033

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f7debabb14610030575b600080fd5b61004361003e366004612bea565b61005a565b6040516100519291906133fb565b60405180910390f35b610062611ddc565b61006a611ed1565b610072611ed1565b606461008686600001516101800151610fb0565b8651610100015161009791906135c2565b6100a191906135ef565b8551610100015284516101c0015160200151156100f05783604001518460600151036100f05784516101c00151602001516100dd90600a6135c2565b6100e890606e613603565b855161012001525b6101c084015161016001511561011c57601e8560000151610120018181516101189190613616565b9052505b6101c084015161018001511561014857601e8560000151610120018181516101449190613603565b9052505b6101c08401516101e00151156101835760328560000151610120018181516101709190613603565b9052506101c084015160006101e0909101525b84516101208101516101009091015160649161019e916135c2565b6101a891906135ef565b855161010001528451600161016090910152600085516101800151600a8111156101d4576101d4612df7565b1480156101f6575060018560c0015160048111156101f4576101f4612df7565b145b156102b65760208501516060015115610238576102198586602001516000611108565b6020820181905260e0820151919650915060ff16600003610238578093505b60408501516060015115610275576102568586604001516001611108565b6040820181905260e0820151919650915060ff16600103610275578093505b6060808601510151156102b1576102928586606001516002611108565b6060820181905260e0820151919650915060ff166002036102b1578093505b610fa7565b600185516101800151600a8111156102d0576102d0612df7565b1480156102f2575060018560c0015160048111156102f0576102f0612df7565b145b1561036f57845160a001516103089060026135c2565b8551610100015260e0850151610324908690869060ff16611108565b6101c0810151610380015191965091506000036103675761034c8560006002600b60016111f7565b6101c0820151606001805191965061036382613629565b9052505b809350610fa7565b600285516101800151600a81111561038957610389612df7565b1480156103ab575060018560c0015160048111156103a9576103a9612df7565b145b15610569576103bd856009600261124f565b9450600285600001516101a001516020018181516103db9190613603565b90525060e08501516103f3908690869060ff16611108565b81516020015191965091506000906002602002015160030b13156104e95784516020015160009060149061042f9060025b602002015160030b90565b61043991906135ef565b610444906001613603565b90505b80156104e35761045f86608001518760a0015161126e565b60a0870181905261047290600290613658565b6000036104d1576104a46040518060400160405280600a81526020016948697420616761696e2160b01b8152506112bc565b6104b686838860e0015160ff16611108565b81516101600180519298509093506104cd82613629565b9052505b806104db8161366c565b915050610447565b50610367565b6104fb85608001518660a0015161126e565b60a0860181905261050e90600290613658565b600003610367576105406040518060400160405280600a81526020016948697420416761696e2160b01b8152506112bc565b61055285858760e0015160ff16611108565b815161016001805192975090925061036382613629565b600385516101800151600a81111561058357610583612df7565b0361065c5760018560c0015160048111156105a0576105a0612df7565b036105d5576105b285601b600261124f565b9450600285600001516101a00151610260018181516105d19190613603565b9052505b845160026101609091015260005b6002811015610653576105fe86868860e0015160ff16611108565b6101c08101516103a001519197509250600003610641576106268660006002600a60016111f7565b6101c0830151604001805191975061063d82613629565b9052505b8061064b81613629565b9150506105e3565b50809350610fa7565b600485516101800151600a81111561067657610676612df7565b148015610698575060018560c00151600481111561069657610696612df7565b145b15610840576106af85858760e0015160ff16611108565b81516101a001516102800151919650915060000361082957845160200151601e906000906005602002015160030b131561071957855160200151600a906106f7906005610424565b61070191906135ef565b61070c906001613603565b6107169082613603565b90505b8551602001516000906003602002015160030b131561076857855160200151600a90610746906003610424565b61075091906135ef565b61075b906001613603565b6107659082613603565b90505b61079686600360008060648b60000151604001518761078791906135c2565b61079191906135ef565b611302565b8051604001519096506064906107ac90836135c2565b6107b691906135ef565b865160600180516107c8908390613603565b9052508551604081015160609091015111156107ec57855160408101516060909101525b8551604001516064906107ff90836135c2565b61080991906135ef565b866101a0015160400181815161081f9190613603565b9052506103679050565b84516101a00151610280018051906103638261366c565b600585516101800151600a81111561085a5761085a612df7565b0361098f5760018560c00151600481111561087757610877612df7565b036108b8576002856000015160800181815161089391906135c2565b9052508451608081015161010090910180516108b0908390613603565b905250610970565b845160a001516000906108cd90600a906135ef565b8651602001519091506000906005602002015160030b131561091f57855160200151600a906108fd906005610424565b61090791906135ef565b610912906001613603565b61091c9082613603565b90505b8551602001516000906001602002015160030b131561096e5785516020015160059061094c906001610424565b61095691906135ef565b610961906001613603565b61096b9082613603565b90505b505b61098285858760e0015160ff16611108565b9095509350839050610fa7565b600685516101800151600a8111156109a9576109a9612df7565b03610a8b5760018560c0015160048111156109c6576109c6612df7565b0361097057600285600001516101a00151610120018181516109e89190613603565b90525084516101a0015161018001805190610a0282613629565b90525084516101a0015161024001805190610a1c82613629565b90525084516101a0015160e001805160029190610a3a908390613603565b905250610a4a856011600261124f565b9450610a59856014600161124f565b9450610a6885601a600161124f565b9450610a7785600f600261124f565b945061098285858760e0015160ff16611108565b600785516101800151600a811115610aa557610aa5612df7565b148015610ac7575060018560c001516004811115610ac557610ac5612df7565b145b15610bdd57845160a08101516020909101516000906003602002015160030b1315610b2257855160200151600a90610b00906003610424565b610b0a91906135ef565b610b15906001613603565b610b1f9082613603565b90505b8551602001516000906006602002015160030b1315610b7157855160200151600590610b4f906006610424565b610b5991906135ef565b610b64906001613603565b610b6e9082613603565b90505b610b8086600360008085611302565b9550808660000151606001818151610b989190613603565b905250855160408101516060909101511115610bbc57855160408101516060909101525b80866101a00151604001818151610bd39190613603565b905250610fa79050565b600885516101800151600a811115610bf757610bf7612df7565b03610da55760018560c001516004811115610c1457610c14612df7565b03610c6857610c2b85858760e0015160ff16611108565b606081015191965091506000036102b157845160a00151610c4e90600a906135ef565b855160a0018051610c60908390613603565b905250610fa7565b610c7a85858760e0015160ff16611108565b815160a001519196509150600090610c9490600a906135ef565b8651602001519091506000906003602002015160030b1315610ce657855160200151600a90610cc4906003610424565b610cce91906135ef565b610cd9906001613603565b610ce39082613603565b90505b8551602001516000906006602002015160030b1315610d3557855160200151600a90610d13906006610424565b610d1d91906135ef565b610d28906001613603565b610d329082613603565b90505b610d4486600360008085611302565b9550808660000151606001818151610d5c9190613603565b905250855160408101516060909101511115610d8057855160408101516060909101525b80866101a00151604001818151610d979190613603565b905250909350839050610fa7565b600985516101800151600a811115610dbf57610dbf612df7565b148015610de1575060018560c001516004811115610ddf57610ddf612df7565b145b15610f8c57845160a08101516101009091015284516020015151600060039190910b1315610e4957845160200151600590610e1d906000610424565b610e2791906135ef565b610e32906001613603565b8551610100018051610e45908390613603565b9052505b60208501516060015115610eb457610e678586602001516000611108565b9095509050610e7c8560006002601d816111f7565b94506002816101c001516102a001818151610e979190613603565b9052506020850181905260e085015160ff16600003610eb4578093505b60408501516060015115610f1f57610ed28586604001516001611108565b9095509050610ee78560016002601d816111f7565b94506002816101c001516102a001818151610f029190613603565b9052506040850181905260e085015160ff16600103610f1f578093505b6060808601510151156102b157610f3c8586606001516002611108565b9095509050610f5085600280601d816111f7565b94506002816101c001516102a001818151610f6b9190613603565b9052506060850181905260e085015160ff166002036102b157809350610fa7565b610f9e85858760e0015160ff16611108565b90955093508390505b50929391925050565b60008082600a811115610fc557610fc5612df7565b03610fd257506064919050565b600182600a811115610fe657610fe6612df7565b03610ff35750603c919050565b600282600a81111561100757611007612df7565b0361101457506050919050565b600382600a81111561102857611028612df7565b0361103557506032919050565b600482600a81111561104957611049612df7565b0361105657506046919050565b600582600a81111561106a5761106a612df7565b0361107757506032919050565b600682600a81111561108b5761108b612df7565b0361109857506078919050565b600782600a8111156110ac576110ac612df7565b036110b957506028919050565b600882600a8111156110cd576110cd612df7565b036110da57506037919050565b600982600a8111156110ee576110ee612df7565b036110fb5750603c919050565b506032919050565b919050565b611110611ddc565b611118611ed1565b836101c0015161022001516000036111c95784516101a001516102e001511561115c576111528560000151610100015185606001516113af565b6060850152611183565b61117885600001516101000151856060015186608001516113d2565b608086015260608501525b61119b858460016000896000015161010001516111f7565b805161010001516101a0820151805192975090916111ba908390613603565b9052506111c68461142e565b93505b6111d4858585611497565b6060810151919650945015610fa7576111ee858585611b2a565b95939450505050565b6111ff611ddc565b8460000361121c57611215868585600186611302565b9550611243565b8460010361123257611215868585600286611302565b611240868585600386611302565b95505b50845b95945050505050565b611257611ddc565b61126684600285600086611302565b949350505050565b6000600282901c6000036112ab576040805160208082018690528183018590528251808303840181526060909201909252805191012091506112b3565b600282901c91505b50805b92915050565b6112ff816040516024016112d09190613683565b60408051601f198184030181529190526020810180516001600160e01b031663104c13eb60e21b179052611cf2565b50565b61130a611ddc565b60648661020001511061131e575084611246565b604051806080016040528086600681111561133b5761133b612df7565b815260200185602e81111561135257611352612df7565b815260200184602e81111561136957611369612df7565b81526020018390526101e0870151610200880180519061138882613629565b90528151811061139a5761139a613642565b60209081029190910101525093949350505050565b6000818311156113c1575060006112b6565b6113cb8383613616565b90506112b6565b6000808285111561141757836113e88487613616565b11156113f7576000935061140e565b6114018386613616565b61140b9085613616565b93505b60009250611424565b6114218584613616565b92505b5091939092509050565b611436611ed1565b8160600151600003611493576101c082015161032001511561146c57604082015160608301526101c08201516000610320909101525b6101c082015161024001511561149357600160608301526101c08201516000610240909101525b5090565b61149f611ddc565b6114a7611ed1565b84516101c00151608001511561155057836101c001516103a001516000036115505784516101a0015161044001516114e0906001613603565b85516101c00151608001516114f591906135c2565b846101c0015160400181815161150b9190613603565b90525084516101a00151610440015161154d9086908590600290600a90611533906001613603565b8a516101c001516080015161154891906135c2565b6111f7565b94505b84516101c0015160a00151156115f457836101c0015161038001516000036115f45784516101a001516104400151611589906001613603565b85516101c0015160a0015161159e91906135c2565b846101c001516060018181516115b49190613603565b90525084516101a0015161044001516115f19086908590600290600b906115dc906001613603565b8a516101c0015160a0015161154891906135c2565b94505b84516101c0015160c00151156116865784516101a00151610440015161161b906001613603565b85516101c0015160c0015161163091906135c2565b846101c001516080018181516116469190613603565b90525084516101a0015161044001516116839086908590600290600c9061166e906001613603565b8a516101c0015160c0015161154891906135c2565b94505b84516101c0015160e00151156117185784516101a0015161044001516116ad906001613603565b85516101c0015160e001516116c291906135c2565b846101c0015160a0018181516116d89190613603565b90525084516101a0015161044001516117159086908590600290600d90611700906001613603565b8a516101c0015160e0015161154891906135c2565b94505b84516101c001516101000151156117d8576101c08401516103e0015115801561174957506101c08401516103400151155b80156117585750610160840151155b156117d85761176f85608001518660a0015161126e565b60a086015284516101c00151610100015161178b9060146135c2565b611796906014613603565b60648660a001516117a79190613658565b10156117d8576101c084015160c0018051906117c282613629565b9052506117d585846002600e60016111f7565b94505b84516101c00151610120015115611884576101c084015161034001511580156118045750610160840151155b156118845761181b85608001518660a0015161126e565b60a086015284516101c0015161012001516118379060146135c2565b611842906014613603565b60648660a001516118539190613658565b1015611884576101c084015160e00180519061186e82613629565b90525061188185846002600f60016111f7565b94505b84516101c0015161014001511561191b5784516101a0015161044001516118ac906001613603565b85516101c0015161014001516118c291906135c2565b85516101a001516101200180516118da908390613603565b90525084516101a0015161044001516119189086908590600290601190611902906001613603565b8a516101c00151610140015161154891906135c2565b94505b84516101c001516101600151156119b15784516101a001516104400151611943906001613603565b85516101c00151610160015161195991906135c2565b846101c00151610140018181516119709190613603565b90525084516101a0015161044001516119ae9086908590600290601290611998906001613603565b8a516101c00151610160015161154891906135c2565b94505b84516101c001516060015115610fa75784516101a0015161044001516119d8906001613603565b85516101c00151606001516064906119f190600a6135c2565b87516101000151611a0291906135c2565b611a0c91906135ef565b611a1691906135c2565b85516060018051611a28908390613603565b90525084516101a001516104400151611a8f908690600390600790600090611a51906001613603565b8a516101c0015160600151606490611a6a90600a6135c2565b8c516101000151611a7b91906135c2565b611a8591906135ef565b61079191906135c2565b805160408101516060909101519196501015611ab357845160408101516060909101525b84516101a001516104400151611aca906001613603565b85516101c0015160600151606490611ae390600a6135c2565b87516101000151611af491906135c2565b611afe91906135ef565b611b0891906135c2565b856101a00151604001818151611b1e9190613603565b90525093949293505050565b611b32611ddc565b6101c08301516102c0015115611bb457611b618360a001518560000151606001518660000151608001516113d2565b855160808101919091526060015260a08301516101a08501516020018051611b8a908390613603565b91508181525050611ba2848360018660a00151611cfb565b9350611bb18460000151611d53565b84525b6101c08301516101a0015115611c6457611bf0836101c001516101a001516005611bde91906135c2565b855160608101516080909101516113d2565b85516080810191909152606001526101c08301516101a00151611c149060056135c2565b846101a00151602001818151611c2a9190613603565b91508181525050611c5284600160156000876101c001516101a00151600561079191906135c2565b9350611c618460000151611d53565b84525b6101c08301516104c0015115611cea57835160a08101516060820151608090920151611c9092906113d2565b8551608081019190915260600152835160a00151611cb8908590600190602e90600090611302565b9350836000015160a00151846101a00151602001818151611cd99190613603565b9052508351611ce790611d53565b84525b509192915050565b6112ff81611dbb565b611d03611ddc565b83600003611d2157611d1a85846001600086611302565b9450611d4a565b83600103611d3857611d1a85846002600086611302565b611d4785846003600086611302565b94505b50929392505050565b611d5b611f68565b8160600151600003611493576101a0820151610320015115611d9157604082015160608301526101a08201516000610320909101525b6101a082015161024001511561149357600160608301526101a08201516000610240909101525090565b60006a636f6e736f6c652e6c6f679050600080835160208501845afa505050565b604051806102200160405280611df0611f68565b8152602001611dfd611ed1565b8152602001611e0a611ed1565b8152602001611e17611ed1565b8152602001600081526020016000815260200160006004811115611e3d57611e3d612df7565b8152600060208201819052604082018190526060808301526080820181905260a0820181905260c0909101908152602001611eb660405180610100016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b81526020016000815260200160608152602001600081525090565b6040805161020081019091528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160001515815260200160008152602001600081526020016000815260200160006017811115611f3957611f39612df7565b8152600060208201819052604082018190526060820152608001611f5b6120cb565b8152602001606081525090565b60405180610280016040528060008152602001611f836121e9565b81526020016000815260200160008152602001600081526020016000815260200160001515815260200160008152602001600081526020016000815260200160008152602001600081526020016000600a811115611fe357611fe3612df7565b8152602001611ff06120cb565b8152602001612067604051806101c0016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b81526040805160808101825260008082526020828101829052928201819052606082015291019081526020016120b0604051806040016040528060008152602001600081525090565b81526020016000815260200160008152602001600081525090565b604051806104e001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b600052604160045260246000fd5b6040516104e081016001600160401b038111828210171561224057612240612207565b60405290565b6040516101c081016001600160401b038111828210171561224057612240612207565b604051608081016001600160401b038111828210171561224057612240612207565b60405161028081016001600160401b038111828210171561224057612240612207565b60405161020081016001600160401b038111828210171561224057612240612207565b60405161022081016001600160401b038111828210171561224057612240612207565b604051601f8201601f191681016001600160401b038111828210171561231c5761231c612207565b604052919050565b600082601f83011261233557600080fd5b60405160e081018181106001600160401b038211171561235757612357612207565b6040528060e084018581111561236c57600080fd5b845b818110156123965780358060030b81146123885760008081fd5b83526020928301920161236e565b509195945050505050565b8035801515811461110357600080fd5b8035600b811061110357600080fd5b60006104e082840312156123d357600080fd5b6123db61221d565b823581526020808401359082015260408084013590820152606080840135908201526080808401359082015260a0808401359082015260c0808401359082015260e08084013590820152610100808401359082015261012080840135908201526101408084013590820152610160808401359082015261018080840135908201526101a080840135908201526101c080840135908201526101e08084013590820152610200808401359082015261022080840135908201526102408084013590820152610260808401359082015261028080840135908201526102a080840135908201526102c080840135908201526102e08084013590820152610300808401359082015261032080840135908201526103408084013590820152610360808401359082015261038080840135908201526103a080840135908201526103c080840135908201526103e08084013590820152610400808401359082015261042080840135908201526104408084013590820152610460808401359082015261048080840135908201526104a080840135908201526104c0928301359281019290925250919050565b60006101c0828403121561259657600080fd5b61259e612246565b9050813581526020820135602082015260408201356040820152606082013560608201526080820135608082015260a082013560a082015260c082013560c082015260e082013560e08201526101008083013581830152506101208083013581830152506101408083013581830152506101608083013581830152506101808083013581830152506101a080830135818301525092915050565b600581106112ff57600080fd5b803561110381612638565b60006080828403121561266257600080fd5b61266a612269565b9050813561267781612638565b8152612685602083016123a1565b6020820152604082013560408201526060820135606082015292915050565b6000604082840312156126b657600080fd5b604051604081018181106001600160401b03821117156126d8576126d8612207565b604052823581526020928301359281019290925250919050565b6000610a20828403121561270557600080fd5b61270d61228b565b9050813581526127208360208401612324565b60208201526101008083013560408301526101208084013560608401526101408085013560808501526101608086013560a08601526101806127638188016123a1565b60c08701526101a08088013560e08801526101c080890135878901526101e096508689013586890152610200955085890135858901526102209450848901358489015261024093506127b6848a016123b1565b8389015261026092506127cb8a848b016123c0565b828901526127dd8a6107408b01612583565b90880152506127f0886109008901612650565b858701526128028861098089016126a4565b848701526109c0870135838701526109e087013582870152610a0087013581870152505050505092915050565b8035601c811061110357600080fd5b80356018811061110357600080fd5b600082601f83011261285e57600080fd5b81356001600160401b0381111561287757612877612207565b61288a601f8201601f19166020016122f4565b81815284602083860101111561289f57600080fd5b816020850160208301376000918101602001919091529392505050565b60006106c082840312156128cf57600080fd5b6128d76122ae565b90506128e28261282f565b81526020820135602082015260408201356040820152606082013560608201526080820135608082015260a082013560a082015261292260c083016123a1565b60c082015260e082810135908201526101008083013590820152610120808301359082015261014061295581840161283e565b908201526101606129678382016123a1565b908201526101806129798382016123a1565b908201526101a061298b8382016123a1565b908201526101c061299e848483016123c0565b908201526106a08201356001600160401b038111156129bc57600080fd5b6129c88482850161284d565b6101e08301525092915050565b803560ff8116811461110357600080fd5b60006001600160401b038211156129ff576129ff612207565b5060051b60200190565b600082601f830112612a1a57600080fd5b81356020612a2f612a2a836129e6565b6122f4565b82815260059290921b84018101918181019086841115612a4e57600080fd5b8286015b84811015612a77578035600f8110612a6a5760008081fd5b8352918301918301612a52565b509695505050505050565b80356003811061110357600080fd5b6000610100808385031215612aa557600080fd5b604051908101906001600160401b0382118183101715612ac757612ac7612207565b81604052809250833581526020840135602082015260408401356040820152606084013560608201526080840135608082015260a084013560a082015260c084013560c082015260e084013560e0820152505092915050565b8035602f811061110357600080fd5b600082601f830112612b4057600080fd5b81356020612b50612a2a836129e6565b828152600792831b8501820192828201919087851115612b6f57600080fd5b8387015b85811015612bdd576080818a031215612b8c5760008081fd5b612b94612269565b8135838110612ba35760008081fd5b8152612bb0828701612b20565b868201526040612bc1818401612b20565b9082015260608281013590820152845292840192608001612b73565b5090979650505050505050565b60008060408385031215612bfd57600080fd5b82356001600160401b0380821115612c1457600080fd5b90840190610d008287031215612c2957600080fd5b612c316122d1565b612c3b87846126f2565b8152610a2083013582811115612c5057600080fd5b612c5c888286016128bc565b602083015250610a4083013582811115612c7557600080fd5b612c81888286016128bc565b604083015250610a6083013582811115612c9a57600080fd5b612ca6888286016128bc565b606083015250610a808301356080820152610aa083013560a0820152612ccf610ac08401612645565b60c0820152612ce1610ae084016129d5565b60e0820152610b00830135610100820152610b2083013582811115612d0557600080fd5b612d1188828601612a09565b61012083015250610b40830135610140820152612d31610b6084016123a1565b610160820152612d44610b808401612a82565b610180820152612d5887610ba08501612a91565b6101a0820152610ca08301356101c0820152610cc083013582811115612d7d57600080fd5b612d8988828601612b2f565b6101e083015250610ce0830135610200820152809450506020850135915080821115612db457600080fd5b50612dc1858286016128bc565b9150509250929050565b8060005b6007811015612df157815160030b845260209384019390910190600101612dcf565b50505050565b634e487b7160e01b600052602160045260246000fd5b600b8110612e1d57612e1d612df7565b9052565b805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a0808201519083015260c0808201519083015260e08082015190830152610100808201519083015261012080820151908301526101408082015190830152610160808201519083015261018080820151908301526101a080820151908301526101c080820151908301526101e08082015190830152610200808201519083015261022080820151908301526102408082015190830152610260808201519083015261028080820151908301526102a080820151908301526102c080820151908301526102e08082015190830152610300808201519083015261032080820151908301526103408082015190830152610360808201519083015261038080820151908301526103a080820151908301526103c080820151908301526103e08082015190830152610400808201519083015261042080820151908301526104408082015190830152610460808201519083015261048080820151908301526104a080820151908301526104c090810151910152565b600581106112ff576112ff612df7565b8051612fdc81612fc1565b825260208181015115159083015260408082015190830152606090810151910152565b8051825260208101516130156020840182612dcb565b506040810151610100818185015260608301519150610120828186015260808401519250610140838187015260a08501519350610160848188015260c086015194506101806130678189018715159052565b60e08701516101a089810191909152948701516101c0808a0191909152938701516101e0808a019190915292870151610200808a019190915291870151610220808a0191909152908701519550929391929091610240906130ca828a0188612e0d565b87015195506102606130de89820188612e21565b8588015180516107408b015260208101516107608b015260408101516107808b015260608101516107a08b015260808101516107c08b015260a08101516107e08b015260c08101516108008b015260e08101516108208b01526101008101516108408b01526101208101516108608b01526101408101516108808b01526101608101516108a08b01526101808101516108c08b01526101a001516108e08a01528488015196506131926109008a0188612fd1565b9287015180516109808a0152602001516109a0890152908601516109c08801528501516109e087015290930151610a0090940193909352505050565b601c8110612e1d57612e1d612df7565b60188110612e1d57612e1d612df7565b6000815180845260005b81811015613214576020818501810151868301820152016131f8565b506000602082860101526020601f19601f83011685010191505092915050565b60006106c06132448484516131ce565b6020830151602085015260408301516040850152606083015160608501526080830151608085015260a083015160a085015260c083015161328960c086018215159052565b5060e0838101519085015261010080840151908501526101208084015190850152610140808401516132bd828701826131de565b505061016083810151151590850152610180808401511515908501526101a0808401511515908501526101c0808401516132f982870182612e21565b50506101e0830151816106a0860152611246828601826131ee565b612e1d81612fc1565b600081518084526020808501945080840160005b8381101561335d578151600f811061334b5761334b612df7565b87529582019590820190600101613331565b509495945050505050565b60038110612e1d57612e1d612df7565b602f8110612e1d57612e1d612df7565b600081518084526020808501945080840160005b8381101561335d5781518051600781106133b8576133b8612df7565b8852808401516133ca858a0182613378565b506040808201516133dd828b0182613378565b5050606090810151908801526080909601959082019060010161339c565b6040815261340d604082018451612fff565b60006020840151610d0080610a6085015261342c610d40850183613234565b91506040860151603f198086850301610a8087015261344b8483613234565b9350606088015191508086850301610aa08701526134698483613234565b93506080880151610ac087015260a0880151610ae087015260c08801519150613496610b00870183613314565b60e088015160ff16610b20870152610100880151610b408701526101208801518685038201610b6088015291506134cd848361331d565b9350610140880151610b8087015261016088015191506134f2610ba087018315159052565b6101808801519150613508610bc0870183613368565b6101a08801518051610be08801526020810151610c008801526040810151610c208801526060810151610c408801526080810151610c6088015260a0810151610c8088015260c0810151610ca088015260e00151610cc08701526101c0880151610ce08701526101e088015186850390910183870152905061358a8382613388565b92505050610200850151610d2084015282810360208401526112468185613234565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176112b6576112b66135ac565b634e487b7160e01b600052601260045260246000fd5b6000826135fe576135fe6135d9565b500490565b808201808211156112b6576112b66135ac565b818103818111156112b6576112b66135ac565b60006001820161363b5761363b6135ac565b5060010190565b634e487b7160e01b600052603260045260246000fd5b600082613667576136676135d9565b500690565b60008161367b5761367b6135ac565b506000190190565b60208152600061369660208301846131ee565b939250505056fea26469706673582212206b4539fd0915402706c010916c7d9fb68eeb79290fa4bf9a64f39460f5e3430264736f6c63430008130033

Block Transaction Gas Used Reward
view all blocks ##produced##

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits

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