POL Price: $0.174597 (-1.51%)
 

Overview

POL Balance

Polygon PoS Chain LogoPolygon PoS Chain LogoPolygon PoS Chain Logo0 POL

POL Value

$0.00

Token Holdings

More Info

Private Name Tags

TokenTracker

Multichain Info

1 address found via
Transaction Hash
Method
Block
From
To
Set Approval For...789595652025-11-13 8:53:361 hr ago1763024016IN
Skyweaver: Token
0 POL0.01540285334.51732003
Set Approval For...789505022025-11-13 3:51:306 hrs ago1763005890IN
Skyweaver: Token
0 POL0.03102594673.81786056
Set Approval For...788901062025-11-11 18:18:1740 hrs ago1762885097IN
Skyweaver: Token
0 POL0.00522538113.484305
Safe Transfer Fr...788898512025-11-11 18:09:4740 hrs ago1762884587IN
Skyweaver: Token
0 POL0.00499409107.78923728
Set Approval For...788141892025-11-10 0:07:393 days ago1762733259IN
Skyweaver: Token
0 POL0.00517717112.23258799
Set Approval For...788102742025-11-09 21:57:093 days ago1762725429IN
Skyweaver: Token
0 POL0.0023517851.0757739
Safe Transfer Fr...786601572025-11-06 10:32:577 days ago1762425177IN
Skyweaver: Token
0 POL0.0043422183.0728526
Set Approval For...786359022025-11-05 21:04:277 days ago1762376667IN
Skyweaver: Token
0 POL0.0021600146.91099504
Set Approval For...786295972025-11-05 17:34:177 days ago1762364057IN
Skyweaver: Token
0 POL0.00511268111.03672161
Set Approval For...786055422025-11-05 4:12:278 days ago1762315947IN
Skyweaver: Token
0 POL0.00487283105.63500185
Set Approval For...785837862025-11-04 16:07:158 days ago1762272435IN
Skyweaver: Token
0 POL0.01204693261.63395701
Set Approval For...785038372025-11-02 19:42:0710 days ago1762112527IN
Skyweaver: Token
0 POL0.0014326331.1138259
Set Approval For...784858572025-11-02 9:42:4711 days ago1762076567IN
Skyweaver: Token
0 POL0.0039337185.43205593
Set Approval For...783653972025-10-30 14:47:0313 days ago1761835623IN
Skyweaver: Token
0 POL0.01633056354.66528338
Set Approval For...783390042025-10-30 0:07:1714 days ago1761782837IN
Skyweaver: Token
0 POL0.0021556446.81597498
Set Approval For...783141282025-10-29 10:18:0515 days ago1761733085IN
Skyweaver: Token
0 POL0.0016978370.35322068
Set Approval For...783097422025-10-29 7:51:5315 days ago1761724313IN
Skyweaver: Token
0 POL0.0043656394.81233994
Set Approval For...783034602025-10-29 4:22:2915 days ago1761711749IN
Skyweaver: Token
0 POL0.0007432530.79845652
Set Approval For...783029472025-10-29 4:05:2315 days ago1761710723IN
Skyweaver: Token
0 POL0.0007432630.79857071
Set Approval For...783028252025-10-29 4:01:1915 days ago1761710479IN
Skyweaver: Token
0 POL0.0007250230.0427777
Set Approval For...782840482025-10-28 17:35:2515 days ago1761672925IN
Skyweaver: Token
0 POL0.0008656735.87116085
Set Approval For...781957562025-10-26 16:32:1917 days ago1761496339IN
Skyweaver: Token
0 POL0.0018238439.61
Set Approval For...781929552025-10-26 14:58:5717 days ago1761490737IN
Skyweaver: Token
0 POL0.0013838730.00000213
Safe Transfer Fr...780641962025-10-23 15:26:5520 days ago1761233215IN
Skyweaver: Token
0 POL0.0036460869.75485845
Set Approval For...780479692025-10-23 6:26:0121 days ago1761200761IN
Skyweaver: Token
0 POL0.0016615636.08575586
View all transactions

Latest 1 internal transaction

Parent Transaction Hash Block From To
217504602021-11-24 15:52:231449 days ago1637769143  Contract Creation0 POL
Cross-Chain Transactions
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0x27A11C15...BaD9C0cf6
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
SkyweaverAssets

Compiler Version
v0.7.4+commit.3f05b770

Optimization Enabled:
Yes with 100000 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Standard Json-Input format)

pragma solidity 0.7.4;
pragma experimental ABIEncoderV2;

import "../utils/Ownable.sol";

import "@0xsequence/erc-1155/contracts/tokens/ERC1155PackedBalance/ERC1155MintBurnPackedBalance.sol";
import "@0xsequence/erc-1155/contracts/tokens/ERC1155/ERC1155Metadata.sol";
import "@0xsequence/erc-1155/contracts/tokens/ERC2981/ERC2981Global.sol";
import "@0xsequence/erc-1155/contracts/utils/SafeMath.sol";


/**
 * ERC-1155 token contract for skyweaver assets.
 * This contract manages the various SW asset factories
 * and ensures that each factory has constraint access in
 * terms of the id space they are allowed to mint.
 * @dev Mint permissions use range because factory contracts
 *      could be minting large numbers of NFTs or be built
 *      with granular, but efficient permission checks.
 */
contract SkyweaverAssets is ERC1155MintBurnPackedBalance, ERC1155Metadata, ERC2981Global, Ownable {
  using SafeMath for uint256;

  /***********************************|
  |             Variables             |
  |__________________________________*/

  // Factory mapping variables
  mapping(address => bool) internal isFactoryActive;          // Whether an address can print tokens or not
  mapping(address => AssetRange[]) internal mintAccessRanges; // Contains the ID ranges factories are allowed to mint
  AssetRange[] internal lockedRanges;                         // Ranges of IDs that can't be granted permission to mint

  // Issuance mapping variables
  mapping (uint256 => uint256) internal currentIssuance; // Current Issuance of token for tokens that have max issuance ONLY
  mapping (uint256 => uint256) internal maxIssuance;     // Issuance is counted and capped to associated maxIssuance if it's non-zero

  // Struct for mint ID ranges permissions
  struct AssetRange {
    uint64 minID;     // Minimum value the ID need to be to fall in the range
    uint64 maxID;     // Maximum value the ID need to be to fall in the range
    uint64 startTime; // Timestamp when the range becomes valid
    uint64 endTime;   // Timestamp after which the range is no longer valid 
  }

  /***********************************|
  |               Events              |
  |__________________________________*/

  event FactoryActivation(address indexed factory);
  event FactoryShutdown(address indexed factory);
  event MaxIssuancesChanged(uint256[] ids, uint256[] newMaxIssuances);
  event MintPermissionAdded(address indexed factory, AssetRange new_range);
  event MintPermissionRemoved(address indexed factory, AssetRange deleted_range);
  event RangeLocked(AssetRange locked_range);


  /***********************************|
  |             Constuctor            |
  |__________________________________*/
  
  constructor (address _firstOwner) ERC1155Metadata("Skyweaver", "") Ownable(_firstOwner) public {}


  /***********************************|
  |     Factory Management Methods    |
  |__________________________________*/

  /**
   * @notice Will ALLOW factory to print some assets specified in `canPrint` mapping
   * @param _factory Address of the factory to activate
   */
  function activateFactory(address _factory) external onlyOwner() {
    isFactoryActive[_factory] = true;
    emit FactoryActivation(_factory);
  }

  /**
   * @notice Will DISALLOW factory to print any asset
   * @param _factory Address of the factory to shutdown
   */
  function shutdownFactory(address _factory) external onlyOwner() {
    isFactoryActive[_factory] = false;
    emit FactoryShutdown(_factory);
  }

  /**
   * @notice Will allow a factory to mint some token ids
   * @param _factory   Address of the factory to update permission
   * @param _minRange  Minimum ID (inclusive) in id range that factory will be able to mint
   * @param _maxRange  Maximum ID (inclusive) in id range that factory will be able to mint
   * @param _startTime Timestamp when the range becomes valid
   * @param _endTime   Timestamp after which the range is no longer valid 
   */
  function addMintPermission(address _factory, uint64 _minRange, uint64 _maxRange, uint64 _startTime, uint64 _endTime) external onlyOwner() {
    require(_maxRange > 0, "SkyweaverAssets#addMintPermission: NULL_RANGE");
    require(_minRange <= _maxRange, "SkyweaverAssets#addMintPermission: INVALID_RANGE");
    require(_startTime < _endTime, "SkyweaverAssets#addMintPermission: START_TIME_IS_NOT_LESSER_THEN_END_TIME");

    // Check if new range has an overlap with locked ranges.
    // lockedRanges is expected to be a small array
    for (uint256 i = 0; i < lockedRanges.length; i++) {
      AssetRange memory locked_range = lockedRanges[i];
      require(
        (_maxRange < locked_range.minID) || (locked_range.maxID < _minRange),
        "SkyweaverAssets#addMintPermission: OVERLAP_WITH_LOCKED_RANGE"
      );
    }

    // Create and store range struct for _factory
    AssetRange memory range = AssetRange(_minRange, _maxRange, _startTime, _endTime);
    mintAccessRanges[_factory].push(range);
    emit MintPermissionAdded(_factory, range);
  }

  /**
   * @notice Will remove the permission a factory has to mint some token ids
   * @param _factory    Address of the factory to update permission
   * @param _rangeIndex Array's index where the range to delete is located for _factory
   */
  function removeMintPermission(address _factory, uint256 _rangeIndex) external onlyOwner() {
    // Will take the last range and put it where the "hole" will be after
    // the AssetRange struct at _rangeIndex is deleted
    uint256 last_index = mintAccessRanges[_factory].length - 1; // won't underflow because of require() statement above
    AssetRange memory range_to_delete = mintAccessRanges[_factory][_rangeIndex]; // Stored for log

    if (_rangeIndex != last_index) {
      AssetRange memory last_range = mintAccessRanges[_factory][last_index]; // Retrieve the range that will be moved
      mintAccessRanges[_factory][_rangeIndex] = last_range;                  // Overwrite the "to-be-deleted" range
    }

    // Delete last element of the array
    mintAccessRanges[_factory].pop();
    emit MintPermissionRemoved(_factory, range_to_delete);
  }

  /**
   * @notice Will forever prevent new mint permissions for provided ids
   * @dev THIS ACTION IS IRREVERSIBLE, USE WITH CAUTION
   * @dev In order to forever restrict minting of certain ids to a set of factories,
   *      one first needs to call `addMintPermission()` for the corresponding factory
   *      and the corresponding ids, then call this method to prevent further mint
   *      permissions to be granted. One can also remove mint permissions after ids
   *      mint permissions where locked down.
   * @param _range AssetRange struct for range of asset that can't be granted
   *               new mint permission to
   */
  function lockRangeMintPermissions(AssetRange memory _range) public onlyOwner() {
    lockedRanges.push(_range);
    emit RangeLocked(_range);
  }

  /***********************************|
  |    Supplies Management Methods    |
  |__________________________________*/

  /**
   * @notice Set max issuance for some token IDs that can't ever be increased
   * @dev Can only decrease the max issuance if already set, but can't set it *back* to 0.
   * @param _ids Array of token IDs to set the max issuance
   * @param _newMaxIssuances Array of max issuances for each corresponding ID
   */
  function setMaxIssuances(uint256[] calldata _ids, uint256[] calldata _newMaxIssuances) external onlyOwner() {
    require(_ids.length == _newMaxIssuances.length, "SkyweaverAssets#setMaxIssuances: INVALID_ARRAYS_LENGTH");

    // Can only *decrease* a max issuance
    // Can't set max issuance back to 0
    for (uint256 i = 0; i < _ids.length; i++ ) {
      if (maxIssuance[_ids[i]] > 0) {
        require(
          0 < _newMaxIssuances[i] && _newMaxIssuances[i] < maxIssuance[_ids[i]],
          "SkyweaverAssets#setMaxIssuances: INVALID_NEW_MAX_ISSUANCE"
        );
      }
      maxIssuance[_ids[i]] = _newMaxIssuances[i];
    }

    emit MaxIssuancesChanged(_ids, _newMaxIssuances);
  }

  /***********************************|
  |    Royalty Management Methods     |
  |__________________________________*/

  /**
   * @notice Will set the basis point and royalty recipient that is applied to all Skyweaver assets
   * @param _receiver Fee recipient that will receive the royalty payments
   * @param _royaltyBasisPoints Basis points with 3 decimals representing the fee %
   *        e.g. a fee of 2% would be 20 (i.e. 20 / 1000 == 0.02, or 2%)
   */
  function setGlobalRoyaltyInfo(address _receiver, uint256 _royaltyBasisPoints) external onlyOwner() {
    _setGlobalRoyaltyInfo(_receiver, _royaltyBasisPoints);
  }

  /***********************************|
  |      Receiver Method Handler      |
  |__________________________________*/

  /**
   * @notice Prevents receiving Ether or calls to unsuported methods
   */
  fallback () external {
    revert("UNSUPPORTED_METHOD");
  }

  /***********************************|
  |          Minting Function         |
  |__________________________________*/

  /**
   * @notice Mint tokens for each ids in _ids
   * @dev This methods assumes ids are sorted by how the ranges are sorted in
   *      the corresponding mintAccessRanges[msg.sender] array. Call might throw
   *      if they are not.
   * @param _to      The address to mint tokens to.
   * @param _ids     Array of ids to mint
   * @param _amounts Array of amount of tokens to mint per id
   * @param _data    Byte array of data to pass to recipient if it's a contract
   */
  function batchMint(
    address _to,
    uint256[] memory _ids,
    uint256[] memory _amounts,
    bytes memory _data) public
  {
    // Validate assets to be minted
    _validateMints(_ids, _amounts);

    // If hasn't reverted yet, all IDs are allowed for factory
    _batchMint(_to, _ids, _amounts, _data);
  }

  /**
   * @notice Mint _amount of tokens of a given id, if allowed.
   * @param _to      The address to mint tokens to
   * @param _id      Token id to mint
   * @param _amount  The amount to be minted
   * @param _data    Data to pass if receiver is contract
   */
  function mint(address _to, uint256 _id, uint256 _amount, bytes calldata _data) external
  {
    // Put into array for validation
    uint256[] memory ids = new uint256[](1);
    uint256[] memory amounts = new uint256[](1);
    ids[0] = _id;
    amounts[0] = _amount;

    // Validate and mint
    _validateMints(ids, amounts);
    _mint(_to, _id, _amount, _data);
  }

  /**
   * @notice Will validate the ids and amounts to mint
   * @dev This methods assumes ids are sorted by how the ranges are sorted in
   *      the corresponding mintAccessRanges[msg.sender] array. Call will revert
   *      if they are not.
   * @dev When the maxIssuance of an asset is set to a non-zero value, the
   *      supply manager contract will start keeping track of how many of that
   *      token are minted, until the maxIssuance hit.
   * @param _ids     Array of ids to mint
   * @param _amounts Array of amount of tokens to mint per id
   */
  function _validateMints(uint256[] memory _ids, uint256[] memory _amounts) internal {
    require(isFactoryActive[msg.sender], "SkyweaverAssets#_validateMints: FACTORY_NOT_ACTIVE");

    // Number of mint ranges
    uint256 n_ranges = mintAccessRanges[msg.sender].length;

    // Load factory's default range
    AssetRange memory range = mintAccessRanges[msg.sender][0];
    uint256 range_index = 0;

    // Will make sure that factory is allowed to print all ids
    // and that no max issuance is exceeded
    for (uint256 i = 0; i < _ids.length; i++) {
      uint256 id = _ids[i];
      uint256 amount = _amounts[i];
      uint256 max_issuance = maxIssuance[id];

      // If ID is out of current range, move to next range, else skip.
      // This function only moves forwards in the AssetRange array,
      // hence if _ids are not sorted correctly, the call will fail.
      while (block.timestamp < range.startTime || block.timestamp > range.endTime || id < range.minID || range.maxID < id) {
        range_index += 1;

        // Load next range. If none left, ID is assumed to be out of all ranges
        require(range_index < n_ranges, "SkyweaverAssets#_validateMints: ID_OUT_OF_RANGE");
        range = mintAccessRanges[msg.sender][range_index];
      }

      // If max supply is specified for id
      if (max_issuance > 0) {
        uint256 new_current_issuance = currentIssuance[id].add(amount);
        require(new_current_issuance <= max_issuance, "SkyweaverAssets#_validateMints: MAX_ISSUANCE_EXCEEDED");
        currentIssuance[id] = new_current_issuance;
      }
    }
  }

  /***********************************|
  |         Getter Functions          |
  |__________________________________*/

  /**
   * @notice Get the max issuance of multiple asset IDs
   * @dev The max issuance of a token does not reflect the maximum supply, only
   *      how many tokens can be minted once the maxIssuance for a token is set.
   * @param _ids Array containing the assets IDs
   * @return The current max issuance of each asset ID in _ids
   */
  function getMaxIssuances(uint256[] calldata _ids) external view returns (uint256[] memory) {
    uint256 nIds = _ids.length;
    uint256[] memory max_issuances = new uint256[](nIds);

    // Iterate over each owner and token ID
    for (uint256 i = 0; i < nIds; i++) {
      max_issuances[i] = maxIssuance[_ids[i]];
    }

    return max_issuances;
  }

  /**
   * @notice Get the current issuanc of multiple asset ID
   * @dev The current issuance of a token does not reflect the current supply, only
   *      how many tokens since a max issuance was set for a given token id.
   * @param _ids Array containing the assets IDs
   * @return The current issuance of each asset ID in _ids
   */
  function getCurrentIssuances(uint256[] calldata _ids) external view returns (uint256[] memory) {
    uint256 nIds = _ids.length;
    uint256[] memory current_issuances = new uint256[](nIds);

    // Iterate over each owner and token ID
    for (uint256 i = 0; i < nIds; i++) {
      current_issuances[i] = currentIssuance[_ids[i]];
    }

    return current_issuances;
  }

  /**
   * @return Returns whether a factory is active or not
   */
  function getFactoryStatus(address _factory) external view returns (bool) {
    return isFactoryActive[_factory];
  }

  /**
   * @return Returns whether the sale has ended or not
   */
  function getFactoryAccessRanges(address _factory) external view returns (AssetRange[] memory) {
    return mintAccessRanges[_factory];
  }

  /**
   * @return Returns all the ranges that are locked
   */
  function getLockedRanges() external view returns (AssetRange[] memory) {
    return lockedRanges;
  }

  /***********************************|
  |          Burning Functions        |
  |__________________________________*/

  /**
   * @notice Burn _amount of tokens of a given id from msg.sender
   * @dev This will not change the current issuance tracked in _supplyManagerAddr.
   * @param _id     Asset id to burn
   * @param _amount The amount to be burn
   */
  function burn(
    uint256 _id,
    uint256 _amount)
    external
  {
    _burn(msg.sender, _id, _amount);
  }

  /**
   * @notice Burn _amounts of tokens of given ids from msg.sender
   * @dev This will not change the current issuance tracked in _supplyManagerAddr.
   * @param _ids     Asset id to burn
   * @param _amounts The amount to be burn
   */
  function batchBurn(
    uint256[] calldata _ids,
    uint256[] calldata _amounts)
    external
  {
    _batchBurn(msg.sender, _ids, _amounts);
  }

  /***********************************|
  |           URI Functions           |
  |__________________________________*/

  /**
   * @dev Will update the base URL of token's URI
   * @param _newBaseMetadataURI New base URL of token's URI
   */
  function setBaseMetadataURI(string calldata _newBaseMetadataURI) external onlyOwner() {
    _setBaseMetadataURI(_newBaseMetadataURI);
  }

  /**
   * @dev Will emit default URI log event for corresponding token _id
   * @param _tokenIDs Array of IDs of tokens to log default URI
   */
  function logURIs(uint256[] calldata _tokenIDs) external onlyOwner() {
    _logURIs(_tokenIDs);
  }

  /***********************************|
  |          ERC165 Functions         |
  |__________________________________*/

  /**
   * @notice Query if a contract implements an interface
   * @param _interfaceID  The interface identifier, as specified in ERC-165
   * @return `true` if the contract implements `_interfaceID`
   */
  function supportsInterface(bytes4 _interfaceID) public override(ERC1155PackedBalance, ERC1155Metadata, ERC2981Global) virtual pure returns (bool) {
    return super.supportsInterface(_interfaceID);
  }
}

pragma solidity 0.7.4;
pragma experimental ABIEncoderV2;

interface ISkyweaverAssets {

  /***********************************|
  |               Events              |
  |__________________________________*/

  event FactoryActivation(address indexed factory);
  event FactoryShutdown(address indexed factory);
  event MintPermissionAdded(address indexed factory, AssetRange new_range);
  event MintPermissionRemoved(address indexed factory, AssetRange deleted_range);

  // Struct for mint ID ranges permissions
  struct AssetRange {
    uint256 minID;
    uint256 maxID;
  }

  /***********************************|
  |    Supplies Management Methods    |
  |__________________________________*/

  /**
   * @notice Set max issuance for some token IDs that can't ever be increased
   * @dev Can only decrease the max issuance if already set, but can't set it *back* to 0.
   * @param _ids Array of token IDs to set the max issuance
   * @param _newMaxIssuances Array of max issuances for each corresponding ID
   */
  function setMaxIssuances(uint256[] calldata _ids, uint256[] calldata _newMaxIssuances) external;

  /***********************************|
  |     Factory Management Methods    |
  |__________________________________*/

  /**
   * @notice Will allow a factory to mint some token ids
   * @param _factory   Address of the factory to update permission
   * @param _minRange  Minimum ID (inclusive) in id range that factory will be able to mint
   * @param _maxRange  Maximum ID (inclusive) in id range that factory will be able to mint
   * @param _startTime Timestamp when the range becomes valid
   * @param _endTime   Timestamp after which the range is no longer valid 
   */
  function addMintPermission(address _factory, uint64 _minRange, uint64 _maxRange, uint64 _startTime, uint64 _endTime) external;

  /**
   * @notice Will remove the permission a factory has to mint some token ids
   * @param _factory    Address of the factory to update permission
   * @param _rangeIndex Array's index where the range to delete is located for _factory
   */
  function removeMintPermission(address _factory, uint256 _rangeIndex) external;

  /**
   * @notice Will ALLOW factory to print some assets specified in `canPrint` mapping
   * @param _factory Address of the factory to activate
   */
  function activateFactory(address _factory) external;

  /**
   * @notice Will DISALLOW factory to print any asset
   * @param _factory Address of the factory to shutdown
   */
  function shutdownFactory(address _factory) external;

  /**
   * @notice Will forever prevent new mint permissions for provided ids
   * @param _range AssetRange struct for range of asset that can't be granted
   *               new mint permission to
   */
  function lockRangeMintPermissions(AssetRange calldata _range) external;


  /***********************************|
  |         Getter Functions          |
  |__________________________________*/

  /**
   * @return Returns whether a factory is active or not
   */
  function getFactoryStatus(address _factory) external view returns (bool);

  /**
   * @return Returns whether the sale has ended or not
   */
  function getFactoryAccessRanges(address _factory) external view returns ( AssetRange[] memory);

  /**
   * @notice Get the max issuance of multiple asset IDs
   * @dev The max issuance of a token does not reflect the maximum supply, only
   *      how many tokens can be minted once the maxIssuance for a token is set.
   * @param _ids Array containing the assets IDs
   * @return The current max issuance of each asset ID in _ids
   */
  function getMaxIssuances(uint256[] calldata _ids) external view returns (uint256[] memory);

  /**
   * @notice Get the current issuanc of multiple asset ID
   * @dev The current issuance of a token does not reflect the current supply, only
   *      how many tokens since a max issuance was set for a given token id.
   * @param _ids Array containing the assets IDs
   * @return The current issuance of each asset ID in _ids
   */
  function getCurrentIssuances(uint256[] calldata _ids)external view returns (uint256[] memory);

  /***************************************|
  |           Minting Functions           |
  |______________________________________*/

  /**
   * @dev Mint _amount of tokens of a given id if not frozen and if max supply not exceeded
   * @param _to     The address to mint tokens to.
   * @param _id     Token id to mint
   * @param _amount The amount to be minted
   * @param _data   Byte array of data to pass to recipient if it's a contract
   */
  function mint(address _to, uint256 _id, uint256 _amount, bytes calldata _data) external;

  /**
   * @dev Mint tokens for each ids in _ids
   * @param _to      The address to mint tokens to.
   * @param _ids     Array of ids to mint
   * @param _amounts Array of amount of tokens to mint per id
   * @param _data    Byte array of data to pass to recipient if it's a contract
   */
  function batchMint(address _to, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data) external;


  /***************************************|
  |           Burning Functions           |
  |______________________________________*/

  /**
   * @notice Burn sender's_amount of tokens of a given token id
   * @param _id      Token id to burn
   * @param _amount  The amount to be burned
   */
  function burn(uint256 _id, uint256 _amount) external;

  /**
   * @notice Burn sender's tokens of given token id for each (_ids[i], _amounts[i]) pair
   * @param _ids      Array of token ids to burn
   * @param _amounts  Array of the amount to be burned
   */
  function batchBurn(uint256[] calldata _ids, uint256[] calldata _amounts) external;
}

pragma solidity 0.7.4;

import "../utils/TieredOwnable.sol";
import "../interfaces/ISkyweaverAssets.sol";
import "../interfaces/IRewardFactory.sol";
import "@0xsequence/erc-1155/contracts/utils/SafeMath.sol";
import "@0xsequence/erc-1155/contracts/interfaces/IERC165.sol";
import "@0xsequence/erc-1155/contracts/interfaces/IERC1155.sol";
import "@0xsequence/erc-1155/contracts/interfaces/IERC1155TokenReceiver.sol";

/**
 * @notice Keep track of players participation in Conquest and used to issue rewards.
 * @dev This contract must be at least a TIER 1 owner of the silverCardFactory and
 *      goldCardFactory.
 */
contract Conquest is IERC1155TokenReceiver, TieredOwnable {
  using SafeMath for uint256;

  /***********************************|
  |             Variables             |
  |__________________________________*/

  // Parameters
  uint256 constant internal TIME_BETWEEN_CONQUESTS = 1 seconds; // Seconds that must elapse between two conquest
  uint256 constant internal ENTRIES_DECIMALS = 2;               // Amount of decimals conquest entries have
  uint256 constant internal CARDS_DECIMALS = 2;                 // Number of decimals cards have

  // Contracts
  IRewardFactory immutable public silverCardFactory; // Factory that mints Silver cards
  IRewardFactory immutable public goldCardFactory;   // Factory that mints Gold cards
  ISkyweaverAssets immutable public skyweaverAssets; // ERC-1155 Skyweaver assets contract
  uint256 immutable public conquestEntryID;          // Conquest entry token id

  // Mappings
  mapping(address => bool) public isActiveConquest;    // Whether a given player is currently in a conquest
  mapping(address => uint256) public conquestsEntered; // Number of conquest a given player has entered so far
  mapping(address => uint256) public nextConquestTime; // Time when the next conquest can be started for players

  // Event
  event ConquestEntered(address user, uint256 nConquests);


  /***********************************|
  |            Constructor            |
  |__________________________________*/

  /**
   * @notice Link factories and skyweaver assets, store initial parameters
   * @param _firstOwner               Address of the first owner
   * @param _skyweaverAssetsAddress   The address of the ERC-1155 Assets Token contract
   * @param _silverCardFactoryAddress The address of the Silver Card Factory
   * @param _goldCardFactoryAddress   The address of the Gold Card Factory
   * @param _conquestEntryTokenId     Conquest entry token id
   */
  constructor(
    address _firstOwner,
    address _skyweaverAssetsAddress,
    address _silverCardFactoryAddress,
    address _goldCardFactoryAddress,
    uint256 _conquestEntryTokenId
  ) TieredOwnable(_firstOwner) public 
  {
    require(
      _skyweaverAssetsAddress != address(0) &&
      _silverCardFactoryAddress != address(0) &&
      _goldCardFactoryAddress != address(0),
      "Conquest#constructor: INVALID_INPUT"
    );

    // Store parameters
    skyweaverAssets = ISkyweaverAssets(_skyweaverAssetsAddress);
    silverCardFactory = IRewardFactory(_silverCardFactoryAddress);
    goldCardFactory = IRewardFactory(_goldCardFactoryAddress);
    conquestEntryID = _conquestEntryTokenId;
  }

  
  /***********************************|
  |      Receiver Method Handler      |
  |__________________________________*/

  /**
   * @notice Prevents receiving Ether or calls to unsupported methods
   */
  fallback () external {
    revert("Conquest#_: UNSUPPORTED_METHOD");
  }

  /**
   * @notice Players entering conquest with conquest entry token
   * @dev Payload is passed to and verified by onERC1155BatchReceived()
   */
  function onERC1155Received(
    address _operator,
    address _from,
    uint256 _id, 
    uint256 _amount, 
    bytes calldata _data
  )
    external override returns(bytes4)
  {
    // Convert payload to arrays to pass to onERC1155BatchReceived()
    uint256[] memory ids = new uint256[](1);
    uint256[] memory amounts = new uint256[](1);
    ids[0] = _id;
    amounts[0] = _amount;

    // Will revert call if doesn't pass
    onERC1155BatchReceived(_operator, _from, ids, amounts, _data);
    
    // Return success
    return IERC1155TokenReceiver.onERC1155Received.selector;
  }

  /**
   * @notice Conquest entry point. Will mark user as having entered conquest if valid entry.
   * @param _from    Address who sent the token
   * @param _ids     An array containing ids of each Token being transferred
   * @param _amounts An array containing amounts of each Token being transferred
   */
  function onERC1155BatchReceived(
    address, // _operator
    address _from,
    uint256[] memory _ids,
    uint256[] memory _amounts,
    bytes memory // _data
  )
    public override returns(bytes4)
  {
    require(msg.sender == address(skyweaverAssets), "Conquest#entry: INVALID_ENTRY_TOKEN_ADDRESS");
    require(_ids.length == 1, "Conquest#entry: INVALID_IDS_ARRAY_LENGTH");
    require(_amounts.length == 1, "Conquest#entry: INVALID_AMOUNTS_ARRAY_LENGTH");
    require(_ids[0] == conquestEntryID, "Conquest#entry: INVALID_ENTRY_TOKEN_ID");
    require(_amounts[0] == 10**ENTRIES_DECIMALS, "Conquest#entry: INVALID_ENTRY_TOKEN_AMOUNT");
    require(!isActiveConquest[_from], "Conquest#entry: PLAYER_ALREADY_IN_CONQUEST");
    require(nextConquestTime[_from] <= block.timestamp, "Conquest#entry: NEW_CONQUEST_TOO_EARLY");

    // Mark player as playing
    isActiveConquest[_from] = true;
    conquestsEntered[_from] = conquestsEntered[_from].add(1);
    nextConquestTime[_from] = block.timestamp.add(TIME_BETWEEN_CONQUESTS);

    // Burn tickets
    skyweaverAssets.burn(conquestEntryID, 10**ENTRIES_DECIMALS);

    // Emit event
    emit ConquestEntered(_from, conquestsEntered[_from]);

    // Return success
    return IERC1155TokenReceiver.onERC1155BatchReceived.selector;
  }


  /***********************************|
  |         Minting Functions         |
  |__________________________________*/

  /**
   * @notice Will exit user from conquest and mint tokens to user 
   * @param _user      The address that exits conquest and receive the rewards
   * @param _silverIds Ids of silver cards to mint (duplicate ids if amount > 1)
   * @param _goldIds   Ids of gold cards to mint (duplicate ids if amount > 1)
   */
  function exitConquest(address _user, uint256[] calldata _silverIds, uint256[] calldata _goldIds)
    external onlyOwnerTier(1)
  { 
    require(isActiveConquest[_user], "Conquest#exitConquest: USER_IS_NOT_IN_CONQUEST");

    // Mark player as not playing anymore
    isActiveConquest[_user] = false;

    // 0 win - 1 loss ===> 0 rewards
    if (_silverIds.length == 0 && _goldIds.length == 0) {
      /*  Do nothing if user didn't win any matches  */

    // 1 win - 1 loss ===> 1 Silver card
    } else if (_silverIds.length == 1 && _goldIds.length == 0) { 
      silverCardFactory.batchMint(_user, _silverIds, array(1, 10**CARDS_DECIMALS), "");

    // 2 wins - 1 loss ===> 2 silver cards
    } else if (_silverIds.length == 2 && _goldIds.length == 0) { 
      silverCardFactory.batchMint(_user, _silverIds, array(2, 10**CARDS_DECIMALS), "");

    // 3 wins - 0 loss ===> 1 Silver card and 1 Gold card
    } else if (_silverIds.length == 1 && _goldIds.length == 1) { 
      silverCardFactory.batchMint(_user, _silverIds, array(1, 10**CARDS_DECIMALS), "");
      goldCardFactory.batchMint(_user, _goldIds, array(1, 10**CARDS_DECIMALS), "");

    // Revert for any other combination
    } else {
      revert("Conquest#exitConquest: INVALID_REWARDS");
    }
  }

  /***********************************|
  |         Utility Functions         |
  |__________________________________*/

  /** 
   * @notice Will create an array of uint _value of length _length
   * @param _length Number of elements in array
   * @param _value  Value to put in array at each element
   */
  function array(uint256 _length, uint256 _value) internal pure returns (uint256[] memory) {
    uint256[] memory a = new uint256[](_length);
    for (uint256 i = 0; i < _length; i++) {
      a[i] = _value;
    }
    return a;
  }

  /**
   * @notice Indicates whether a contract implements a given interface.
   * @param interfaceID The ERC-165 interface ID that is queried for support.
   * @return True if contract interface is supported.
   */
  function supportsInterface(bytes4 interfaceID) external pure returns (bool) {
    return  interfaceID == type(IERC165).interfaceId || 
      interfaceID == type(IERC1155TokenReceiver).interfaceId;
  }
}

pragma solidity 0.7.4;

/**
 * @notice The TieredOwnable can assign ownership tiers to addresses,
 * allowing inheriting contracts to choose which tier can call which function.
 */
contract TieredOwnable {
  uint256 constant internal HIGHEST_OWNER_TIER = 2**256-1; //Highest possible tier

  mapping(address => uint256) internal ownerTier;
  event OwnershipGranted(address indexed owner, uint256 indexed previousTier, uint256 indexed newTier);

  /**
   * @dev Sets the _firstOwner provided to highest owner tier
   * @dev _firstOwner First address to be a owner of this contract
   */
  constructor (address _firstOwner) {
    require(_firstOwner != address(0), "TieredOwnable#constructor: INVALID_FIRST_OWNER");
    ownerTier[_firstOwner] = HIGHEST_OWNER_TIER;
    emit OwnershipGranted(_firstOwner, 0, HIGHEST_OWNER_TIER);
  }

  /**
   * @dev Throws if called by an account that's in lower ownership tier than expected
   */
  modifier onlyOwnerTier(uint256 _minTier) {
    require(ownerTier[msg.sender] >= _minTier, "TieredOwnable#onlyOwnerTier: OWNER_TIER_IS_TOO_LOW");
    _;
  }

  /**
   * @notice Highest owners can change ownership tier of other owners
   * @dev Prevents changing sender's tier to ensure there is always at least one HIGHEST_OWNER_TIER owner.
   * @param _address Address of the owner
   * @param _tier    Ownership tier assigned to owner
   */
  function assignOwnership(address _address, uint256 _tier) external onlyOwnerTier(HIGHEST_OWNER_TIER) {
    require(_address != address(0), "TieredOwnable#assignOwnership: INVALID_ADDRESS");
    require(msg.sender != _address, "TieredOwnable#assignOwnership: UPDATING_SELF_TIER");
    emit OwnershipGranted(_address, ownerTier[_address], _tier);
    ownerTier[_address] = _tier;
  }

  /**
   * @notice Returns the ownership tier of provided owner
   * @param _owner Owner's address to query ownership tier
   */
  function getOwnerTier(address _owner) external view returns (uint256) {
    return ownerTier[_owner];
  }
}

pragma solidity 0.7.4;

/**
 * @notice This is a contract allowing contract owner to mint up to N
 *         assets per period of 6 hours.
 * @dev This contract should only be able to mint some assets types
 */
interface IRewardFactory {

  // Event
  event PeriodMintLimitChanged(uint256 oldMintingLimit, uint256 newMintingLimit);

  /***********************************|
  |         Management Methods        |
  |__________________________________*/

  /**
   * @notice Will update the daily mint limit
   * @dev This change will take effect immediatly once executed
   * @param _newPeriodMintLimit Amount of assets that can be minted within a period
   */
  function updatePeriodMintLimit(uint256 _newPeriodMintLimit) external;


  /***********************************|
  |         Minting Functions         |
  |__________________________________*/

  /**
   * @notice Will mint tokens to user
   * @dev Can only mint up to the periodMintLimit in a given 6hour period
   * @param _to      The address that receives the assets
   * @param _ids     Array of Tokens ID that are minted
   * @param _amounts Amount of Tokens id minted for each corresponding Token id in _tokenIds
   * @param _data    Byte array passed to recipient if recipient is a contract
   */
  function batchMint(address _to, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data) external;

  /***********************************|
  |         Utility Functions         |
  |__________________________________*/

  /**
   * @notice Returns how many cards can currently be minted by this factory
   */
  function getAvailableSupply() external view returns (uint256);

  /**
   * @notice Calculate the current period
   */
  function livePeriod() external view returns (uint256);

  /**
   * @notice Indicates whether a contract implements the `ERC1155TokenReceiver` functions and so can accept ERC1155 token types.
   * @param  interfaceID The ERC-165 interface ID that is queried for support.s
   * @dev This function MUST return true if it implements the ERC1155TokenReceiver interface and ERC-165 interface.
   *      This function MUST NOT consume more than 5,000 gas.
   * @return Wheter ERC-165 or ERC1155TokenReceiver interfaces are supported.
   */
  function supportsInterface(bytes4 interfaceID) external pure returns (bool);
}

pragma solidity 0.7.4;


/**
 * @title SafeMath
 * @dev Unsigned math operations with safety checks that revert on error
 */
library SafeMath {

  /**
   * @dev Multiplies two unsigned integers, reverts on overflow.
   */
  function mul(uint256 a, uint256 b) internal pure returns (uint256) {
    // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
    // benefit is lost if 'b' is also tested.
    // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
    if (a == 0) {
      return 0;
    }

    uint256 c = a * b;
    require(c / a == b, "SafeMath#mul: OVERFLOW");

    return c;
  }

  /**
   * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
   */
  function div(uint256 a, uint256 b) internal pure returns (uint256) {
    // Solidity only automatically asserts when dividing by 0
    require(b > 0, "SafeMath#div: DIVISION_BY_ZERO");
    uint256 c = a / b;
    // assert(a == b * c + a % b); // There is no case in which this doesn't hold

    return c;
  }

  /**
   * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
   */
  function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b <= a, "SafeMath#sub: UNDERFLOW");
    uint256 c = a - b;

    return c;
  }

  /**
   * @dev Adds two unsigned integers, reverts on overflow.
   */
  function add(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a + b;
    require(c >= a, "SafeMath#add: OVERFLOW");

    return c; 
  }

  /**
   * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
   * reverts when dividing by zero.
   */
  function mod(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b != 0, "SafeMath#mod: DIVISION_BY_ZERO");
    return a % b;
  }
}

// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;


/**
 * @title ERC165
 * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md
 */
interface IERC165 {

    /**
     * @notice Query if a contract implements an interface
     * @dev Interface identification is specified in ERC-165. This function
     * uses less than 30,000 gas
     * @param _interfaceId The interface identifier, as specified in ERC-165
     */
    function supportsInterface(bytes4 _interfaceId)
    external
    view
    returns (bool);
}

// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;
import './IERC165.sol';


interface IERC1155 is IERC165 {

  /****************************************|
  |                 Events                 |
  |_______________________________________*/

  /**
   * @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, including zero amount transfers as well as minting or burning
   *   Operator MUST be msg.sender
   *   When minting/creating tokens, the `_from` field MUST be set to `0x0`
   *   When burning/destroying tokens, the `_to` field MUST be set to `0x0`
   *   The total amount transferred from address 0x0 minus the total amount transferred to 0x0 may be used by clients and exchanges to be added to the "circulating supply" for a given token ID
   *   To broadcast the existence of a token ID with no initial balance, the contract SHOULD emit the TransferSingle event from `0x0` to `0x0`, with the token creator as `_operator`, and a `_amount` of 0
   */
  event TransferSingle(address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _amount);

  /**
   * @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, including zero amount transfers as well as minting or burning
   *   Operator MUST be msg.sender
   *   When minting/creating tokens, the `_from` field MUST be set to `0x0`
   *   When burning/destroying tokens, the `_to` field MUST be set to `0x0`
   *   The total amount transferred from address 0x0 minus the total amount transferred to 0x0 may be used by clients and exchanges to be added to the "circulating supply" for a given token ID
   *   To broadcast the existence of multiple token IDs with no initial balance, this SHOULD emit the TransferBatch event from `0x0` to `0x0`, with the token creator as `_operator`, and a `_amount` of 0
   */
  event TransferBatch(address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _amounts);

  /**
   * @dev MUST emit when an approval is updated
   */
  event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);


  /****************************************|
  |                Functions               |
  |_______________________________________*/

  /**
    * @notice Transfers amount of an _id from the _from address to the _to address specified
    * @dev MUST emit TransferSingle event on success
    * Caller must be approved to manage the _from account's tokens (see isApprovedForAll)
    * MUST throw if `_to` is the zero address
    * MUST throw if balance of sender for token `_id` is lower than the `_amount` sent
    * MUST throw on any other error
    * When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0). If so, it MUST call `onERC1155Received` on `_to` and revert if the return amount is not `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
    * @param _from    Source address
    * @param _to      Target address
    * @param _id      ID of the token type
    * @param _amount  Transfered amount
    * @param _data    Additional data with no specified format, sent in call to `_to`
    */
  function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount, bytes calldata _data) external;

  /**
    * @notice Send multiple types of Tokens from the _from address to the _to address (with safety call)
    * @dev MUST emit TransferBatch event on success
    * Caller must be approved to manage the _from account's tokens (see isApprovedForAll)
    * MUST throw if `_to` is the zero address
    * MUST throw if length of `_ids` is not the same as length of `_amounts`
    * MUST throw if any of the balance of sender for token `_ids` is lower than the respective `_amounts` sent
    * MUST throw on any other error
    * When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0). If so, it MUST call `onERC1155BatchReceived` on `_to` and revert if the return amount is not `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
    * Transfers and events MUST occur in the array order they were submitted (_ids[0] before _ids[1], etc)
    * @param _from     Source addresses
    * @param _to       Target addresses
    * @param _ids      IDs of each token type
    * @param _amounts  Transfer amounts per token type
    * @param _data     Additional data with no specified format, sent in call to `_to`
  */
  function safeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data) external;

  /**
   * @notice Get the balance of an account's Tokens
   * @param _owner  The address of the token holder
   * @param _id     ID of the Token
   * @return        The _owner's balance of the Token type requested
   */
  function balanceOf(address _owner, uint256 _id) external view returns (uint256);

  /**
   * @notice Get the balance of multiple account/token pairs
   * @param _owners The addresses of the token holders
   * @param _ids    ID of the Tokens
   * @return        The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair)
   */
  function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) external view returns (uint256[] memory);

  /**
   * @notice Enable or disable approval for a third party ("operator") to manage all of caller's tokens
   * @dev MUST emit the ApprovalForAll event on success
   * @param _operator  Address to add to the set of authorized operators
   * @param _approved  True if the operator is approved, false to revoke approval
   */
  function setApprovalForAll(address _operator, bool _approved) external;

  /**
   * @notice Queries the approval status of an operator for a given owner
   * @param _owner     The owner of the Tokens
   * @param _operator  Address of authorized operator
   * @return isOperator True if the operator is approved, false if not
   */
  function isApprovedForAll(address _owner, address _operator) external view returns (bool isOperator);
}

// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;

/**
 * @dev ERC-1155 interface for accepting safe transfers.
 */
interface IERC1155TokenReceiver {

  /**
   * @notice Handle the receipt of a single ERC1155 token type
   * @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeTransferFrom` after the balance has been updated
   * This function MAY throw to revert and reject the transfer
   * Return of other amount than the magic value MUST result in the transaction being reverted
   * Note: The token contract address is always the message sender
   * @param _operator  The address which called the `safeTransferFrom` function
   * @param _from      The address which previously owned the token
   * @param _id        The id of the token being transferred
   * @param _amount    The amount of tokens being transferred
   * @param _data      Additional data with no specified format
   * @return           `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
   */
  function onERC1155Received(address _operator, address _from, uint256 _id, uint256 _amount, bytes calldata _data) external returns(bytes4);

  /**
   * @notice Handle the receipt of multiple ERC1155 token types
   * @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeBatchTransferFrom` after the balances have been updated
   * This function MAY throw to revert and reject the transfer
   * Return of other amount than the magic value WILL result in the transaction being reverted
   * Note: The token contract address is always the message sender
   * @param _operator  The address which called the `safeBatchTransferFrom` function
   * @param _from      The address which previously owned the token
   * @param _ids       An array containing ids of each token being transferred
   * @param _amounts   An array containing amounts of each token being transferred
   * @param _data      Additional data with no specified format
   * @return           `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
   */
  function onERC1155BatchReceived(address _operator, address _from, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data) external returns(bytes4);
}

// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;

import "../../utils/SafeMath.sol";
import "../../interfaces/IERC1155TokenReceiver.sol";
import "../../interfaces/IERC1155.sol";
import "../../utils/Address.sol";
import "../../utils/ERC165.sol";


/**
 * @dev Implementation of Multi-Token Standard contract. This implementation of the ERC-1155 standard
 *      utilizes the fact that balances of different token ids can be concatenated within individual
 *      uint256 storage slots. This allows the contract to batch transfer tokens more efficiently at
 *      the cost of limiting the maximum token balance each address can hold. This limit is
 *      2^IDS_BITS_SIZE, which can be adjusted below. In practice, using IDS_BITS_SIZE smaller than 16
 *      did not lead to major efficiency gains.
 */
contract ERC1155PackedBalance is IERC1155, ERC165 {
  using SafeMath for uint256;
  using Address for address;

  /***********************************|
  |        Variables and Events       |
  |__________________________________*/

  // onReceive function signatures
  bytes4 constant internal ERC1155_RECEIVED_VALUE = 0xf23a6e61;
  bytes4 constant internal ERC1155_BATCH_RECEIVED_VALUE = 0xbc197c81;

  // Constants regarding bin sizes for balance packing
  // IDS_BITS_SIZE **MUST** be a power of 2 (e.g. 2, 4, 8, 16, 32, 64, 128)
  uint256 internal constant IDS_BITS_SIZE   = 32;                  // Max balance amount in bits per token ID
  uint256 internal constant IDS_PER_UINT256 = 256 / IDS_BITS_SIZE; // Number of ids per uint256

  // Operations for _updateIDBalance
  enum Operations { Add, Sub }

  // Token IDs balances ; balances[address][id] => balance (using array instead of mapping for efficiency)
  mapping (address => mapping(uint256 => uint256)) internal balances;

  // Operators
  mapping (address => mapping(address => bool)) internal operators;


  /***********************************|
  |     Public Transfer Functions     |
  |__________________________________*/

  /**
   * @notice Transfers amount amount of an _id from the _from address to the _to address specified
   * @param _from    Source address
   * @param _to      Target address
   * @param _id      ID of the token type
   * @param _amount  Transfered amount
   * @param _data    Additional data with no specified format, sent in call to `_to`
   */
  function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount, bytes memory _data)
    public override
  {
    // Requirements
    require((msg.sender == _from) || isApprovedForAll(_from, msg.sender), "ERC1155PackedBalance#safeTransferFrom: INVALID_OPERATOR");
    require(_to != address(0),"ERC1155PackedBalance#safeTransferFrom: INVALID_RECIPIENT");
    // require(_amount <= balances);  Not necessary since checked with _viewUpdateBinValue() checks

    _safeTransferFrom(_from, _to, _id, _amount);
    _callonERC1155Received(_from, _to, _id, _amount, gasleft(), _data);
  }

  /**
   * @notice Send multiple types of Tokens from the _from address to the _to address (with safety call)
   * @dev Arrays should be sorted so that all ids in a same storage slot are adjacent (more efficient)
   * @param _from     Source addresses
   * @param _to       Target addresses
   * @param _ids      IDs of each token type
   * @param _amounts  Transfer amounts per token type
   * @param _data     Additional data with no specified format, sent in call to `_to`
   */
  function safeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data)
    public override
  {
    // Requirements
    require((msg.sender == _from) || isApprovedForAll(_from, msg.sender), "ERC1155PackedBalance#safeBatchTransferFrom: INVALID_OPERATOR");
    require(_to != address(0),"ERC1155PackedBalance#safeBatchTransferFrom: INVALID_RECIPIENT");

    _safeBatchTransferFrom(_from, _to, _ids, _amounts);
    _callonERC1155BatchReceived(_from, _to, _ids, _amounts, gasleft(), _data);
  }


  /***********************************|
  |    Internal Transfer Functions    |
  |__________________________________*/

  /**
   * @notice Transfers amount amount of an _id from the _from address to the _to address specified
   * @param _from    Source address
   * @param _to      Target address
   * @param _id      ID of the token type
   * @param _amount  Transfered amount
   */
  function _safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount)
    internal
  {
    //Update balances
    _updateIDBalance(_from, _id, _amount, Operations.Sub); // Subtract amount from sender
    _updateIDBalance(_to,   _id, _amount, Operations.Add); // Add amount to recipient

    // Emit event
    emit TransferSingle(msg.sender, _from, _to, _id, _amount);
  }

  /**
   * @notice Verifies if receiver is contract and if so, calls (_to).onERC1155Received(...)
   */
  function _callonERC1155Received(address _from, address _to, uint256 _id, uint256 _amount, uint256 _gasLimit, bytes memory _data)
    internal
  {
    // Check if recipient is contract
    if (_to.isContract()) {
      bytes4 retval = IERC1155TokenReceiver(_to).onERC1155Received{gas:_gasLimit}(msg.sender, _from, _id, _amount, _data);
      require(retval == ERC1155_RECEIVED_VALUE, "ERC1155PackedBalance#_callonERC1155Received: INVALID_ON_RECEIVE_MESSAGE");
    }
  }

  /**
   * @notice Send multiple types of Tokens from the _from address to the _to address (with safety call)
   * @dev Arrays should be sorted so that all ids in a same storage slot are adjacent (more efficient)
   * @param _from     Source addresses
   * @param _to       Target addresses
   * @param _ids      IDs of each token type
   * @param _amounts  Transfer amounts per token type
   */
  function _safeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts)
    internal
  {
    uint256 nTransfer = _ids.length; // Number of transfer to execute
    require(nTransfer == _amounts.length, "ERC1155PackedBalance#_safeBatchTransferFrom: INVALID_ARRAYS_LENGTH");

    if (_from != _to && nTransfer > 0) {
      // Load first bin and index where the token ID balance exists
      (uint256 bin, uint256 index) = getIDBinIndex(_ids[0]);

      // Balance for current bin in memory (initialized with first transfer)
      uint256 balFrom = _viewUpdateBinValue(balances[_from][bin], index, _amounts[0], Operations.Sub);
      uint256 balTo = _viewUpdateBinValue(balances[_to][bin], index, _amounts[0], Operations.Add);

      // Last bin updated
      uint256 lastBin = bin;

      for (uint256 i = 1; i < nTransfer; i++) {
        (bin, index) = getIDBinIndex(_ids[i]);

        // If new bin
        if (bin != lastBin) {
          // Update storage balance of previous bin
          balances[_from][lastBin] = balFrom;
          balances[_to][lastBin] = balTo;

          balFrom = balances[_from][bin];
          balTo = balances[_to][bin];

          // Bin will be the most recent bin
          lastBin = bin;
        }

        // Update memory balance
        balFrom = _viewUpdateBinValue(balFrom, index, _amounts[i], Operations.Sub);
        balTo = _viewUpdateBinValue(balTo, index, _amounts[i], Operations.Add);
      }

      // Update storage of the last bin visited
      balances[_from][bin] = balFrom;
      balances[_to][bin] = balTo;

    // If transfer to self, just make sure all amounts are valid
    } else {
      for (uint256 i = 0; i < nTransfer; i++) {
        require(balanceOf(_from, _ids[i]) >= _amounts[i], "ERC1155PackedBalance#_safeBatchTransferFrom: UNDERFLOW");
      }
    }

    // Emit event
    emit TransferBatch(msg.sender, _from, _to, _ids, _amounts);
  }

  /**
   * @notice Verifies if receiver is contract and if so, calls (_to).onERC1155BatchReceived(...)
   */
  function _callonERC1155BatchReceived(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, uint256 _gasLimit, bytes memory _data)
    internal
  {
    // Pass data if recipient is contract
    if (_to.isContract()) {
      bytes4 retval = IERC1155TokenReceiver(_to).onERC1155BatchReceived{gas: _gasLimit}(msg.sender, _from, _ids, _amounts, _data);
      require(retval == ERC1155_BATCH_RECEIVED_VALUE, "ERC1155PackedBalance#_callonERC1155BatchReceived: INVALID_ON_RECEIVE_MESSAGE");
    }
  }


  /***********************************|
  |         Operator Functions        |
  |__________________________________*/

  /**
   * @notice Enable or disable approval for a third party ("operator") to manage all of caller's tokens
   * @param _operator  Address to add to the set of authorized operators
   * @param _approved  True if the operator is approved, false to revoke approval
   */
  function setApprovalForAll(address _operator, bool _approved)
    external override
  {
    // Update operator status
    operators[msg.sender][_operator] = _approved;
    emit ApprovalForAll(msg.sender, _operator, _approved);
  }

  /**
   * @notice Queries the approval status of an operator for a given owner
   * @param _owner     The owner of the Tokens
   * @param _operator  Address of authorized operator
   * @return isOperator True if the operator is approved, false if not
   */
  function isApprovedForAll(address _owner, address _operator)
    public override view returns (bool isOperator)
  {
    return operators[_owner][_operator];
  }


  /***********************************|
  |     Public Balance Functions      |
  |__________________________________*/

  /**
   * @notice Get the balance of an account's Tokens
   * @param _owner  The address of the token holder
   * @param _id     ID of the Token
   * @return The _owner's balance of the Token type requested
   */
  function balanceOf(address _owner, uint256 _id)
    public override view returns (uint256)
  {
    uint256 bin;
    uint256 index;

    //Get bin and index of _id
    (bin, index) = getIDBinIndex(_id);
    return getValueInBin(balances[_owner][bin], index);
  }

  /**
   * @notice Get the balance of multiple account/token pairs
   * @param _owners The addresses of the token holders (sorted owners will lead to less gas usage)
   * @param _ids    ID of the Tokens (sorted ids will lead to less gas usage
   * @return The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair)
    */
  function balanceOfBatch(address[] memory _owners, uint256[] memory _ids)
    public override view returns (uint256[] memory)
  {
    uint256 n_owners = _owners.length;
    require(n_owners == _ids.length, "ERC1155PackedBalance#balanceOfBatch: INVALID_ARRAY_LENGTH");

    // First values
    (uint256 bin, uint256 index) = getIDBinIndex(_ids[0]);
    uint256 balance_bin = balances[_owners[0]][bin];
    uint256 last_bin = bin;

    // Initialization
    uint256[] memory batchBalances = new uint256[](n_owners);
    batchBalances[0] = getValueInBin(balance_bin, index);

    // Iterate over each owner and token ID
    for (uint256 i = 1; i < n_owners; i++) {
      (bin, index) = getIDBinIndex(_ids[i]);

      // SLOAD if bin changed for the same owner or if owner changed
      if (bin != last_bin || _owners[i-1] != _owners[i]) {
        balance_bin = balances[_owners[i]][bin];
        last_bin = bin;
      }

      batchBalances[i] = getValueInBin(balance_bin, index);
    }

    return batchBalances;
  }


  /***********************************|
  |      Packed Balance Functions     |
  |__________________________________*/

  /**
   * @notice Update the balance of a id for a given address
   * @param _address    Address to update id balance
   * @param _id         Id to update balance of
   * @param _amount     Amount to update the id balance
   * @param _operation  Which operation to conduct :
   *   Operations.Add: Add _amount to id balance
   *   Operations.Sub: Substract _amount from id balance
   */
  function _updateIDBalance(address _address, uint256 _id, uint256 _amount, Operations _operation)
    internal
  {
    uint256 bin;
    uint256 index;

    // Get bin and index of _id
    (bin, index) = getIDBinIndex(_id);

    // Update balance
    balances[_address][bin] = _viewUpdateBinValue(balances[_address][bin], index, _amount, _operation);
  }

  /**
   * @notice Update a value in _binValues
   * @param _binValues  Uint256 containing values of size IDS_BITS_SIZE (the token balances)
   * @param _index      Index of the value in the provided bin
   * @param _amount     Amount to update the id balance
   * @param _operation  Which operation to conduct :
   *   Operations.Add: Add _amount to value in _binValues at _index
   *   Operations.Sub: Substract _amount from value in _binValues at _index
   */
  function _viewUpdateBinValue(uint256 _binValues, uint256 _index, uint256 _amount, Operations _operation)
    internal pure returns (uint256 newBinValues)
  {
    uint256 shift = IDS_BITS_SIZE * _index;
    uint256 mask = (uint256(1) << IDS_BITS_SIZE) - 1;

    if (_operation == Operations.Add) {
      newBinValues = _binValues + (_amount << shift);
      require(newBinValues >= _binValues, "ERC1155PackedBalance#_viewUpdateBinValue: OVERFLOW");
      require(
        ((_binValues >> shift) & mask) + _amount < 2**IDS_BITS_SIZE, // Checks that no other id changed
        "ERC1155PackedBalance#_viewUpdateBinValue: OVERFLOW"
      );

    } else if (_operation == Operations.Sub) {
      newBinValues = _binValues - (_amount << shift);
      require(newBinValues <= _binValues, "ERC1155PackedBalance#_viewUpdateBinValue: UNDERFLOW");
      require(
        ((_binValues >> shift) & mask) >= _amount, // Checks that no other id changed
        "ERC1155PackedBalance#_viewUpdateBinValue: UNDERFLOW"
      );

    } else {
      revert("ERC1155PackedBalance#_viewUpdateBinValue: INVALID_BIN_WRITE_OPERATION"); // Bad operation
    }

    return newBinValues;
  }

  /**
  * @notice Return the bin number and index within that bin where ID is
  * @param _id  Token id
  * @return bin index (Bin number, ID"s index within that bin)
  */
  function getIDBinIndex(uint256 _id)
    public pure returns (uint256 bin, uint256 index)
  {
    bin = _id / IDS_PER_UINT256;
    index = _id % IDS_PER_UINT256;
    return (bin, index);
  }

  /**
   * @notice Return amount in _binValues at position _index
   * @param _binValues  uint256 containing the balances of IDS_PER_UINT256 ids
   * @param _index      Index at which to retrieve amount
   * @return amount at given _index in _bin
   */
  function getValueInBin(uint256 _binValues, uint256 _index)
    public pure returns (uint256)
  {
    // require(_index < IDS_PER_UINT256) is not required since getIDBinIndex ensures `_index < IDS_PER_UINT256`

    // Mask to retrieve data for a given binData
    uint256 mask = (uint256(1) << IDS_BITS_SIZE) - 1;

    // Shift amount
    uint256 rightShift = IDS_BITS_SIZE * _index;
    return (_binValues >> rightShift) & mask;
  }


  /***********************************|
  |          ERC165 Functions         |
  |__________________________________*/

  /**
   * @notice Query if a contract implements an interface
   * @param _interfaceID  The interface identifier, as specified in ERC-165
   * @return `true` if the contract implements `_interfaceID` and
   */
  function supportsInterface(bytes4 _interfaceID) public override(ERC165, IERC165) virtual pure returns (bool) {
    if (_interfaceID == type(IERC1155).interfaceId) {
      return true;
    }
    return super.supportsInterface(_interfaceID);
  }
}

pragma solidity 0.7.4;


/**
 * Utility library of inline functions on addresses
 */
library Address {

  // Default hash for EOA accounts returned by extcodehash
  bytes32 constant internal ACCOUNT_HASH = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;

  /**
   * Returns whether the target address is a contract
   * @dev This function will return false if invoked during the constructor of a contract.
   * @param _address address of the account to check
   * @return Whether the target address is a contract
   */
  function isContract(address _address) internal view returns (bool) {
    bytes32 codehash;

    // Currently there is no better way to check if there is a contract in an address
    // than to check the size of the code at that address or if it has a non-zero code hash or account hash
    assembly { codehash := extcodehash(_address) }
    return (codehash != 0x0 && codehash != ACCOUNT_HASH);
  }
}

pragma solidity 0.7.4;
import "../interfaces/IERC165.sol";

abstract contract ERC165 is IERC165 {
  /**
   * @notice Query if a contract implements an interface
   * @param _interfaceID The interface identifier, as specified in ERC-165
   * @return `true` if the contract implements `_interfaceID`
   */
  function supportsInterface(bytes4 _interfaceID) virtual override public pure returns (bool) {
    return _interfaceID == this.supportsInterface.selector;
  }
}

// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;
import "../../utils/ERC165.sol";
import "../../utils/SafeMath.sol";
import "../../interfaces/IERC2981.sol";

/**
 * @notice Contract return royalty information for tokens of this contract
 * @dev This contract sets a global fee information for all token ids.
 */
contract ERC2981Global is IERC2981, ERC165 {
  using SafeMath for uint256;

  struct FeeInfo {
    address receiver;
    uint256 feeBasisPoints;
  }

  // Royalty Fee information struct
  FeeInfo public globalRoyaltyInfo;

  /**
   * @notice Will set the basis point and royalty recipient that is applied to all assets
   * @param _receiver Fee recipient that will receive the royalty payments
   * @param _royaltyBasisPoints Basis points with 3 decimals representing the fee %
   *        e.g. a fee of 2% would be 20 (i.e. 20 / 1000 == 0.02, or 2%)
   */
  function _setGlobalRoyaltyInfo(address _receiver, uint256 _royaltyBasisPoints) internal {
    require(_receiver != address(0x0), "ERC2981Global#_setGlobalRoyalty: RECIPIENT_IS_0x0");
    require(_royaltyBasisPoints <= 1000, "ERC2981Global#_setGlobalRoyalty: FEE_IS_ABOVE_100_PERCENT");
    globalRoyaltyInfo.receiver = _receiver;
    globalRoyaltyInfo.feeBasisPoints = _royaltyBasisPoints;
  }


  /***********************************|
  |         ERC-2981 Functions        |
  |__________________________________*/

    /**  
    * @notice Called with the sale price to determine how much royalty is owed and to whom.
    * @param _saleCost - the sale cost of the NFT asset specified by _tokenId
    * @return receiver - address of who should be sent the royalty payment
    * @return royaltyAmount - the royalty payment amount for _salePrice
    */
  function royaltyInfo(
    uint256, 
    uint256 _saleCost
  ) external view override returns (address receiver, uint256 royaltyAmount) 
  {
    FeeInfo memory info = globalRoyaltyInfo;
    return (info.receiver, _saleCost.mul(info.feeBasisPoints).div(1000));
  }


  /***********************************|
  |         ERC-165 Functions         |
  |__________________________________*/

  /**
   * @notice Query if a contract implements an interface
   * @param _interfaceID  The interface identifier, as specified in ERC-165
   * @return `true` if the contract implements `_interfaceID` and
   */
  function supportsInterface(bytes4 _interfaceID) public override(ERC165, IERC165) virtual pure returns (bool) {
    if (_interfaceID == type(IERC2981).interfaceId) {
      return true;
    }
    return super.supportsInterface(_interfaceID);
  }
}

// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;
import './IERC165.sol';

interface IERC2981 is IERC165 {
  /**  
    * @notice Called with the sale price to determine how much royalty is owed and to whom.
    * @param _tokenId - the NFT asset queried for royalty information
    * @param _saleCost - the sale cost of the NFT asset specified by _tokenId
    * @return receiver - address of who should be sent the royalty payment
    * @return royaltyAmount - the royalty payment amount for _salePrice
    */
  function royaltyInfo(uint256 _tokenId, uint256 _saleCost) external view returns (address receiver, uint256 royaltyAmount);
}

pragma solidity 0.7.4;

import "../utils/TieredOwnable.sol";
import "../interfaces/ISkyweaverAssets.sol";
import "@0xsequence/erc-1155/contracts/utils/SafeMath.sol";
import "@0xsequence/erc-1155/contracts/interfaces/IERC165.sol";

/**
 * @notice This is a contract allowing contract owner to mint up to N 
 *         assets per period of 6 hours.
 * @dev This contract should only be able to mint some asset types
 */
contract RewardFactory is TieredOwnable {
  using SafeMath for uint256;

  /***********************************|
  |             Variables             |
  |__________________________________*/

  // Token information
  ISkyweaverAssets immutable public skyweaverAssets; // ERC-1155 Skyweaver assets contract

  // Period variables
  uint256 internal period;                // Current period
  uint256 internal availableSupply;       // Amount of assets that can currently be minted
  uint256 public periodMintLimit;         // Amount that can be minted within 6h
  uint256 immutable public PERIOD_LENGTH; // Length of each mint periods in seconds

  // Whitelist
  bool internal immutable MINT_WHITELIST_ONLY;
  mapping(uint256 => bool) public mintWhitelist;

  // Event
  event PeriodMintLimitChanged(uint256 oldMintingLimit, uint256 newMintingLimit);
  event AssetsEnabled(uint256[] enabledIds);
  event AssetsDisabled(uint256[] disabledIds);
  
  /***********************************|
  |            Constructor            |
  |__________________________________*/

  /**
   * @notice Create factory, link skyweaver assets and store initial parameters
   * @param _firstOwner      Address of the first owner
   * @param _assetsAddr      The address of the ERC-1155 Assets Token contract
   * @param _periodLength    Number of seconds each period lasts
   * @param _periodMintLimit Can only mint N assets per period
   * @param _whitelistOnly   Whether this factory uses a mint whitelist or not
   */
  constructor(
    address _firstOwner,
    address _assetsAddr,
    uint256 _periodLength,
    uint256 _periodMintLimit,
    bool _whitelistOnly
  ) TieredOwnable(_firstOwner) public {
    require(
      _assetsAddr != address(0) &&
      _periodLength > 0 &&
      _periodMintLimit > 0,
      "RewardFactory#constructor: INVALID_INPUT"
    );

    // Assets
    skyweaverAssets = ISkyweaverAssets(_assetsAddr);

    // Set Period length
    PERIOD_LENGTH = _periodLength;

    // Set whether this factory uses a mint whitelist or not
    MINT_WHITELIST_ONLY = _whitelistOnly;

    // Set current period
    period = block.timestamp / _periodLength; // From livePeriod()
    availableSupply = _periodMintLimit;

    // Rewards parameters
    periodMintLimit = _periodMintLimit;
    emit PeriodMintLimitChanged(0, _periodMintLimit);
  }


  /***********************************|
  |         Management Methods        |
  |__________________________________*/

  /**
   * @notice Will update the daily mint limit
   * @dev This change will take effect immediatly once executed
   * @param _newPeriodMintLimit Amount of assets that can be minted within a period
   */
  function updatePeriodMintLimit(uint256 _newPeriodMintLimit) external onlyOwnerTier(HIGHEST_OWNER_TIER) {
    // Immediately update supply instead of waiting for next period
    if (availableSupply > _newPeriodMintLimit) {
      availableSupply = _newPeriodMintLimit;
    }

    emit PeriodMintLimitChanged(periodMintLimit, _newPeriodMintLimit);
    periodMintLimit = _newPeriodMintLimit;
  }

  /**
   * @notice Will enable these tokens to be minted by this factory
   * @param _enabledIds IDs this factory can mint
   */
  function enableMint(uint256[] calldata _enabledIds) external onlyOwnerTier(HIGHEST_OWNER_TIER) {
    for (uint256 i = 0; i < _enabledIds.length; i++) {
      mintWhitelist[_enabledIds[i]] = true;
    }
    emit AssetsEnabled(_enabledIds);
  }

  /**
   * @notice Will prevent these ids from being minted by this factory
   * @param _disabledIds IDs this factory can mint
   */
  function disableMint(uint256[] calldata _disabledIds) external onlyOwnerTier(HIGHEST_OWNER_TIER) {
    for (uint256 i = 0; i < _disabledIds.length; i++) {
      mintWhitelist[_disabledIds[i]] = false;
    }
    emit AssetsDisabled(_disabledIds);
  }


  /***********************************|
  |      Receiver Method Handler      |
  |__________________________________*/

  /**
   * @notice Prevents receiving Ether or calls to unsuported methods
   */
  fallback () external {
    revert("RewardFactory#_: UNSUPPORTED_METHOD");
  }

  /***********************************|
  |         Minting Functions         |
  |__________________________________*/

  /**
   * @notice Will mint tokens to user
   * @dev Can only mint up to the periodMintLimit in a given 6hour period
   * @param _to      The address that receives the assets
   * @param _ids     Array of Tokens ID that are minted
   * @param _amounts Amount of Tokens id minted for each corresponding Token id in _ids
   * @param _data    Byte array passed to recipient if recipient is a contract
   */
  function batchMint(address _to, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data)
    external onlyOwnerTier(1)
  {
    uint256 live_period = livePeriod();
    uint256 stored_period = period;
    uint256 available_supply;

    // Update period and refresh the available supply if period
    // is different, otherwise use current available supply.
    if (live_period == stored_period) {
      available_supply = availableSupply;
    } else {
      available_supply = periodMintLimit;
      period = live_period;
    }

    // If there is an insufficient available supply, this will revert
    for (uint256 i = 0; i < _ids.length; i++) {
      available_supply = available_supply.sub(_amounts[i]);
      if (MINT_WHITELIST_ONLY) {
        require(mintWhitelist[_ids[i]], "RewardFactory#batchMint: ID_IS_NOT_WHITELISTED");
      }
    }

    // Store available supply
    availableSupply = available_supply;
    
    // Mint assets
    skyweaverAssets.batchMint(_to, _ids, _amounts, _data);
  }


  /***********************************|
  |         Utility Functions         |
  |__________________________________*/

  /**
   * @notice Returns how many cards can currently be minted by this factory
   */
  function getAvailableSupply() external view returns (uint256) {
    return livePeriod() == period ? availableSupply : periodMintLimit;
  }

  /**
   * @notice Calculate the current period
   */
  function livePeriod() public view returns (uint256) {
    return block.timestamp / PERIOD_LENGTH;
  }

  /**
   * @notice Indicates whether a contract implements a given interface.
   * @param interfaceID The ERC-165 interface ID that is queried for support.
   * @return True if contract interface is supported.
   */
  function supportsInterface(bytes4 interfaceID) external pure returns (bool) {
    return  interfaceID == type(IERC165).interfaceId;
  }
}

pragma solidity 0.7.4;
pragma experimental ABIEncoderV2;

import "./Ownable.sol";
import "@0xsequence/erc-1155/contracts/utils/SafeMath.sol";

/**
 * @dev This contract allows an owner to execute registered calls after an expiration
 *      delay has passed. This contract can then be the owner of another contract to
 *      enforce delayed function calls.
 * @dev Does not support passing ETH in calls for simplicity, but could be added in V2.
 */
contract DelayedOwner is Ownable {
  using SafeMath for uint256;

  // Time transactions must be registered before being executable
  uint256 immutable internal EXECUTION_DELAY;
  
  // Mapping between transaction id and transaction hashes
  mapping(uint256 => bytes32) public txHashes;

  // Events
  event TransactionRegistered(Transaction transaction);
  event TransactionCancelled(Transaction transaction);
  event TransactionExecuted(Transaction transaction);

  // Transaction structure
  struct Transaction {
    Status status;       // Transaction status
    uint256 triggerTime; // Timestamp after which the transaction can be executed
    address target;      // Address of the contract to call
    uint256 id;          // Transaction identifier (unique)
    bytes data;          // calldata to pass
  }

  enum Status {
    NotRegistered, // 0x0 - Transaction was not registered
    Pending,       // 0x1 - Transaction was registered but not executed
    Executed,      // 0x2 - Transaction was executed
    Cancelled      // 0x3 - Transaction was registered and cancelled
  }

  /**
   * @dev Registers the execution delay for this contract 
   * @param _firstOwner Address of the first owner
   * @param _delay Amount of time in seconds the delay will be
   */
  constructor (address _firstOwner, uint256 _delay) Ownable(_firstOwner) {
    EXECUTION_DELAY = _delay;
  }


  /***********************************|
  |           Core Functions          |
  |__________________________________*/

  /**
   * @notice Register a transaction to execute post delay
   * @param _tx Transaction to execute
   */
  function register(Transaction memory _tx) onlyOwner() public {
    require(txHashes[_tx.id] == 0x0, "DelayedOwner#register: TX_ALREADY_REGISTERED");

    // Set trigger time and mark transaction as pending
    _tx.triggerTime = block.timestamp.add(EXECUTION_DELAY);
    _tx.status = Status.Pending;

    // Store transaction
    txHashes[_tx.id] = keccak256(abi.encode(_tx));
    emit TransactionRegistered(_tx);
  }

  /**
   * @notice Cancels a transaction that was registered but not yet executed or cancelled
   * @param _tx Transaction to cancel
   */
  function cancel(Transaction memory _tx) onlyOwner() onlyValidWitnesses(_tx) public {
    require(_tx.status == Status.Pending, "DelayedOwner#cancel: TX_NOT_PENDING");

    // Set status to Cancelled
    _tx.status = Status.Cancelled;

    // Store transaction
    txHashes[_tx.id] = keccak256(abi.encode(_tx));
    emit TransactionCancelled(_tx);
  }

  /**
   * @notice Will execute transaction specified
   * @param _tx Transaction to execute
   */
  function execute(Transaction memory _tx) onlyValidWitnesses(_tx) public {
    require(_tx.status == Status.Pending, "DelayedOwner#execute: TX_NOT_PENDING");
    require(_tx.triggerTime <= block.timestamp, "DelayedOwne#execute: TX_NOT_YET_EXECUTABLE");

    // Mark transaction as executed, preventing re-entrancy and replay
    _tx.status = Status.Executed;

    // Store transaction
    txHashes[_tx.id] = keccak256(abi.encode(_tx));

    // Execute transaction
    (bool success,) = _tx.target.call(_tx.data);
    require(success, "DelayedOwner#execute: TX_FAILED");
    emit TransactionExecuted(_tx); 
  }


  /***********************************|
  |         Utility Functions         |
  |__________________________________*/

  /**
   * @notice Verify if provided transaction object matches registered transaction
   * @param _tx Transaction to validate
   */
  function isValidWitness(Transaction memory _tx) public view returns (bool isValid) {
    return txHashes[_tx.id] == keccak256(abi.encode(_tx));
  }

  /**
   * @notice Will enforce that the provided transaction witness is valid
   * @param _tx Transaction to validate
   */
  modifier onlyValidWitnesses(Transaction memory _tx) {
    require(
      isValidWitness(_tx),
      "DelayedOwner#onlyValidWitnesses: INVALID_TX_WITNESS"
    );

    _;
  }
}

pragma solidity 0.7.4;
pragma experimental ABIEncoderV2;

/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 */
contract Ownable {
  address internal owner;

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

  /**
   * @dev The Ownable constructor sets the original `owner` of the contract to the specied address
   * @param _firstOwner Address of the first owner
   */
  constructor (address _firstOwner) {
    owner = _firstOwner;
    emit OwnershipTransferred(address(0), _firstOwner);
  }

  /**
   * @dev Throws if called by any account other than the master owner.
   */
  modifier onlyOwner() {
    require(msg.sender == owner, "Ownable#onlyOwner: SENDER_IS_NOT_OWNER");
    _;
  }

  /**
   * @notice Transfers the ownership of the contract to new address
   * @param _newOwner Address of the new owner
   */
  function transferOwnership(address _newOwner) public onlyOwner {
    require(_newOwner != address(0), "Ownable#transferOwnership: INVALID_ADDRESS");
    owner = _newOwner;
    emit OwnershipTransferred(owner, _newOwner);
  }

  /**
   * @notice Returns the address of the owner.
   */
  function getOwner() public view returns (address) {
    return owner;
  }

}

// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;

import "./ERC1155PackedBalance.sol";


/**
 * @dev Multi-Fungible Tokens with minting and burning methods. These methods assume
 *      a parent contract to be executed as they are `internal` functions.
 */
contract ERC1155MintBurnPackedBalance is ERC1155PackedBalance {

  /****************************************|
  |            Minting Functions           |
  |_______________________________________*/

  /**
   * @notice Mint _amount of tokens of a given id
   * @param _to      The address to mint tokens to
   * @param _id      Token id to mint
   * @param _amount  The amount to be minted
   * @param _data    Data to pass if receiver is contract
   */
  function _mint(address _to, uint256 _id, uint256 _amount, bytes memory _data)
    internal
  {
    //Add _amount
    _updateIDBalance(_to,   _id, _amount, Operations.Add); // Add amount to recipient

    // Emit event
    emit TransferSingle(msg.sender, address(0x0), _to, _id, _amount);

    // Calling onReceive method if recipient is contract
    _callonERC1155Received(address(0x0), _to, _id, _amount, gasleft(), _data);
  }

  /**
   * @notice Mint tokens for each (_ids[i], _amounts[i]) pair
   * @param _to       The address to mint tokens to
   * @param _ids      Array of ids to mint
   * @param _amounts  Array of amount of tokens to mint per id
   * @param _data    Data to pass if receiver is contract
   */
  function _batchMint(address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data)
    internal
  {
    require(_ids.length == _amounts.length, "ERC1155MintBurnPackedBalance#_batchMint: INVALID_ARRAYS_LENGTH");

    if (_ids.length > 0) {
      // Load first bin and index where the token ID balance exists
      (uint256 bin, uint256 index) = getIDBinIndex(_ids[0]);

      // Balance for current bin in memory (initialized with first transfer)
      uint256 balTo = _viewUpdateBinValue(balances[_to][bin], index, _amounts[0], Operations.Add);

      // Number of transfer to execute
      uint256 nTransfer = _ids.length;

      // Last bin updated
      uint256 lastBin = bin;

      for (uint256 i = 1; i < nTransfer; i++) {
        (bin, index) = getIDBinIndex(_ids[i]);

        // If new bin
        if (bin != lastBin) {
          // Update storage balance of previous bin
          balances[_to][lastBin] = balTo;
          balTo = balances[_to][bin];

          // Bin will be the most recent bin
          lastBin = bin;
        }

        // Update memory balance
        balTo = _viewUpdateBinValue(balTo, index, _amounts[i], Operations.Add);
      }

      // Update storage of the last bin visited
      balances[_to][bin] = balTo;
    }

    // //Emit event
    emit TransferBatch(msg.sender, address(0x0), _to, _ids, _amounts);

    // Calling onReceive method if recipient is contract
    _callonERC1155BatchReceived(address(0x0), _to, _ids, _amounts, gasleft(), _data);
  }


  /****************************************|
  |            Burning Functions           |
  |_______________________________________*/

  /**
   * @notice Burn _amount of tokens of a given token id
   * @param _from    The address to burn tokens from
   * @param _id      Token id to burn
   * @param _amount  The amount to be burned
   */
  function _burn(address _from, uint256 _id, uint256 _amount)
    internal
  {
    // Substract _amount
    _updateIDBalance(_from, _id, _amount, Operations.Sub);

    // Emit event
    emit TransferSingle(msg.sender, _from, address(0x0), _id, _amount);
  }

  /**
   * @notice Burn tokens of given token id for each (_ids[i], _amounts[i]) pair
   * @dev This batchBurn method does not implement the most efficient way of updating
   *      balances to reduce the potential bug surface as this function is expected to
   *      be less common than transfers. EIP-2200 makes this method significantly
   *      more efficient already for packed balances.
   * @param _from     The address to burn tokens from
   * @param _ids      Array of token ids to burn
   * @param _amounts  Array of the amount to be burned
   */
  function _batchBurn(address _from, uint256[] memory _ids, uint256[] memory _amounts)
    internal
  {
    // Number of burning to execute
    uint256 nBurn = _ids.length;
    require(nBurn == _amounts.length, "ERC1155MintBurnPackedBalance#batchBurn: INVALID_ARRAYS_LENGTH");

    // Executing all burning
    for (uint256 i = 0; i < nBurn; i++) {
      // Update storage balance
      _updateIDBalance(_from,   _ids[i], _amounts[i], Operations.Sub); // Add amount to recipient
    }

    // Emit batch burn event
    emit TransferBatch(msg.sender, _from, address(0x0), _ids, _amounts);
  }
}

// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;
import "../../interfaces/IERC1155Metadata.sol";
import "../../utils/ERC165.sol";


/**
 * @notice Contract that handles metadata related methods.
 * @dev Methods assume a deterministic generation of URI based on token IDs.
 *      Methods also assume that URI uses hex representation of token IDs.
 */
contract ERC1155Metadata is IERC1155Metadata, ERC165 {
  // URI's default URI prefix
  string public baseURI;
  string public name;

  // set the initial name and base URI
  constructor(string memory _name, string memory _baseURI) {
    name = _name;
    baseURI = _baseURI;
  }

  /***********************************|
  |     Metadata Public Functions     |
  |__________________________________*/

  /**
   * @notice A distinct Uniform Resource Identifier (URI) for a given token.
   * @dev URIs are defined in RFC 3986.
   *      URIs are assumed to be deterministically generated based on token ID
   * @return URI string
   */
  function uri(uint256 _id) public override view returns (string memory) {
    return string(abi.encodePacked(baseURI, _uint2str(_id), ".json"));
  }


  /***********************************|
  |    Metadata Internal Functions    |
  |__________________________________*/

  /**
   * @notice Will emit default URI log event for corresponding token _id
   * @param _tokenIDs Array of IDs of tokens to log default URI
   */
  function _logURIs(uint256[] memory _tokenIDs) internal {
    string memory baseURL = baseURI;
    string memory tokenURI;

    for (uint256 i = 0; i < _tokenIDs.length; i++) {
      tokenURI = string(abi.encodePacked(baseURL, _uint2str(_tokenIDs[i]), ".json"));
      emit URI(tokenURI, _tokenIDs[i]);
    }
  }

  /**
   * @notice Will update the base URL of token's URI
   * @param _newBaseMetadataURI New base URL of token's URI
   */
  function _setBaseMetadataURI(string memory _newBaseMetadataURI) internal {
    baseURI = _newBaseMetadataURI;
  }

  /**
   * @notice Will update the name of the contract
   * @param _newName New contract name
   */
  function _setContractName(string memory _newName) internal {
    name = _newName;
  }

  /**
   * @notice Query if a contract implements an interface
   * @param _interfaceID  The interface identifier, as specified in ERC-165
   * @return `true` if the contract implements `_interfaceID` and
   */
  function supportsInterface(bytes4 _interfaceID) public override virtual pure returns (bool) {
    if (_interfaceID == type(IERC1155Metadata).interfaceId) {
      return true;
    }
    return super.supportsInterface(_interfaceID);
  }


  /***********************************|
  |    Utility Internal Functions     |
  |__________________________________*/

  /**
   * @notice Convert uint256 to string
   * @param _i Unsigned integer to convert to string
   */
  function _uint2str(uint256 _i) internal pure returns (string memory _uintAsString) {
    if (_i == 0) {
      return "0";
    }

    uint256 j = _i;
    uint256 ii = _i;
    uint256 len;

    // Get number of bytes
    while (j != 0) {
      len++;
      j /= 10;
    }

    bytes memory bstr = new bytes(len);
    uint256 k = len - 1;

    // Get each individual ASCII
    while (ii != 0) {
      bstr[k--] = byte(uint8(48 + ii % 10));
      ii /= 10;
    }

    // Convert to string
    return string(bstr);
  }
}

File 20 of 29 : IERC1155Metadata.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;


interface IERC1155Metadata {

  event URI(string _uri, uint256 indexed _id);

  /****************************************|
  |                Functions               |
  |_______________________________________*/

  /**
   * @notice A distinct Uniform Resource Identifier (URI) for a given token.
   * @dev URIs are defined in RFC 3986.
   *      URIs are assumed to be deterministically generated based on token ID
   *      Token IDs are assumed to be represented in their hex format in URIs
   * @return URI string
   */
  function uri(uint256 _id) external view returns (string memory);
}

// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;
pragma experimental ABIEncoderV2;

import "../tokens/ERC1155/ERC1155MintBurn.sol";
import "../tokens/ERC1155/ERC1155Metadata.sol";


contract ERC1155MintBurnMock is ERC1155MintBurn, ERC1155Metadata {

  // set the initial name and base URI
  constructor(string memory _name, string memory _baseURI) ERC1155Metadata(_name, _baseURI) {}

  /**
   * @notice Query if a contract implements an interface
   * @dev Parent contract inheriting multiple contracts with supportsInterface()
   *      need to implement an overriding supportsInterface() function specifying
   *      all inheriting contracts that have a supportsInterface() function.
   * @param _interfaceID The interface identifier, as specified in ERC-165
   * @return `true` if the contract implements `_interfaceID`
   */
  function supportsInterface(
    bytes4 _interfaceID
  ) public override(
    ERC1155,
    ERC1155Metadata
  ) pure virtual returns (bool) {
    return super.supportsInterface(_interfaceID);
  }

  /***********************************|
  |         Minting Functions         |
  |__________________________________*/

  /**
   * @dev Mint _value of tokens of a given id
   * @param _to The address to mint tokens to.
   * @param _id token id to mint
   * @param _value The amount to be minted
   * @param _data Data to be passed if receiver is contract
   */
  function mintMock(address _to, uint256 _id, uint256 _value, bytes memory _data)
    public
  {
    super._mint(_to, _id, _value, _data);
  }

  /**
   * @dev Mint tokens for each ids in _ids
   * @param _to The address to mint tokens to.
   * @param _ids Array of ids to mint
   * @param _values Array of amount of tokens to mint per id
   * @param _data Data to be passed if receiver is contract
   */
  function batchMintMock(address _to, uint256[] memory _ids, uint256[] memory _values, bytes memory _data)
    public
  {
    super._batchMint(_to, _ids, _values, _data);
  }


  /***********************************|
  |         Burning Functions         |
  |__________________________________*/

  /**
   * @dev burn _value of tokens of a given token id
   * @param _from The address to burn tokens from.
   * @param _id token id to burn
   * @param _value The amount to be burned
   */
  function burnMock(address _from, uint256 _id, uint256 _value)
    public
  {
    super._burn(_from, _id, _value);
  }

  /**
   * @dev burn _value of tokens of a given token id
   * @param _from The address to burn tokens from.
   * @param _ids Array of token ids to burn
   * @param _values Array of the amount to be burned
   */
  function batchBurnMock(address _from, uint256[] memory _ids, uint256[] memory _values)
    public
  {
    super._batchBurn(_from, _ids, _values);
  }
  
  /***********************************|
  |       Unsupported Functions       |
  |__________________________________*/

  fallback () virtual external {
    revert("ERC1155MetaMintBurnMock: INVALID_METHOD");
  }
}

// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;
import "./ERC1155.sol";


/**
 * @dev Multi-Fungible Tokens with minting and burning methods. These methods assume
 *      a parent contract to be executed as they are `internal` functions
 */
contract ERC1155MintBurn is ERC1155 {
  using SafeMath for uint256;

  /****************************************|
  |            Minting Functions           |
  |_______________________________________*/

  /**
   * @notice Mint _amount of tokens of a given id
   * @param _to      The address to mint tokens to
   * @param _id      Token id to mint
   * @param _amount  The amount to be minted
   * @param _data    Data to pass if receiver is contract
   */
  function _mint(address _to, uint256 _id, uint256 _amount, bytes memory _data)
    internal
  {
    // Add _amount
    balances[_to][_id] = balances[_to][_id].add(_amount);

    // Emit event
    emit TransferSingle(msg.sender, address(0x0), _to, _id, _amount);

    // Calling onReceive method if recipient is contract
    _callonERC1155Received(address(0x0), _to, _id, _amount, gasleft(), _data);
  }

  /**
   * @notice Mint tokens for each ids in _ids
   * @param _to       The address to mint tokens to
   * @param _ids      Array of ids to mint
   * @param _amounts  Array of amount of tokens to mint per id
   * @param _data    Data to pass if receiver is contract
   */
  function _batchMint(address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data)
    internal
  {
    require(_ids.length == _amounts.length, "ERC1155MintBurn#batchMint: INVALID_ARRAYS_LENGTH");

    // Number of mints to execute
    uint256 nMint = _ids.length;

     // Executing all minting
    for (uint256 i = 0; i < nMint; i++) {
      // Update storage balance
      balances[_to][_ids[i]] = balances[_to][_ids[i]].add(_amounts[i]);
    }

    // Emit batch mint event
    emit TransferBatch(msg.sender, address(0x0), _to, _ids, _amounts);

    // Calling onReceive method if recipient is contract
    _callonERC1155BatchReceived(address(0x0), _to, _ids, _amounts, gasleft(), _data);
  }


  /****************************************|
  |            Burning Functions           |
  |_______________________________________*/

  /**
   * @notice Burn _amount of tokens of a given token id
   * @param _from    The address to burn tokens from
   * @param _id      Token id to burn
   * @param _amount  The amount to be burned
   */
  function _burn(address _from, uint256 _id, uint256 _amount)
    internal
  {
    //Substract _amount
    balances[_from][_id] = balances[_from][_id].sub(_amount);

    // Emit event
    emit TransferSingle(msg.sender, _from, address(0x0), _id, _amount);
  }

  /**
   * @notice Burn tokens of given token id for each (_ids[i], _amounts[i]) pair
   * @param _from     The address to burn tokens from
   * @param _ids      Array of token ids to burn
   * @param _amounts  Array of the amount to be burned
   */
  function _batchBurn(address _from, uint256[] memory _ids, uint256[] memory _amounts)
    internal
  {
    // Number of mints to execute
    uint256 nBurn = _ids.length;
    require(nBurn == _amounts.length, "ERC1155MintBurn#batchBurn: INVALID_ARRAYS_LENGTH");

    // Executing all minting
    for (uint256 i = 0; i < nBurn; i++) {
      // Update storage balance
      balances[_from][_ids[i]] = balances[_from][_ids[i]].sub(_amounts[i]);
    }

    // Emit batch mint event
    emit TransferBatch(msg.sender, _from, address(0x0), _ids, _amounts);
  }
}

// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;

import "../../utils/SafeMath.sol";
import "../../interfaces/IERC1155TokenReceiver.sol";
import "../../interfaces/IERC1155.sol";
import "../../utils/Address.sol";
import "../../utils/ERC165.sol";


/**
 * @dev Implementation of Multi-Token Standard contract
 */
contract ERC1155 is IERC1155, ERC165 {
  using SafeMath for uint256;
  using Address for address;

  /***********************************|
  |        Variables and Events       |
  |__________________________________*/

  // onReceive function signatures
  bytes4 constant internal ERC1155_RECEIVED_VALUE = 0xf23a6e61;
  bytes4 constant internal ERC1155_BATCH_RECEIVED_VALUE = 0xbc197c81;

  // Objects balances
  mapping (address => mapping(uint256 => uint256)) internal balances;

  // Operator Functions
  mapping (address => mapping(address => bool)) internal operators;


  /***********************************|
  |     Public Transfer Functions     |
  |__________________________________*/

  /**
   * @notice Transfers amount amount of an _id from the _from address to the _to address specified
   * @param _from    Source address
   * @param _to      Target address
   * @param _id      ID of the token type
   * @param _amount  Transfered amount
   * @param _data    Additional data with no specified format, sent in call to `_to`
   */
  function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount, bytes memory _data)
    public override
  {
    require((msg.sender == _from) || isApprovedForAll(_from, msg.sender), "ERC1155#safeTransferFrom: INVALID_OPERATOR");
    require(_to != address(0),"ERC1155#safeTransferFrom: INVALID_RECIPIENT");
    // require(_amount <= balances[_from][_id]) is not necessary since checked with safemath operations

    _safeTransferFrom(_from, _to, _id, _amount);
    _callonERC1155Received(_from, _to, _id, _amount, gasleft(), _data);
  }

  /**
   * @notice Send multiple types of Tokens from the _from address to the _to address (with safety call)
   * @param _from     Source addresses
   * @param _to       Target addresses
   * @param _ids      IDs of each token type
   * @param _amounts  Transfer amounts per token type
   * @param _data     Additional data with no specified format, sent in call to `_to`
   */
  function safeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data)
    public override
  {
    // Requirements
    require((msg.sender == _from) || isApprovedForAll(_from, msg.sender), "ERC1155#safeBatchTransferFrom: INVALID_OPERATOR");
    require(_to != address(0), "ERC1155#safeBatchTransferFrom: INVALID_RECIPIENT");

    _safeBatchTransferFrom(_from, _to, _ids, _amounts);
    _callonERC1155BatchReceived(_from, _to, _ids, _amounts, gasleft(), _data);
  }


  /***********************************|
  |    Internal Transfer Functions    |
  |__________________________________*/

  /**
   * @notice Transfers amount amount of an _id from the _from address to the _to address specified
   * @param _from    Source address
   * @param _to      Target address
   * @param _id      ID of the token type
   * @param _amount  Transfered amount
   */
  function _safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount)
    internal
  {
    // Update balances
    balances[_from][_id] = balances[_from][_id].sub(_amount); // Subtract amount
    balances[_to][_id] = balances[_to][_id].add(_amount);     // Add amount

    // Emit event
    emit TransferSingle(msg.sender, _from, _to, _id, _amount);
  }

  /**
   * @notice Verifies if receiver is contract and if so, calls (_to).onERC1155Received(...)
   */
  function _callonERC1155Received(address _from, address _to, uint256 _id, uint256 _amount, uint256 _gasLimit, bytes memory _data)
    internal
  {
    // Check if recipient is contract
    if (_to.isContract()) {
      bytes4 retval = IERC1155TokenReceiver(_to).onERC1155Received{gas: _gasLimit}(msg.sender, _from, _id, _amount, _data);
      require(retval == ERC1155_RECEIVED_VALUE, "ERC1155#_callonERC1155Received: INVALID_ON_RECEIVE_MESSAGE");
    }
  }

  /**
   * @notice Send multiple types of Tokens from the _from address to the _to address (with safety call)
   * @param _from     Source addresses
   * @param _to       Target addresses
   * @param _ids      IDs of each token type
   * @param _amounts  Transfer amounts per token type
   */
  function _safeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts)
    internal
  {
    require(_ids.length == _amounts.length, "ERC1155#_safeBatchTransferFrom: INVALID_ARRAYS_LENGTH");

    // Number of transfer to execute
    uint256 nTransfer = _ids.length;

    // Executing all transfers
    for (uint256 i = 0; i < nTransfer; i++) {
      // Update storage balance of previous bin
      balances[_from][_ids[i]] = balances[_from][_ids[i]].sub(_amounts[i]);
      balances[_to][_ids[i]] = balances[_to][_ids[i]].add(_amounts[i]);
    }

    // Emit event
    emit TransferBatch(msg.sender, _from, _to, _ids, _amounts);
  }

  /**
   * @notice Verifies if receiver is contract and if so, calls (_to).onERC1155BatchReceived(...)
   */
  function _callonERC1155BatchReceived(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, uint256 _gasLimit, bytes memory _data)
    internal
  {
    // Pass data if recipient is contract
    if (_to.isContract()) {
      bytes4 retval = IERC1155TokenReceiver(_to).onERC1155BatchReceived{gas: _gasLimit}(msg.sender, _from, _ids, _amounts, _data);
      require(retval == ERC1155_BATCH_RECEIVED_VALUE, "ERC1155#_callonERC1155BatchReceived: INVALID_ON_RECEIVE_MESSAGE");
    }
  }


  /***********************************|
  |         Operator Functions        |
  |__________________________________*/

  /**
   * @notice Enable or disable approval for a third party ("operator") to manage all of caller's tokens
   * @param _operator  Address to add to the set of authorized operators
   * @param _approved  True if the operator is approved, false to revoke approval
   */
  function setApprovalForAll(address _operator, bool _approved)
    external override
  {
    // Update operator status
    operators[msg.sender][_operator] = _approved;
    emit ApprovalForAll(msg.sender, _operator, _approved);
  }

  /**
   * @notice Queries the approval status of an operator for a given owner
   * @param _owner     The owner of the Tokens
   * @param _operator  Address of authorized operator
   * @return isOperator True if the operator is approved, false if not
   */
  function isApprovedForAll(address _owner, address _operator)
    public override view returns (bool isOperator)
  {
    return operators[_owner][_operator];
  }


  /***********************************|
  |         Balance Functions         |
  |__________________________________*/

  /**
   * @notice Get the balance of an account's Tokens
   * @param _owner  The address of the token holder
   * @param _id     ID of the Token
   * @return The _owner's balance of the Token type requested
   */
  function balanceOf(address _owner, uint256 _id)
    public override view returns (uint256)
  {
    return balances[_owner][_id];
  }

  /**
   * @notice Get the balance of multiple account/token pairs
   * @param _owners The addresses of the token holders
   * @param _ids    ID of the Tokens
   * @return        The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair)
   */
  function balanceOfBatch(address[] memory _owners, uint256[] memory _ids)
    public override view returns (uint256[] memory)
  {
    require(_owners.length == _ids.length, "ERC1155#balanceOfBatch: INVALID_ARRAY_LENGTH");

    // Variables
    uint256[] memory batchBalances = new uint256[](_owners.length);

    // Iterate over each owner and token ID
    for (uint256 i = 0; i < _owners.length; i++) {
      batchBalances[i] = balances[_owners[i]][_ids[i]];
    }

    return batchBalances;
  }


  /***********************************|
  |          ERC165 Functions         |
  |__________________________________*/

  /**
   * @notice Query if a contract implements an interface
   * @param _interfaceID  The interface identifier, as specified in ERC-165
   * @return `true` if the contract implements `_interfaceID` and
   */
  function supportsInterface(bytes4 _interfaceID) public override(ERC165, IERC165) virtual pure returns (bool) {
    if (_interfaceID == type(IERC1155).interfaceId) {
      return true;
    }
    return super.supportsInterface(_interfaceID);
  }
}

pragma solidity 0.7.4;

import "../utils/TieredOwnable.sol";
import "../interfaces/ISkyweaverAssets.sol";
import "@0xsequence/erc-1155/contracts/utils/SafeMath.sol";
import "@0xsequence/erc-1155/contracts/interfaces/IERC165.sol";
import "@0xsequence/erc-1155/contracts/interfaces/IERC1155.sol";
import "@0xsequence/erc-1155/contracts/interfaces/IERC1155TokenReceiver.sol";

/**
 * @notice Allows players to convert their silver cards and Wrapped DAI (wDAI) to conquest entries.
 *
 * @dev Assumes both cards and entries have the same number of decimals, if not, need to change
 * the amount minted.
 * 
 * @dev This contract should only be able to mint conquest entries.
 */
contract ConquestEntriesFactory is IERC1155TokenReceiver, TieredOwnable {
  using SafeMath for uint256;
  
  /***********************************|
  |             Variables             |
  |__________________________________*/

  // Assets
  ISkyweaverAssets immutable public skyweaverAssets; // ERC-1155 Skyweaver assets contract
  IERC1155 immutable internal wDai;                  // ERC-1155 Wrapped DAI contract
  uint256 immutable public wDaiID;                   // ID of wDAI token in respective ERC-1155 contract
  uint256 immutable public silverRangeMin;           // Lower bound for the range of asset IDs that can be converted to entries
  uint256 immutable public silverRangeMax;           // Upper bound for the range of asset IDs that can be converted to entries

  // Conquest entry token id
  uint256 immutable public conquestEntryID; 

  // Parameters
  uint256 constant internal CARD_DECIMALS = 2;                     // Number of decimals cards have
  uint256 constant internal ENTRIES_DECIMALS = 2;                  // Number of decimals entries have
  uint256 constant internal wDAI_DECIMALS = 6;                    // Number of decimals wDAI have
  uint256 constant internal wDAI_REQUIRED = 15 * 10**(wDAI_DECIMALS-1); // 1.5 wDAI for 1 conquest entry (after decimals)


  /***********************************|
  |            Constructor            |
  |__________________________________*/

  /**
   * @notice Create factory, link skyweaver assets and store initial parameters
   * @param _firstOwner             Address of the first owner
   * @param _skyweaverAssetsAddress The address of the ERC-1155 Assets Token contract
   * @param _wDaiAddress            The address of the ERC-1155 Wrapped DAI
   * @param _wDaiID                 Wrapped DAI token id
   * @param _conquestEntryTokenId   Conquest entry token id
   * @param _silverRangeMin         Minimum id for silver cards
   * @param _silverRangeMax         Maximum id for silver cards
   */
  constructor(
    address _firstOwner,
    address _skyweaverAssetsAddress,
    address _wDaiAddress,
    uint256 _wDaiID,
    uint256 _conquestEntryTokenId,
    uint256 _silverRangeMin,
    uint256 _silverRangeMax
  ) TieredOwnable(_firstOwner) public 
  {
    require(
      _skyweaverAssetsAddress != address(0) && 
      _wDaiAddress != address(0) &&
      _silverRangeMin < _silverRangeMax,
      "ConquestEntriesFactory#constructor: INVALID_INPUT"
    );

    // Assets
    skyweaverAssets = ISkyweaverAssets(_skyweaverAssetsAddress);
    wDai = IERC1155(_wDaiAddress);
    wDaiID = _wDaiID;
    conquestEntryID = _conquestEntryTokenId;
    silverRangeMin = _silverRangeMin;
    silverRangeMax = _silverRangeMax;
  }

  
  /***********************************|
  |      Receiver Method Handler      |
  |__________________________________*/

  /**
   * @notice Prevents receiving Ether or calls to unsuported methods
   */
  fallback () external {
    revert("ConquestEntriesFactory#_: UNSUPPORTED_METHOD");
  }

  /**
   * @notice Players converting silver cards to conquest entries
   * @dev Payload is passed to and verified by onERC1155BatchReceived()
   */
  function onERC1155Received(
    address _operator,
    address _from,
    uint256 _id, 
    uint256 _amount, 
    bytes calldata _data
  )
    external override returns(bytes4)
  {
    // Convert payload to arrays to pass to onERC1155BatchReceived()
    uint256[] memory ids = new uint256[](1);
    uint256[] memory amounts = new uint256[](1);
    ids[0] = _id;
    amounts[0] = _amount;

    // Will revert call if doesn't pass
    onERC1155BatchReceived(_operator, _from, ids, amounts, _data);
    
    // Return success
    return IERC1155TokenReceiver.onERC1155Received.selector;
  }

  /**
   * @notice Players converting silver cards or wDAIs to conquest entries
   * @param _from    Address who sent the token
   * @param _ids     An array containing ids of each Token being transferred
   * @param _amounts An array containing amounts of each Token being transferred
   * @param _data    If data is provided, it should be address who will receive the entries
   */
  function onERC1155BatchReceived(
    address, // _operator
    address _from,
    uint256[] memory _ids,
    uint256[] memory _amounts,
    bytes memory _data
  )
    public override returns(bytes4)
  { 
    // Number of entries to mint
    uint256 n_entries = 0; 

    // Burn cards or store wDAI
    if (msg.sender == address(skyweaverAssets)) {
      
      // Validate IDs and count number of entries to mint
      for (uint256 i = 0; i < _ids.length; i++) {
        require(
          silverRangeMin <= _ids[i] && _ids[i] <= silverRangeMax, 
          "ConquestEntriesFactory#onERC1155BatchReceived: ID_IS_OUT_OF_RANGE"
        );
        n_entries = n_entries.add(_amounts[i]);
      }
      // Account for cards decimals
      n_entries = n_entries.div(10**CARD_DECIMALS);

      // Burn silver cards received
      skyweaverAssets.batchBurn(_ids, _amounts);

    } else if (msg.sender == address(wDai)) {
      require(_ids.length == 1, "ConquestEntriesFactory#onERC1155BatchReceived: INVALID_ARRAY_LENGTH");
      require(_ids[0] == wDaiID, "ConquestEntriesFactory#onERC1155BatchReceived: INVALID_wDAI_ID");
      n_entries = _amounts[0] / wDAI_REQUIRED; 

      // Do nothing else. wDAIs are stored until withdrawn

    } else {
      revert("ConquestEntriesFactory#onERC1155BatchReceived: INVALID_TOKEN_ADDRESS");
    }

    // If an address is specified in _data, use it as receiver, otherwise use _from address
    address receiver = _data.length > 0 ? abi.decode(_data, (address)) : _from;

    // Mint conquest entries (with decimals)
    skyweaverAssets.mint(receiver, conquestEntryID, n_entries*10**ENTRIES_DECIMALS, "");

    // Return success
    return IERC1155TokenReceiver.onERC1155BatchReceived.selector;
  }

  /**
   * @notice Send current wDAI balance of this contract to recipient
   * @param _recipient Address where the currency will be sent to
   * @param _data      Data to pass with transfer function
   */
  function withdraw(address _recipient, bytes calldata _data) external onlyOwnerTier(HIGHEST_OWNER_TIER) {
    require(_recipient != address(0x0), "ConquestEntriesFactory#withdraw: INVALID_RECIPIENT");
    uint256 this_balance = wDai.balanceOf(address(this), wDaiID);
    wDai.safeTransferFrom(address(this), _recipient, wDaiID, this_balance, _data);
  }


  /***********************************|
  |         Utility Functions         |
  |__________________________________*/

  /**
   * @notice Indicates whether a contract implements a given interface.
   * @param interfaceID The ERC-165 interface ID that is queried for support.
   * @return True if contract interface is supported.
   */
  function supportsInterface(bytes4 interfaceID) external pure returns (bool) {
    return  interfaceID == type(IERC165).interfaceId || 
      interfaceID == type(IERC1155TokenReceiver).interfaceId;
  }
}

pragma solidity 0.7.4;
import "../interfaces/ISkyweaverAssets.sol";

contract FactoryMock {

  ISkyweaverAssets internal skyweaverAssets; //SkyWeaver Curencies Factory Manager Contract

  constructor(address _factoryManagerAddr) public {
    skyweaverAssets = ISkyweaverAssets(_factoryManagerAddr);
  }

  function batchMint(
    address _to,
    uint256[] memory _ids,
    uint256[] memory _amounts,
    bytes memory _data) public
  {
    skyweaverAssets.batchMint(_to, _ids, _amounts, _data);
  }

  function mint(
    address _to,
    uint256 _id,
    uint256 _amount,
    bytes memory _data) public
  {
    skyweaverAssets.mint(_to, _id, _amount, _data);
  }

}

pragma solidity 0.7.4;

import "../utils/TieredOwnable.sol";
import "../interfaces/ISkyweaverAssets.sol";
import "@0xsequence/erc-1155/contracts/interfaces/IERC165.sol";

/**
 * This is a contract allowing owner to mint any tokens within a given
 * range. This factory will be used to mint community related assets, special
 * event assets that are meant to be given away.
 */
contract FreemintFactory is TieredOwnable {

  // ERC-1155 Skyweaver assets contract
  ISkyweaverAssets internal skyweaverAssets;

  /***********************************|
  |            Constructor            |
  |__________________________________*/

  /**
   * @notice Create factory & link skyweaver assets
   * @param _firstOwner Address of the first owner
   * @param _assetsAddr The address of the ERC-1155 Assets Token contract
   */
  constructor(address _firstOwner, address _assetsAddr) TieredOwnable(_firstOwner) public {
    require(
      _assetsAddr != address(0),
      "FreemintFactory#constructor: INVALID_INPUT"
    );
    skyweaverAssets = ISkyweaverAssets(_assetsAddr);
  }


  /***********************************|
  |         Minting Function          |
  |__________________________________*/

  /**
   * @notice Will mint a bundle of tokens to users
   * @param _recipients Arrays of addresses to mint _amounts of _ids
   * @param _ids        Array of Tokens ID that are minted
   * @param _amounts    Amount of Tokens id minted for each corresponding Token id in _ids
   */
  function batchMint(address[] calldata _recipients, uint256[] calldata _ids, uint256[] calldata _amounts)
    external onlyOwnerTier(1)
  {
    for (uint256 i = 0 ; i < _recipients.length; i++) {
      skyweaverAssets.batchMint(_recipients[i], _ids, _amounts, "");
    }
  }


  /***********************************|
  |          Misc Functions           |
  |__________________________________*/

  /**
   * @notice Returns the address of the  skyweaver assets contract
   */
  function getSkyweaverAssets() external view returns (address) {
    return address(skyweaverAssets);
  }

  /**
   * @notice Prevents receiving Ether, ERC-1155 or calls to unsuported methods
   */
  fallback () external {
    revert("FreemintFactory#_: UNSUPPORTED_METHOD");
  }

  /**
   * @notice Indicates whether a contract implements a given interface.
   * @param interfaceID The ERC-165 interface ID that is queried for support.
   * @return True if contract interface is supported.
   */
  function supportsInterface(bytes4 interfaceID) external pure returns (bool) {
    return  interfaceID == type(IERC165).interfaceId;
  }
}

pragma solidity 0.7.4;
pragma experimental ABIEncoderV2;


import "../utils/TieredOwnable.sol";

contract TieredOwnableMock is TieredOwnable {

  constructor(address _firstOwner) TieredOwnable(_firstOwner) public {}

  function onlyMaxTier() external onlyOwnerTier(HIGHEST_OWNER_TIER) returns(bool) {
    return true;
  }

  function onlyTierFive() external onlyOwnerTier(5) returns(bool) {
    return true;
  }

  function onlyTierZero() external onlyOwnerTier(0) returns(bool) {
    return true;
  }

  function anyone() external returns(bool) {
    return true;
  }
}

File 28 of 29 : ERC1155Mock.sol
pragma solidity 0.7.4;
pragma experimental ABIEncoderV2;


import "@0xsequence/erc-1155/contracts/mocks/ERC1155MintBurnMock.sol";

contract ERC1155Mock is ERC1155MintBurnMock {

  constructor() ERC1155MintBurnMock('ERC1155Mock', "") {}

}

pragma solidity 0.7.4;
pragma experimental ABIEncoderV2;


import "../utils/Ownable.sol";

contract OwnableMock is Ownable {

  constructor(address _firstOwner) Ownable(_firstOwner) public {}

  function call_onlyOwner() external onlyOwner() returns(bool) {
    return true;
  }
  function call_anyone() external returns(bool) {
    return true;
  }

  function call_throw() external returns(bool) {
    revert(":/");
    return true;
  }

  fallback() external {}
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 100000,
    "details": {
      "yul": true,
      "constantOptimizer": false
    }
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_firstOwner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_operator","type":"address"},{"indexed":false,"internalType":"bool","name":"_approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"factory","type":"address"}],"name":"FactoryActivation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"factory","type":"address"}],"name":"FactoryShutdown","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"newMaxIssuances","type":"uint256[]"}],"name":"MaxIssuancesChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"factory","type":"address"},{"components":[{"internalType":"uint64","name":"minID","type":"uint64"},{"internalType":"uint64","name":"maxID","type":"uint64"},{"internalType":"uint64","name":"startTime","type":"uint64"},{"internalType":"uint64","name":"endTime","type":"uint64"}],"indexed":false,"internalType":"struct SkyweaverAssets.AssetRange","name":"new_range","type":"tuple"}],"name":"MintPermissionAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"factory","type":"address"},{"components":[{"internalType":"uint64","name":"minID","type":"uint64"},{"internalType":"uint64","name":"maxID","type":"uint64"},{"internalType":"uint64","name":"startTime","type":"uint64"},{"internalType":"uint64","name":"endTime","type":"uint64"}],"indexed":false,"internalType":"struct SkyweaverAssets.AssetRange","name":"deleted_range","type":"tuple"}],"name":"MintPermissionRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint64","name":"minID","type":"uint64"},{"internalType":"uint64","name":"maxID","type":"uint64"},{"internalType":"uint64","name":"startTime","type":"uint64"},{"internalType":"uint64","name":"endTime","type":"uint64"}],"indexed":false,"internalType":"struct SkyweaverAssets.AssetRange","name":"locked_range","type":"tuple"}],"name":"RangeLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_operator","type":"address"},{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"_amounts","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_operator","type":"address"},{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"_uri","type":"string"},{"indexed":true,"internalType":"uint256","name":"_id","type":"uint256"}],"name":"URI","type":"event"},{"stateMutability":"nonpayable","type":"fallback"},{"inputs":[{"internalType":"address","name":"_factory","type":"address"}],"name":"activateFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"uint64","name":"_minRange","type":"uint64"},{"internalType":"uint64","name":"_maxRange","type":"uint64"},{"internalType":"uint64","name":"_startTime","type":"uint64"},{"internalType":"uint64","name":"_endTime","type":"uint64"}],"name":"addMintPermission","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_owners","type":"address[]"},{"internalType":"uint256[]","name":"_ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"}],"name":"batchBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"batchMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ids","type":"uint256[]"}],"name":"getCurrentIssuances","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_factory","type":"address"}],"name":"getFactoryAccessRanges","outputs":[{"components":[{"internalType":"uint64","name":"minID","type":"uint64"},{"internalType":"uint64","name":"maxID","type":"uint64"},{"internalType":"uint64","name":"startTime","type":"uint64"},{"internalType":"uint64","name":"endTime","type":"uint64"}],"internalType":"struct SkyweaverAssets.AssetRange[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_factory","type":"address"}],"name":"getFactoryStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"getIDBinIndex","outputs":[{"internalType":"uint256","name":"bin","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getLockedRanges","outputs":[{"components":[{"internalType":"uint64","name":"minID","type":"uint64"},{"internalType":"uint64","name":"maxID","type":"uint64"},{"internalType":"uint64","name":"startTime","type":"uint64"},{"internalType":"uint64","name":"endTime","type":"uint64"}],"internalType":"struct SkyweaverAssets.AssetRange[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ids","type":"uint256[]"}],"name":"getMaxIssuances","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_binValues","type":"uint256"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getValueInBin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"globalRoyaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"feeBasisPoints","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"isOperator","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint64","name":"minID","type":"uint64"},{"internalType":"uint64","name":"maxID","type":"uint64"},{"internalType":"uint64","name":"startTime","type":"uint64"},{"internalType":"uint64","name":"endTime","type":"uint64"}],"internalType":"struct SkyweaverAssets.AssetRange","name":"_range","type":"tuple"}],"name":"lockRangeMintPermissions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIDs","type":"uint256[]"}],"name":"logURIs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"uint256","name":"_rangeIndex","type":"uint256"}],"name":"removeMintPermission","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"_saleCost","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"},{"internalType":"bool","name":"_approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseMetadataURI","type":"string"}],"name":"setBaseMetadataURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"uint256","name":"_royaltyBasisPoints","type":"uint256"}],"name":"setGlobalRoyaltyInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"internalType":"uint256[]","name":"_newMaxIssuances","type":"uint256[]"}],"name":"setMaxIssuances","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_factory","type":"address"}],"name":"shutdownFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]

0x60806040523480156200001157600080fd5b50604051620052dc380380620052dc8339810160408190526200003491620001c7565b604080518082018252600981527f536b797765617665720000000000000000000000000000000000000000000000602080830191825283519081019093526000835281518493916200008a91600391906200011b565b508051620000a09060029060208401906200011b565b5050600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040519091506000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3505062000204565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200015357600085556200019e565b82601f106200016e57805160ff19168380011785556200019e565b828001600101855582156200019e579182015b828111156200019e57825182559160200191906001019062000181565b50620001ac929150620001b0565b5090565b5b80821115620001ac5760008155600101620001b1565b600060208284031215620001d9578081fd5b815173ffffffffffffffffffffffffffffffffffffffff81168114620001fd578182fd5b9392505050565b6150c880620002146000396000f3fe608060405234801561001057600080fd5b50600436106102255760003560e01c80639136ce1f1161012a578063d46c069e116100bd578063e985e9c51161008c578063f242432a11610071578063f242432a146104eb578063f2fde38b146104fe578063f795ab751461051157610225565b8063e985e9c5146104c5578063eaec5f81146104d857610225565b8063d46c069e1461046b578063db90e83c1461047e578063e1a972721461049f578063e4b37d33146104b257610225565b8063adccc471116100f9578063adccc4711461042a578063b390c0ab1461043d578063b48ab8b614610450578063c9823cc61461046357610225565b80639136ce1f146103de57806393cfa682146103f1578063a22cb46514610404578063a36b3f291461041757610225565b80632eb2c2d6116101bd5780636c0360eb1161018c5780637c44a8bb116101715780637c44a8bb146103a35780637e518ec8146103b6578063893d20e8146103c957610225565b80636c0360eb14610388578063731133e91461039057610225565b80632eb2c2d61461032d578063458d2844146103405780634e1273f414610353578063657afa891461037357610225565b80630e89341c116101f95780630e89341c146102d357806315a08ab8146102e657806320ec271b146102f95780632a55205a1461030c57610225565b8062fdd58e1461026057806301ffc9a71461028957806306fdde03146102a957806307800c9b146102be575b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610257906148ce565b60405180910390fd5b61027361026e366004614298565b610524565b6040516102809190614c7e565b60405180910390f35b61029c6102973660046144f5565b61057b565b6040516102809190614798565b6102b161058e565b60405161028091906147a3565b6102d16102cc366004614327565b61063a565b005b6102b16102e13660046145df565b610a0f565b6102d16102f436600461448c565b610b62565b6102d161030736600461448c565b610d3c565b61031f61031a3660046145f7565b610db0565b6040516102809291906146ba565b6102d161033b3660046140c0565b610e12565b6102d161034e366004614298565b610f1d565b61036661036136600461438b565b611312565b6040516102809190614760565b61037b611591565b60405161028091906146e0565b6102b161164c565b6102d161039e3660046142c1565b6116c2565b6102d16103b1366004614074565b611790565b6102d16103c4366004614535565b611855565b6103d16118e9565b6040516102809190614699565b6102d16103ec366004614074565b611905565b6102d16103ff366004614298565b6119cd565b6102d161041236600461425e565b611a28565b61037b610425366004614074565b611ac1565b6102d1610438366004614569565b611b9f565b6102d161044b3660046145f7565b611d57565b6102d161045e3660046141c9565b611d62565b61031f611d78565b6102d161047936600461444c565b611d9a565b61049161048c3660046145df565b611e27565b604051610280929190614c87565b6103666104ad36600461444c565b611e34565b6103666104c036600461444c565b611ed5565b61029c6104d336600461408e565b611f6d565b6102736104e63660046145f7565b611fa8565b6102d16104f9366004614166565b611fbb565b6102d161050c366004614074565b6120bf565b61029c61051f366004614074565b6121d2565b600080600061053284611e27565b73ffffffffffffffffffffffffffffffffffffffff871660009081526020818152604080832085845290915290205491935091506105709082611fa8565b925050505b92915050565b6000610586826121fd565b90505b919050565b6003805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f810184900484028201840190925281815292918301828280156106325780601f1061060757610100808354040283529160200191610632565b820191906000526020600020905b81548152906001019060200180831161061557829003601f168201915b505050505081565b60065473ffffffffffffffffffffffffffffffffffffffff16331461068b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b60008367ffffffffffffffff16116106cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614a79565b8267ffffffffffffffff168467ffffffffffffffff16111561071d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614905565b8067ffffffffffffffff168267ffffffffffffffff161061076a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614b33565b60005b6009548110156108705761077f613de4565b6009828154811061078c57fe5b600091825260209182902060408051608081018252919092015467ffffffffffffffff8082168084526801000000000000000083048216958401959095527001000000000000000000000000000000008204811693830193909352780100000000000000000000000000000000000000000000000090048216606082015292508616108061083157508567ffffffffffffffff16816020015167ffffffffffffffff16105b610867576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614a1c565b5060010161076d565b50610879613de4565b506040805160808101825267ffffffffffffffff808716825285811660208084019182528683168486019081528684166060860190815273ffffffffffffffffffffffffffffffffffffffff8c166000818152600885528881208054600181018255908252949020875194018054955193519251871678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff938816700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff95891668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff979099167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009098169790971795909516969096179290921693909317929092161790915591519091907f188968bccf857d854c73494ca4da4cc4ae2769e4b732db8f40dfa62b86b1c40a906109ff908490614c70565b60405180910390a2505050505050565b60606002610a1c8361225a565b6040516020018083805460018160011615610100020316600290048015610a7a5780601f10610a58576101008083540402835291820191610a7a565b820191906000526020600020905b815481529060010190602001808311610a66575b5050825160208401908083835b60208310610ac457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a87565b5181516020939093036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990911692169190911790527f2e6a736f6e000000000000000000000000000000000000000000000000000000920191825250604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe50181526005909201905295945050505050565b60065473ffffffffffffffffffffffffffffffffffffffff163314610bb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b828114610bec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614871565b60005b83811015610cf8576000600b6000878785818110610c0957fe5b905060200201358152602001908152602001600020541115610cb357828282818110610c3157fe5b905060200201356000108015610c7d5750600b6000868684818110610c5257fe5b90506020020135815260200190815260200160002054838383818110610c7457fe5b90506020020135105b610cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614ad6565b828282818110610cbf57fe5b90506020020135600b6000878785818110610cd657fe5b6020908102929092013583525081019190915260400160002055600101610bef565b507f91f9ea1e3a6a1fd246959c27978a42e04c0c3c954e7ffa52e3ed1509be4811be84848484604051610d2e949392919061472e565b60405180910390a150505050565b610daa338585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080890282810182019093528882529093508892508791829185019084908082843760009201919091525061238692505050565b50505050565b600080610dbb613e0b565b506040805180820190915260045473ffffffffffffffffffffffffffffffffffffffff1680825260055460208301819052610e05906103e890610dff90889061252f565b906125bf565b92509250505b9250929050565b3373ffffffffffffffffffffffffffffffffffffffff86161480610e3b5750610e3b8533611f6d565b610e90576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180614e46603c913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8416610efc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180614d11603d913960400191505060405180910390fd5b610f0885858585612643565b610f16858585855a86612a50565b5050505050565b60065473ffffffffffffffffffffffffffffffffffffffff163314610f6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600860205260409020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610fbe613de4565b73ffffffffffffffffffffffffffffffffffffffff84166000908152600860205260409020805484908110610fef57fe5b600091825260209182902060408051608081018252929091015467ffffffffffffffff8082168452680100000000000000008204811694840194909452700100000000000000000000000000000000810484169183019190915278010000000000000000000000000000000000000000000000009004909116606082015290508183146112585761107e613de4565b73ffffffffffffffffffffffffffffffffffffffff851660009081526008602052604090208054849081106110af57fe5b6000918252602080832060408051608081018252919093015467ffffffffffffffff80821683526801000000000000000082048116838501527001000000000000000000000000000000008204811683860152780100000000000000000000000000000000000000000000000090910416606082015273ffffffffffffffffffffffffffffffffffffffff8916845260089091529120805491925082918690811061115657fe5b60009182526020918290208351910180549284015160408501516060909501517fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090941667ffffffffffffffff938416177fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000091841691909102177fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff16700100000000000000000000000000000000948316949094029390931777ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000009190921602179055505b73ffffffffffffffffffffffffffffffffffffffff8416600090815260086020526040902080548061128657fe5b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9081019190915501905560405173ffffffffffffffffffffffffffffffffffffffff8516907f1bca5c143feb87c2d4e8d2d1fd73ba6f43f551ba73c58634f56bbe30701f06d490611304908490614c70565b60405180910390a250505050565b81518151606091908114611371576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526039815260200180614cd86039913960400191505060405180910390fd5b6000806113918560008151811061138457fe5b6020026020010151611e27565b915091506000806000886000815181106113a757fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000848152602001908152602001600020549050600083905060608567ffffffffffffffff8111801561141b57600080fd5b50604051908082528060200260200182016040528015611445578160200160208202803683370190505b5090506114528385611fa8565b8160008151811061145f57fe5b602090810291909101015260015b868110156115845761148489828151811061138457fe5b909650945082861415806114ed575089818151811061149f57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff168a60018303815181106114cc57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614155b1561155b576000808b838151811061150157fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008781526020019081526020016000205493508592505b6115658486611fa8565b82828151811061157157fe5b602090810291909101015260010161146d565b5098975050505050505050565b60606009805480602002602001604051908101604052809291908181526020016000905b82821015611643576000848152602090819020604080516080810182529185015467ffffffffffffffff80821684526801000000000000000082048116848601527001000000000000000000000000000000008204811692840192909252780100000000000000000000000000000000000000000000000090041660608201528252600190920191016115b5565b50505050905090565b600280546040805160206001841615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01909316849004601f810184900484028201840190925281815292918301828280156106325780601f1061060757610100808354040283529160200191610632565b604080516001808252818301909252606091602080830190803683375050604080516001808252818301909252929350606092915060208083019080368337019050509050858260008151811061171557fe5b602002602001018181525050848160008151811061172f57fe5b6020026020010181815250506117458282612cc5565b61178787878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612fc192505050565b50505050505050565b60065473ffffffffffffffffffffffffffffffffffffffff1633146117e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b73ffffffffffffffffffffffffffffffffffffffff811660008181526007602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f472ecaf428225ecdcc1f686a662ed1ba0627c365542e086b483bacca0fcfa5f99190a250565b60065473ffffffffffffffffffffffffffffffffffffffff1633146118a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b6118e582828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061303592505050565b5050565b60065473ffffffffffffffffffffffffffffffffffffffff1690565b60065473ffffffffffffffffffffffffffffffffffffffff163314611956576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b73ffffffffffffffffffffffffffffffffffffffff811660008181526007602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f672dbf7f8dabd5b1b39124540440a9ef2537a03c053f111f7e90850e57e2efb69190a250565b60065473ffffffffffffffffffffffffffffffffffffffff163314611a1e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b6118e58282613048565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600860209081526040808320805482518185028101850190935280835260609492939192909184015b82821015611b94576000848152602090819020604080516080810182529185015467ffffffffffffffff8082168452680100000000000000008204811684860152700100000000000000000000000000000000820481169284019290925278010000000000000000000000000000000000000000000000009004166060820152825260019092019101611b06565b505050509050919050565b60065473ffffffffffffffffffffffffffffffffffffffff163314611bf0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b6009805460018101825560009190915281517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af9091018054602084015160408086015160608701517fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090941667ffffffffffffffff968716177fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000093871693909302929092177fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff16700100000000000000000000000000000000928616929092029190911777ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000009490921693909302179055517f522c18973f048c2a178766b76cb19456e9dbd776f104c0b77c6166e582212f2c90611d4c908390614c70565b60405180910390a150565b6118e533838361315a565b611d6c8383612cc5565b610daa848484846131c4565b60045460055473ffffffffffffffffffffffffffffffffffffffff9091169082565b60065473ffffffffffffffffffffffffffffffffffffffff163314611deb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b6118e582828080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061344e92505050565b6008810491600790911690565b606081818167ffffffffffffffff81118015611e4f57600080fd5b50604051908082528060200260200182016040528015611e79578160200160208202803683370190505b50905060005b82811015611ecc57600b6000878784818110611e9757fe5b90506020020135815260200190815260200160002054828281518110611eb957fe5b6020908102919091010152600101611e7f565b50949350505050565b606081818167ffffffffffffffff81118015611ef057600080fd5b50604051908082528060200260200182016040528015611f1a578160200160208202803683370190505b50905060005b82811015611ecc57600a6000878784818110611f3857fe5b90506020020135815260200190815260200160002054828281518110611f5a57fe5b6020908102919091010152600101611f20565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205460ff1690565b6020810282901c63ffffffff1692915050565b3373ffffffffffffffffffffffffffffffffffffffff86161480611fe45750611fe48533611f6d565b612039576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526037815260200180614d816037913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff84166120a5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526038815260200180614fa66038913960400191505060405180910390fd5b6120b18585858561370f565b610f16858585855a866137b3565b60065473ffffffffffffffffffffffffffffffffffffffff163314612110576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b73ffffffffffffffffffffffffffffffffffffffff811661215d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610257906149bf565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821792839055604051919216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b73ffffffffffffffffffffffffffffffffffffffff1660009081526007602052604090205460ff1690565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f2a55205a00000000000000000000000000000000000000000000000000000000141561225157506001610589565b610586826139a4565b60608161229b575060408051808201909152600181527f30000000000000000000000000000000000000000000000000000000000000006020820152610589565b818060005b82156122b457600101600a830492506122a0565b60608167ffffffffffffffff811180156122cd57600080fd5b506040519080825280601f01601f1916602001820160405280156122f8576020820181803683370190505b5090507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82015b831561237c57600a840660300160f81b8282806001900393508151811061234257fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8404935061231f565b5095945050505050565b8151815181146123e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180614eb3603d913960400191505060405180910390fd5b60005b818110156124275761241f858583815181106123fc57fe5b602002602001015185848151811061241057fe5b60200260200101516001613a01565b6001016123e4565b50600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156124d55781810151838201526020016124bd565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156125145781810151838201526020016124fc565b5050505090500194505050505060405180910390a450505050565b60008261253e57506000610575565b8282028284828161254b57fe5b04146125b857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f536166654d617468236d756c3a204f564552464c4f5700000000000000000000604482015290519081900360640190fd5b9392505050565b600080821161262f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f536166654d617468236469763a204449564953494f4e5f42595f5a45524f0000604482015290519081900360640190fd5b600082848161263a57fe5b04949350505050565b81518151811461269e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526042815260200180614db86042913960600191505060405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16141580156126da5750600081115b156128ac576000806126f28560008151811061138457fe5b73ffffffffffffffffffffffffffffffffffffffff891660009081526020818152604080832085845290915281205487519395509193509161274a919084908890859061273b57fe5b60200260200101516001613a88565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260208181526040808320878452909152812054875192935090916127a0919085908990859061279157fe5b60200260200101516000613a88565b90508360015b8681101561285a576127bd89828151811061138457fe5b909650945081861461282c5773ffffffffffffffffffffffffffffffffffffffff8b811660009081526020818152604080832086845280835281842098909855928d16825281815282822094825284815282822095909555878152948452808520549290935291909220549084905b61283d84868a848151811061273b57fe5b935061285083868a848151811061279157fe5b92506001016127a6565b505073ffffffffffffffffffffffffffffffffffffffff808a16600090815260208181526040808320888452825280832095909555918a16815280825283812095815294905292209190915550612949565b60005b81811015612947578281815181106128c357fe5b60200260200101516128e8878684815181106128db57fe5b6020026020010151610524565b101561293f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526036815260200180614ef06036913960400191505060405180910390fd5b6001016128af565b505b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156129f55781810151838201526020016129dd565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015612a34578181015183820152602001612a1c565b5050505090500194505050505060405180910390a45050505050565b612a6f8573ffffffffffffffffffffffffffffffffffffffff16613c9b565b15612cbd5760008573ffffffffffffffffffffffffffffffffffffffff1663bc197c8184338a8989886040518763ffffffff1660e01b8152600401808673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b83811015612b27578181015183820152602001612b0f565b50505050905001848103835286818151815260200191508051906020019060200280838360005b83811015612b66578181015183820152602001612b4e565b50505050905001848103825285818151815260200191508051906020019080838360005b83811015612ba2578181015183820152602001612b8a565b50505050905090810190601f168015612bcf5780820380516001836020036101000a031916815260200191505b5098505050505050505050602060405180830381600088803b158015612bf457600080fd5b5087f1158015612c08573d6000803e3d6000fd5b50505050506040513d6020811015612c1f57600080fd5b505190507fffffffff0000000000000000000000000000000000000000000000000000000081167fbc197c810000000000000000000000000000000000000000000000000000000014611787576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604c815260200180614dfa604c913960600191505060405180910390fd5b505050505050565b3360009081526007602052604090205460ff16612d0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614814565b33600090815260086020526040902054612d26613de4565b3360009081526008602052604081208054909190612d4057fe5b6000918252602080832060408051608081018252939091015467ffffffffffffffff80821685526801000000000000000082048116938501939093527001000000000000000000000000000000008104831691840191909152780100000000000000000000000000000000000000000000000090041660608201529150805b8551811015612cbd576000868281518110612dd657fe5b602002602001015190506000868381518110612dee57fe5b602002602001015190506000600b60008481526020019081526020016000205490505b856040015167ffffffffffffffff16421080612e3a5750856060015167ffffffffffffffff1642115b80612e4f5750855167ffffffffffffffff1683105b80612e67575082866020015167ffffffffffffffff16105b15612f4b57600185019450868510612eab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614962565b336000908152600860205260409020805486908110612ec657fe5b600091825260209182902060408051608081018252929091015467ffffffffffffffff808216845268010000000000000000820481169484019490945270010000000000000000000000000000000081048416918301919091527801000000000000000000000000000000000000000000000000900490911660608201529550612e11565b8015612fb6576000838152600a6020526040812054612f6a9084613cd2565b905081811115612fa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614c13565b6000848152600a60205260409020555b505050600101612dbf565b612fce8484846000613a01565b6040805184815260208101849052815173ffffffffffffffffffffffffffffffffffffffff87169260009233927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62929181900390910190a4610daa60008585855a866137b3565b80516118e5906002906020840190613e22565b73ffffffffffffffffffffffffffffffffffffffff82166130b4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526031815260200180614e826031913960400191505060405180910390fd5b6103e881111561310f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526039815260200180614f266039913960400191505060405180910390fd5b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9390931692909217909155600555565b6131678383836001613a01565b6040805183815260208101839052815160009273ffffffffffffffffffffffffffffffffffffffff87169233927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62929181900390910190a4505050565b815183511461321e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603e815260200180615023603e913960400191505060405180910390fd5b82511561333e576000806132388560008151811061138457fe5b73ffffffffffffffffffffffffffffffffffffffff8816600090815260208181526040808320858452909152812054875193955091935091613281919084908890859061279157fe5b86519091508360015b82811015613305576132a189828151811061138457fe5b90965094508186146132ea5773ffffffffffffffffffffffffffffffffffffffff8a16600090815260208181526040808320948352939052828120949094558584529220549184905b6132fb84868a848151811061279157fe5b935060010161328a565b50505073ffffffffffffffffffffffffffffffffffffffff87166000908152602081815260408083209583529490529290922091909155505b8373ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156133eb5781810151838201526020016133d3565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561342a578181015183820152602001613412565b5050505090500194505050505060405180910390a4610daa60008585855a86612a50565b60028054604080516020601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61010060018716150201909416859004938401819004810282018101909252828152606093909290918301828280156134f55780601f106134ca576101008083540402835291602001916134f5565b820191906000526020600020905b8154815290600101906020018083116134d857829003601f168201915b50505050509050606060005b8351811015610daa578261352785838151811061351a57fe5b602002602001015161225a565b6040516020018083805190602001908083835b6020831061357757805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161353a565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905285519190930192850191508083835b602083106135fb57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016135be565b6001836020036101000a038019825116818451168082178552505050505050905001807f2e6a736f6e00000000000000000000000000000000000000000000000000000081525060050192505050604051602081830303815290604052915083818151811061366657fe5b60200260200101517f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b836040518080602001828103825283818151815260200191508051906020019080838360005b838110156136cd5781810151838201526020016136b5565b50505050905090810190601f1680156136fa5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2600101613501565b61371c8483836001613a01565b6137298383836000613a01565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628585604051808381526020018281526020019250505060405180910390a450505050565b6137d28573ffffffffffffffffffffffffffffffffffffffff16613c9b565b15612cbd5760008573ffffffffffffffffffffffffffffffffffffffff1663f23a6e6184338a8989886040518763ffffffff1660e01b8152600401808673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff16815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561388b578181015183820152602001613873565b50505050905090810190601f1680156138b85780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600088803b1580156138db57600080fd5b5087f11580156138ef573d6000803e3d6000fd5b50505050506040513d602081101561390657600080fd5b505190507fffffffff0000000000000000000000000000000000000000000000000000000081167ff23a6e610000000000000000000000000000000000000000000000000000000014611787576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526047815260200180614f5f6047913960600191505060405180910390fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f0e89341c0000000000000000000000000000000000000000000000000000000014156139f857506001610589565b61058682613d46565b600080613a0d85611e27565b73ffffffffffffffffffffffffffffffffffffffff88166000908152602081815260408083208584529091529020549193509150613a4d90828686613a88565b73ffffffffffffffffffffffffffffffffffffffff909616600090815260208181526040808320948352939052919091209490945550505050565b60006020840263ffffffff82846001811115613aa057fe5b1415613b6e5784821b8701925086831015613b06576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806150616032913960400191505060405180910390fd5b64010000000087831c8216860110613b69576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806150616032913960400191505060405180910390fd5b613c91565b6001846001811115613b7c57fe5b1415613c405784821b8703925086831115613be2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526033815260200180614d4e6033913960400191505060405180910390fd5b84818389901c161015613b69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526033815260200180614d4e6033913960400191505060405180910390fd5b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526045815260200180614fde6045913960600191505060405180910390fd5b5050949350505050565b6000813f80158015906125b857507fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470141592915050565b6000828201838110156125b857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f536166654d617468236164643a204f564552464c4f5700000000000000000000604482015290519081900360640190fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fd9b67a26000000000000000000000000000000000000000000000000000000001415613d9a57506001610589565b7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610586565b60408051608081018252600080825260208201819052918101829052606081019190915290565b604080518082019091526000808252602082015290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282613e585760008555613e9e565b82601f10613e7157805160ff1916838001178555613e9e565b82800160010185558215613e9e579182015b82811115613e9e578251825591602001919060010190613e83565b50613eaa929150613eae565b5090565b5b80821115613eaa5760008155600101613eaf565b803573ffffffffffffffffffffffffffffffffffffffff8116811461058957600080fd5b60008083601f840112613ef8578081fd5b50813567ffffffffffffffff811115613f0f578182fd5b6020830191508360208083028501011115610e0b57600080fd5b600082601f830112613f39578081fd5b8135613f4c613f4782614cb9565b614c95565b818152915060208083019084810181840286018201871015613f6d57600080fd5b60005b84811015613f8c57813584529282019290820190600101613f70565b505050505092915050565b60008083601f840112613fa8578182fd5b50813567ffffffffffffffff811115613fbf578182fd5b602083019150836020828501011115610e0b57600080fd5b600082601f830112613fe7578081fd5b813567ffffffffffffffff811115613ffb57fe5b61402c60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614c95565b915080825283602082850101111561404357600080fd5b8060208401602084013760009082016020015292915050565b803567ffffffffffffffff8116811461058957600080fd5b600060208284031215614085578081fd5b6125b882613ec3565b600080604083850312156140a0578081fd5b6140a983613ec3565b91506140b760208401613ec3565b90509250929050565b600080600080600060a086880312156140d7578081fd5b6140e086613ec3565b94506140ee60208701613ec3565b9350604086013567ffffffffffffffff8082111561410a578283fd5b61411689838a01613f29565b9450606088013591508082111561412b578283fd5b61413789838a01613f29565b9350608088013591508082111561414c578283fd5b5061415988828901613fd7565b9150509295509295909350565b600080600080600060a0868803121561417d578081fd5b61418686613ec3565b945061419460208701613ec3565b93506040860135925060608601359150608086013567ffffffffffffffff8111156141bd578182fd5b61415988828901613fd7565b600080600080608085870312156141de578384fd5b6141e785613ec3565b9350602085013567ffffffffffffffff80821115614203578485fd5b61420f88838901613f29565b94506040870135915080821115614224578384fd5b61423088838901613f29565b93506060870135915080821115614245578283fd5b5061425287828801613fd7565b91505092959194509250565b60008060408385031215614270578182fd5b61427983613ec3565b91506020830135801515811461428d578182fd5b809150509250929050565b600080604083850312156142aa578182fd5b6142b383613ec3565b946020939093013593505050565b6000806000806000608086880312156142d8578283fd5b6142e186613ec3565b94506020860135935060408601359250606086013567ffffffffffffffff81111561430a578182fd5b61431688828901613f97565b969995985093965092949392505050565b600080600080600060a0868803121561433e578283fd5b61434786613ec3565b94506143556020870161405c565b93506143636040870161405c565b92506143716060870161405c565b915061437f6080870161405c565b90509295509295909350565b6000806040838503121561439d578182fd5b823567ffffffffffffffff808211156143b4578384fd5b818501915085601f8301126143c7578384fd5b81356143d5613f4782614cb9565b80828252602080830192508086018a8283870289010111156143f5578889fd5b8896505b8487101561441e5761440a81613ec3565b8452600196909601959281019281016143f9565b509096508701359350505080821115614435578283fd5b5061444285828601613f29565b9150509250929050565b6000806020838503121561445e578182fd5b823567ffffffffffffffff811115614474578283fd5b61448085828601613ee7565b90969095509350505050565b600080600080604085870312156144a1578182fd5b843567ffffffffffffffff808211156144b8578384fd5b6144c488838901613ee7565b909650945060208701359150808211156144dc578384fd5b506144e987828801613ee7565b95989497509550505050565b600060208284031215614506578081fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146125b8578182fd5b60008060208385031215614547578182fd5b823567ffffffffffffffff81111561455d578283fd5b61448085828601613f97565b60006080828403121561457a578081fd5b6040516080810181811067ffffffffffffffff8211171561459757fe5b6040526145a38361405c565b81526145b16020840161405c565b60208201526145c26040840161405c565b60408201526145d36060840161405c565b60608201529392505050565b6000602082840312156145f0578081fd5b5035919050565b60008060408385031215614609578182fd5b50508035926020909101359150565b60008284527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115614649578081fd5b6020830280836020870137939093016020019283525090919050565b805167ffffffffffffffff908116835260208083015182169084015260408083015182169084015260609182015116910152565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b73ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b818110156147225761470f838551614665565b92840192608092909201916001016146fc565b50909695505050505050565b600060408252614742604083018688614618565b8281036020840152614755818587614618565b979650505050505050565b6020808252825182820181905260009190848201906040850190845b818110156147225783518352928401929184019160010161477c565b901515815260200190565b6000602080835283518082850152825b818110156147cf578581018301518582016040015282016147b3565b818111156147e05783604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60208082526032908201527f536b79776561766572417373657473235f76616c69646174654d696e74733a2060408201527f464143544f52595f4e4f545f4143544956450000000000000000000000000000606082015260800190565b60208082526036908201527f536b79776561766572417373657473237365744d617849737375616e6365733a60408201527f20494e56414c49445f4152524159535f4c454e47544800000000000000000000606082015260800190565b60208082526012908201527f554e535550504f525445445f4d4554484f440000000000000000000000000000604082015260600190565b60208082526030908201527f536b79776561766572417373657473236164644d696e745065726d697373696f60408201527f6e3a20494e56414c49445f52414e474500000000000000000000000000000000606082015260800190565b6020808252602f908201527f536b79776561766572417373657473235f76616c69646174654d696e74733a2060408201527f49445f4f55545f4f465f52414e47450000000000000000000000000000000000606082015260800190565b6020808252602a908201527f4f776e61626c65237472616e736665724f776e6572736869703a20494e56414c60408201527f49445f4144445245535300000000000000000000000000000000000000000000606082015260800190565b6020808252603c908201527f536b79776561766572417373657473236164644d696e745065726d697373696f60408201527f6e3a204f5645524c41505f574954485f4c4f434b45445f52414e474500000000606082015260800190565b6020808252602d908201527f536b79776561766572417373657473236164644d696e745065726d697373696f60408201527f6e3a204e554c4c5f52414e474500000000000000000000000000000000000000606082015260800190565b60208082526039908201527f536b79776561766572417373657473237365744d617849737375616e6365733a60408201527f20494e56414c49445f4e45575f4d41585f49535355414e434500000000000000606082015260800190565b60208082526049908201527f536b79776561766572417373657473236164644d696e745065726d697373696f60408201527f6e3a2053544152545f54494d455f49535f4e4f545f4c45535345525f5448454e60608201527f5f454e445f54494d450000000000000000000000000000000000000000000000608082015260a00190565b60208082526026908201527f4f776e61626c65236f6e6c794f776e65723a2053454e4445525f49535f4e4f5460408201527f5f4f574e45520000000000000000000000000000000000000000000000000000606082015260800190565b60208082526035908201527f536b79776561766572417373657473235f76616c69646174654d696e74733a2060408201527f4d41585f49535355414e43455f45584345454445440000000000000000000000606082015260800190565b608081016105758284614665565b90815260200190565b918252602082015260400190565b60405181810167ffffffffffffffff81118282101715614cb157fe5b604052919050565b600067ffffffffffffffff821115614ccd57fe5b506020908102019056fe455243313135355061636b656442616c616e63652362616c616e63654f6642617463683a20494e56414c49445f41525241595f4c454e475448455243313135355061636b656442616c616e6365237361666542617463685472616e7366657246726f6d3a20494e56414c49445f524543495049454e54455243313135355061636b656442616c616e6365235f7669657755706461746542696e56616c75653a20554e444552464c4f57455243313135355061636b656442616c616e636523736166655472616e7366657246726f6d3a20494e56414c49445f4f50455241544f52455243313135355061636b656442616c616e6365235f7361666542617463685472616e7366657246726f6d3a20494e56414c49445f4152524159535f4c454e475448455243313135355061636b656442616c616e6365235f63616c6c6f6e45524331313535426174636852656365697665643a20494e56414c49445f4f4e5f524543454956455f4d455353414745455243313135355061636b656442616c616e6365237361666542617463685472616e7366657246726f6d3a20494e56414c49445f4f50455241544f5245524332393831476c6f62616c235f736574476c6f62616c526f79616c74793a20524543495049454e545f49535f307830455243313135354d696e744275726e5061636b656442616c616e63652362617463684275726e3a20494e56414c49445f4152524159535f4c454e475448455243313135355061636b656442616c616e6365235f7361666542617463685472616e7366657246726f6d3a20554e444552464c4f5745524332393831476c6f62616c235f736574476c6f62616c526f79616c74793a204645455f49535f41424f56455f3130305f50455243454e54455243313135355061636b656442616c616e6365235f63616c6c6f6e4552433131353552656365697665643a20494e56414c49445f4f4e5f524543454956455f4d455353414745455243313135355061636b656442616c616e636523736166655472616e7366657246726f6d3a20494e56414c49445f524543495049454e54455243313135355061636b656442616c616e6365235f7669657755706461746542696e56616c75653a20494e56414c49445f42494e5f57524954455f4f5045524154494f4e455243313135354d696e744275726e5061636b656442616c616e6365235f62617463684d696e743a20494e56414c49445f4152524159535f4c454e475448455243313135355061636b656442616c616e6365235f7669657755706461746542696e56616c75653a204f564552464c4f57a2646970667358221220fb1372790e40e3e548bbc115377592682a7efd66fc87555aa190c17a7e2027e864736f6c63430007040033000000000000000000000000ec32359f21cf24e7d5097813577ee1f2c22fa57b

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102255760003560e01c80639136ce1f1161012a578063d46c069e116100bd578063e985e9c51161008c578063f242432a11610071578063f242432a146104eb578063f2fde38b146104fe578063f795ab751461051157610225565b8063e985e9c5146104c5578063eaec5f81146104d857610225565b8063d46c069e1461046b578063db90e83c1461047e578063e1a972721461049f578063e4b37d33146104b257610225565b8063adccc471116100f9578063adccc4711461042a578063b390c0ab1461043d578063b48ab8b614610450578063c9823cc61461046357610225565b80639136ce1f146103de57806393cfa682146103f1578063a22cb46514610404578063a36b3f291461041757610225565b80632eb2c2d6116101bd5780636c0360eb1161018c5780637c44a8bb116101715780637c44a8bb146103a35780637e518ec8146103b6578063893d20e8146103c957610225565b80636c0360eb14610388578063731133e91461039057610225565b80632eb2c2d61461032d578063458d2844146103405780634e1273f414610353578063657afa891461037357610225565b80630e89341c116101f95780630e89341c146102d357806315a08ab8146102e657806320ec271b146102f95780632a55205a1461030c57610225565b8062fdd58e1461026057806301ffc9a71461028957806306fdde03146102a957806307800c9b146102be575b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610257906148ce565b60405180910390fd5b61027361026e366004614298565b610524565b6040516102809190614c7e565b60405180910390f35b61029c6102973660046144f5565b61057b565b6040516102809190614798565b6102b161058e565b60405161028091906147a3565b6102d16102cc366004614327565b61063a565b005b6102b16102e13660046145df565b610a0f565b6102d16102f436600461448c565b610b62565b6102d161030736600461448c565b610d3c565b61031f61031a3660046145f7565b610db0565b6040516102809291906146ba565b6102d161033b3660046140c0565b610e12565b6102d161034e366004614298565b610f1d565b61036661036136600461438b565b611312565b6040516102809190614760565b61037b611591565b60405161028091906146e0565b6102b161164c565b6102d161039e3660046142c1565b6116c2565b6102d16103b1366004614074565b611790565b6102d16103c4366004614535565b611855565b6103d16118e9565b6040516102809190614699565b6102d16103ec366004614074565b611905565b6102d16103ff366004614298565b6119cd565b6102d161041236600461425e565b611a28565b61037b610425366004614074565b611ac1565b6102d1610438366004614569565b611b9f565b6102d161044b3660046145f7565b611d57565b6102d161045e3660046141c9565b611d62565b61031f611d78565b6102d161047936600461444c565b611d9a565b61049161048c3660046145df565b611e27565b604051610280929190614c87565b6103666104ad36600461444c565b611e34565b6103666104c036600461444c565b611ed5565b61029c6104d336600461408e565b611f6d565b6102736104e63660046145f7565b611fa8565b6102d16104f9366004614166565b611fbb565b6102d161050c366004614074565b6120bf565b61029c61051f366004614074565b6121d2565b600080600061053284611e27565b73ffffffffffffffffffffffffffffffffffffffff871660009081526020818152604080832085845290915290205491935091506105709082611fa8565b925050505b92915050565b6000610586826121fd565b90505b919050565b6003805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f810184900484028201840190925281815292918301828280156106325780601f1061060757610100808354040283529160200191610632565b820191906000526020600020905b81548152906001019060200180831161061557829003601f168201915b505050505081565b60065473ffffffffffffffffffffffffffffffffffffffff16331461068b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b60008367ffffffffffffffff16116106cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614a79565b8267ffffffffffffffff168467ffffffffffffffff16111561071d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614905565b8067ffffffffffffffff168267ffffffffffffffff161061076a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614b33565b60005b6009548110156108705761077f613de4565b6009828154811061078c57fe5b600091825260209182902060408051608081018252919092015467ffffffffffffffff8082168084526801000000000000000083048216958401959095527001000000000000000000000000000000008204811693830193909352780100000000000000000000000000000000000000000000000090048216606082015292508616108061083157508567ffffffffffffffff16816020015167ffffffffffffffff16105b610867576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614a1c565b5060010161076d565b50610879613de4565b506040805160808101825267ffffffffffffffff808716825285811660208084019182528683168486019081528684166060860190815273ffffffffffffffffffffffffffffffffffffffff8c166000818152600885528881208054600181018255908252949020875194018054955193519251871678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff938816700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff95891668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff979099167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009098169790971795909516969096179290921693909317929092161790915591519091907f188968bccf857d854c73494ca4da4cc4ae2769e4b732db8f40dfa62b86b1c40a906109ff908490614c70565b60405180910390a2505050505050565b60606002610a1c8361225a565b6040516020018083805460018160011615610100020316600290048015610a7a5780601f10610a58576101008083540402835291820191610a7a565b820191906000526020600020905b815481529060010190602001808311610a66575b5050825160208401908083835b60208310610ac457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a87565b5181516020939093036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990911692169190911790527f2e6a736f6e000000000000000000000000000000000000000000000000000000920191825250604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe50181526005909201905295945050505050565b60065473ffffffffffffffffffffffffffffffffffffffff163314610bb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b828114610bec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614871565b60005b83811015610cf8576000600b6000878785818110610c0957fe5b905060200201358152602001908152602001600020541115610cb357828282818110610c3157fe5b905060200201356000108015610c7d5750600b6000868684818110610c5257fe5b90506020020135815260200190815260200160002054838383818110610c7457fe5b90506020020135105b610cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614ad6565b828282818110610cbf57fe5b90506020020135600b6000878785818110610cd657fe5b6020908102929092013583525081019190915260400160002055600101610bef565b507f91f9ea1e3a6a1fd246959c27978a42e04c0c3c954e7ffa52e3ed1509be4811be84848484604051610d2e949392919061472e565b60405180910390a150505050565b610daa338585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080890282810182019093528882529093508892508791829185019084908082843760009201919091525061238692505050565b50505050565b600080610dbb613e0b565b506040805180820190915260045473ffffffffffffffffffffffffffffffffffffffff1680825260055460208301819052610e05906103e890610dff90889061252f565b906125bf565b92509250505b9250929050565b3373ffffffffffffffffffffffffffffffffffffffff86161480610e3b5750610e3b8533611f6d565b610e90576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180614e46603c913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8416610efc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180614d11603d913960400191505060405180910390fd5b610f0885858585612643565b610f16858585855a86612a50565b5050505050565b60065473ffffffffffffffffffffffffffffffffffffffff163314610f6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600860205260409020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610fbe613de4565b73ffffffffffffffffffffffffffffffffffffffff84166000908152600860205260409020805484908110610fef57fe5b600091825260209182902060408051608081018252929091015467ffffffffffffffff8082168452680100000000000000008204811694840194909452700100000000000000000000000000000000810484169183019190915278010000000000000000000000000000000000000000000000009004909116606082015290508183146112585761107e613de4565b73ffffffffffffffffffffffffffffffffffffffff851660009081526008602052604090208054849081106110af57fe5b6000918252602080832060408051608081018252919093015467ffffffffffffffff80821683526801000000000000000082048116838501527001000000000000000000000000000000008204811683860152780100000000000000000000000000000000000000000000000090910416606082015273ffffffffffffffffffffffffffffffffffffffff8916845260089091529120805491925082918690811061115657fe5b60009182526020918290208351910180549284015160408501516060909501517fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090941667ffffffffffffffff938416177fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000091841691909102177fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff16700100000000000000000000000000000000948316949094029390931777ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000009190921602179055505b73ffffffffffffffffffffffffffffffffffffffff8416600090815260086020526040902080548061128657fe5b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9081019190915501905560405173ffffffffffffffffffffffffffffffffffffffff8516907f1bca5c143feb87c2d4e8d2d1fd73ba6f43f551ba73c58634f56bbe30701f06d490611304908490614c70565b60405180910390a250505050565b81518151606091908114611371576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526039815260200180614cd86039913960400191505060405180910390fd5b6000806113918560008151811061138457fe5b6020026020010151611e27565b915091506000806000886000815181106113a757fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000848152602001908152602001600020549050600083905060608567ffffffffffffffff8111801561141b57600080fd5b50604051908082528060200260200182016040528015611445578160200160208202803683370190505b5090506114528385611fa8565b8160008151811061145f57fe5b602090810291909101015260015b868110156115845761148489828151811061138457fe5b909650945082861415806114ed575089818151811061149f57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff168a60018303815181106114cc57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614155b1561155b576000808b838151811061150157fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008781526020019081526020016000205493508592505b6115658486611fa8565b82828151811061157157fe5b602090810291909101015260010161146d565b5098975050505050505050565b60606009805480602002602001604051908101604052809291908181526020016000905b82821015611643576000848152602090819020604080516080810182529185015467ffffffffffffffff80821684526801000000000000000082048116848601527001000000000000000000000000000000008204811692840192909252780100000000000000000000000000000000000000000000000090041660608201528252600190920191016115b5565b50505050905090565b600280546040805160206001841615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01909316849004601f810184900484028201840190925281815292918301828280156106325780601f1061060757610100808354040283529160200191610632565b604080516001808252818301909252606091602080830190803683375050604080516001808252818301909252929350606092915060208083019080368337019050509050858260008151811061171557fe5b602002602001018181525050848160008151811061172f57fe5b6020026020010181815250506117458282612cc5565b61178787878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612fc192505050565b50505050505050565b60065473ffffffffffffffffffffffffffffffffffffffff1633146117e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b73ffffffffffffffffffffffffffffffffffffffff811660008181526007602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f472ecaf428225ecdcc1f686a662ed1ba0627c365542e086b483bacca0fcfa5f99190a250565b60065473ffffffffffffffffffffffffffffffffffffffff1633146118a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b6118e582828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061303592505050565b5050565b60065473ffffffffffffffffffffffffffffffffffffffff1690565b60065473ffffffffffffffffffffffffffffffffffffffff163314611956576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b73ffffffffffffffffffffffffffffffffffffffff811660008181526007602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f672dbf7f8dabd5b1b39124540440a9ef2537a03c053f111f7e90850e57e2efb69190a250565b60065473ffffffffffffffffffffffffffffffffffffffff163314611a1e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b6118e58282613048565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600860209081526040808320805482518185028101850190935280835260609492939192909184015b82821015611b94576000848152602090819020604080516080810182529185015467ffffffffffffffff8082168452680100000000000000008204811684860152700100000000000000000000000000000000820481169284019290925278010000000000000000000000000000000000000000000000009004166060820152825260019092019101611b06565b505050509050919050565b60065473ffffffffffffffffffffffffffffffffffffffff163314611bf0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b6009805460018101825560009190915281517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af9091018054602084015160408086015160608701517fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090941667ffffffffffffffff968716177fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000093871693909302929092177fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff16700100000000000000000000000000000000928616929092029190911777ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000009490921693909302179055517f522c18973f048c2a178766b76cb19456e9dbd776f104c0b77c6166e582212f2c90611d4c908390614c70565b60405180910390a150565b6118e533838361315a565b611d6c8383612cc5565b610daa848484846131c4565b60045460055473ffffffffffffffffffffffffffffffffffffffff9091169082565b60065473ffffffffffffffffffffffffffffffffffffffff163314611deb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b6118e582828080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061344e92505050565b6008810491600790911690565b606081818167ffffffffffffffff81118015611e4f57600080fd5b50604051908082528060200260200182016040528015611e79578160200160208202803683370190505b50905060005b82811015611ecc57600b6000878784818110611e9757fe5b90506020020135815260200190815260200160002054828281518110611eb957fe5b6020908102919091010152600101611e7f565b50949350505050565b606081818167ffffffffffffffff81118015611ef057600080fd5b50604051908082528060200260200182016040528015611f1a578160200160208202803683370190505b50905060005b82811015611ecc57600a6000878784818110611f3857fe5b90506020020135815260200190815260200160002054828281518110611f5a57fe5b6020908102919091010152600101611f20565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205460ff1690565b6020810282901c63ffffffff1692915050565b3373ffffffffffffffffffffffffffffffffffffffff86161480611fe45750611fe48533611f6d565b612039576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526037815260200180614d816037913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff84166120a5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526038815260200180614fa66038913960400191505060405180910390fd5b6120b18585858561370f565b610f16858585855a866137b3565b60065473ffffffffffffffffffffffffffffffffffffffff163314612110576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b73ffffffffffffffffffffffffffffffffffffffff811661215d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610257906149bf565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821792839055604051919216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b73ffffffffffffffffffffffffffffffffffffffff1660009081526007602052604090205460ff1690565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f2a55205a00000000000000000000000000000000000000000000000000000000141561225157506001610589565b610586826139a4565b60608161229b575060408051808201909152600181527f30000000000000000000000000000000000000000000000000000000000000006020820152610589565b818060005b82156122b457600101600a830492506122a0565b60608167ffffffffffffffff811180156122cd57600080fd5b506040519080825280601f01601f1916602001820160405280156122f8576020820181803683370190505b5090507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82015b831561237c57600a840660300160f81b8282806001900393508151811061234257fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8404935061231f565b5095945050505050565b8151815181146123e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180614eb3603d913960400191505060405180910390fd5b60005b818110156124275761241f858583815181106123fc57fe5b602002602001015185848151811061241057fe5b60200260200101516001613a01565b6001016123e4565b50600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156124d55781810151838201526020016124bd565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156125145781810151838201526020016124fc565b5050505090500194505050505060405180910390a450505050565b60008261253e57506000610575565b8282028284828161254b57fe5b04146125b857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f536166654d617468236d756c3a204f564552464c4f5700000000000000000000604482015290519081900360640190fd5b9392505050565b600080821161262f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f536166654d617468236469763a204449564953494f4e5f42595f5a45524f0000604482015290519081900360640190fd5b600082848161263a57fe5b04949350505050565b81518151811461269e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526042815260200180614db86042913960600191505060405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16141580156126da5750600081115b156128ac576000806126f28560008151811061138457fe5b73ffffffffffffffffffffffffffffffffffffffff891660009081526020818152604080832085845290915281205487519395509193509161274a919084908890859061273b57fe5b60200260200101516001613a88565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260208181526040808320878452909152812054875192935090916127a0919085908990859061279157fe5b60200260200101516000613a88565b90508360015b8681101561285a576127bd89828151811061138457fe5b909650945081861461282c5773ffffffffffffffffffffffffffffffffffffffff8b811660009081526020818152604080832086845280835281842098909855928d16825281815282822094825284815282822095909555878152948452808520549290935291909220549084905b61283d84868a848151811061273b57fe5b935061285083868a848151811061279157fe5b92506001016127a6565b505073ffffffffffffffffffffffffffffffffffffffff808a16600090815260208181526040808320888452825280832095909555918a16815280825283812095815294905292209190915550612949565b60005b81811015612947578281815181106128c357fe5b60200260200101516128e8878684815181106128db57fe5b6020026020010151610524565b101561293f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526036815260200180614ef06036913960400191505060405180910390fd5b6001016128af565b505b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156129f55781810151838201526020016129dd565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015612a34578181015183820152602001612a1c565b5050505090500194505050505060405180910390a45050505050565b612a6f8573ffffffffffffffffffffffffffffffffffffffff16613c9b565b15612cbd5760008573ffffffffffffffffffffffffffffffffffffffff1663bc197c8184338a8989886040518763ffffffff1660e01b8152600401808673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b83811015612b27578181015183820152602001612b0f565b50505050905001848103835286818151815260200191508051906020019060200280838360005b83811015612b66578181015183820152602001612b4e565b50505050905001848103825285818151815260200191508051906020019080838360005b83811015612ba2578181015183820152602001612b8a565b50505050905090810190601f168015612bcf5780820380516001836020036101000a031916815260200191505b5098505050505050505050602060405180830381600088803b158015612bf457600080fd5b5087f1158015612c08573d6000803e3d6000fd5b50505050506040513d6020811015612c1f57600080fd5b505190507fffffffff0000000000000000000000000000000000000000000000000000000081167fbc197c810000000000000000000000000000000000000000000000000000000014611787576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604c815260200180614dfa604c913960600191505060405180910390fd5b505050505050565b3360009081526007602052604090205460ff16612d0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614814565b33600090815260086020526040902054612d26613de4565b3360009081526008602052604081208054909190612d4057fe5b6000918252602080832060408051608081018252939091015467ffffffffffffffff80821685526801000000000000000082048116938501939093527001000000000000000000000000000000008104831691840191909152780100000000000000000000000000000000000000000000000090041660608201529150805b8551811015612cbd576000868281518110612dd657fe5b602002602001015190506000868381518110612dee57fe5b602002602001015190506000600b60008481526020019081526020016000205490505b856040015167ffffffffffffffff16421080612e3a5750856060015167ffffffffffffffff1642115b80612e4f5750855167ffffffffffffffff1683105b80612e67575082866020015167ffffffffffffffff16105b15612f4b57600185019450868510612eab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614962565b336000908152600860205260409020805486908110612ec657fe5b600091825260209182902060408051608081018252929091015467ffffffffffffffff808216845268010000000000000000820481169484019490945270010000000000000000000000000000000081048416918301919091527801000000000000000000000000000000000000000000000000900490911660608201529550612e11565b8015612fb6576000838152600a6020526040812054612f6a9084613cd2565b905081811115612fa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614c13565b6000848152600a60205260409020555b505050600101612dbf565b612fce8484846000613a01565b6040805184815260208101849052815173ffffffffffffffffffffffffffffffffffffffff87169260009233927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62929181900390910190a4610daa60008585855a866137b3565b80516118e5906002906020840190613e22565b73ffffffffffffffffffffffffffffffffffffffff82166130b4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526031815260200180614e826031913960400191505060405180910390fd5b6103e881111561310f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526039815260200180614f266039913960400191505060405180910390fd5b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9390931692909217909155600555565b6131678383836001613a01565b6040805183815260208101839052815160009273ffffffffffffffffffffffffffffffffffffffff87169233927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62929181900390910190a4505050565b815183511461321e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603e815260200180615023603e913960400191505060405180910390fd5b82511561333e576000806132388560008151811061138457fe5b73ffffffffffffffffffffffffffffffffffffffff8816600090815260208181526040808320858452909152812054875193955091935091613281919084908890859061279157fe5b86519091508360015b82811015613305576132a189828151811061138457fe5b90965094508186146132ea5773ffffffffffffffffffffffffffffffffffffffff8a16600090815260208181526040808320948352939052828120949094558584529220549184905b6132fb84868a848151811061279157fe5b935060010161328a565b50505073ffffffffffffffffffffffffffffffffffffffff87166000908152602081815260408083209583529490529290922091909155505b8373ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156133eb5781810151838201526020016133d3565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561342a578181015183820152602001613412565b5050505090500194505050505060405180910390a4610daa60008585855a86612a50565b60028054604080516020601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61010060018716150201909416859004938401819004810282018101909252828152606093909290918301828280156134f55780601f106134ca576101008083540402835291602001916134f5565b820191906000526020600020905b8154815290600101906020018083116134d857829003601f168201915b50505050509050606060005b8351811015610daa578261352785838151811061351a57fe5b602002602001015161225a565b6040516020018083805190602001908083835b6020831061357757805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161353a565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905285519190930192850191508083835b602083106135fb57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016135be565b6001836020036101000a038019825116818451168082178552505050505050905001807f2e6a736f6e00000000000000000000000000000000000000000000000000000081525060050192505050604051602081830303815290604052915083818151811061366657fe5b60200260200101517f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b836040518080602001828103825283818151815260200191508051906020019080838360005b838110156136cd5781810151838201526020016136b5565b50505050905090810190601f1680156136fa5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2600101613501565b61371c8483836001613a01565b6137298383836000613a01565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628585604051808381526020018281526020019250505060405180910390a450505050565b6137d28573ffffffffffffffffffffffffffffffffffffffff16613c9b565b15612cbd5760008573ffffffffffffffffffffffffffffffffffffffff1663f23a6e6184338a8989886040518763ffffffff1660e01b8152600401808673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff16815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561388b578181015183820152602001613873565b50505050905090810190601f1680156138b85780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600088803b1580156138db57600080fd5b5087f11580156138ef573d6000803e3d6000fd5b50505050506040513d602081101561390657600080fd5b505190507fffffffff0000000000000000000000000000000000000000000000000000000081167ff23a6e610000000000000000000000000000000000000000000000000000000014611787576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526047815260200180614f5f6047913960600191505060405180910390fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f0e89341c0000000000000000000000000000000000000000000000000000000014156139f857506001610589565b61058682613d46565b600080613a0d85611e27565b73ffffffffffffffffffffffffffffffffffffffff88166000908152602081815260408083208584529091529020549193509150613a4d90828686613a88565b73ffffffffffffffffffffffffffffffffffffffff909616600090815260208181526040808320948352939052919091209490945550505050565b60006020840263ffffffff82846001811115613aa057fe5b1415613b6e5784821b8701925086831015613b06576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806150616032913960400191505060405180910390fd5b64010000000087831c8216860110613b69576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806150616032913960400191505060405180910390fd5b613c91565b6001846001811115613b7c57fe5b1415613c405784821b8703925086831115613be2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526033815260200180614d4e6033913960400191505060405180910390fd5b84818389901c161015613b69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526033815260200180614d4e6033913960400191505060405180910390fd5b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526045815260200180614fde6045913960600191505060405180910390fd5b5050949350505050565b6000813f80158015906125b857507fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470141592915050565b6000828201838110156125b857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f536166654d617468236164643a204f564552464c4f5700000000000000000000604482015290519081900360640190fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fd9b67a26000000000000000000000000000000000000000000000000000000001415613d9a57506001610589565b7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610586565b60408051608081018252600080825260208201819052918101829052606081019190915290565b604080518082019091526000808252602082015290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282613e585760008555613e9e565b82601f10613e7157805160ff1916838001178555613e9e565b82800160010185558215613e9e579182015b82811115613e9e578251825591602001919060010190613e83565b50613eaa929150613eae565b5090565b5b80821115613eaa5760008155600101613eaf565b803573ffffffffffffffffffffffffffffffffffffffff8116811461058957600080fd5b60008083601f840112613ef8578081fd5b50813567ffffffffffffffff811115613f0f578182fd5b6020830191508360208083028501011115610e0b57600080fd5b600082601f830112613f39578081fd5b8135613f4c613f4782614cb9565b614c95565b818152915060208083019084810181840286018201871015613f6d57600080fd5b60005b84811015613f8c57813584529282019290820190600101613f70565b505050505092915050565b60008083601f840112613fa8578182fd5b50813567ffffffffffffffff811115613fbf578182fd5b602083019150836020828501011115610e0b57600080fd5b600082601f830112613fe7578081fd5b813567ffffffffffffffff811115613ffb57fe5b61402c60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614c95565b915080825283602082850101111561404357600080fd5b8060208401602084013760009082016020015292915050565b803567ffffffffffffffff8116811461058957600080fd5b600060208284031215614085578081fd5b6125b882613ec3565b600080604083850312156140a0578081fd5b6140a983613ec3565b91506140b760208401613ec3565b90509250929050565b600080600080600060a086880312156140d7578081fd5b6140e086613ec3565b94506140ee60208701613ec3565b9350604086013567ffffffffffffffff8082111561410a578283fd5b61411689838a01613f29565b9450606088013591508082111561412b578283fd5b61413789838a01613f29565b9350608088013591508082111561414c578283fd5b5061415988828901613fd7565b9150509295509295909350565b600080600080600060a0868803121561417d578081fd5b61418686613ec3565b945061419460208701613ec3565b93506040860135925060608601359150608086013567ffffffffffffffff8111156141bd578182fd5b61415988828901613fd7565b600080600080608085870312156141de578384fd5b6141e785613ec3565b9350602085013567ffffffffffffffff80821115614203578485fd5b61420f88838901613f29565b94506040870135915080821115614224578384fd5b61423088838901613f29565b93506060870135915080821115614245578283fd5b5061425287828801613fd7565b91505092959194509250565b60008060408385031215614270578182fd5b61427983613ec3565b91506020830135801515811461428d578182fd5b809150509250929050565b600080604083850312156142aa578182fd5b6142b383613ec3565b946020939093013593505050565b6000806000806000608086880312156142d8578283fd5b6142e186613ec3565b94506020860135935060408601359250606086013567ffffffffffffffff81111561430a578182fd5b61431688828901613f97565b969995985093965092949392505050565b600080600080600060a0868803121561433e578283fd5b61434786613ec3565b94506143556020870161405c565b93506143636040870161405c565b92506143716060870161405c565b915061437f6080870161405c565b90509295509295909350565b6000806040838503121561439d578182fd5b823567ffffffffffffffff808211156143b4578384fd5b818501915085601f8301126143c7578384fd5b81356143d5613f4782614cb9565b80828252602080830192508086018a8283870289010111156143f5578889fd5b8896505b8487101561441e5761440a81613ec3565b8452600196909601959281019281016143f9565b509096508701359350505080821115614435578283fd5b5061444285828601613f29565b9150509250929050565b6000806020838503121561445e578182fd5b823567ffffffffffffffff811115614474578283fd5b61448085828601613ee7565b90969095509350505050565b600080600080604085870312156144a1578182fd5b843567ffffffffffffffff808211156144b8578384fd5b6144c488838901613ee7565b909650945060208701359150808211156144dc578384fd5b506144e987828801613ee7565b95989497509550505050565b600060208284031215614506578081fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146125b8578182fd5b60008060208385031215614547578182fd5b823567ffffffffffffffff81111561455d578283fd5b61448085828601613f97565b60006080828403121561457a578081fd5b6040516080810181811067ffffffffffffffff8211171561459757fe5b6040526145a38361405c565b81526145b16020840161405c565b60208201526145c26040840161405c565b60408201526145d36060840161405c565b60608201529392505050565b6000602082840312156145f0578081fd5b5035919050565b60008060408385031215614609578182fd5b50508035926020909101359150565b60008284527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115614649578081fd5b6020830280836020870137939093016020019283525090919050565b805167ffffffffffffffff908116835260208083015182169084015260408083015182169084015260609182015116910152565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b73ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b818110156147225761470f838551614665565b92840192608092909201916001016146fc565b50909695505050505050565b600060408252614742604083018688614618565b8281036020840152614755818587614618565b979650505050505050565b6020808252825182820181905260009190848201906040850190845b818110156147225783518352928401929184019160010161477c565b901515815260200190565b6000602080835283518082850152825b818110156147cf578581018301518582016040015282016147b3565b818111156147e05783604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60208082526032908201527f536b79776561766572417373657473235f76616c69646174654d696e74733a2060408201527f464143544f52595f4e4f545f4143544956450000000000000000000000000000606082015260800190565b60208082526036908201527f536b79776561766572417373657473237365744d617849737375616e6365733a60408201527f20494e56414c49445f4152524159535f4c454e47544800000000000000000000606082015260800190565b60208082526012908201527f554e535550504f525445445f4d4554484f440000000000000000000000000000604082015260600190565b60208082526030908201527f536b79776561766572417373657473236164644d696e745065726d697373696f60408201527f6e3a20494e56414c49445f52414e474500000000000000000000000000000000606082015260800190565b6020808252602f908201527f536b79776561766572417373657473235f76616c69646174654d696e74733a2060408201527f49445f4f55545f4f465f52414e47450000000000000000000000000000000000606082015260800190565b6020808252602a908201527f4f776e61626c65237472616e736665724f776e6572736869703a20494e56414c60408201527f49445f4144445245535300000000000000000000000000000000000000000000606082015260800190565b6020808252603c908201527f536b79776561766572417373657473236164644d696e745065726d697373696f60408201527f6e3a204f5645524c41505f574954485f4c4f434b45445f52414e474500000000606082015260800190565b6020808252602d908201527f536b79776561766572417373657473236164644d696e745065726d697373696f60408201527f6e3a204e554c4c5f52414e474500000000000000000000000000000000000000606082015260800190565b60208082526039908201527f536b79776561766572417373657473237365744d617849737375616e6365733a60408201527f20494e56414c49445f4e45575f4d41585f49535355414e434500000000000000606082015260800190565b60208082526049908201527f536b79776561766572417373657473236164644d696e745065726d697373696f60408201527f6e3a2053544152545f54494d455f49535f4e4f545f4c45535345525f5448454e60608201527f5f454e445f54494d450000000000000000000000000000000000000000000000608082015260a00190565b60208082526026908201527f4f776e61626c65236f6e6c794f776e65723a2053454e4445525f49535f4e4f5460408201527f5f4f574e45520000000000000000000000000000000000000000000000000000606082015260800190565b60208082526035908201527f536b79776561766572417373657473235f76616c69646174654d696e74733a2060408201527f4d41585f49535355414e43455f45584345454445440000000000000000000000606082015260800190565b608081016105758284614665565b90815260200190565b918252602082015260400190565b60405181810167ffffffffffffffff81118282101715614cb157fe5b604052919050565b600067ffffffffffffffff821115614ccd57fe5b506020908102019056fe455243313135355061636b656442616c616e63652362616c616e63654f6642617463683a20494e56414c49445f41525241595f4c454e475448455243313135355061636b656442616c616e6365237361666542617463685472616e7366657246726f6d3a20494e56414c49445f524543495049454e54455243313135355061636b656442616c616e6365235f7669657755706461746542696e56616c75653a20554e444552464c4f57455243313135355061636b656442616c616e636523736166655472616e7366657246726f6d3a20494e56414c49445f4f50455241544f52455243313135355061636b656442616c616e6365235f7361666542617463685472616e7366657246726f6d3a20494e56414c49445f4152524159535f4c454e475448455243313135355061636b656442616c616e6365235f63616c6c6f6e45524331313535426174636852656365697665643a20494e56414c49445f4f4e5f524543454956455f4d455353414745455243313135355061636b656442616c616e6365237361666542617463685472616e7366657246726f6d3a20494e56414c49445f4f50455241544f5245524332393831476c6f62616c235f736574476c6f62616c526f79616c74793a20524543495049454e545f49535f307830455243313135354d696e744275726e5061636b656442616c616e63652362617463684275726e3a20494e56414c49445f4152524159535f4c454e475448455243313135355061636b656442616c616e6365235f7361666542617463685472616e7366657246726f6d3a20554e444552464c4f5745524332393831476c6f62616c235f736574476c6f62616c526f79616c74793a204645455f49535f41424f56455f3130305f50455243454e54455243313135355061636b656442616c616e6365235f63616c6c6f6e4552433131353552656365697665643a20494e56414c49445f4f4e5f524543454956455f4d455353414745455243313135355061636b656442616c616e636523736166655472616e7366657246726f6d3a20494e56414c49445f524543495049454e54455243313135355061636b656442616c616e6365235f7669657755706461746542696e56616c75653a20494e56414c49445f42494e5f57524954455f4f5045524154494f4e455243313135354d696e744275726e5061636b656442616c616e6365235f62617463684d696e743a20494e56414c49445f4152524159535f4c454e475448455243313135355061636b656442616c616e6365235f7669657755706461746542696e56616c75653a204f564552464c4f57a2646970667358221220fb1372790e40e3e548bbc115377592682a7efd66fc87555aa190c17a7e2027e864736f6c63430007040033

Deployed Bytecode Sourcemap

802:16008:25:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8925:28;;;;;;;;;;:::i;:::-;;;;;;;;9699:261:10;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;16607:201:25;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;476:18:7:-;;;:::i;:::-;;;;;;;:::i;3968:1055:25:-;;;;;;:::i;:::-;;:::i;:::-;;999:147:7;;;;;;:::i;:::-;;:::i;7368:692:25:-;;;;;;:::i;:::-;;:::i;15497:146::-;;;;;;:::i;:::-;;:::i;1737:262:11:-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;3444:547:10:-;;;;;;:::i;:::-;;:::i;5272:859:25:-;;;;;;:::i;:::-;;:::i;10318:1013:10:-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;14675:101:25:-;;;:::i;:::-;;;;;;;:::i;451:21:7:-;;;:::i;10147:367:25:-;;;;;;:::i;:::-;;:::i;3363:144::-;;;;;;:::i;:::-;;:::i;15890:137::-;;;;;;:::i;:::-;;:::i;1280:73:27:-;;;:::i;:::-;;;;;;;:::i;3092:145:25:-;;;;;;:::i;:::-;;:::i;8529:163::-;;;;;;:::i;:::-;;:::i;8707:230:10:-;;;;;;:::i;:::-;;:::i;14469:138:25:-;;;;;;:::i;:::-;;:::i;6779:145::-;;;;;;:::i;:::-;;:::i;15141:110::-;;;;;;:::i;:::-;;:::i;9563:313::-;;;;;;:::i;:::-;;:::i;513:32:11:-;;;:::i;16177:98:25:-;;;;;;:::i;:::-;;:::i;14001:189:10:-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;13143:352:25:-;;;;;;:::i;:::-;;:::i;13838:372::-;;;;;;:::i;:::-;;:::i;9199:160:10:-;;;;;;:::i;:::-;;:::i;14447:432::-;;;;;;:::i;:::-;;:::i;2360:598::-;;;;;;:::i;:::-;;:::i;993:224:27:-;;;;;;:::i;:::-;;:::i;14282:116:25:-;;;;;;:::i;:::-;;:::i;9699:261:10:-;9781:7;9798:11;9815:13;9881:18;9895:3;9881:13;:18::i;:::-;9926:16;;;:8;:16;;;;;;;;;;;:21;;;;;;;;;9866:33;;-1:-1:-1;9866:33:10;-1:-1:-1;9912:43:10;;9866:33;9912:13;:43::i;:::-;9905:50;;;;9699:261;;;;;:::o;16607:201:25:-;16747:4;16766:37;16790:12;16766:23;:37::i;:::-;16759:44;;16607:201;;;;:::o;476:18:7:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;3968:1055:25:-;802:5:27;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;4132:1:25::1;4120:9;:13;;;4112:71;;;;;;;;;;;;:::i;:::-;4210:9;4197:22;;:9;:22;;;;4189:83;;;;;;;;;;;;:::i;:::-;4299:8;4286:21;;:10;:21;;;4278:107;;;;;;;;;;;;:::i;:::-;4510:9;4505:286;4529:12;:19:::0;4525:23;::::1;4505:286;;;4563:30;;:::i;:::-;4596:12;4609:1;4596:15;;;;;;;;;::::0;;;::::1;::::0;;;;4563:48:::1;::::0;;::::1;::::0;::::1;::::0;;4596:15;;;::::1;4563:48:::0;::::1;::::0;;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;::::1;::::0;;;;;;::::1;::::0;::::1;::::0;;;;;;;;;::::1;::::0;::::1;::::0;;;;;-1:-1:-1;4637:30:25;::::1;;::::0;4636:68:::1;;;4694:9;4673:30;;:12;:18;;;:30;;;4636:68;4619:165;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;4550:3:25::1;;4505:286;;;;4847:23;;:::i;:::-;-1:-1:-1::0;4873:54:25::1;::::0;;::::1;::::0;::::1;::::0;;::::1;::::0;;::::1;::::0;;;;::::1;;::::0;;::::1;::::0;;;;;::::1;::::0;;;;;;;;::::1;::::0;;;;;;4933:26:::1;::::0;::::1;-1:-1:-1::0;4933:26:25;;;:16:::1;:26:::0;;;;;:38;;::::1;::::0;::::1;::::0;;;;;;;;;;;::::1;::::0;;;;;;;;;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;::::1;;::::0;;;4982:36;;4873:54;;4933:26;4982:36:::1;::::0;::::1;::::0;4873:54;;4982:36:::1;:::i;:::-;;;;;;;;856:1:27;3968:1055:25::0;;;;;:::o;999:147:7:-;1055:13;1107:7;1116:14;1126:3;1116:9;:14::i;:::-;1090:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1090:50:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1090:50:7;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;999:147:7:o;7368:692:25:-;802:5:27;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;7490:38:25;;::::1;7482:105;;;;;;;;;;;;:::i;:::-;7681:9;7676:325;7696:15:::0;;::::1;7676:325;;;7754:1;7731:11;:20;7743:4;;7748:1;7743:7;;;;;;;;;;;;;7731:20;;;;;;;;;;;;:24;7727:218;;;7790:16;;7807:1;7790:19;;;;;;;;;;;;;7786:1;:23;:69;;;;;7835:11;:20;7847:4;;7852:1;7847:7;;;;;;;;;;;;;7835:20;;;;;;;;;;;;7813:16;;7830:1;7813:19;;;;;;;;;;;;;:42;7786:69;7767:169;;;;;;;;;;;;:::i;:::-;7975:16;;7992:1;7975:19;;;;;;;;;;;;;7952:11;:20;7964:4;;7969:1;7964:7;;;;;;;;::::0;;::::1;::::0;;;::::1;;7952:20:::0;;-1:-1:-1;7952:20:25;::::1;::::0;;;;;;-1:-1:-1;7952:20:25;:42;7713:3:::1;;7676:325;;;;8012:43;8032:4;;8038:16;;8012:43;;;;;;;;;:::i;:::-;;;;;;;;7368:692:::0;;;;:::o;15497:146::-;15600:38;15611:10;15623:4;;15600:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;15600:38:25;;;;;;;;;;;;;;;;;;;;-1:-1:-1;15629:8:25;;-1:-1:-1;15629:8:25;;;;15600:38;;;15629:8;;15600:38;15629:8;15600:38;;;;;;;;;-1:-1:-1;15600:10:25;;-1:-1:-1;;;15600:38:25:i;:::-;15497:146;;;;:::o;1737:262:11:-;1831:16;1849:21;1881:19;;:::i;:::-;-1:-1:-1;1881:39:11;;;;;;;;;1903:17;1881:39;;;;;;;;;;;;;;1949:44;;1988:4;;1949:34;;:9;;:13;:34::i;:::-;:38;;:44::i;:::-;1926:68;;;;;1737:262;;;;;;:::o;3444:547:10:-;3630:10;:19;;;;;3629:60;;;3654:35;3671:5;3678:10;3654:16;:35::i;:::-;3621:133;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3768:17;;;3760:90;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3857:50;3880:5;3887:3;3892:4;3898:8;3857:22;:50::i;:::-;3913:73;3941:5;3948:3;3953:4;3959:8;3969:9;3980:5;3913:27;:73::i;:::-;3444:547;;;;;:::o;5272:859:25:-;802:5:27;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;5518:26:25::1;::::0;::::1;5497:18;5518:26:::0;;;:16:::1;:26;::::0;;;;:33;:37;;5617:33:::1;;:::i;:::-;5653:26;::::0;::::1;;::::0;;;:16:::1;:26;::::0;;;;:39;;5680:11;;5653:39;::::1;;;;;;::::0;;;::::1;::::0;;;;5617:75:::1;::::0;;::::1;::::0;::::1;::::0;;5653:39;;;::::1;5617:75:::0;::::1;::::0;;::::1;::::0;;;;::::1;::::0;::::1;::::0;;::::1;::::0;;;;;;::::1;::::0;::::1;::::0;;;;;;;;;::::1;::::0;;::::1;::::0;;;;;-1:-1:-1;5721:25:25;;::::1;5717:272;;5756:28;;:::i;:::-;5787:26;::::0;::::1;;::::0;;;:16:::1;:26;::::0;;;;:38;;5814:10;;5787:38;::::1;;;;;;::::0;;;::::1;::::0;;;5756:69:::1;::::0;;::::1;::::0;::::1;::::0;;5787:38;;;::::1;5756:69:::0;::::1;::::0;;::::1;::::0;;;;::::1;::::0;::::1;::::0;;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;;;;::::1;;::::0;;;;5874:26:::1;::::0;::::1;::::0;;5756:69:::1;5874:26:::0;;;;;:39;;5756:69;;-1:-1:-1;5756:69:25;;5901:11;;5874:39;::::1;;;;;;::::0;;;::::1;::::0;;;;:52;;:39;::::1;:52:::0;;;;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;;;;::::1;;::::0;;::::1;;::::0;::::1;::::0;;;::::1;::::0;;;::::1;;::::0;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;::::1;;;::::0;;-1:-1:-1;5717:272:25::1;6035:26;::::0;::::1;;::::0;;;:16:::1;:26;::::0;;;;:32;;;::::1;;;;;::::0;;;::::1;::::0;;;;;;;;;;;;;;;6078:48:::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;6110:15;;6078:48:::1;:::i;:::-;;;;;;;;856:1:27;;5272:859:25::0;;:::o;10318:1013:10:-;10470:14;;10510:11;;10425:16;;10470:14;10498:23;;10490:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10611:11;10624:13;10641:22;10655:4;10660:1;10655:7;;;;;;;;;;;;;;10641:13;:22::i;:::-;10610:53;;;;10669:19;10691:8;:20;10700:7;10708:1;10700:10;;;;;;;;;;;;;;10691:20;;;;;;;;;;;;;;;:25;10712:3;10691:25;;;;;;;;;;;;10669:47;;10722:16;10741:3;10722:22;;10773:30;10820:8;10806:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10806:23:10;;10773:56;;10854:33;10868:11;10881:5;10854:13;:33::i;:::-;10835:13;10849:1;10835:16;;;;;;;;;;;;;;;;;:52;10955:1;10938:362;10962:8;10958:1;:12;10938:362;;;11000:22;11014:4;11019:1;11014:7;;;;;;;11000:22;10985:37;;-1:-1:-1;10985:37:10;-1:-1:-1;11104:15:10;;;;;:45;;;11139:7;11147:1;11139:10;;;;;;;;;;;;;;11123:26;;:7;11133:1;11131;:3;11123:12;;;;;;;;;;;;;;:26;;;;11104:45;11100:133;;;11175:8;:20;11184:7;11192:1;11184:10;;;;;;;;;;;;;;11175:20;;;;;;;;;;;;;;;:25;11196:3;11175:25;;;;;;;;;;;;11161:39;;11221:3;11210:14;;11100:133;11260:33;11274:11;11287:5;11260:13;:33::i;:::-;11241:13;11255:1;11241:16;;;;;;;;;;;;;;;;;:52;10972:3;;10938:362;;;-1:-1:-1;11313:13:10;10318:1013;-1:-1:-1;;;;;;;;10318:1013:10:o;14675:101:25:-;14725:19;14759:12;14752:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14675:101;:::o;451:21:7:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10147:367:25;10303:16;;;10317:1;10303:16;;;;;;;;;10280:20;;10303:16;;;;;;;;;-1:-1:-1;;10352:16:25;;;10366:1;10352:16;;;;;;;;;10280:39;;-1:-1:-1;10325:24:25;;10352:16;-1:-1:-1;10352:16:25;;;;;;;;;;;-1:-1:-1;10352:16:25;10325:43;;10383:3;10374;10378:1;10374:6;;;;;;;;;;;;;:12;;;;;10405:7;10392;10400:1;10392:10;;;;;;;;;;;;;:20;;;;;10444:28;10459:3;10464:7;10444:14;:28::i;:::-;10478:31;10484:3;10489;10494:7;10503:5;;10478:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10478:5:25;;-1:-1:-1;;;10478:31:25:i;:::-;10147:367;;;;;;;:::o;3363:144::-;802:5:27;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;3433:25:25::1;::::0;::::1;3461:5;3433:25:::0;;;:15:::1;:25;::::0;;;;;:33;;;::::1;::::0;;3477:25;::::1;::::0;3461:5;3477:25:::1;3363:144:::0;:::o;15890:137::-;802:5:27;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;15982:40:25::1;16002:19;;15982:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;15982:19:25::1;::::0;-1:-1:-1;;;15982:40:25:i:1;:::-;15890:137:::0;;:::o;1280:73:27:-;1343:5;;;;1280:73;:::o;3092:145:25:-;802:5:27;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;3162:25:25::1;::::0;::::1;;::::0;;;:15:::1;:25;::::0;;;;;:32;;;::::1;3190:4;3162:32;::::0;;3205:27;::::1;::::0;3162:25;3205:27:::1;3092:145:::0;:::o;8529:163::-;802:5:27;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;8634:53:25::1;8656:9;8667:19;8634:21;:53::i;8707:230:10:-:0;8839:10;8829:21;;;;:9;:21;;;;;;;;;:32;;;;;;;;;;;;:44;;;;;;;;;;;;;8884:48;;;;;;;8829:32;;8839:10;8884:48;;;;;;;;;;;8707:230;;:::o;14469:138:25:-;14576:26;;;;;;;:16;:26;;;;;;;;14569:33;;;;;;;;;;;;;;;;;14542:19;;14569:33;;14576:26;;14569:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14469:138;;;:::o;6779:145::-;802:5:27;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;6864:12:25::1;:25:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;6864:25:25;;;;;;;;;::::1;::::0;;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;::::0;::::1;::::0;;;;::::1;;::::0;;::::1;;::::0;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;::::1;;::::0;;6900:19;::::1;::::0;::::1;::::0;6864:25;;6900:19:::1;:::i;:::-;;;;;;;;6779:145:::0;:::o;15141:110::-;15215:31;15221:10;15233:3;15238:7;15215:5;:31::i;9563:313::-;9733:30;9748:4;9754:8;9733:14;:30::i;:::-;9833:38;9844:3;9849:4;9855:8;9865:5;9833:10;:38::i;513:32:11:-;;;;;;;;;;;:::o;16177:98:25:-;802:5:27;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;16251:19:25::1;16260:9;;16251:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;16251:8:25::1;::::0;-1:-1:-1;;;16251:19:25:i:1;14001:189:10:-:0;1505:19;14104:21;;;14139;;;;;14001:189::o;13143:352:25:-;13216:16;13255:4;13216:16;13255:4;13305:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;13305:19:25;;13272:52;;13380:9;13375:89;13399:4;13395:1;:8;13375:89;;;13437:11;:20;13449:4;;13454:1;13449:7;;;;;;;;;;;;;13437:20;;;;;;;;;;;;13418:13;13432:1;13418:16;;;;;;;;;;;;;;;;;:39;13405:3;;13375:89;;;-1:-1:-1;13477:13:25;13143:352;-1:-1:-1;;;;13143:352:25:o;13838:372::-;13915:16;13954:4;13915:16;13954:4;14008:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;14008:19:25;;13971:56;;14083:9;14078:97;14102:4;14098:1;:8;14078:97;;;14144:15;:24;14160:4;;14165:1;14160:7;;;;;;;;;;;;;14144:24;;;;;;;;;;;;14121:17;14139:1;14121:20;;;;;;;;;;;;;;;;;:47;14108:3;;14078:97;;9199:160:10;9326:17;;;;9294:15;9326:17;;;:9;:17;;;;;;;;:28;;;;;;;;;;;;;;;9199:160::o;14447:432::-;1395:2;14806:22;;14842:24;;;14725:33;14841;14447:432;;;;:::o;2360:598::-;2521:10;:19;;;;;2520:60;;;2545:35;2562:5;2569:10;2545:16;:35::i;:::-;2512:128;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2654:17;;;2646:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2838:43;2856:5;2863:3;2868;2873:7;2838:17;:43::i;:::-;2887:66;2910:5;2917:3;2922;2927:7;2936:9;2947:5;2887:22;:66::i;993:224:27:-;802:5;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;1070:23:::1;::::0;::::1;1062:78;;;;;;;;;;;;:::i;:::-;1146:5;:17:::0;;;::::1;;::::0;;::::1;::::0;;::::1;::::0;;;;1174:38:::1;::::0;1146:17;;1195:5:::1;::::0;1174:38:::1;::::0;-1:-1:-1;;1174:38:27::1;993:224:::0;:::o;14282:116:25:-;14368:25;;14349:4;14368:25;;;:15;:25;;;;;;;;;14282:116::o;2336:243:11:-;2439:4;2455:42;;;2471:26;2455:42;2451:74;;;-1:-1:-1;2514:4:11;2507:11;;2451:74;2537:37;2561:12;2537:23;:37::i;2843:513:7:-;2897:27;2936:7;2932:38;;-1:-1:-1;2953:10:7;;;;;;;;;;;;;;;;;;;2932:38;2988:2;;2976:9;3062:50;3069:6;;3062:50;;3085:5;;3103:2;3098:7;;;;3062:50;;;3118:17;3148:3;3138:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3138:14:7;-1:-1:-1;3118:34:7;-1:-1:-1;3170:7:7;;;3217:84;3224:7;;3217:84;;3274:2;3269;:7;3264:2;:12;3253:25;;3241:4;3246:3;;;;;;;3241:9;;;;;;;;;;;:37;;;;;;;;;;-1:-1:-1;3292:2:7;3286:8;;;;3217:84;;;-1:-1:-1;3346:4:7;2843:513;-1:-1:-1;;;;;2843:513:7:o;4124:589:9:-;4282:11;;4316:15;;4307:24;;4299:98;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4438:9;4433:173;4457:5;4453:1;:9;4433:173;;;4509:63;4526:5;4535:4;4540:1;4535:7;;;;;;;;;;;;;;4544:8;4553:1;4544:11;;;;;;;;;;;;;;4557:14;4509:16;:63::i;:::-;4464:3;;4433:173;;;;4687:3;4646:62;;4672:5;4646:62;;4660:10;4646:62;;;4693:4;4699:8;4646:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4124:589;;;;:::o;224:407:14:-;282:7;506:6;502:35;;-1:-1:-1;529:1:14;522:8;;502:35;555:5;;;559:1;555;:5;:1;574:5;;;;;:10;566:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;625:1;224:407;-1:-1:-1;;;224:407:14:o;753:308::-;811:7;900:1;896;:5;888:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;942:9;958:1;954;:5;;;;;;;753:308;-1:-1:-1;;;;753:308:14:o;5742:1939:10:-;5893:11;;5964:15;;5951:28;;5943:107;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6070:3;6061:12;;:5;:12;;;;:29;;;;;6089:1;6077:9;:13;6061:29;6057:1537;;;6169:11;6182:13;6199:22;6213:4;6218:1;6213:7;;;;;;;6199:22;6345:15;;;6307;6345;;;;;;;;;;;:20;;;;;;;;;6374:11;;6168:53;;-1:-1:-1;6168:53:10;;-1:-1:-1;6307:15:10;6325:77;;6345:20;6168:53;;6374:8;;6307:15;;6374:11;;;;;;;;;;6387:14;6325:19;:77::i;:::-;6446:13;;;6410;6446;;;;;;;;;;;:18;;;;;;;;;6473:11;;6307:95;;-1:-1:-1;6410:13:10;;6426:75;;6446:18;6466:5;;6473:8;;6410:13;;6473:11;;;;;;;;;;6486:14;6426:19;:75::i;:::-;6410:91;-1:-1:-1;6554:3:10;6583:1;6566:649;6590:9;6586:1;:13;6566:649;;;6631:22;6645:4;6650:1;6645:7;;;;;;;6631:22;6616:37;;-1:-1:-1;6616:37:10;-1:-1:-1;6690:14:10;;;6686:323;;6770:15;;;;:8;:15;;;;;;;;;;;:24;;;;;;;;;:34;;;;6816:13;;;;;;;;;;;:22;;;;;;;;;:30;;;;6869:20;;;;;;;;;;6909:18;;;;;;;;;;6869:20;;6686:323;7062:64;7082:7;7091:5;7098:8;7107:1;7098:11;;;;;;;7062:64;7052:74;;7144:62;7164:5;7171;7178:8;7187:1;7178:11;;;;;;;7144:62;7136:70;-1:-1:-1;6601:3:10;;6566:649;;;-1:-1:-1;;7271:15:10;;;;:8;:15;;;;;;;;;;;:20;;;;;;;;:30;;;;7309:13;;;;;;;;;;;:18;;;;;;;;:26;;;;-1:-1:-1;6057:1537:10;;;7427:9;7422:166;7446:9;7442:1;:13;7422:166;;;7509:8;7518:1;7509:11;;;;;;;;;;;;;;7480:25;7490:5;7497:4;7502:1;7497:7;;;;;;;;;;;;;;7480:9;:25::i;:::-;:40;;7472:107;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7457:3;;7422:166;;;;6057:1537;7656:3;7623:53;;7649:5;7623:53;;7637:10;7623:53;;;7661:4;7667:8;7623:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5742:1939;;;;;:::o;7794:516::-;8015:16;:3;:14;;;:16::i;:::-;8011:295;;;8041:13;8079:3;8057:49;;;8112:9;8123:10;8135:5;8142:4;8148:8;8158:5;8057:107;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8057:107:10;;-1:-1:-1;8180:38:10;;;8190:28;8180:38;8172:127;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8011:295;7794:516;;;;;;:::o;11084:1593:25:-;11197:10;11181:27;;;;:15;:27;;;;;;;;11173:90;;;;;;;;;;;;:::i;:::-;11335:10;11299:16;11318:28;;;:16;:28;;;;;:35;11396:23;;:::i;:::-;11439:10;11422:28;;;;:16;:28;;;;;:31;;:28;;;:31;;;;;;;;;;;;11396:57;;;;;;;;11422:31;;;;11396:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11422:31:25;11596:1077;11620:4;:11;11616:1;:15;11596:1077;;;11646:10;11659:4;11664:1;11659:7;;;;;;;;;;;;;;11646:20;;11674:14;11691:8;11700:1;11691:11;;;;;;;;;;;;;;11674:28;;11710:20;11733:11;:15;11745:2;11733:15;;;;;;;;;;;;11710:38;;11965:384;11990:5;:15;;;11972:33;;:15;:33;:68;;;;12027:5;:13;;;12009:31;;:15;:31;11972:68;:88;;;-1:-1:-1;12049:11:25;;12044:16;;;;11972:88;:108;;;;12078:2;12064:5;:11;;;:16;;;11972:108;11965:384;;;12107:1;12092:16;;;;12221:8;12207:11;:22;12199:82;;;;;;;;;;;;:::i;:::-;12316:10;12299:28;;;;:16;:28;;;;;:41;;12328:11;;12299:41;;;;;;;;;;;;;;;12291:49;;;;;;;;12299:41;;;;12291:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11965:384:25;;;12404:16;;12400:267;;12432:28;12463:19;;;:15;:19;;;;;;:31;;12487:6;12463:23;:31::i;:::-;12432:62;;12536:12;12512:20;:36;;12504:102;;;;;;;;;;;;:::i;:::-;12616:19;;;;:15;:19;;;;;:42;12400:267;-1:-1:-1;;;11633:3:25;;11596:1077;;727:428:9;844:53;861:3;868;873:7;882:14;844:16;:53::i;:::-;954:59;;;;;;;;;;;;;;;;;;989:3;;969:10;;954:59;;;;;;;;;;;1077:73;1108:3;1114;1119;1124:7;1133:9;1144:5;1077:22;:73::i;1861:113:7:-;1940:29;;;;:7;;:29;;;;;:::i;884:393:11:-;986:25;;;978:87;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1102:4;1079:19;:27;;1071:97;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1174:17;:38;;;;;;;;;;;;;;;;1218:32;:54;884:393::o;3306:255:9:-;3412:53;3429:5;3436:3;3441:7;3450:14;3412:16;:53::i;:::-;3495:61;;;;;;;;;;;;;;3537:3;;3495:61;;;;3510:10;;3495:61;;;;;;;;;;;3306:255;;;:::o;1449:1512::-;1596:8;:15;1581:4;:11;:30;1573:105;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1689:11;;:15;1685:1036;;1783:11;1796:13;1813:22;1827:4;1832:1;1827:7;;;;;;;1813:22;1957:13;;;1921;1957;;;;;;;;;;;:18;;;;;;;;;1984:11;;1782:53;;-1:-1:-1;1782:53:9;;-1:-1:-1;1921:13:9;1937:75;;1957:18;1782:53;;1984:8;;1921:13;;1984:11;;;1937:75;2080:11;;1921:91;;-1:-1:-1;2144:3:9;2173:1;2156:476;2180:9;2176:1;:13;2156:476;;;2221:22;2235:4;2240:1;2235:7;;;;;;;2221:22;2206:37;;-1:-1:-1;2206:37:9;-1:-1:-1;2280:14:9;;;2276:234;;2360:13;;;:8;:13;;;;;;;;;;;:22;;;;;;;;;:30;;;;2410:18;;;;;;;;;2276:234;2561:62;2581:5;2588;2595:8;2604:1;2595:11;;;;;;;2561:62;2553:70;-1:-1:-1;2191:3:9;;2156:476;;;-1:-1:-1;;;2688:13:9;;;:8;:13;;;;;;;;;;;:18;;;;;;;;;;:26;;;;-1:-1:-1;1685:1036:9;2792:3;2752:60;;2786:3;2752:60;;2766:10;2752:60;;;2797:4;2803:8;2752:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2876:80;2912:3;2918;2923:4;2929:8;2939:9;2950:5;2876:27;:80::i;1421:311:7:-;1506:7;1482:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:21;;:31;;1506:7;;1482:31;;1506:7;1482:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1519:22;1553:9;1548:180;1572:9;:16;1568:1;:20;1548:180;;;1638:7;1647:23;1657:9;1667:1;1657:12;;;;;;;;;;;;;;1647:9;:23::i;:::-;1621:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1621:59:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1603:78;;1708:9;1718:1;1708:12;;;;;;;;;;;;;;1694:27;1698:8;1694:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1590:3;;1548:180;;4381:385:10;4509:53;4526:5;4533:3;4538:7;4547:14;4509:16;:53::i;:::-;4599;4616:3;4623;4628:7;4637:14;4599:16;:53::i;:::-;4743:3;4709:52;;4736:5;4709:52;;4724:10;4709:52;;;4748:3;4753:7;4709:52;;;;;;;;;;;;;;;;;;;;;;;;4381:385;;;;:::o;4874:468::-;5066:16;:3;:14;;;:16::i;:::-;5062:276;;;5092:13;5130:3;5108:44;;;5157:9;5168:10;5180:5;5187:3;5192:7;5201:5;5108:99;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5108:99:10;;-1:-1:-1;5223:32:10;;;5233:22;5223:32;5215:116;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2379:234:7;2465:4;2481:50;;;2497:34;2481:50;2477:82;;;-1:-1:-1;2548:4:7;2541:11;;2477:82;2571:37;2595:12;2571:23;:37::i;11845:352:10:-;11963:11;11980:13;12047:18;12061:3;12047:13;:18::i;:::-;12140;;;:8;:18;;;;;;;;;;;:23;;;;;;;;;12032:33;;-1:-1:-1;12032:33:10;-1:-1:-1;12120:72:10;;12032:33;12172:7;12181:10;12120:19;:72::i;:::-;12094:18;;;;:8;:18;;;;;;;;;;;:23;;;;;;;;;;:98;;;;-1:-1:-1;;;;11845:352:10:o;12664:1162::-;12796:20;1395:2;12842:22;;12885:33;12796:20;12929:10;:28;;;;;;;;;12925:871;;;12996:16;;;12982:31;;;-1:-1:-1;13029:26:10;;;;13021:89;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13178:16;13137:19;;;13136:28;;13135:40;;:59;13118:181;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12925:871;;;13331:14;13317:10;:28;;;;;;;;;13313:483;;;13384:16;;;13370:31;;;-1:-1:-1;13417:26:10;;;;13409:90;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13558:7;13549:4;13540:5;13526:10;:19;;13525:28;13524:41;;13507:164;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13313:483;13693:79;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13313:483;13802:19;;12664:1162;;;;;;:::o;541:398:12:-;602:4;854:21;;890:15;;;;;:43;;-1:-1:-1;206:66:12;909:24;;;882:52;-1:-1:-1;;541:398:12:o;1419:158:14:-;1477:7;1504:5;;;1523:6;;;;1515:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15216:243:10;15319:4;15335:42;;;15351:26;15335:42;15331:74;;;-1:-1:-1;15394:4:10;15387:11;;15331:74;427:31:13;411:47;;;;15417:37:10;306:157:13:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:198:29;84:20;;144:42;133:54;;123:65;;113:2;;202:1;199;192:12;217:400;;;350:3;343:4;335:6;331:17;327:27;317:2;;373:6;365;358:22;317:2;-1:-1:-1;401:20:29;;444:18;433:30;;430:2;;;483:8;473;466:26;430:2;527:4;519:6;515:17;503:29;;590:3;583:4;575;567:6;563:17;555:6;551:30;547:41;544:50;541:2;;;607:1;604;597:12;622:692;;735:3;728:4;720:6;716:17;712:27;702:2;;757:5;750;743:20;702:2;801:6;788:20;826:69;841:53;887:6;841:53;:::i;:::-;826:69;:::i;:::-;929:21;;;817:78;-1:-1:-1;969:4:29;989:14;;;;1023:15;;;1069;;;1057:28;;1053:37;;1050:46;-1:-1:-1;1047:2:29;;;1109:1;1106;1099:12;1047:2;1131:1;1141:167;1155:6;1152:1;1149:13;1141:167;;;1216:17;;1204:30;;1254:12;;;;1286;;;;1177:1;1170:9;1141:167;;;1145:3;;;;;692:622;;;;:::o;1319:377::-;;;1436:3;1429:4;1421:6;1417:17;1413:27;1403:2;;1461:8;1451;1444:26;1403:2;-1:-1:-1;1491:20:29;;1534:18;1523:30;;1520:2;;;1573:8;1563;1556:26;1520:2;1617:4;1609:6;1605:17;1593:29;;1669:3;1662:4;1653:6;1645;1641:19;1637:30;1634:39;1631:2;;;1686:1;1683;1676:12;1701:580;;1798:3;1791:4;1783:6;1779:17;1775:27;1765:2;;1820:5;1813;1806:20;1765:2;1864:6;1851:20;1894:18;1886:6;1883:30;1880:2;;;1916:9;1880:2;1945:117;2056:4;1987:66;1980:4;1972:6;1968:17;1964:90;1960:101;1945:117;:::i;:::-;1936:126;;2085:6;2078:5;2071:21;2139:3;2132:4;2123:6;2115;2111:19;2107:30;2104:39;2101:2;;;2156:1;2153;2146:12;2101:2;2219:6;2212:4;2204:6;2200:17;2193:4;2186:5;2182:16;2169:57;2273:1;2246:18;;;2266:4;2242:29;2235:40;2250:5;1755:526;-1:-1:-1;;1755:526:29:o;2286:173::-;2355:20;;2415:18;2404:30;;2394:41;;2384:2;;2449:1;2446;2439:12;2464:198;;2576:2;2564:9;2555:7;2551:23;2547:32;2544:2;;;2597:6;2589;2582:22;2544:2;2625:31;2646:9;2625:31;:::i;2667:274::-;;;2796:2;2784:9;2775:7;2771:23;2767:32;2764:2;;;2817:6;2809;2802:22;2764:2;2845:31;2866:9;2845:31;:::i;:::-;2835:41;;2895:40;2931:2;2920:9;2916:18;2895:40;:::i;:::-;2885:50;;2754:187;;;;;:::o;2946:1001::-;;;;;;3185:3;3173:9;3164:7;3160:23;3156:33;3153:2;;;3207:6;3199;3192:22;3153:2;3235:31;3256:9;3235:31;:::i;:::-;3225:41;;3285:40;3321:2;3310:9;3306:18;3285:40;:::i;:::-;3275:50;;3376:2;3365:9;3361:18;3348:32;3399:18;3440:2;3432:6;3429:14;3426:2;;;3461:6;3453;3446:22;3426:2;3489:67;3548:7;3539:6;3528:9;3524:22;3489:67;:::i;:::-;3479:77;;3609:2;3598:9;3594:18;3581:32;3565:48;;3638:2;3628:8;3625:16;3622:2;;;3659:6;3651;3644:22;3622:2;3687:69;3748:7;3737:8;3726:9;3722:24;3687:69;:::i;:::-;3677:79;;3809:3;3798:9;3794:19;3781:33;3765:49;;3839:2;3829:8;3826:16;3823:2;;;3860:6;3852;3845:22;3823:2;;3888:53;3933:7;3922:8;3911:9;3907:24;3888:53;:::i;:::-;3878:63;;;3143:804;;;;;;;;:::o;3952:632::-;;;;;;4141:3;4129:9;4120:7;4116:23;4112:33;4109:2;;;4163:6;4155;4148:22;4109:2;4191:31;4212:9;4191:31;:::i;:::-;4181:41;;4241:40;4277:2;4266:9;4262:18;4241:40;:::i;:::-;4231:50;;4328:2;4317:9;4313:18;4300:32;4290:42;;4379:2;4368:9;4364:18;4351:32;4341:42;;4434:3;4423:9;4419:19;4406:33;4462:18;4454:6;4451:30;4448:2;;;4499:6;4491;4484:22;4448:2;4527:51;4570:7;4561:6;4550:9;4546:22;4527:51;:::i;4589:924::-;;;;;4811:3;4799:9;4790:7;4786:23;4782:33;4779:2;;;4833:6;4825;4818:22;4779:2;4861:31;4882:9;4861:31;:::i;:::-;4851:41;;4943:2;4932:9;4928:18;4915:32;4966:18;5007:2;4999:6;4996:14;4993:2;;;5028:6;5020;5013:22;4993:2;5056:67;5115:7;5106:6;5095:9;5091:22;5056:67;:::i;:::-;5046:77;;5176:2;5165:9;5161:18;5148:32;5132:48;;5205:2;5195:8;5192:16;5189:2;;;5226:6;5218;5211:22;5189:2;5254:69;5315:7;5304:8;5293:9;5289:24;5254:69;:::i;:::-;5244:79;;5376:2;5365:9;5361:18;5348:32;5332:48;;5405:2;5395:8;5392:16;5389:2;;;5426:6;5418;5411:22;5389:2;;5454:53;5499:7;5488:8;5477:9;5473:24;5454:53;:::i;:::-;5444:63;;;4769:744;;;;;;;:::o;5518:369::-;;;5644:2;5632:9;5623:7;5619:23;5615:32;5612:2;;;5665:6;5657;5650:22;5612:2;5693:31;5714:9;5693:31;:::i;:::-;5683:41;;5774:2;5763:9;5759:18;5746:32;5821:5;5814:13;5807:21;5800:5;5797:32;5787:2;;5848:6;5840;5833:22;5787:2;5876:5;5866:15;;;5602:285;;;;;:::o;5892:266::-;;;6021:2;6009:9;6000:7;5996:23;5992:32;5989:2;;;6042:6;6034;6027:22;5989:2;6070:31;6091:9;6070:31;:::i;:::-;6060:41;6148:2;6133:18;;;;6120:32;;-1:-1:-1;;;5979:179:29:o;6163:644::-;;;;;;6345:3;6333:9;6324:7;6320:23;6316:33;6313:2;;;6367:6;6359;6352:22;6313:2;6395:31;6416:9;6395:31;:::i;:::-;6385:41;;6473:2;6462:9;6458:18;6445:32;6435:42;;6524:2;6513:9;6509:18;6496:32;6486:42;;6579:2;6568:9;6564:18;6551:32;6606:18;6598:6;6595:30;6592:2;;;6643:6;6635;6628:22;6592:2;6687:60;6739:7;6730:6;6719:9;6715:22;6687:60;:::i;:::-;6303:504;;;;-1:-1:-1;6303:504:29;;-1:-1:-1;6766:8:29;;6661:86;6303:504;-1:-1:-1;;;6303:504:29:o;6812:496::-;;;;;;6988:3;6976:9;6967:7;6963:23;6959:33;6956:2;;;7010:6;7002;6995:22;6956:2;7038:31;7059:9;7038:31;:::i;:::-;7028:41;;7088:39;7123:2;7112:9;7108:18;7088:39;:::i;:::-;7078:49;;7146:39;7181:2;7170:9;7166:18;7146:39;:::i;:::-;7136:49;;7204:39;7239:2;7228:9;7224:18;7204:39;:::i;:::-;7194:49;;7262:40;7297:3;7286:9;7282:19;7262:40;:::i;:::-;7252:50;;6946:362;;;;;;;;:::o;7313:1246::-;;;7492:2;7480:9;7471:7;7467:23;7463:32;7460:2;;;7513:6;7505;7498:22;7460:2;7558:9;7545:23;7587:18;7628:2;7620:6;7617:14;7614:2;;;7649:6;7641;7634:22;7614:2;7692:6;7681:9;7677:22;7667:32;;7737:7;7730:4;7726:2;7722:13;7718:27;7708:2;;7764:6;7756;7749:22;7708:2;7809;7796:16;7832:69;7847:53;7893:6;7847:53;:::i;7832:69::-;7923:3;7947:6;7942:3;7935:19;7973:4;8002:2;7997:3;7993:12;7986:19;;8033:2;8029;8025:11;8086:7;8081:2;8075;8067:6;8063:15;8059:2;8055:24;8051:33;8048:46;8045:2;;;8112:6;8104;8097:22;8045:2;8139:6;8130:15;;8154:175;8168:6;8165:1;8162:13;8154:175;;;8229:25;8250:3;8229:25;:::i;:::-;8217:38;;8190:1;8183:9;;;;;8275:12;;;;8307;;8154:175;;;-1:-1:-1;8348:5:29;;-1:-1:-1;8391:18:29;;8378:32;;-1:-1:-1;;;8422:16:29;;;8419:2;;;8456:6;8448;8441:22;8419:2;;8484:69;8545:7;8534:8;8523:9;8519:24;8484:69;:::i;:::-;8474:79;;;7450:1109;;;;;:::o;8564:463::-;;;8711:2;8699:9;8690:7;8686:23;8682:32;8679:2;;;8732:6;8724;8717:22;8679:2;8777:9;8764:23;8810:18;8802:6;8799:30;8796:2;;;8847:6;8839;8832:22;8796:2;8891:76;8959:7;8950:6;8939:9;8935:22;8891:76;:::i;:::-;8986:8;;8865:102;;-1:-1:-1;8669:358:29;-1:-1:-1;;;;8669:358:29:o;9032:815::-;;;;;9231:2;9219:9;9210:7;9206:23;9202:32;9199:2;;;9252:6;9244;9237:22;9199:2;9297:9;9284:23;9326:18;9367:2;9359:6;9356:14;9353:2;;;9388:6;9380;9373:22;9353:2;9432:76;9500:7;9491:6;9480:9;9476:22;9432:76;:::i;:::-;9527:8;;-1:-1:-1;9406:102:29;-1:-1:-1;9615:2:29;9600:18;;9587:32;;-1:-1:-1;9631:16:29;;;9628:2;;;9665:6;9657;9650:22;9628:2;;9709:78;9779:7;9768:8;9757:9;9753:24;9709:78;:::i;:::-;9189:658;;;;-1:-1:-1;9806:8:29;-1:-1:-1;;;;9189:658:29:o;9852:352::-;;9963:2;9951:9;9942:7;9938:23;9934:32;9931:2;;;9984:6;9976;9969:22;9931:2;10028:9;10015:23;10078:66;10071:5;10067:78;10060:5;10057:89;10047:2;;10165:6;10157;10150:22;10209:432;;;10341:2;10329:9;10320:7;10316:23;10312:32;10309:2;;;10362:6;10354;10347:22;10309:2;10407:9;10394:23;10440:18;10432:6;10429:30;10426:2;;;10477:6;10469;10462:22;10426:2;10521:60;10573:7;10564:6;10553:9;10549:22;10521:60;:::i;10646:670::-;;10786:3;10774:9;10765:7;10761:23;10757:33;10754:2;;;10808:6;10800;10793:22;10754:2;10846;10840:9;10888:3;10880:6;10876:16;10958:6;10946:10;10943:22;10922:18;10910:10;10907:34;10904:62;10901:2;;;10969:9;10901:2;10996;10989:22;11035:30;11055:9;11035:30;:::i;:::-;11027:6;11020:46;11099:39;11134:2;11123:9;11119:18;11099:39;:::i;:::-;11094:2;11086:6;11082:15;11075:64;11172:39;11207:2;11196:9;11192:18;11172:39;:::i;:::-;11167:2;11159:6;11155:15;11148:64;11245:39;11280:2;11269:9;11265:18;11245:39;:::i;:::-;11240:2;11228:15;;11221:64;11232:6;10744:572;-1:-1:-1;;;10744:572:29:o;11321:190::-;;11433:2;11421:9;11412:7;11408:23;11404:32;11401:2;;;11454:6;11446;11439:22;11401:2;-1:-1:-1;11482:23:29;;11391:120;-1:-1:-1;11391:120:29:o;11516:258::-;;;11645:2;11633:9;11624:7;11620:23;11616:32;11613:2;;;11666:6;11658;11651:22;11613:2;-1:-1:-1;;11694:23:29;;;11764:2;11749:18;;;11736:32;;-1:-1:-1;11603:171:29:o;11779:416::-;;11885:6;11880:3;11873:19;11915:66;11907:6;11904:78;11901:2;;;11997:3;11992;11985:16;11901:2;12040:4;12032:6;12028:17;12090:8;12083:5;12076:4;12071:3;12067:14;12054:45;12122:18;;;;12142:4;12118:29;12156:15;;;-1:-1:-1;12118:29:29;;11863:332;-1:-1:-1;11863:332:29:o;12200:339::-;12320:12;;12277:18;12316:21;;;12304:34;;12391:4;12380:16;;;12374:23;12370:32;;12354:14;;;12347:56;12456:4;12445:16;;;12439:23;12435:32;;12419:14;;;12412:56;12521:4;12510:16;;;12504:23;12500:32;12484:14;;12477:56;12257:282::o;12544:226::-;12720:42;12708:55;;;;12690:74;;12678:2;12663:18;;12645:125::o;12775:297::-;12979:42;12967:55;;;;12949:74;;13054:2;13039:18;;13032:34;12937:2;12922:18;;12904:168::o;13077:718::-;13304:2;13356:21;;;13426:13;;13329:18;;;13448:22;;;13077:718;;13304:2;13527:15;;;;13501:2;13486:18;;;13077:718;13573:196;13587:6;13584:1;13581:13;13573:196;;;13636:51;13683:3;13674:6;13668:13;13636:51;:::i;:::-;13744:15;;;;13716:4;13707:14;;;;;13609:1;13602:9;13573:196;;;-1:-1:-1;13786:3:29;;13284:511;-1:-1:-1;;;;;;13284:511:29:o;13800:531::-;;14077:2;14066:9;14059:21;14103:79;14178:2;14167:9;14163:18;14155:6;14147;14103:79;:::i;:::-;14230:9;14222:6;14218:22;14213:2;14202:9;14198:18;14191:50;14258:67;14318:6;14310;14302;14258:67;:::i;:::-;14250:75;14049:282;-1:-1:-1;;;;;;;14049:282:29:o;14336:635::-;14507:2;14559:21;;;14629:13;;14532:18;;;14651:22;;;14336:635;;14507:2;14730:15;;;;14704:2;14689:18;;;14336:635;14776:169;14790:6;14787:1;14784:13;14776:169;;;14851:13;;14839:26;;14920:15;;;;14885:12;;;;14812:1;14805:9;14776:169;;14976:187;15141:14;;15134:22;15116:41;;15104:2;15089:18;;15071:92::o;15168:662::-;;15309:2;15338;15327:9;15320:21;15370:6;15364:13;15413:6;15408:2;15397:9;15393:18;15386:34;15438:4;15451:140;15465:6;15462:1;15459:13;15451:140;;;15560:14;;;15556:23;;15550:30;15526:17;;;15545:2;15522:26;15515:66;15480:10;;15451:140;;;15609:6;15606:1;15603:13;15600:2;;;15679:4;15674:2;15665:6;15654:9;15650:22;15646:31;15639:45;15600:2;-1:-1:-1;15746:2:29;15734:15;15751:66;15730:88;15715:104;;;;15821:2;15711:113;;15289:541;-1:-1:-1;;;15289:541:29:o;15835:414::-;16037:2;16019:21;;;16076:2;16056:18;;;16049:30;16115:34;16110:2;16095:18;;16088:62;16186:20;16181:2;16166:18;;16159:48;16239:3;16224:19;;16009:240::o;16254:418::-;16456:2;16438:21;;;16495:2;16475:18;;;16468:30;16534:34;16529:2;16514:18;;16507:62;16605:24;16600:2;16585:18;;16578:52;16662:3;16647:19;;16428:244::o;16677:342::-;16879:2;16861:21;;;16918:2;16898:18;;;16891:30;16957:20;16952:2;16937:18;;16930:48;17010:2;16995:18;;16851:168::o;17024:412::-;17226:2;17208:21;;;17265:2;17245:18;;;17238:30;17304:34;17299:2;17284:18;;17277:62;17375:18;17370:2;17355:18;;17348:46;17426:3;17411:19;;17198:238::o;17441:411::-;17643:2;17625:21;;;17682:2;17662:18;;;17655:30;17721:34;17716:2;17701:18;;17694:62;17792:17;17787:2;17772:18;;17765:45;17842:3;17827:19;;17615:237::o;17857:406::-;18059:2;18041:21;;;18098:2;18078:18;;;18071:30;18137:34;18132:2;18117:18;;18110:62;18208:12;18203:2;18188:18;;18181:40;18253:3;18238:19;;18031:232::o;18268:424::-;18470:2;18452:21;;;18509:2;18489:18;;;18482:30;18548:34;18543:2;18528:18;;18521:62;18619:30;18614:2;18599:18;;18592:58;18682:3;18667:19;;18442:250::o;18697:409::-;18899:2;18881:21;;;18938:2;18918:18;;;18911:30;18977:34;18972:2;18957:18;;18950:62;19048:15;19043:2;19028:18;;19021:43;19096:3;19081:19;;18871:235::o;19111:421::-;19313:2;19295:21;;;19352:2;19332:18;;;19325:30;19391:34;19386:2;19371:18;;19364:62;19462:27;19457:2;19442:18;;19435:55;19522:3;19507:19;;19285:247::o;19537:477::-;19739:2;19721:21;;;19778:2;19758:18;;;19751:30;19817:34;19812:2;19797:18;;19790:62;19888:34;19883:2;19868:18;;19861:62;19960:11;19954:3;19939:19;;19932:40;20004:3;19989:19;;19711:303::o;20019:402::-;20221:2;20203:21;;;20260:2;20240:18;;;20233:30;20299:34;20294:2;20279:18;;20272:62;20370:8;20365:2;20350:18;;20343:36;20411:3;20396:19;;20193:228::o;20426:417::-;20628:2;20610:21;;;20667:2;20647:18;;;20640:30;20706:34;20701:2;20686:18;;20679:62;20777:23;20772:2;20757:18;;20750:51;20833:3;20818:19;;20600:243::o;20848:259::-;21038:3;21023:19;;21051:50;21027:9;21083:6;21051:50;:::i;21112:177::-;21258:25;;;21246:2;21231:18;;21213:76::o;21294:248::-;21468:25;;;21524:2;21509:18;;21502:34;21456:2;21441:18;;21423:119::o;21547:242::-;21617:2;21611:9;21647:17;;;21694:18;21679:34;;21715:22;;;21676:62;21673:2;;;21741:9;21673:2;21768;21761:22;21591:198;;-1:-1:-1;21591:198:29:o;21794:183::-;;21893:18;21885:6;21882:30;21879:2;;;21915:9;21879:2;-1:-1:-1;21966:4:29;21947:17;;;21943:28;;21869:108::o

Swarm Source

ipfs://fb1372790e40e3e548bbc115377592682a7efd66fc87555aa190c17a7e2027e8

Block Transaction Gas Used Reward
view all blocks produced

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

OVERVIEW

A trading card game from another dimension.

Loading...
Loading

Validator Index Block Amount
View All Withdrawals

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

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