{
  "address": "0x59E16fcCd424Cc24e280Be16E11Bcd56fb0CE547",
  "abi": [
    {
      "inputs": [
        {
          "internalType": "contract BaseRegistrarImplementation",
          "name": "_base",
          "type": "address"
        },
        {
          "internalType": "contract IPriceOracle",
          "name": "_prices",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "_minCommitmentAge",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "_maxCommitmentAge",
          "type": "uint256"
        },
        {
          "internalType": "contract IReverseRegistrar",
          "name": "_reverseRegistrar",
          "type": "address"
        },
        {
          "internalType": "contract IDefaultReverseRegistrar",
          "name": "_defaultReverseRegistrar",
          "type": "address"
        },
        {
          "internalType": "contract ENS",
          "name": "_ens",
          "type": "address"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "constructor"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "commitment",
          "type": "bytes32"
        }
      ],
      "name": "CommitmentNotFound",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "commitment",
          "type": "bytes32"
        },
        {
          "internalType": "uint256",
          "name": "minimumCommitmentTimestamp",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "currentTimestamp",
          "type": "uint256"
        }
      ],
      "name": "CommitmentTooNew",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "commitment",
          "type": "bytes32"
        },
        {
          "internalType": "uint256",
          "name": "maximumCommitmentTimestamp",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "currentTimestamp",
          "type": "uint256"
        }
      ],
      "name": "CommitmentTooOld",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "duration",
          "type": "uint256"
        }
      ],
      "name": "DurationTooShort",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "InsufficientValue",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "MaxCommitmentAgeTooHigh",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "MaxCommitmentAgeTooLow",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "string",
          "name": "name",
          "type": "string"
        }
      ],
      "name": "NameNotAvailable",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "ResolverRequiredForReverseRecord",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "ResolverRequiredWhenDataSupplied",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "commitment",
          "type": "bytes32"
        }
      ],
      "name": "UnexpiredCommitmentExists",
      "type": "error"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "string",
          "name": "label",
          "type": "string"
        },
        {
          "indexed": true,
          "internalType": "bytes32",
          "name": "labelhash",
          "type": "bytes32"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "owner",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "baseCost",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "premium",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "expires",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "bytes32",
          "name": "referrer",
          "type": "bytes32"
        }
      ],
      "name": "NameRegistered",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "string",
          "name": "label",
          "type": "string"
        },
        {
          "indexed": true,
          "internalType": "bytes32",
          "name": "labelhash",
          "type": "bytes32"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "cost",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "expires",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "bytes32",
          "name": "referrer",
          "type": "bytes32"
        }
      ],
      "name": "NameRenewed",
      "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"
    },
    {
      "inputs": [],
      "name": "MIN_REGISTRATION_DURATION",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "string",
          "name": "label",
          "type": "string"
        }
      ],
      "name": "available",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "commitment",
          "type": "bytes32"
        }
      ],
      "name": "commit",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "",
          "type": "bytes32"
        }
      ],
      "name": "commitments",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "defaultReverseRegistrar",
      "outputs": [
        {
          "internalType": "contract IDefaultReverseRegistrar",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "ens",
      "outputs": [
        {
          "internalType": "contract ENS",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "components": [
            {
              "internalType": "string",
              "name": "label",
              "type": "string"
            },
            {
              "internalType": "address",
              "name": "owner",
              "type": "address"
            },
            {
              "internalType": "uint256",
              "name": "duration",
              "type": "uint256"
            },
            {
              "internalType": "bytes32",
              "name": "secret",
              "type": "bytes32"
            },
            {
              "internalType": "address",
              "name": "resolver",
              "type": "address"
            },
            {
              "internalType": "bytes[]",
              "name": "data",
              "type": "bytes[]"
            },
            {
              "internalType": "uint8",
              "name": "reverseRecord",
              "type": "uint8"
            },
            {
              "internalType": "bytes32",
              "name": "referrer",
              "type": "bytes32"
            }
          ],
          "internalType": "struct IETHRegistrarController.Registration",
          "name": "registration",
          "type": "tuple"
        }
      ],
      "name": "makeCommitment",
      "outputs": [
        {
          "internalType": "bytes32",
          "name": "commitment",
          "type": "bytes32"
        }
      ],
      "stateMutability": "pure",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "maxCommitmentAge",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "minCommitmentAge",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "owner",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "prices",
      "outputs": [
        {
          "internalType": "contract IPriceOracle",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_token",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "_to",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "_amount",
          "type": "uint256"
        }
      ],
      "name": "recoverFunds",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "components": [
            {
              "internalType": "string",
              "name": "label",
              "type": "string"
            },
            {
              "internalType": "address",
              "name": "owner",
              "type": "address"
            },
            {
              "internalType": "uint256",
              "name": "duration",
              "type": "uint256"
            },
            {
              "internalType": "bytes32",
              "name": "secret",
              "type": "bytes32"
            },
            {
              "internalType": "address",
              "name": "resolver",
              "type": "address"
            },
            {
              "internalType": "bytes[]",
              "name": "data",
              "type": "bytes[]"
            },
            {
              "internalType": "uint8",
              "name": "reverseRecord",
              "type": "uint8"
            },
            {
              "internalType": "bytes32",
              "name": "referrer",
              "type": "bytes32"
            }
          ],
          "internalType": "struct IETHRegistrarController.Registration",
          "name": "registration",
          "type": "tuple"
        }
      ],
      "name": "register",
      "outputs": [],
      "stateMutability": "payable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "string",
          "name": "label",
          "type": "string"
        },
        {
          "internalType": "uint256",
          "name": "duration",
          "type": "uint256"
        },
        {
          "internalType": "bytes32",
          "name": "referrer",
          "type": "bytes32"
        }
      ],
      "name": "renew",
      "outputs": [],
      "stateMutability": "payable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "renounceOwnership",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "string",
          "name": "label",
          "type": "string"
        },
        {
          "internalType": "uint256",
          "name": "duration",
          "type": "uint256"
        }
      ],
      "name": "rentPrice",
      "outputs": [
        {
          "components": [
            {
              "internalType": "uint256",
              "name": "base",
              "type": "uint256"
            },
            {
              "internalType": "uint256",
              "name": "premium",
              "type": "uint256"
            }
          ],
          "internalType": "struct IPriceOracle.Price",
          "name": "price",
          "type": "tuple"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "reverseRegistrar",
      "outputs": [
        {
          "internalType": "contract IReverseRegistrar",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes4",
          "name": "interfaceID",
          "type": "bytes4"
        }
      ],
      "name": "supportsInterface",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "newOwner",
          "type": "address"
        }
      ],
      "name": "transferOwnership",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "string",
          "name": "label",
          "type": "string"
        }
      ],
      "name": "valid",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "pure",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "withdraw",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    }
  ],
  "transactionHash": "0xd11b2868fe9ac278f473439f32c67d0c1935aefc0143301179b7c2457b01afe9",
  "receipt": {
    "to": null,
    "from": "0x69420f05A11f617B4B74fFe2E04B2D300dFA556F",
    "contractAddress": "0x59E16fcCd424Cc24e280Be16E11Bcd56fb0CE547",
    "transactionIndex": 32,
    "gasUsed": "2170943",
    "logsBloom": "0x00000000010000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400100000000000000000040000000000000008000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000",
    "blockHash": "0xd8a4aac92b509daf65e40b73d93ecfff13a08f3dbe71b0eaf152e02f765dc5b6",
    "transactionHash": "0xd11b2868fe9ac278f473439f32c67d0c1935aefc0143301179b7c2457b01afe9",
    "logs": [
      {
        "transactionIndex": 32,
        "blockNumber": 22764821,
        "transactionHash": "0xd11b2868fe9ac278f473439f32c67d0c1935aefc0143301179b7c2457b01afe9",
        "address": "0x59E16fcCd424Cc24e280Be16E11Bcd56fb0CE547",
        "topics": [
          "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
          "0x0000000000000000000000000000000000000000000000000000000000000000",
          "0x00000000000000000000000069420f05a11f617b4b74ffe2e04b2d300dfa556f"
        ],
        "data": "0x",
        "logIndex": 187,
        "blockHash": "0xd8a4aac92b509daf65e40b73d93ecfff13a08f3dbe71b0eaf152e02f765dc5b6"
      }
    ],
    "blockNumber": 22764821,
    "cumulativeGasUsed": "9234242",
    "status": 1,
    "byzantium": true
  },
  "args": [
    "0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85",
    "0x7542565191d074cE84fBfA92cAE13AcB84788CA9",
    "60",
    "86400",
    "0xa58E81fe9b61B5c3fE2AFD33CF304c454AbFc7Cb",
    "0x283F227c4Bd38ecE252C4Ae7ECE650B0e913f1f9",
    "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"
  ],
  "numDeployments": 2,
  "solcInputHash": "66ae8ece08cf62450fe50df51b345695",
  "metadata": "{\"compiler\":{\"version\":\"0.8.26+commit.8a97fa7a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract BaseRegistrarImplementation\",\"name\":\"_base\",\"type\":\"address\"},{\"internalType\":\"contract IPriceOracle\",\"name\":\"_prices\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_minCommitmentAge\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxCommitmentAge\",\"type\":\"uint256\"},{\"internalType\":\"contract IReverseRegistrar\",\"name\":\"_reverseRegistrar\",\"type\":\"address\"},{\"internalType\":\"contract IDefaultReverseRegistrar\",\"name\":\"_defaultReverseRegistrar\",\"type\":\"address\"},{\"internalType\":\"contract ENS\",\"name\":\"_ens\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"commitment\",\"type\":\"bytes32\"}],\"name\":\"CommitmentNotFound\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"commitment\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"minimumCommitmentTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"currentTimestamp\",\"type\":\"uint256\"}],\"name\":\"CommitmentTooNew\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"commitment\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"maximumCommitmentTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"currentTimestamp\",\"type\":\"uint256\"}],\"name\":\"CommitmentTooOld\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"}],\"name\":\"DurationTooShort\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCommitmentAgeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCommitmentAgeTooLow\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NameNotAvailable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ResolverRequiredForReverseRecord\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ResolverRequiredWhenDataSupplied\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"commitment\",\"type\":\"bytes32\"}],\"name\":\"UnexpiredCommitmentExists\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"label\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"labelhash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"baseCost\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"premium\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"expires\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"referrer\",\"type\":\"bytes32\"}],\"name\":\"NameRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"label\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"labelhash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"cost\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"expires\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"referrer\",\"type\":\"bytes32\"}],\"name\":\"NameRenewed\",\"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\"},{\"inputs\":[],\"name\":\"MIN_REGISTRATION_DURATION\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"label\",\"type\":\"string\"}],\"name\":\"available\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"commitment\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"commitments\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"defaultReverseRegistrar\",\"outputs\":[{\"internalType\":\"contract IDefaultReverseRegistrar\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ens\",\"outputs\":[{\"internalType\":\"contract ENS\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"label\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"secret\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"resolver\",\"type\":\"address\"},{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"},{\"internalType\":\"uint8\",\"name\":\"reverseRecord\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"referrer\",\"type\":\"bytes32\"}],\"internalType\":\"struct IETHRegistrarController.Registration\",\"name\":\"registration\",\"type\":\"tuple\"}],\"name\":\"makeCommitment\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"commitment\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxCommitmentAge\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minCommitmentAge\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"prices\",\"outputs\":[{\"internalType\":\"contract IPriceOracle\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"label\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"secret\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"resolver\",\"type\":\"address\"},{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"},{\"internalType\":\"uint8\",\"name\":\"reverseRecord\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"referrer\",\"type\":\"bytes32\"}],\"internalType\":\"struct IETHRegistrarController.Registration\",\"name\":\"registration\",\"type\":\"tuple\"}],\"name\":\"register\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"label\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"referrer\",\"type\":\"bytes32\"}],\"name\":\"renew\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"label\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"}],\"name\":\"rentPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"base\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"premium\",\"type\":\"uint256\"}],\"internalType\":\"struct IPriceOracle.Price\",\"name\":\"price\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"reverseRegistrar\",\"outputs\":[{\"internalType\":\"contract IReverseRegistrar\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceID\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"label\",\"type\":\"string\"}],\"name\":\"valid\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"A registrar controller for registering and renewing names at fixed cost.\",\"events\":{\"NameRegistered(string,bytes32,address,uint256,uint256,uint256,bytes32)\":{\"params\":{\"baseCost\":\"The base cost of the name.\",\"expires\":\"The expiry time of the name.\",\"label\":\"The label of the name.\",\"labelhash\":\"The keccak256 hash of the label.\",\"owner\":\"The owner of the name.\",\"premium\":\"The premium cost of the name.\",\"referrer\":\"The referrer of the registration.\"}},\"NameRenewed(string,bytes32,uint256,uint256,bytes32)\":{\"params\":{\"cost\":\"The cost of the name.\",\"expires\":\"The expiry time of the name.\",\"label\":\"The label of the name.\",\"labelhash\":\"The keccak256 hash of the label.\",\"referrer\":\"The referrer of the registration.\"}}},\"kind\":\"dev\",\"methods\":{\"available(string)\":{\"params\":{\"label\":\"The label to check.\"},\"returns\":{\"_0\":\"True if the label is valid and available, false otherwise.\"}},\"commit(bytes32)\":{\"params\":{\"commitment\":\"The commitment to commit.\"}},\"constructor\":{\"params\":{\"_base\":\"The base registrar implementation for the eth TLD.\",\"_defaultReverseRegistrar\":\"The registrar for default.reverse.\",\"_ens\":\"The ENS registry.\",\"_maxCommitmentAge\":\"The maximum time a commitment can exist to be valid.\",\"_minCommitmentAge\":\"The minimum time a commitment must exist to be valid.\",\"_prices\":\"The price oracle for the eth TLD.\",\"_reverseRegistrar\":\"The registrar for addr.reverse.\"}},\"makeCommitment((string,address,uint256,bytes32,address,bytes[],uint8,bytes32))\":{\"params\":{\"registration\":\"The registration to make a commitment for.\"},\"returns\":{\"commitment\":\"The commitment for the registration.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"recoverFunds(address,address,uint256)\":{\"details\":\"The contract is Ownable and only the owner can call the recover function.\",\"params\":{\"_amount\":\"The amount of tokens to recover.\",\"_to\":\"The address to send the tokens to.\",\"_token\":\"The address of the ERC20 token to recover\"}},\"register((string,address,uint256,bytes32,address,bytes[],uint8,bytes32))\":{\"params\":{\"registration\":\".referrer The referrer of the registration.\"}},\"renew(string,uint256,bytes32)\":{\"params\":{\"duration\":\"The duration of the registration.\",\"label\":\"The label of the name.\",\"referrer\":\"The referrer of the registration.\"}},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"rentPrice(string,uint256)\":{\"params\":{\"duration\":\"The duration of the registration.\",\"label\":\"The label of the name.\"},\"returns\":{\"price\":\"The price of the registration.\"}},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"valid(string)\":{\"params\":{\"label\":\"The label to check.\"},\"returns\":{\"_0\":\"True if the label is valid, false otherwise.\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"CommitmentNotFound(bytes32)\":[{\"notice\":\"Thrown when a commitment is not found.\"}],\"CommitmentTooNew(bytes32,uint256,uint256)\":[{\"notice\":\"Thrown when a commitment is too new.\"}],\"CommitmentTooOld(bytes32,uint256,uint256)\":[{\"notice\":\"Thrown when a commitment is too old.\"}],\"DurationTooShort(uint256)\":[{\"notice\":\"Thrown when the duration supplied for a registration is too short.\"}],\"InsufficientValue()\":[{\"notice\":\"Thrown when the value sent for a registration is insufficient.\"}],\"MaxCommitmentAgeTooHigh()\":[{\"notice\":\"Thrown when the maximum commitment age is too high.\"}],\"MaxCommitmentAgeTooLow()\":[{\"notice\":\"Thrown when the maximum commitment age is too low.\"}],\"NameNotAvailable(string)\":[{\"notice\":\"Thrown when a name is not available to register.\"}],\"ResolverRequiredForReverseRecord()\":[{\"notice\":\"Thrown when a reverse record is requested without a resolver.\"}],\"ResolverRequiredWhenDataSupplied()\":[{\"notice\":\"Thrown when data is supplied for a registration without a resolver.\"}],\"UnexpiredCommitmentExists(bytes32)\":[{\"notice\":\"Thrown when a matching unexpired commitment exists.\"}]},\"events\":{\"NameRegistered(string,bytes32,address,uint256,uint256,uint256,bytes32)\":{\"notice\":\"Emitted when a name is registered.\"},\"NameRenewed(string,bytes32,uint256,uint256,bytes32)\":{\"notice\":\"Emitted when a name is renewed.\"}},\"kind\":\"user\",\"methods\":{\"MIN_REGISTRATION_DURATION()\":{\"notice\":\"The minimum duration for a registration.\"},\"available(string)\":{\"notice\":\"Returns true if the label is valid and available for registration.\"},\"commit(bytes32)\":{\"notice\":\"Commits a registration.\"},\"commitments(bytes32)\":{\"notice\":\"A mapping of commitments to their timestamp.\"},\"constructor\":{\"notice\":\"Constructor for the ETHRegistrarController.\"},\"defaultReverseRegistrar()\":{\"notice\":\"The registrar for default.reverse. (i.e. fallback reverse for all EVM chains)\"},\"ens()\":{\"notice\":\"The ENS registry.\"},\"makeCommitment((string,address,uint256,bytes32,address,bytes[],uint8,bytes32))\":{\"notice\":\"Returns the commitment for a registration.\"},\"maxCommitmentAge()\":{\"notice\":\"The maximum time a commitment can exist to be valid.\"},\"minCommitmentAge()\":{\"notice\":\"The minimum time a commitment must exist to be valid.\"},\"prices()\":{\"notice\":\"The price oracle for the eth TLD.\"},\"recoverFunds(address,address,uint256)\":{\"notice\":\"Recover ERC20 tokens sent to the contract by mistake.\"},\"register((string,address,uint256,bytes32,address,bytes[],uint8,bytes32))\":{\"notice\":\"Registers a name.\"},\"renew(string,uint256,bytes32)\":{\"notice\":\"Renews a name.\"},\"rentPrice(string,uint256)\":{\"notice\":\"Returns the price of a registration for the given label and duration.\"},\"reverseRegistrar()\":{\"notice\":\"The registrar for addr.reverse. (i.e. reverse for coinType 60)\"},\"valid(string)\":{\"notice\":\"Returns true if the label is valid for registration.\"},\"withdraw()\":{\"notice\":\"Withdraws the balance of the contract to the owner.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ethregistrar/ETHRegistrarController.sol\":\"ETHRegistrarController\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n    address private _owner;\\n\\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n    /**\\n     * @dev Initializes the contract setting the deployer as the initial owner.\\n     */\\n    constructor() {\\n        _transferOwnership(_msgSender());\\n    }\\n\\n    /**\\n     * @dev Throws if called by any account other than the owner.\\n     */\\n    modifier onlyOwner() {\\n        _checkOwner();\\n        _;\\n    }\\n\\n    /**\\n     * @dev Returns the address of the current owner.\\n     */\\n    function owner() public view virtual returns (address) {\\n        return _owner;\\n    }\\n\\n    /**\\n     * @dev Throws if the sender is not the owner.\\n     */\\n    function _checkOwner() internal view virtual {\\n        require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n    }\\n\\n    /**\\n     * @dev Leaves the contract without owner. It will not be possible to call\\n     * `onlyOwner` functions. Can only be called by the current owner.\\n     *\\n     * NOTE: Renouncing ownership will leave the contract without an owner,\\n     * thereby disabling any functionality that is only available to the owner.\\n     */\\n    function renounceOwnership() public virtual onlyOwner {\\n        _transferOwnership(address(0));\\n    }\\n\\n    /**\\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n     * Can only be called by the current owner.\\n     */\\n    function transferOwnership(address newOwner) public virtual onlyOwner {\\n        require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n        _transferOwnership(newOwner);\\n    }\\n\\n    /**\\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n     * Internal function without access restriction.\\n     */\\n    function _transferOwnership(address newOwner) internal virtual {\\n        address oldOwner = _owner;\\n        _owner = newOwner;\\n        emit OwnershipTransferred(oldOwner, newOwner);\\n    }\\n}\\n\",\"keccak256\":\"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n    /**\\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n     * another (`to`).\\n     *\\n     * Note that `value` may be zero.\\n     */\\n    event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n    /**\\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n     * a call to {approve}. `value` is the new allowance.\\n     */\\n    event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n    /**\\n     * @dev Returns the amount of tokens in existence.\\n     */\\n    function totalSupply() external view returns (uint256);\\n\\n    /**\\n     * @dev Returns the amount of tokens owned by `account`.\\n     */\\n    function balanceOf(address account) external view returns (uint256);\\n\\n    /**\\n     * @dev Moves `amount` tokens from the caller's account to `to`.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function transfer(address to, uint256 amount) external returns (bool);\\n\\n    /**\\n     * @dev Returns the remaining number of tokens that `spender` will be\\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n     * zero by default.\\n     *\\n     * This value changes when {approve} or {transferFrom} are called.\\n     */\\n    function allowance(address owner, address spender) external view returns (uint256);\\n\\n    /**\\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n     * that someone may use both the old and the new allowance by unfortunate\\n     * transaction ordering. One possible solution to mitigate this race\\n     * condition is to first reduce the spender's allowance to 0 and set the\\n     * desired value afterwards:\\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n     *\\n     * Emits an {Approval} event.\\n     */\\n    function approve(address spender, uint256 amount) external returns (bool);\\n\\n    /**\\n     * @dev Moves `amount` tokens from `from` to `to` using the\\n     * allowance mechanism. `amount` is then deducted from the caller's\\n     * allowance.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function transferFrom(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n    using Address for address;\\n    using Strings for uint256;\\n\\n    // Token name\\n    string private _name;\\n\\n    // Token symbol\\n    string private _symbol;\\n\\n    // Mapping from token ID to owner address\\n    mapping(uint256 => address) private _owners;\\n\\n    // Mapping owner address to token count\\n    mapping(address => uint256) private _balances;\\n\\n    // Mapping from token ID to approved address\\n    mapping(uint256 => address) private _tokenApprovals;\\n\\n    // Mapping from owner to operator approvals\\n    mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n    /**\\n     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n     */\\n    constructor(string memory name_, string memory symbol_) {\\n        _name = name_;\\n        _symbol = symbol_;\\n    }\\n\\n    /**\\n     * @dev See {IERC165-supportsInterface}.\\n     */\\n    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n        return\\n            interfaceId == type(IERC721).interfaceId ||\\n            interfaceId == type(IERC721Metadata).interfaceId ||\\n            super.supportsInterface(interfaceId);\\n    }\\n\\n    /**\\n     * @dev See {IERC721-balanceOf}.\\n     */\\n    function balanceOf(address owner) public view virtual override returns (uint256) {\\n        require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n        return _balances[owner];\\n    }\\n\\n    /**\\n     * @dev See {IERC721-ownerOf}.\\n     */\\n    function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n        address owner = _ownerOf(tokenId);\\n        require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n        return owner;\\n    }\\n\\n    /**\\n     * @dev See {IERC721Metadata-name}.\\n     */\\n    function name() public view virtual override returns (string memory) {\\n        return _name;\\n    }\\n\\n    /**\\n     * @dev See {IERC721Metadata-symbol}.\\n     */\\n    function symbol() public view virtual override returns (string memory) {\\n        return _symbol;\\n    }\\n\\n    /**\\n     * @dev See {IERC721Metadata-tokenURI}.\\n     */\\n    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n        _requireMinted(tokenId);\\n\\n        string memory baseURI = _baseURI();\\n        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n    }\\n\\n    /**\\n     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n     * by default, can be overridden in child contracts.\\n     */\\n    function _baseURI() internal view virtual returns (string memory) {\\n        return \\\"\\\";\\n    }\\n\\n    /**\\n     * @dev See {IERC721-approve}.\\n     */\\n    function approve(address to, uint256 tokenId) public virtual override {\\n        address owner = ERC721.ownerOf(tokenId);\\n        require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n        require(\\n            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n            \\\"ERC721: approve caller is not token owner or approved for all\\\"\\n        );\\n\\n        _approve(to, tokenId);\\n    }\\n\\n    /**\\n     * @dev See {IERC721-getApproved}.\\n     */\\n    function getApproved(uint256 tokenId) public view virtual override returns (address) {\\n        _requireMinted(tokenId);\\n\\n        return _tokenApprovals[tokenId];\\n    }\\n\\n    /**\\n     * @dev See {IERC721-setApprovalForAll}.\\n     */\\n    function setApprovalForAll(address operator, bool approved) public virtual override {\\n        _setApprovalForAll(_msgSender(), operator, approved);\\n    }\\n\\n    /**\\n     * @dev See {IERC721-isApprovedForAll}.\\n     */\\n    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\\n        return _operatorApprovals[owner][operator];\\n    }\\n\\n    /**\\n     * @dev See {IERC721-transferFrom}.\\n     */\\n    function transferFrom(address from, address to, uint256 tokenId) public virtual override {\\n        //solhint-disable-next-line max-line-length\\n        require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner or approved\\\");\\n\\n        _transfer(from, to, tokenId);\\n    }\\n\\n    /**\\n     * @dev See {IERC721-safeTransferFrom}.\\n     */\\n    function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\\n        safeTransferFrom(from, to, tokenId, \\\"\\\");\\n    }\\n\\n    /**\\n     * @dev See {IERC721-safeTransferFrom}.\\n     */\\n    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\\n        require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner or approved\\\");\\n        _safeTransfer(from, to, tokenId, data);\\n    }\\n\\n    /**\\n     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n     * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n     *\\n     * `data` is additional data, it has no specified format and it is sent in call to `to`.\\n     *\\n     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\\n     * implement alternative mechanisms to perform token transfer, such as signature-based.\\n     *\\n     * Requirements:\\n     *\\n     * - `from` cannot be the zero address.\\n     * - `to` cannot be the zero address.\\n     * - `tokenId` token must exist and be owned by `from`.\\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\\n        _transfer(from, to, tokenId);\\n        require(_checkOnERC721Received(from, to, tokenId, data), \\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\\n     */\\n    function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\\n        return _owners[tokenId];\\n    }\\n\\n    /**\\n     * @dev Returns whether `tokenId` exists.\\n     *\\n     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\\n     *\\n     * Tokens start existing when they are minted (`_mint`),\\n     * and stop existing when they are burned (`_burn`).\\n     */\\n    function _exists(uint256 tokenId) internal view virtual returns (bool) {\\n        return _ownerOf(tokenId) != address(0);\\n    }\\n\\n    /**\\n     * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n     *\\n     * Requirements:\\n     *\\n     * - `tokenId` must exist.\\n     */\\n    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n        address owner = ERC721.ownerOf(tokenId);\\n        return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n    }\\n\\n    /**\\n     * @dev Safely mints `tokenId` and transfers it to `to`.\\n     *\\n     * Requirements:\\n     *\\n     * - `tokenId` must not exist.\\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function _safeMint(address to, uint256 tokenId) internal virtual {\\n        _safeMint(to, tokenId, \\\"\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n     */\\n    function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\\n        _mint(to, tokenId);\\n        require(\\n            _checkOnERC721Received(address(0), to, tokenId, data),\\n            \\\"ERC721: transfer to non ERC721Receiver implementer\\\"\\n        );\\n    }\\n\\n    /**\\n     * @dev Mints `tokenId` and transfers it to `to`.\\n     *\\n     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\\n     *\\n     * Requirements:\\n     *\\n     * - `tokenId` must not exist.\\n     * - `to` cannot be the zero address.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function _mint(address to, uint256 tokenId) internal virtual {\\n        require(to != address(0), \\\"ERC721: mint to the zero address\\\");\\n        require(!_exists(tokenId), \\\"ERC721: token already minted\\\");\\n\\n        _beforeTokenTransfer(address(0), to, tokenId, 1);\\n\\n        // Check that tokenId was not minted by `_beforeTokenTransfer` hook\\n        require(!_exists(tokenId), \\\"ERC721: token already minted\\\");\\n\\n        unchecked {\\n            // Will not overflow unless all 2**256 token ids are minted to the same owner.\\n            // Given that tokens are minted one by one, it is impossible in practice that\\n            // this ever happens. Might change if we allow batch minting.\\n            // The ERC fails to describe this case.\\n            _balances[to] += 1;\\n        }\\n\\n        _owners[tokenId] = to;\\n\\n        emit Transfer(address(0), to, tokenId);\\n\\n        _afterTokenTransfer(address(0), to, tokenId, 1);\\n    }\\n\\n    /**\\n     * @dev Destroys `tokenId`.\\n     * The approval is cleared when the token is burned.\\n     * This is an internal function that does not check if the sender is authorized to operate on the token.\\n     *\\n     * Requirements:\\n     *\\n     * - `tokenId` must exist.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function _burn(uint256 tokenId) internal virtual {\\n        address owner = ERC721.ownerOf(tokenId);\\n\\n        _beforeTokenTransfer(owner, address(0), tokenId, 1);\\n\\n        // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\\n        owner = ERC721.ownerOf(tokenId);\\n\\n        // Clear approvals\\n        delete _tokenApprovals[tokenId];\\n\\n        unchecked {\\n            // Cannot overflow, as that would require more tokens to be burned/transferred\\n            // out than the owner initially received through minting and transferring in.\\n            _balances[owner] -= 1;\\n        }\\n        delete _owners[tokenId];\\n\\n        emit Transfer(owner, address(0), tokenId);\\n\\n        _afterTokenTransfer(owner, address(0), tokenId, 1);\\n    }\\n\\n    /**\\n     * @dev Transfers `tokenId` from `from` to `to`.\\n     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\\n     *\\n     * Requirements:\\n     *\\n     * - `to` cannot be the zero address.\\n     * - `tokenId` token must be owned by `from`.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function _transfer(address from, address to, uint256 tokenId) internal virtual {\\n        require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n        require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n        _beforeTokenTransfer(from, to, tokenId, 1);\\n\\n        // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\\n        require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n\\n        // Clear approvals from the previous owner\\n        delete _tokenApprovals[tokenId];\\n\\n        unchecked {\\n            // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\\n            // `from`'s balance is the number of token held, which is at least one before the current\\n            // transfer.\\n            // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\\n            // all 2**256 token ids to be minted, which in practice is impossible.\\n            _balances[from] -= 1;\\n            _balances[to] += 1;\\n        }\\n        _owners[tokenId] = to;\\n\\n        emit Transfer(from, to, tokenId);\\n\\n        _afterTokenTransfer(from, to, tokenId, 1);\\n    }\\n\\n    /**\\n     * @dev Approve `to` to operate on `tokenId`\\n     *\\n     * Emits an {Approval} event.\\n     */\\n    function _approve(address to, uint256 tokenId) internal virtual {\\n        _tokenApprovals[tokenId] = to;\\n        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n    }\\n\\n    /**\\n     * @dev Approve `operator` to operate on all of `owner` tokens\\n     *\\n     * Emits an {ApprovalForAll} event.\\n     */\\n    function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\\n        require(owner != operator, \\\"ERC721: approve to caller\\\");\\n        _operatorApprovals[owner][operator] = approved;\\n        emit ApprovalForAll(owner, operator, approved);\\n    }\\n\\n    /**\\n     * @dev Reverts if the `tokenId` has not been minted yet.\\n     */\\n    function _requireMinted(uint256 tokenId) internal view virtual {\\n        require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n    }\\n\\n    /**\\n     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n     * The call is not executed if the target address is not a contract.\\n     *\\n     * @param from address representing the previous owner of the given token ID\\n     * @param to target address that will receive the tokens\\n     * @param tokenId uint256 ID of the token to be transferred\\n     * @param data bytes optional data to send along with the call\\n     * @return bool whether the call correctly returned the expected magic value\\n     */\\n    function _checkOnERC721Received(\\n        address from,\\n        address to,\\n        uint256 tokenId,\\n        bytes memory data\\n    ) private returns (bool) {\\n        if (to.isContract()) {\\n            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n                return retval == IERC721Receiver.onERC721Received.selector;\\n            } catch (bytes memory reason) {\\n                if (reason.length == 0) {\\n                    revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n                } else {\\n                    /// @solidity memory-safe-assembly\\n                    assembly {\\n                        revert(add(32, reason), mload(reason))\\n                    }\\n                }\\n            }\\n        } else {\\n            return true;\\n        }\\n    }\\n\\n    /**\\n     * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\\n     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\\n     *\\n     * Calling conditions:\\n     *\\n     * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\\n     * - When `from` is zero, the tokens will be minted for `to`.\\n     * - When `to` is zero, ``from``'s tokens will be burned.\\n     * - `from` and `to` are never both zero.\\n     * - `batchSize` is non-zero.\\n     *\\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n     */\\n    function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\\n\\n    /**\\n     * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\\n     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\\n     *\\n     * Calling conditions:\\n     *\\n     * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\\n     * - When `from` is zero, the tokens were minted for `to`.\\n     * - When `to` is zero, ``from``'s tokens were burned.\\n     * - `from` and `to` are never both zero.\\n     * - `batchSize` is non-zero.\\n     *\\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n     */\\n    function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\\n\\n    /**\\n     * @dev Unsafe write access to the balances, used by extensions that \\\"mint\\\" tokens using an {ownerOf} override.\\n     *\\n     * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\\n     * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\\n     * that `ownerOf(tokenId)` is `a`.\\n     */\\n    // solhint-disable-next-line func-name-mixedcase\\n    function __unsafe_increaseBalance(address account, uint256 amount) internal {\\n        _balances[account] += amount;\\n    }\\n}\\n\",\"keccak256\":\"0x2c309e7df9e05e6ce15bedfe74f3c61b467fc37e0fae9eab496acf5ea0bbd7ff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721 is IERC165 {\\n    /**\\n     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n     */\\n    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\n\\n    /**\\n     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n     */\\n    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\n\\n    /**\\n     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n     */\\n    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n    /**\\n     * @dev Returns the number of tokens in ``owner``'s account.\\n     */\\n    function balanceOf(address owner) external view returns (uint256 balance);\\n\\n    /**\\n     * @dev Returns the owner of the `tokenId` token.\\n     *\\n     * Requirements:\\n     *\\n     * - `tokenId` must exist.\\n     */\\n    function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n    /**\\n     * @dev Safely transfers `tokenId` token from `from` to `to`.\\n     *\\n     * Requirements:\\n     *\\n     * - `from` cannot be the zero address.\\n     * - `to` cannot be the zero address.\\n     * - `tokenId` token must exist and be owned by `from`.\\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\\n\\n    /**\\n     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n     * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n     *\\n     * Requirements:\\n     *\\n     * - `from` cannot be the zero address.\\n     * - `to` cannot be the zero address.\\n     * - `tokenId` token must exist and be owned by `from`.\\n     * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function safeTransferFrom(address from, address to, uint256 tokenId) external;\\n\\n    /**\\n     * @dev Transfers `tokenId` token from `from` to `to`.\\n     *\\n     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n     * understand this adds an external call which potentially creates a reentrancy vulnerability.\\n     *\\n     * Requirements:\\n     *\\n     * - `from` cannot be the zero address.\\n     * - `to` cannot be the zero address.\\n     * - `tokenId` token must be owned by `from`.\\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function transferFrom(address from, address to, uint256 tokenId) external;\\n\\n    /**\\n     * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n     * The approval is cleared when the token is transferred.\\n     *\\n     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n     *\\n     * Requirements:\\n     *\\n     * - The caller must own the token or be an approved operator.\\n     * - `tokenId` must exist.\\n     *\\n     * Emits an {Approval} event.\\n     */\\n    function approve(address to, uint256 tokenId) external;\\n\\n    /**\\n     * @dev Approve or remove `operator` as an operator for the caller.\\n     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n     *\\n     * Requirements:\\n     *\\n     * - The `operator` cannot be the caller.\\n     *\\n     * Emits an {ApprovalForAll} event.\\n     */\\n    function setApprovalForAll(address operator, bool approved) external;\\n\\n    /**\\n     * @dev Returns the account approved for `tokenId` token.\\n     *\\n     * Requirements:\\n     *\\n     * - `tokenId` must exist.\\n     */\\n    function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n    /**\\n     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n     *\\n     * See {setApprovalForAll}\\n     */\\n    function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x5bce51e11f7d194b79ea59fe00c9e8de9fa2c5530124960f29a24d4c740a3266\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n    /**\\n     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n     * by `operator` from `from`, this function is called.\\n     *\\n     * It must return its Solidity selector to confirm the token transfer.\\n     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n     *\\n     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n     */\\n    function onERC721Received(\\n        address operator,\\n        address from,\\n        uint256 tokenId,\\n        bytes calldata data\\n    ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n    /**\\n     * @dev Returns the token collection name.\\n     */\\n    function name() external view returns (string memory);\\n\\n    /**\\n     * @dev Returns the token collection symbol.\\n     */\\n    function symbol() external view returns (string memory);\\n\\n    /**\\n     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n     */\\n    function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n    /**\\n     * @dev Returns true if `account` is a contract.\\n     *\\n     * [IMPORTANT]\\n     * ====\\n     * It is unsafe to assume that an address for which this function returns\\n     * false is an externally-owned account (EOA) and not a contract.\\n     *\\n     * Among others, `isContract` will return false for the following\\n     * types of addresses:\\n     *\\n     *  - an externally-owned account\\n     *  - a contract in construction\\n     *  - an address where a contract will be created\\n     *  - an address where a contract lived, but was destroyed\\n     *\\n     * Furthermore, `isContract` will also return true if the target contract within\\n     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n     * which only has an effect at the end of a transaction.\\n     * ====\\n     *\\n     * [IMPORTANT]\\n     * ====\\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n     *\\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n     * constructor.\\n     * ====\\n     */\\n    function isContract(address account) internal view returns (bool) {\\n        // This method relies on extcodesize/address.code.length, which returns 0\\n        // for contracts in construction, since the code is only stored at the end\\n        // of the constructor execution.\\n\\n        return account.code.length > 0;\\n    }\\n\\n    /**\\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n     * `recipient`, forwarding all available gas and reverting on errors.\\n     *\\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n     * imposed by `transfer`, making them unable to receive funds via\\n     * `transfer`. {sendValue} removes this limitation.\\n     *\\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n     *\\n     * IMPORTANT: because control is transferred to `recipient`, care must be\\n     * taken to not create reentrancy vulnerabilities. Consider using\\n     * {ReentrancyGuard} or the\\n     * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n     */\\n    function sendValue(address payable recipient, uint256 amount) internal {\\n        require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n        (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n        require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n    }\\n\\n    /**\\n     * @dev Performs a Solidity function call using a low level `call`. A\\n     * plain `call` is an unsafe replacement for a function call: use this\\n     * function instead.\\n     *\\n     * If `target` reverts with a revert reason, it is bubbled up by this\\n     * function (like regular Solidity function calls).\\n     *\\n     * Returns the raw returned data. To convert to the expected return value,\\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n     *\\n     * Requirements:\\n     *\\n     * - `target` must be a contract.\\n     * - calling `target` with `data` must not revert.\\n     *\\n     * _Available since v3.1._\\n     */\\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n        return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n     * `errorMessage` as a fallback revert reason when `target` reverts.\\n     *\\n     * _Available since v3.1._\\n     */\\n    function functionCall(\\n        address target,\\n        bytes memory data,\\n        string memory errorMessage\\n    ) internal returns (bytes memory) {\\n        return functionCallWithValue(target, data, 0, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n     * but also transferring `value` wei to `target`.\\n     *\\n     * Requirements:\\n     *\\n     * - the calling contract must have an ETH balance of at least `value`.\\n     * - the called Solidity function must be `payable`.\\n     *\\n     * _Available since v3.1._\\n     */\\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n        return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\\n     *\\n     * _Available since v3.1._\\n     */\\n    function functionCallWithValue(\\n        address target,\\n        bytes memory data,\\n        uint256 value,\\n        string memory errorMessage\\n    ) internal returns (bytes memory) {\\n        require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n     * but performing a static call.\\n     *\\n     * _Available since v3.3._\\n     */\\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n        return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n     * but performing a static call.\\n     *\\n     * _Available since v3.3._\\n     */\\n    function functionStaticCall(\\n        address target,\\n        bytes memory data,\\n        string memory errorMessage\\n    ) internal view returns (bytes memory) {\\n        (bool success, bytes memory returndata) = target.staticcall(data);\\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n     * but performing a delegate call.\\n     *\\n     * _Available since v3.4._\\n     */\\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n        return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n     * but performing a delegate call.\\n     *\\n     * _Available since v3.4._\\n     */\\n    function functionDelegateCall(\\n        address target,\\n        bytes memory data,\\n        string memory errorMessage\\n    ) internal returns (bytes memory) {\\n        (bool success, bytes memory returndata) = target.delegatecall(data);\\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n     *\\n     * _Available since v4.8._\\n     */\\n    function verifyCallResultFromTarget(\\n        address target,\\n        bool success,\\n        bytes memory returndata,\\n        string memory errorMessage\\n    ) internal view returns (bytes memory) {\\n        if (success) {\\n            if (returndata.length == 0) {\\n                // only check isContract if the call was successful and the return data is empty\\n                // otherwise we already know that it was a contract\\n                require(isContract(target), \\\"Address: call to non-contract\\\");\\n            }\\n            return returndata;\\n        } else {\\n            _revert(returndata, errorMessage);\\n        }\\n    }\\n\\n    /**\\n     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n     * revert reason or using the provided one.\\n     *\\n     * _Available since v4.3._\\n     */\\n    function verifyCallResult(\\n        bool success,\\n        bytes memory returndata,\\n        string memory errorMessage\\n    ) internal pure returns (bytes memory) {\\n        if (success) {\\n            return returndata;\\n        } else {\\n            _revert(returndata, errorMessage);\\n        }\\n    }\\n\\n    function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n        // Look for revert reason and bubble it up if present\\n        if (returndata.length > 0) {\\n            // The easiest way to bubble the revert reason is using memory via assembly\\n            /// @solidity memory-safe-assembly\\n            assembly {\\n                let returndata_size := mload(returndata)\\n                revert(add(32, returndata), returndata_size)\\n            }\\n        } else {\\n            revert(errorMessage);\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n    function _msgSender() internal view virtual returns (address) {\\n        return msg.sender;\\n    }\\n\\n    function _msgData() internal view virtual returns (bytes calldata) {\\n        return msg.data;\\n    }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n    bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n    uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n    /**\\n     * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n     */\\n    function toString(uint256 value) internal pure returns (string memory) {\\n        unchecked {\\n            uint256 length = Math.log10(value) + 1;\\n            string memory buffer = new string(length);\\n            uint256 ptr;\\n            /// @solidity memory-safe-assembly\\n            assembly {\\n                ptr := add(buffer, add(32, length))\\n            }\\n            while (true) {\\n                ptr--;\\n                /// @solidity memory-safe-assembly\\n                assembly {\\n                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n                }\\n                value /= 10;\\n                if (value == 0) break;\\n            }\\n            return buffer;\\n        }\\n    }\\n\\n    /**\\n     * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n     */\\n    function toString(int256 value) internal pure returns (string memory) {\\n        return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n    }\\n\\n    /**\\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n     */\\n    function toHexString(uint256 value) internal pure returns (string memory) {\\n        unchecked {\\n            return toHexString(value, Math.log256(value) + 1);\\n        }\\n    }\\n\\n    /**\\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n     */\\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n        bytes memory buffer = new bytes(2 * length + 2);\\n        buffer[0] = \\\"0\\\";\\n        buffer[1] = \\\"x\\\";\\n        for (uint256 i = 2 * length + 1; i > 1; --i) {\\n            buffer[i] = _SYMBOLS[value & 0xf];\\n            value >>= 4;\\n        }\\n        require(value == 0, \\\"Strings: hex length insufficient\\\");\\n        return string(buffer);\\n    }\\n\\n    /**\\n     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n     */\\n    function toHexString(address addr) internal pure returns (string memory) {\\n        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n    }\\n\\n    /**\\n     * @dev Returns true if the two strings are equal.\\n     */\\n    function equal(string memory a, string memory b) internal pure returns (bool) {\\n        return keccak256(bytes(a)) == keccak256(bytes(b));\\n    }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165 is IERC165 {\\n    /**\\n     * @dev See {IERC165-supportsInterface}.\\n     */\\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n        return interfaceId == type(IERC165).interfaceId;\\n    }\\n}\\n\",\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n    /**\\n     * @dev Returns true if this contract implements the interface defined by\\n     * `interfaceId`. See the corresponding\\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n     * to learn more about how these ids are created.\\n     *\\n     * This function call must use less than 30 000 gas.\\n     */\\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n    enum Rounding {\\n        Down, // Toward negative infinity\\n        Up, // Toward infinity\\n        Zero // Toward zero\\n    }\\n\\n    /**\\n     * @dev Returns the largest of two numbers.\\n     */\\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n        return a > b ? a : b;\\n    }\\n\\n    /**\\n     * @dev Returns the smallest of two numbers.\\n     */\\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n        return a < b ? a : b;\\n    }\\n\\n    /**\\n     * @dev Returns the average of two numbers. The result is rounded towards\\n     * zero.\\n     */\\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n        // (a + b) / 2 can overflow.\\n        return (a & b) + (a ^ b) / 2;\\n    }\\n\\n    /**\\n     * @dev Returns the ceiling of the division of two numbers.\\n     *\\n     * This differs from standard division with `/` in that it rounds up instead\\n     * of rounding down.\\n     */\\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n        // (a + b - 1) / b can overflow on addition, so we distribute.\\n        return a == 0 ? 0 : (a - 1) / b + 1;\\n    }\\n\\n    /**\\n     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n     * with further edits by Uniswap Labs also under MIT license.\\n     */\\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n        unchecked {\\n            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n            // variables such that product = prod1 * 2^256 + prod0.\\n            uint256 prod0; // Least significant 256 bits of the product\\n            uint256 prod1; // Most significant 256 bits of the product\\n            assembly {\\n                let mm := mulmod(x, y, not(0))\\n                prod0 := mul(x, y)\\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n            }\\n\\n            // Handle non-overflow cases, 256 by 256 division.\\n            if (prod1 == 0) {\\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n                // The surrounding unchecked block does not change this fact.\\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n                return prod0 / denominator;\\n            }\\n\\n            // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n            require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n            ///////////////////////////////////////////////\\n            // 512 by 256 division.\\n            ///////////////////////////////////////////////\\n\\n            // Make division exact by subtracting the remainder from [prod1 prod0].\\n            uint256 remainder;\\n            assembly {\\n                // Compute remainder using mulmod.\\n                remainder := mulmod(x, y, denominator)\\n\\n                // Subtract 256 bit number from 512 bit number.\\n                prod1 := sub(prod1, gt(remainder, prod0))\\n                prod0 := sub(prod0, remainder)\\n            }\\n\\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n            // See https://cs.stackexchange.com/q/138556/92363.\\n\\n            // Does not overflow because the denominator cannot be zero at this stage in the function.\\n            uint256 twos = denominator & (~denominator + 1);\\n            assembly {\\n                // Divide denominator by twos.\\n                denominator := div(denominator, twos)\\n\\n                // Divide [prod1 prod0] by twos.\\n                prod0 := div(prod0, twos)\\n\\n                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n                twos := add(div(sub(0, twos), twos), 1)\\n            }\\n\\n            // Shift in bits from prod1 into prod0.\\n            prod0 |= prod1 * twos;\\n\\n            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n            // four bits. That is, denominator * inv = 1 mod 2^4.\\n            uint256 inverse = (3 * denominator) ^ 2;\\n\\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n            // in modular arithmetic, doubling the correct bits in each step.\\n            inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n            inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n            inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n            inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n            inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n            inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n            // is no longer required.\\n            result = prod0 * inverse;\\n            return result;\\n        }\\n    }\\n\\n    /**\\n     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n     */\\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n        uint256 result = mulDiv(x, y, denominator);\\n        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n            result += 1;\\n        }\\n        return result;\\n    }\\n\\n    /**\\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n     *\\n     * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n     */\\n    function sqrt(uint256 a) internal pure returns (uint256) {\\n        if (a == 0) {\\n            return 0;\\n        }\\n\\n        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n        //\\n        // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n        //\\n        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n        // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n        // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n        //\\n        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n        uint256 result = 1 << (log2(a) >> 1);\\n\\n        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n        // into the expected uint128 result.\\n        unchecked {\\n            result = (result + a / result) >> 1;\\n            result = (result + a / result) >> 1;\\n            result = (result + a / result) >> 1;\\n            result = (result + a / result) >> 1;\\n            result = (result + a / result) >> 1;\\n            result = (result + a / result) >> 1;\\n            result = (result + a / result) >> 1;\\n            return min(result, a / result);\\n        }\\n    }\\n\\n    /**\\n     * @notice Calculates sqrt(a), following the selected rounding direction.\\n     */\\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n        unchecked {\\n            uint256 result = sqrt(a);\\n            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n        }\\n    }\\n\\n    /**\\n     * @dev Return the log in base 2, rounded down, of a positive value.\\n     * Returns 0 if given 0.\\n     */\\n    function log2(uint256 value) internal pure returns (uint256) {\\n        uint256 result = 0;\\n        unchecked {\\n            if (value >> 128 > 0) {\\n                value >>= 128;\\n                result += 128;\\n            }\\n            if (value >> 64 > 0) {\\n                value >>= 64;\\n                result += 64;\\n            }\\n            if (value >> 32 > 0) {\\n                value >>= 32;\\n                result += 32;\\n            }\\n            if (value >> 16 > 0) {\\n                value >>= 16;\\n                result += 16;\\n            }\\n            if (value >> 8 > 0) {\\n                value >>= 8;\\n                result += 8;\\n            }\\n            if (value >> 4 > 0) {\\n                value >>= 4;\\n                result += 4;\\n            }\\n            if (value >> 2 > 0) {\\n                value >>= 2;\\n                result += 2;\\n            }\\n            if (value >> 1 > 0) {\\n                result += 1;\\n            }\\n        }\\n        return result;\\n    }\\n\\n    /**\\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n     * Returns 0 if given 0.\\n     */\\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n        unchecked {\\n            uint256 result = log2(value);\\n            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n        }\\n    }\\n\\n    /**\\n     * @dev Return the log in base 10, rounded down, of a positive value.\\n     * Returns 0 if given 0.\\n     */\\n    function log10(uint256 value) internal pure returns (uint256) {\\n        uint256 result = 0;\\n        unchecked {\\n            if (value >= 10 ** 64) {\\n                value /= 10 ** 64;\\n                result += 64;\\n            }\\n            if (value >= 10 ** 32) {\\n                value /= 10 ** 32;\\n                result += 32;\\n            }\\n            if (value >= 10 ** 16) {\\n                value /= 10 ** 16;\\n                result += 16;\\n            }\\n            if (value >= 10 ** 8) {\\n                value /= 10 ** 8;\\n                result += 8;\\n            }\\n            if (value >= 10 ** 4) {\\n                value /= 10 ** 4;\\n                result += 4;\\n            }\\n            if (value >= 10 ** 2) {\\n                value /= 10 ** 2;\\n                result += 2;\\n            }\\n            if (value >= 10 ** 1) {\\n                result += 1;\\n            }\\n        }\\n        return result;\\n    }\\n\\n    /**\\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n     * Returns 0 if given 0.\\n     */\\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n        unchecked {\\n            uint256 result = log10(value);\\n            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n        }\\n    }\\n\\n    /**\\n     * @dev Return the log in base 256, rounded down, of a positive value.\\n     * Returns 0 if given 0.\\n     *\\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n     */\\n    function log256(uint256 value) internal pure returns (uint256) {\\n        uint256 result = 0;\\n        unchecked {\\n            if (value >> 128 > 0) {\\n                value >>= 128;\\n                result += 16;\\n            }\\n            if (value >> 64 > 0) {\\n                value >>= 64;\\n                result += 8;\\n            }\\n            if (value >> 32 > 0) {\\n                value >>= 32;\\n                result += 4;\\n            }\\n            if (value >> 16 > 0) {\\n                value >>= 16;\\n                result += 2;\\n            }\\n            if (value >> 8 > 0) {\\n                result += 1;\\n            }\\n        }\\n        return result;\\n    }\\n\\n    /**\\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n     * Returns 0 if given 0.\\n     */\\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n        unchecked {\\n            uint256 result = log256(value);\\n            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n    /**\\n     * @dev Returns the largest of two signed numbers.\\n     */\\n    function max(int256 a, int256 b) internal pure returns (int256) {\\n        return a > b ? a : b;\\n    }\\n\\n    /**\\n     * @dev Returns the smallest of two signed numbers.\\n     */\\n    function min(int256 a, int256 b) internal pure returns (int256) {\\n        return a < b ? a : b;\\n    }\\n\\n    /**\\n     * @dev Returns the average of two signed numbers without overflow.\\n     * The result is rounded towards zero.\\n     */\\n    function average(int256 a, int256 b) internal pure returns (int256) {\\n        // Formula from the book \\\"Hacker's Delight\\\"\\n        int256 x = (a & b) + ((a ^ b) >> 1);\\n        return x + (int256(uint256(x) >> 255) & (a ^ b));\\n    }\\n\\n    /**\\n     * @dev Returns the absolute unsigned value of a signed value.\\n     */\\n    function abs(int256 n) internal pure returns (uint256) {\\n        unchecked {\\n            // must be unchecked in order to support `n = type(int256).min`\\n            return uint256(n >= 0 ? n : -n);\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/ethregistrar/BaseRegistrarImplementation.sol\":{\"content\":\"pragma solidity >=0.8.4;\\n\\nimport \\\"../registry/ENS.sol\\\";\\nimport \\\"./IBaseRegistrar.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\ncontract BaseRegistrarImplementation is ERC721, IBaseRegistrar, Ownable {\\n    // A map of expiry times\\n    mapping(uint256 => uint256) expiries;\\n    // The ENS registry\\n    ENS public ens;\\n    // The namehash of the TLD this registrar owns (eg, .eth)\\n    bytes32 public baseNode;\\n    // A map of addresses that are authorised to register and renew names.\\n    mapping(address => bool) public controllers;\\n    uint256 public constant GRACE_PERIOD = 90 days;\\n    bytes4 private constant INTERFACE_META_ID =\\n        bytes4(keccak256(\\\"supportsInterface(bytes4)\\\"));\\n    bytes4 private constant ERC721_ID =\\n        bytes4(\\n            keccak256(\\\"balanceOf(address)\\\") ^\\n                keccak256(\\\"ownerOf(uint256)\\\") ^\\n                keccak256(\\\"approve(address,uint256)\\\") ^\\n                keccak256(\\\"getApproved(uint256)\\\") ^\\n                keccak256(\\\"setApprovalForAll(address,bool)\\\") ^\\n                keccak256(\\\"isApprovedForAll(address,address)\\\") ^\\n                keccak256(\\\"transferFrom(address,address,uint256)\\\") ^\\n                keccak256(\\\"safeTransferFrom(address,address,uint256)\\\") ^\\n                keccak256(\\\"safeTransferFrom(address,address,uint256,bytes)\\\")\\n        );\\n    bytes4 private constant RECLAIM_ID =\\n        bytes4(keccak256(\\\"reclaim(uint256,address)\\\"));\\n\\n    /// v2.1.3 version of _isApprovedOrOwner which calls ownerOf(tokenId) and takes grace period into consideration instead of ERC721.ownerOf(tokenId);\\n    /// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v2.1.3/contracts/token/ERC721/ERC721.sol#L187\\n    /// @dev Returns whether the given spender can transfer a given token ID\\n    /// @param spender address of the spender to query\\n    /// @param tokenId uint256 ID of the token to be transferred\\n    /// @return bool whether the msg.sender is approved for the given token ID,\\n    ///              is an operator of the owner, or is the owner of the token\\n    function _isApprovedOrOwner(\\n        address spender,\\n        uint256 tokenId\\n    ) internal view override returns (bool) {\\n        address owner = ownerOf(tokenId);\\n        return (spender == owner ||\\n            getApproved(tokenId) == spender ||\\n            isApprovedForAll(owner, spender));\\n    }\\n\\n    constructor(ENS _ens, bytes32 _baseNode) ERC721(\\\"\\\", \\\"\\\") {\\n        ens = _ens;\\n        baseNode = _baseNode;\\n    }\\n\\n    modifier live() {\\n        require(ens.owner(baseNode) == address(this));\\n        _;\\n    }\\n\\n    modifier onlyController() {\\n        require(controllers[msg.sender]);\\n        _;\\n    }\\n\\n    /// @dev Gets the owner of the specified token ID. Names become unowned\\n    ///      when their registration expires.\\n    /// @param tokenId uint256 ID of the token to query the owner of\\n    /// @return address currently marked as the owner of the given token ID\\n    function ownerOf(\\n        uint256 tokenId\\n    ) public view override(IERC721, ERC721) returns (address) {\\n        require(expiries[tokenId] > block.timestamp);\\n        return super.ownerOf(tokenId);\\n    }\\n\\n    // Authorises a controller, who can register and renew domains.\\n    function addController(address controller) external override onlyOwner {\\n        controllers[controller] = true;\\n        emit ControllerAdded(controller);\\n    }\\n\\n    // Revoke controller permission for an address.\\n    function removeController(address controller) external override onlyOwner {\\n        controllers[controller] = false;\\n        emit ControllerRemoved(controller);\\n    }\\n\\n    // Set the resolver for the TLD this registrar manages.\\n    function setResolver(address resolver) external override onlyOwner {\\n        ens.setResolver(baseNode, resolver);\\n    }\\n\\n    // Returns the expiration timestamp of the specified id.\\n    function nameExpires(uint256 id) external view override returns (uint256) {\\n        return expiries[id];\\n    }\\n\\n    // Returns true iff the specified name is available for registration.\\n    function available(uint256 id) public view override returns (bool) {\\n        // Not available if it's registered here or in its grace period.\\n        return expiries[id] + GRACE_PERIOD < block.timestamp;\\n    }\\n\\n    /// @dev Register a name.\\n    /// @param id The token ID (keccak256 of the label).\\n    /// @param owner The address that should own the registration.\\n    /// @param duration Duration in seconds for the registration.\\n    function register(\\n        uint256 id,\\n        address owner,\\n        uint256 duration\\n    ) external override returns (uint256) {\\n        return _register(id, owner, duration, true);\\n    }\\n\\n    /// @dev Register a name, without modifying the registry.\\n    /// @param id The token ID (keccak256 of the label).\\n    /// @param owner The address that should own the registration.\\n    /// @param duration Duration in seconds for the registration.\\n    function registerOnly(\\n        uint256 id,\\n        address owner,\\n        uint256 duration\\n    ) external returns (uint256) {\\n        return _register(id, owner, duration, false);\\n    }\\n\\n    function _register(\\n        uint256 id,\\n        address owner,\\n        uint256 duration,\\n        bool updateRegistry\\n    ) internal live onlyController returns (uint256) {\\n        require(available(id));\\n        require(\\n            block.timestamp + duration + GRACE_PERIOD >\\n                block.timestamp + GRACE_PERIOD\\n        ); // Prevent future overflow\\n\\n        expiries[id] = block.timestamp + duration;\\n        if (_exists(id)) {\\n            // Name was previously owned, and expired\\n            _burn(id);\\n        }\\n        _mint(owner, id);\\n        if (updateRegistry) {\\n            ens.setSubnodeOwner(baseNode, bytes32(id), owner);\\n        }\\n\\n        emit NameRegistered(id, owner, block.timestamp + duration);\\n\\n        return block.timestamp + duration;\\n    }\\n\\n    function renew(\\n        uint256 id,\\n        uint256 duration\\n    ) external override live onlyController returns (uint256) {\\n        require(expiries[id] + GRACE_PERIOD >= block.timestamp); // Name must be registered here or in grace period\\n        require(\\n            expiries[id] + duration + GRACE_PERIOD > duration + GRACE_PERIOD\\n        ); // Prevent future overflow\\n\\n        expiries[id] += duration;\\n        emit NameRenewed(id, expiries[id]);\\n        return expiries[id];\\n    }\\n\\n    /// @dev Reclaim ownership of a name in ENS, if you own it in the registrar.\\n    function reclaim(uint256 id, address owner) external override live {\\n        require(_isApprovedOrOwner(msg.sender, id));\\n        ens.setSubnodeOwner(baseNode, bytes32(id), owner);\\n    }\\n\\n    function supportsInterface(\\n        bytes4 interfaceID\\n    ) public view override(ERC721, IERC165) returns (bool) {\\n        return\\n            interfaceID == INTERFACE_META_ID ||\\n            interfaceID == ERC721_ID ||\\n            interfaceID == RECLAIM_ID;\\n    }\\n}\\n\",\"keccak256\":\"0xf7d55afacf1b9b2c54e2ac3603af9a8a1bcafcb9209d246a7854a28a884f1142\"},\"contracts/ethregistrar/ETHRegistrarController.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ~0.8.17;\\n\\nimport {Ownable} from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport {ERC165} from \\\"@openzeppelin/contracts/utils/introspection/ERC165.sol\\\";\\nimport {IERC165} from \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\n\\nimport {BaseRegistrarImplementation} from \\\"./BaseRegistrarImplementation.sol\\\";\\nimport {StringUtils} from \\\"../utils/StringUtils.sol\\\";\\nimport {Resolver} from \\\"../resolvers/Resolver.sol\\\";\\nimport {ENS} from \\\"../registry/ENS.sol\\\";\\nimport {IReverseRegistrar} from \\\"../reverseRegistrar/IReverseRegistrar.sol\\\";\\nimport {IDefaultReverseRegistrar} from \\\"../reverseRegistrar/IDefaultReverseRegistrar.sol\\\";\\nimport {IETHRegistrarController, IPriceOracle} from \\\"./IETHRegistrarController.sol\\\";\\nimport {ERC20Recoverable} from \\\"../utils/ERC20Recoverable.sol\\\";\\n\\n/// @dev A registrar controller for registering and renewing names at fixed cost.\\ncontract ETHRegistrarController is\\n    Ownable,\\n    IETHRegistrarController,\\n    ERC165,\\n    ERC20Recoverable\\n{\\n    using StringUtils for *;\\n\\n    /// @notice The bitmask for the Ethereum reverse record.\\n    uint8 constant REVERSE_RECORD_ETHEREUM_BIT = 1;\\n\\n    /// @notice The bitmask for the default reverse record.\\n    uint8 constant REVERSE_RECORD_DEFAULT_BIT = 2;\\n\\n    /// @notice The minimum duration for a registration.\\n    uint256 public constant MIN_REGISTRATION_DURATION = 28 days;\\n\\n    // @notice The node (i.e. namehash) for the eth TLD.\\n    bytes32 private constant ETH_NODE =\\n        0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae;\\n\\n    /// @notice The maximum expiry time for a registration.\\n    uint64 private constant MAX_EXPIRY = type(uint64).max;\\n\\n    /// @notice The ENS registry.\\n    ENS public immutable ens;\\n\\n    // @notice The base registrar implementation for the eth TLD.\\n    BaseRegistrarImplementation immutable base;\\n\\n    /// @notice The minimum time a commitment must exist to be valid.\\n    uint256 public immutable minCommitmentAge;\\n\\n    /// @notice The maximum time a commitment can exist to be valid.\\n    uint256 public immutable maxCommitmentAge;\\n\\n    /// @notice The registrar for addr.reverse. (i.e. reverse for coinType 60)\\n    IReverseRegistrar public immutable reverseRegistrar;\\n\\n    /// @notice The registrar for default.reverse. (i.e. fallback reverse for all EVM chains)\\n    IDefaultReverseRegistrar public immutable defaultReverseRegistrar;\\n\\n    /// @notice The price oracle for the eth TLD.\\n    IPriceOracle public immutable prices;\\n\\n    /// @notice A mapping of commitments to their timestamp.\\n    mapping(bytes32 => uint256) public commitments;\\n\\n    /// @notice Thrown when a commitment is not found.\\n    error CommitmentNotFound(bytes32 commitment);\\n\\n    /// @notice Thrown when a commitment is too new.\\n    error CommitmentTooNew(\\n        bytes32 commitment,\\n        uint256 minimumCommitmentTimestamp,\\n        uint256 currentTimestamp\\n    );\\n\\n    /// @notice Thrown when a commitment is too old.\\n    error CommitmentTooOld(\\n        bytes32 commitment,\\n        uint256 maximumCommitmentTimestamp,\\n        uint256 currentTimestamp\\n    );\\n\\n    /// @notice Thrown when a name is not available to register.\\n    error NameNotAvailable(string name);\\n\\n    /// @notice Thrown when the duration supplied for a registration is too short.\\n    error DurationTooShort(uint256 duration);\\n\\n    /// @notice Thrown when data is supplied for a registration without a resolver.\\n    error ResolverRequiredWhenDataSupplied();\\n\\n    /// @notice Thrown when a reverse record is requested without a resolver.\\n    error ResolverRequiredForReverseRecord();\\n\\n    /// @notice Thrown when a matching unexpired commitment exists.\\n    error UnexpiredCommitmentExists(bytes32 commitment);\\n\\n    /// @notice Thrown when the value sent for a registration is insufficient.\\n    error InsufficientValue();\\n\\n    /// @notice Thrown when the maximum commitment age is too low.\\n    error MaxCommitmentAgeTooLow();\\n\\n    /// @notice Thrown when the maximum commitment age is too high.\\n    error MaxCommitmentAgeTooHigh();\\n\\n    /// @notice Emitted when a name is registered.\\n    ///\\n    /// @param label The label of the name.\\n    /// @param labelhash The keccak256 hash of the label.\\n    /// @param owner The owner of the name.\\n    /// @param baseCost The base cost of the name.\\n    /// @param premium The premium cost of the name.\\n    /// @param expires The expiry time of the name.\\n    /// @param referrer The referrer of the registration.\\n    event NameRegistered(\\n        string label,\\n        bytes32 indexed labelhash,\\n        address indexed owner,\\n        uint256 baseCost,\\n        uint256 premium,\\n        uint256 expires,\\n        bytes32 referrer\\n    );\\n\\n    /// @notice Emitted when a name is renewed.\\n    ///\\n    /// @param label The label of the name.\\n    /// @param labelhash The keccak256 hash of the label.\\n    /// @param cost The cost of the name.\\n    /// @param expires The expiry time of the name.\\n    /// @param referrer The referrer of the registration.\\n    event NameRenewed(\\n        string label,\\n        bytes32 indexed labelhash,\\n        uint256 cost,\\n        uint256 expires,\\n        bytes32 referrer\\n    );\\n\\n    /// @notice Constructor for the ETHRegistrarController.\\n    ///\\n    /// @param _base The base registrar implementation for the eth TLD.\\n    /// @param _prices The price oracle for the eth TLD.\\n    /// @param _minCommitmentAge The minimum time a commitment must exist to be valid.\\n    /// @param _maxCommitmentAge The maximum time a commitment can exist to be valid.\\n    /// @param _reverseRegistrar The registrar for addr.reverse.\\n    /// @param _defaultReverseRegistrar The registrar for default.reverse.\\n    /// @param _ens The ENS registry.\\n    constructor(\\n        BaseRegistrarImplementation _base,\\n        IPriceOracle _prices,\\n        uint256 _minCommitmentAge,\\n        uint256 _maxCommitmentAge,\\n        IReverseRegistrar _reverseRegistrar,\\n        IDefaultReverseRegistrar _defaultReverseRegistrar,\\n        ENS _ens\\n    ) {\\n        if (_maxCommitmentAge <= _minCommitmentAge)\\n            revert MaxCommitmentAgeTooLow();\\n\\n        if (_maxCommitmentAge > block.timestamp)\\n            revert MaxCommitmentAgeTooHigh();\\n\\n        ens = _ens;\\n        base = _base;\\n        prices = _prices;\\n        minCommitmentAge = _minCommitmentAge;\\n        maxCommitmentAge = _maxCommitmentAge;\\n        reverseRegistrar = _reverseRegistrar;\\n        defaultReverseRegistrar = _defaultReverseRegistrar;\\n    }\\n\\n    /// @notice Returns the price of a registration for the given label and duration.\\n    ///\\n    /// @param label The label of the name.\\n    /// @param duration The duration of the registration.\\n    /// @return price The price of the registration.\\n    function rentPrice(\\n        string calldata label,\\n        uint256 duration\\n    ) public view override returns (IPriceOracle.Price memory price) {\\n        bytes32 labelhash = keccak256(bytes(label));\\n        price = _rentPrice(label, labelhash, duration);\\n    }\\n\\n    /// @notice Returns true if the label is valid for registration.\\n    ///\\n    /// @param label The label to check.\\n    /// @return True if the label is valid, false otherwise.\\n    function valid(string calldata label) public pure returns (bool) {\\n        return label.strlen() >= 3;\\n    }\\n\\n    /// @notice Returns true if the label is valid and available for registration.\\n    ///\\n    /// @param label The label to check.\\n    /// @return True if the label is valid and available, false otherwise.\\n    function available(\\n        string calldata label\\n    ) public view override returns (bool) {\\n        bytes32 labelhash = keccak256(bytes(label));\\n        return _available(label, labelhash);\\n    }\\n\\n    /// @notice Returns the commitment for a registration.\\n    ///\\n    /// @param registration The registration to make a commitment for.\\n    /// @return commitment The commitment for the registration.\\n    function makeCommitment(\\n        Registration calldata registration\\n    ) public pure override returns (bytes32 commitment) {\\n        if (registration.data.length > 0 && registration.resolver == address(0))\\n            revert ResolverRequiredWhenDataSupplied();\\n\\n        if (\\n            registration.reverseRecord != 0 &&\\n            registration.resolver == address(0)\\n        ) revert ResolverRequiredForReverseRecord();\\n\\n        if (registration.duration < MIN_REGISTRATION_DURATION)\\n            revert DurationTooShort(registration.duration);\\n\\n        return keccak256(abi.encode(registration));\\n    }\\n\\n    /// @notice Commits a registration.\\n    ///\\n    /// @param commitment The commitment to commit.\\n    function commit(bytes32 commitment) public override {\\n        if (commitments[commitment] + maxCommitmentAge >= block.timestamp) {\\n            revert UnexpiredCommitmentExists(commitment);\\n        }\\n        commitments[commitment] = block.timestamp;\\n    }\\n\\n    /// @notice Registers a name.\\n    ///\\n    /// @param registration The registration to register.\\n    /// @param registration.label The label of the name.\\n    /// @param registration.owner The owner of the name.\\n    /// @param registration.duration The duration of the registration.\\n    /// @param registration.resolver The resolver for the name.\\n    /// @param registration.data The data for the name.\\n    /// @param registration.reverseRecord Which reverse record(s) to set.\\n    /// @param registration.referrer The referrer of the registration.\\n    function register(\\n        Registration calldata registration\\n    ) public payable override {\\n        bytes32 labelhash = keccak256(bytes(registration.label));\\n        IPriceOracle.Price memory price = _rentPrice(\\n            registration.label,\\n            labelhash,\\n            registration.duration\\n        );\\n        uint256 totalPrice = price.base + price.premium;\\n        if (msg.value < totalPrice) revert InsufficientValue();\\n\\n        if (!_available(registration.label, labelhash))\\n            revert NameNotAvailable(registration.label);\\n\\n        bytes32 commitment = makeCommitment(registration);\\n        uint256 commitmentTimestamp = commitments[commitment];\\n\\n        // Require an old enough commitment.\\n        if (commitmentTimestamp + minCommitmentAge > block.timestamp)\\n            revert CommitmentTooNew(\\n                commitment,\\n                commitmentTimestamp + minCommitmentAge,\\n                block.timestamp\\n            );\\n\\n        // If the commitment is too old, or the name is registered, stop\\n        if (commitmentTimestamp + maxCommitmentAge <= block.timestamp) {\\n            if (commitmentTimestamp == 0) revert CommitmentNotFound(commitment);\\n            revert CommitmentTooOld(\\n                commitment,\\n                commitmentTimestamp + maxCommitmentAge,\\n                block.timestamp\\n            );\\n        }\\n\\n        delete (commitments[commitment]);\\n\\n        uint256 expires;\\n\\n        if (registration.resolver == address(0)) {\\n            expires = base.register(\\n                uint256(labelhash),\\n                registration.owner,\\n                registration.duration\\n            );\\n        } else {\\n            expires = base.register(\\n                uint256(labelhash),\\n                address(this),\\n                registration.duration\\n            );\\n\\n            bytes32 namehash = keccak256(abi.encodePacked(ETH_NODE, labelhash));\\n            ens.setRecord(\\n                namehash,\\n                registration.owner,\\n                registration.resolver,\\n                0\\n            );\\n            if (registration.data.length > 0)\\n                Resolver(registration.resolver).multicallWithNodeCheck(\\n                    namehash,\\n                    registration.data\\n                );\\n\\n            base.transferFrom(\\n                address(this),\\n                registration.owner,\\n                uint256(labelhash)\\n            );\\n\\n            if (registration.reverseRecord & REVERSE_RECORD_ETHEREUM_BIT != 0)\\n                reverseRegistrar.setNameForAddr(\\n                    msg.sender,\\n                    msg.sender,\\n                    registration.resolver,\\n                    string.concat(registration.label, \\\".eth\\\")\\n                );\\n            if (registration.reverseRecord & REVERSE_RECORD_DEFAULT_BIT != 0)\\n                defaultReverseRegistrar.setNameForAddr(\\n                    msg.sender,\\n                    string.concat(registration.label, \\\".eth\\\")\\n                );\\n        }\\n\\n        emit NameRegistered(\\n            registration.label,\\n            labelhash,\\n            registration.owner,\\n            price.base,\\n            price.premium,\\n            expires,\\n            registration.referrer\\n        );\\n\\n        if (msg.value > totalPrice)\\n            payable(msg.sender).transfer(msg.value - totalPrice);\\n    }\\n\\n    /// @notice Renews a name.\\n    ///\\n    /// @param label The label of the name.\\n    /// @param duration The duration of the registration.\\n    /// @param referrer The referrer of the registration.\\n    function renew(\\n        string calldata label,\\n        uint256 duration,\\n        bytes32 referrer\\n    ) external payable override {\\n        bytes32 labelhash = keccak256(bytes(label));\\n\\n        IPriceOracle.Price memory price = _rentPrice(\\n            label,\\n            labelhash,\\n            duration\\n        );\\n        if (msg.value < price.base) revert InsufficientValue();\\n\\n        uint256 expires = base.renew(uint256(labelhash), duration);\\n\\n        emit NameRenewed(label, labelhash, price.base, expires, referrer);\\n\\n        if (msg.value > price.base)\\n            payable(msg.sender).transfer(msg.value - price.base);\\n    }\\n\\n    /// @notice Withdraws the balance of the contract to the owner.\\n    function withdraw() public {\\n        payable(owner()).transfer(address(this).balance);\\n    }\\n\\n    /// @inheritdoc IERC165\\n    function supportsInterface(\\n        bytes4 interfaceID\\n    ) public view override returns (bool) {\\n        return\\n            interfaceID == type(IETHRegistrarController).interfaceId ||\\n            super.supportsInterface(interfaceID);\\n    }\\n\\n    /* Internal functions */\\n\\n    function _rentPrice(\\n        string calldata label,\\n        bytes32 labelhash,\\n        uint256 duration\\n    ) internal view returns (IPriceOracle.Price memory price) {\\n        price = prices.price(\\n            label,\\n            base.nameExpires(uint256(labelhash)),\\n            duration\\n        );\\n    }\\n\\n    function _available(\\n        string calldata label,\\n        bytes32 labelhash\\n    ) internal view returns (bool) {\\n        return valid(label) && base.available(uint256(labelhash));\\n    }\\n}\\n\",\"keccak256\":\"0xe2dc2abd748fddba9cda518519cbeaf21fde3025bcb529d484a47129ae53151a\",\"license\":\"MIT\"},\"contracts/ethregistrar/IBaseRegistrar.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\nimport \\\"../registry/ENS.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\n\\ninterface IBaseRegistrar is IERC721 {\\n    event ControllerAdded(address indexed controller);\\n    event ControllerRemoved(address indexed controller);\\n    event NameMigrated(\\n        uint256 indexed id,\\n        address indexed owner,\\n        uint256 expires\\n    );\\n    event NameRegistered(\\n        uint256 indexed id,\\n        address indexed owner,\\n        uint256 expires\\n    );\\n    event NameRenewed(uint256 indexed id, uint256 expires);\\n\\n    // Authorises a controller, who can register and renew domains.\\n    function addController(address controller) external;\\n\\n    // Revoke controller permission for an address.\\n    function removeController(address controller) external;\\n\\n    // Set the resolver for the TLD this registrar manages.\\n    function setResolver(address resolver) external;\\n\\n    // Returns the expiration timestamp of the specified label hash.\\n    function nameExpires(uint256 id) external view returns (uint256);\\n\\n    // Returns true if the specified name is available for registration.\\n    function available(uint256 id) external view returns (bool);\\n\\n    /// @dev Register a name.\\n    function register(\\n        uint256 id,\\n        address owner,\\n        uint256 duration\\n    ) external returns (uint256);\\n\\n    function renew(uint256 id, uint256 duration) external returns (uint256);\\n\\n    /// @dev Reclaim ownership of a name in ENS, if you own it in the registrar.\\n    function reclaim(uint256 id, address owner) external;\\n}\\n\",\"keccak256\":\"0x984447817adfb8fc76447da9c24a492379bcfa4cd4e7ed8e795ea1981be3db83\",\"license\":\"MIT\"},\"contracts/ethregistrar/IETHRegistrarController.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ~0.8.17;\\n\\nimport \\\"./IPriceOracle.sol\\\";\\n\\ninterface IETHRegistrarController {\\n    struct Registration {\\n        string label;\\n        address owner;\\n        uint256 duration;\\n        bytes32 secret;\\n        address resolver;\\n        bytes[] data;\\n        uint8 reverseRecord;\\n        bytes32 referrer;\\n    }\\n\\n    function rentPrice(\\n        string memory label,\\n        uint256 duration\\n    ) external view returns (IPriceOracle.Price memory);\\n\\n    function available(string memory label) external returns (bool);\\n\\n    function makeCommitment(\\n        Registration memory registration\\n    ) external pure returns (bytes32 commitment);\\n\\n    function commit(bytes32 commitment) external;\\n\\n    function register(Registration memory registration) external payable;\\n\\n    function renew(\\n        string calldata label,\\n        uint256 duration,\\n        bytes32 referrer\\n    ) external payable;\\n}\\n\",\"keccak256\":\"0x7cd3669d0a5e7bcb8dbf82d33344f54c3b9643127a1d7d54cf69ef4e98188d07\",\"license\":\"MIT\"},\"contracts/ethregistrar/IPriceOracle.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.17 <0.9.0;\\n\\ninterface IPriceOracle {\\n    struct Price {\\n        uint256 base;\\n        uint256 premium;\\n    }\\n\\n    /// @dev Returns the price to register or renew a name.\\n    /// @param name The name being registered or renewed.\\n    /// @param expires When the name presently expires (0 if this is a new registration).\\n    /// @param duration How long the name is being registered or extended for, in seconds.\\n    /// @return base premium tuple of base price + premium price\\n    function price(\\n        string calldata name,\\n        uint256 expires,\\n        uint256 duration\\n    ) external view returns (Price calldata);\\n}\\n\",\"keccak256\":\"0x969d967cd3c79a1d9f631a8dbc416ecd3c6d1492cc3f1e8155a34424ca8b06f6\",\"license\":\"MIT\"},\"contracts/registry/ENS.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface ENS {\\n    // Logged when the owner of a node assigns a new owner to a subnode.\\n    event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);\\n\\n    // Logged when the owner of a node transfers ownership to a new account.\\n    event Transfer(bytes32 indexed node, address owner);\\n\\n    // Logged when the resolver for a node changes.\\n    event NewResolver(bytes32 indexed node, address resolver);\\n\\n    // Logged when the TTL of a node changes\\n    event NewTTL(bytes32 indexed node, uint64 ttl);\\n\\n    // Logged when an operator is added or removed.\\n    event ApprovalForAll(\\n        address indexed owner,\\n        address indexed operator,\\n        bool approved\\n    );\\n\\n    function setRecord(\\n        bytes32 node,\\n        address owner,\\n        address resolver,\\n        uint64 ttl\\n    ) external;\\n\\n    function setSubnodeRecord(\\n        bytes32 node,\\n        bytes32 label,\\n        address owner,\\n        address resolver,\\n        uint64 ttl\\n    ) external;\\n\\n    function setSubnodeOwner(\\n        bytes32 node,\\n        bytes32 label,\\n        address owner\\n    ) external returns (bytes32);\\n\\n    function setResolver(bytes32 node, address resolver) external;\\n\\n    function setOwner(bytes32 node, address owner) external;\\n\\n    function setTTL(bytes32 node, uint64 ttl) external;\\n\\n    function setApprovalForAll(address operator, bool approved) external;\\n\\n    function owner(bytes32 node) external view returns (address);\\n\\n    function resolver(bytes32 node) external view returns (address);\\n\\n    function ttl(bytes32 node) external view returns (uint64);\\n\\n    function recordExists(bytes32 node) external view returns (bool);\\n\\n    function isApprovedForAll(\\n        address owner,\\n        address operator\\n    ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x8e208b44d5dbf22552fe72d79b45c640855b84fbc9ee21f4c3bb4bfe81cbe8db\",\"license\":\"MIT\"},\"contracts/resolvers/Resolver.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\nimport \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport \\\"./profiles/IABIResolver.sol\\\";\\nimport \\\"./profiles/IAddressResolver.sol\\\";\\nimport \\\"./profiles/IAddrResolver.sol\\\";\\nimport \\\"./profiles/IContentHashResolver.sol\\\";\\nimport \\\"./profiles/IDNSRecordResolver.sol\\\";\\nimport \\\"./profiles/IDNSZoneResolver.sol\\\";\\nimport \\\"./profiles/IInterfaceResolver.sol\\\";\\nimport \\\"./profiles/INameResolver.sol\\\";\\nimport \\\"./profiles/IPubkeyResolver.sol\\\";\\nimport \\\"./profiles/ITextResolver.sol\\\";\\nimport \\\"./profiles/IExtendedResolver.sol\\\";\\n\\n/// A generic resolver interface which includes all the functions including the ones deprecated\\ninterface Resolver is\\n    IERC165,\\n    IABIResolver,\\n    IAddressResolver,\\n    IAddrResolver,\\n    IContentHashResolver,\\n    IDNSRecordResolver,\\n    IDNSZoneResolver,\\n    IInterfaceResolver,\\n    INameResolver,\\n    IPubkeyResolver,\\n    ITextResolver,\\n    IExtendedResolver\\n{\\n    /* Deprecated events */\\n    event ContentChanged(bytes32 indexed node, bytes32 hash);\\n\\n    function setApprovalForAll(address, bool) external;\\n\\n    function approve(bytes32 node, address delegate, bool approved) external;\\n\\n    function isApprovedForAll(address account, address operator) external;\\n\\n    function isApprovedFor(\\n        address owner,\\n        bytes32 node,\\n        address delegate\\n    ) external;\\n\\n    function setABI(\\n        bytes32 node,\\n        uint256 contentType,\\n        bytes calldata data\\n    ) external;\\n\\n    function setAddr(bytes32 node, address addr) external;\\n\\n    function setAddr(bytes32 node, uint256 coinType, bytes calldata a) external;\\n\\n    function setContenthash(bytes32 node, bytes calldata hash) external;\\n\\n    function setDnsrr(bytes32 node, bytes calldata data) external;\\n\\n    function setName(bytes32 node, string calldata _name) external;\\n\\n    function setPubkey(bytes32 node, bytes32 x, bytes32 y) external;\\n\\n    function setText(\\n        bytes32 node,\\n        string calldata key,\\n        string calldata value\\n    ) external;\\n\\n    function setInterface(\\n        bytes32 node,\\n        bytes4 interfaceID,\\n        address implementer\\n    ) external;\\n\\n    function multicall(\\n        bytes[] calldata data\\n    ) external returns (bytes[] memory results);\\n\\n    function multicallWithNodeCheck(\\n        bytes32 nodehash,\\n        bytes[] calldata data\\n    ) external returns (bytes[] memory results);\\n\\n    /* Deprecated functions */\\n    function content(bytes32 node) external view returns (bytes32);\\n\\n    function multihash(bytes32 node) external view returns (bytes memory);\\n\\n    function setContent(bytes32 node, bytes32 hash) external;\\n\\n    function setMultihash(bytes32 node, bytes calldata hash) external;\\n}\\n\",\"keccak256\":\"0xef8edb006018266adfb5ece290cae97945040d67da671a61e4039d334ea7bb9b\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IABIResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IABIResolver {\\n    event ABIChanged(bytes32 indexed node, uint256 indexed contentType);\\n\\n    /// Returns the ABI associated with an ENS node.\\n    /// Defined in EIP205.\\n    /// @param node The ENS node to query\\n    /// @param contentTypes A bitwise OR of the ABI formats accepted by the caller.\\n    /// @return contentType The content type of the return value\\n    /// @return data The ABI data\\n    function ABI(\\n        bytes32 node,\\n        uint256 contentTypes\\n    ) external view returns (uint256, bytes memory);\\n}\\n\",\"keccak256\":\"0x3a7a763d7a4f0d196c4b628545b022b1d1d0e37baf84eaa6eecb1a57a1633cad\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IAddrResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\n/// Interface for the legacy (ETH-only) addr function.\\ninterface IAddrResolver {\\n    event AddrChanged(bytes32 indexed node, address a);\\n\\n    /// Returns the address associated with an ENS node.\\n    /// @param node The ENS node to query.\\n    /// @return The associated address.\\n    function addr(bytes32 node) external view returns (address payable);\\n}\\n\",\"keccak256\":\"0x91dd0c350698c505d6c7e4c919da9f981d4b8d7ad062e25073fa1f6af7cb79d1\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IAddressResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\n/// Interface for the new (multicoin) addr function.\\ninterface IAddressResolver {\\n    event AddressChanged(\\n        bytes32 indexed node,\\n        uint256 coinType,\\n        bytes newAddress\\n    );\\n\\n    function addr(\\n        bytes32 node,\\n        uint256 coinType\\n    ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x8da5dd0fc1c5ab4f47e03c23126976a86d4b2dbeac161e70e3af9e2a13330cf0\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IContentHashResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IContentHashResolver {\\n    event ContenthashChanged(bytes32 indexed node, bytes hash);\\n\\n    /// Returns the contenthash associated with an ENS node.\\n    /// @param node The ENS node to query.\\n    /// @return The associated contenthash.\\n    function contenthash(bytes32 node) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xaa978b1ee4c19e99c8aa409dc553e9b4c1bf9fe3c5bad718cd3589e6c9e6d121\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IDNSRecordResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IDNSRecordResolver {\\n    // DNSRecordChanged is emitted whenever a given node/name/resource's RRSET is updated.\\n    event DNSRecordChanged(\\n        bytes32 indexed node,\\n        bytes name,\\n        uint16 resource,\\n        bytes record\\n    );\\n    // DNSRecordDeleted is emitted whenever a given node/name/resource's RRSET is deleted.\\n    event DNSRecordDeleted(bytes32 indexed node, bytes name, uint16 resource);\\n\\n    /// Obtain a DNS record.\\n    /// @param node the namehash of the node for which to fetch the record\\n    /// @param name the keccak-256 hash of the fully-qualified name for which to fetch the record\\n    /// @param resource the ID of the resource as per https://en.wikipedia.org/wiki/List_of_DNS_record_types\\n    /// @return the DNS record in wire format if present, otherwise empty\\n    function dnsRecord(\\n        bytes32 node,\\n        bytes32 name,\\n        uint16 resource\\n    ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x434bf76bba71eed3e0f22b3a5b9f8aaed0ddd8b79f6a1e7c7447785be5924d3b\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IDNSZoneResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IDNSZoneResolver {\\n    // DNSZonehashChanged is emitted whenever a given node's zone hash is updated.\\n    event DNSZonehashChanged(\\n        bytes32 indexed node,\\n        bytes lastzonehash,\\n        bytes zonehash\\n    );\\n\\n    /// zonehash obtains the hash for the zone.\\n    /// @param node The ENS node to query.\\n    /// @return The associated contenthash.\\n    function zonehash(bytes32 node) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x3a028c0b13721c7627c55bbf5a7d0762d5b1db1045fdc0f8e417011876bd2d29\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IExtendedResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IExtendedResolver {\\n    function resolve(\\n        bytes memory name,\\n        bytes memory data\\n    ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x5d81521cfae7d9a4475d27533cd8ed0d3475d369eb0674fd90ffbdbdf292faa3\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IInterfaceResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IInterfaceResolver {\\n    event InterfaceChanged(\\n        bytes32 indexed node,\\n        bytes4 indexed interfaceID,\\n        address implementer\\n    );\\n\\n    /// Returns the address of a contract that implements the specified interface for this name.\\n    /// If an implementer has not been set for this interfaceID and name, the resolver will query\\n    /// the contract at `addr()`. If `addr()` is set, a contract exists at that address, and that\\n    /// contract implements EIP165 and returns `true` for the specified interfaceID, its address\\n    /// will be returned.\\n    /// @param node The ENS node to query.\\n    /// @param interfaceID The EIP 165 interface ID to check for.\\n    /// @return The address that implements this interface, or 0 if the interface is unsupported.\\n    function interfaceImplementer(\\n        bytes32 node,\\n        bytes4 interfaceID\\n    ) external view returns (address);\\n}\\n\",\"keccak256\":\"0x510176a3fe60471775328756ab025d8bafda7063f52f218728ca559b8f61a357\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/INameResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface INameResolver {\\n    event NameChanged(bytes32 indexed node, string name);\\n\\n    /// Returns the name associated with an ENS node, for reverse records.\\n    /// Defined in EIP181.\\n    /// @param node The ENS node to query.\\n    /// @return The associated name.\\n    function name(bytes32 node) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x3ab986332e0baad7aeb4b426aace3aa1c235be5efff8db4b6f1ce501bcdd9e68\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IPubkeyResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IPubkeyResolver {\\n    event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y);\\n\\n    /// Returns the SECP256k1 public key associated with an ENS node.\\n    /// Defined in EIP 619.\\n    /// @param node The ENS node to query\\n    /// @return x The X coordinate of the curve point for the public key.\\n    /// @return y The Y coordinate of the curve point for the public key.\\n    function pubkey(bytes32 node) external view returns (bytes32 x, bytes32 y);\\n}\\n\",\"keccak256\":\"0x1a21561b58ce17db400c015882ff07f12f9bd0df0e7b9305841799aada441820\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/ITextResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface ITextResolver {\\n    event TextChanged(\\n        bytes32 indexed node,\\n        string indexed indexedKey,\\n        string key,\\n        string value\\n    );\\n\\n    /// Returns the text data associated with an ENS node and key.\\n    /// @param node The ENS node to query.\\n    /// @param key The text data key to query.\\n    /// @return The associated text data.\\n    function text(\\n        bytes32 node,\\n        string calldata key\\n    ) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0xe91c15697be2d20417cce3c58d4ecce34796986fdedc97be5b93a823be58e471\",\"license\":\"MIT\"},\"contracts/reverseRegistrar/IDefaultReverseRegistrar.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\n/// @notice Interface for the Default Reverse Registrar.\\ninterface IDefaultReverseRegistrar {\\n    /// @notice Sets the `nameForAddr()` record for the calling account.\\n    ///\\n    /// @param name The name to set.\\n    function setName(string memory name) external;\\n\\n    /// @notice Sets the `nameForAddr()` record for the addr provided account using a signature.\\n    ///\\n    /// @param addr The address to set the name for.\\n    /// @param name The name to set.\\n    /// @param signatureExpiry Date when the signature expires.\\n    /// @param signature The signature from the addr.\\n    function setNameForAddrWithSignature(\\n        address addr,\\n        uint256 signatureExpiry,\\n        string memory name,\\n        bytes memory signature\\n    ) external;\\n\\n    function setNameForAddr(address addr, string memory name) external;\\n}\\n\",\"keccak256\":\"0x45187ce3d3f5da57eac0453ae7df24295e820da379eeaf21cfc967a21038fe7e\",\"license\":\"MIT\"},\"contracts/reverseRegistrar/IReverseRegistrar.sol\":{\"content\":\"pragma solidity >=0.8.4;\\n\\ninterface IReverseRegistrar {\\n    function setDefaultResolver(address resolver) external;\\n\\n    function claim(address owner) external returns (bytes32);\\n\\n    function claimForAddr(\\n        address addr,\\n        address owner,\\n        address resolver\\n    ) external returns (bytes32);\\n\\n    function claimWithResolver(\\n        address owner,\\n        address resolver\\n    ) external returns (bytes32);\\n\\n    function setName(string memory name) external returns (bytes32);\\n\\n    function setNameForAddr(\\n        address addr,\\n        address owner,\\n        address resolver,\\n        string memory name\\n    ) external returns (bytes32);\\n\\n    function node(address addr) external pure returns (bytes32);\\n}\\n\",\"keccak256\":\"0x83adfcf6da72b1bcd1e3ac387afe5fc7fdf7f2ac28b7601544d2ca4b9d45d159\"},\"contracts/utils/ERC20Recoverable.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.17 <0.9.0;\\n\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n/// @notice Contract is used to recover ERC20 tokens sent to the contract by mistake.\\n\\ncontract ERC20Recoverable is Ownable {\\n    /// @notice Recover ERC20 tokens sent to the contract by mistake.\\n    /// @dev The contract is Ownable and only the owner can call the recover function.\\n    /// @param _to The address to send the tokens to.\\n    /// @param _token The address of the ERC20 token to recover\\n    /// @param _amount The amount of tokens to recover.\\n    function recoverFunds(\\n        address _token,\\n        address _to,\\n        uint256 _amount\\n    ) external onlyOwner {\\n        IERC20(_token).transfer(_to, _amount);\\n    }\\n}\\n\",\"keccak256\":\"0xb4d1d380606e2c2949f97894c35cae862c2b7a8a6b034af82513f0e7d81435de\",\"license\":\"MIT\"},\"contracts/utils/StringUtils.sol\":{\"content\":\"pragma solidity >=0.8.4;\\n\\nlibrary StringUtils {\\n    /// @dev Returns the length of a given string\\n    /// @param s The string to measure the length of\\n    /// @return The length of the input string\\n    function strlen(string memory s) internal pure returns (uint256) {\\n        uint256 len;\\n        uint256 i = 0;\\n        uint256 bytelength = bytes(s).length;\\n        for (len = 0; i < bytelength; len++) {\\n            bytes1 b = bytes(s)[i];\\n            if (b < 0x80) {\\n                i += 1;\\n            } else if (b < 0xE0) {\\n                i += 2;\\n            } else if (b < 0xF0) {\\n                i += 3;\\n            } else if (b < 0xF8) {\\n                i += 4;\\n            } else if (b < 0xFC) {\\n                i += 5;\\n            } else {\\n                i += 6;\\n            }\\n        }\\n        return len;\\n    }\\n\\n    /// @dev Escapes special characters in a given string\\n    /// @param str The string to escape\\n    /// @return The escaped string\\n    function escape(string memory str) internal pure returns (string memory) {\\n        bytes memory strBytes = bytes(str);\\n        uint extraChars = 0;\\n\\n        // count extra space needed for escaping\\n        for (uint i = 0; i < strBytes.length; i++) {\\n            if (_needsEscaping(strBytes[i])) {\\n                extraChars++;\\n            }\\n        }\\n\\n        // allocate buffer with the exact size needed\\n        bytes memory buffer = new bytes(strBytes.length + extraChars);\\n        uint index = 0;\\n\\n        // escape characters\\n        for (uint i = 0; i < strBytes.length; i++) {\\n            if (_needsEscaping(strBytes[i])) {\\n                buffer[index++] = \\\"\\\\\\\\\\\";\\n                buffer[index++] = _getEscapedChar(strBytes[i]);\\n            } else {\\n                buffer[index++] = strBytes[i];\\n            }\\n        }\\n\\n        return string(buffer);\\n    }\\n\\n    // determine if a character needs escaping\\n    function _needsEscaping(bytes1 char) private pure returns (bool) {\\n        return\\n            char == '\\\"' ||\\n            char == \\\"/\\\" ||\\n            char == \\\"\\\\\\\\\\\" ||\\n            char == \\\"\\\\n\\\" ||\\n            char == \\\"\\\\r\\\" ||\\n            char == \\\"\\\\t\\\";\\n    }\\n\\n    // get the escaped character\\n    function _getEscapedChar(bytes1 char) private pure returns (bytes1) {\\n        if (char == \\\"\\\\n\\\") return \\\"n\\\";\\n        if (char == \\\"\\\\r\\\") return \\\"r\\\";\\n        if (char == \\\"\\\\t\\\") return \\\"t\\\";\\n        return char;\\n    }\\n}\\n\",\"keccak256\":\"0xcb3dae708e7c20e153b30c2383947135a3bb087ad0adf472f774995a437e9444\"}},\"version\":1}",
  "bytecode": "0x61016060405234801561001157600080fd5b5060405161286638038061286683398101604081905261003091610116565b610039336100ae565b848411610059576040516307cb550760e31b815260040160405180910390fd5b4284111561007a57604051630b4319e560e21b815260040160405180910390fd5b6001600160a01b0390811660805295861660a0529385166101405260c09290925260e052821661010052166101205261019f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038116811461011357600080fd5b50565b600080600080600080600060e0888a03121561013157600080fd5b875161013c816100fe565b602089015190975061014d816100fe565b604089015160608a015160808b0151929850909650945061016d816100fe565b60a089015190935061017e816100fe565b60c089015190925061018f816100fe565b8091505092959891949750929550565b60805160a05160c05160e05161010051610120516101405161260b61025b6000396000818161045601526115ac01526000818161023901526112e30152600081816102a201526111ea01526000818161040201528181610bfb01528181610c68015261142e01526000818161036301528181610b5e0152610b8f01526000818161060501528181610d2201528181610e3e015281816110f2015281816115da01526119e40152600081816101e00152610f13015261260b6000f3fe60806040526004361061016a5760003560e01c80638a95b09f116100cb578063ce1e09c01161007f578063ef9c880511610059578063ef9c880514610478578063f14fcbc81461048b578063f2fde38b146104ab57600080fd5b8063ce1e09c0146103f0578063cf7d6e0114610424578063d3419bf31461044457600080fd5b80638da5cb5b116100b05780638da5cb5b146103855780639791c097146103b0578063aeb8ce9b146103d057600080fd5b80638a95b09f1461033a5780638d839ffe1461035157600080fd5b80635d3590d51161012257806380869853116101075780638086985314610290578063839df945146102c457806383e7f6ff146102ff57600080fd5b80635d3590d51461025b578063715018a61461027b57600080fd5b80633ccfd60b116101535780633ccfd60b146101b95780633f15457f146101ce578063469bf4411461022757600080fd5b806301ffc9a71461016f57806318026ad1146101a4575b600080fd5b34801561017b57600080fd5b5061018f61018a366004611a64565b6104cb565b60405190151581526020015b60405180910390f35b6101b76101b2366004611af6565b610564565b005b3480156101c557600080fd5b506101b761071b565b3480156101da57600080fd5b506102027f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b34801561023357600080fd5b506102027f000000000000000000000000000000000000000000000000000000000000000081565b34801561026757600080fd5b506101b7610276366004611b70565b610765565b34801561028757600080fd5b506101b761080c565b34801561029c57600080fd5b506102027f000000000000000000000000000000000000000000000000000000000000000081565b3480156102d057600080fd5b506102f16102df366004611bad565b60016020526000908152604090205481565b60405190815260200161019b565b34801561030b57600080fd5b5061031f61031a366004611bc6565b610820565b6040805182518152602092830151928101929092520161019b565b34801561034657600080fd5b506102f16224ea0081565b34801561035d57600080fd5b506102f17f000000000000000000000000000000000000000000000000000000000000000081565b34801561039157600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610202565b3480156103bc57600080fd5b5061018f6103cb366004611c12565b610865565b3480156103dc57600080fd5b5061018f6103eb366004611c12565b6108b1565b3480156103fc57600080fd5b506102f17f000000000000000000000000000000000000000000000000000000000000000081565b34801561043057600080fd5b506102f161043f366004611c54565b6108e1565b34801561045057600080fd5b506102027f000000000000000000000000000000000000000000000000000000000000000081565b6101b7610486366004611c54565b610a53565b34801561049757600080fd5b506101b76104a6366004611bad565b611417565b3480156104b757600080fd5b506101b76104c6366004611c90565b6114a0565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe4f37f7900000000000000000000000000000000000000000000000000000000148061055e57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60008484604051610576929190611cab565b60405180910390209050600061058e86868487611554565b80519091503410156105cc576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fc475abff00000000000000000000000000000000000000000000000000000000815260048101839052602481018590526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063c475abff906044016020604051808303816000875af1158015610663573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106879190611cbb565b9050827ffa956c3bce4cb4b01166868ecaf0620566bc7e33fc70b0b9c6aef61e37e50b948888856000015185896040516106c5959493929190611d1d565b60405180910390a2815134111561071257815133906108fc906106e89034611d7d565b6040518115909202916000818181858888f19350505050158015610710573d6000803e3d6000fd5b505b50505050505050565b6000805460405173ffffffffffffffffffffffffffffffffffffffff909116914780156108fc02929091818181858888f19350505050158015610762573d6000803e3d6000fd5b50565b61076d6116a5565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526024820183905284169063a9059cbb906044016020604051808303816000875af11580156107e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108069190611d90565b50505050565b6108146116a5565b61081e6000611726565b565b604080518082019091526000808252602082015260008484604051610846929190611cab565b6040518091039020905061085c85858386611554565b95945050505050565b600060036108a884848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061179b92505050565b10159392505050565b60008083836040516108c4929190611cab565b604051809103902090506108d98484836119a2565b949350505050565b6000806108f160a0840184611db2565b90501180156109255750600061090d60a0840160808501611c90565b73ffffffffffffffffffffffffffffffffffffffff16145b1561095c576040517fd3f605c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61096c60e0830160c08401611e2b565b60ff16158015906109a25750600061098a60a0840160808501611c90565b73ffffffffffffffffffffffffffffffffffffffff16145b156109d9576040517f7d4a034a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6224ea0082604001351015610a2557604080517f9a71997b0000000000000000000000000000000000000000000000000000000081529083013560048201526024015b60405180910390fd5b81604051602001610a369190611f92565b604051602081830303815290604052805190602001209050919050565b6000610a5f828061209e565b604051610a6d929190611cab565b60405190819003902090506000610a92610a87848061209e565b848660400135611554565b9050600081602001518260000151610aaa9190612103565b905080341015610ae6576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610af9610af3858061209e565b856119a2565b610b3b57610b07848061209e565b6040517f477707e8000000000000000000000000000000000000000000000000000000008152600401610a1c929190612116565b6000610b46856108e1565b60008181526001602052604090205490915042610b837f000000000000000000000000000000000000000000000000000000000000000083612103565b1115610bf55781610bb47f000000000000000000000000000000000000000000000000000000000000000083612103565b6040517f74480cc900000000000000000000000000000000000000000000000000000000815260048101929092526024820152426044820152606401610a1c565b42610c207f000000000000000000000000000000000000000000000000000000000000000083612103565b11610cce5780600003610c62576040517f836588c900000000000000000000000000000000000000000000000000000000815260048101839052602401610a1c565b81610c8d7f000000000000000000000000000000000000000000000000000000000000000083612103565b6040517f256e221600000000000000000000000000000000000000000000000000000000815260048101929092526024820152426044820152606401610a1c565b600082815260016020526040812081905580610cf060a0890160808a01611c90565b73ffffffffffffffffffffffffffffffffffffffff1603610dff5773ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663fca247ac87610d5860408b0160208c01611c90565b604080517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b168152600481019390935273ffffffffffffffffffffffffffffffffffffffff90911660248301528a013560448201526064016020604051808303816000875af1158015610dd4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610df89190611cbb565b9050611385565b604080517ffca247ac000000000000000000000000000000000000000000000000000000008152600481018890523060248201529088013560448201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063fca247ac906064016020604051808303816000875af1158015610e9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ec09190611cbb565b604080517f93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae60208201529081018890529091506000906060016040516020818303038152906040528051906020012090507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663cf408823828a6020016020810190610f619190611c90565b610f7160a08d0160808e01611c90565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b168152600481019390935273ffffffffffffffffffffffffffffffffffffffff918216602484015216604482015260006064820152608401600060405180830381600087803b158015610fec57600080fd5b505af1158015611000573d6000803e3d6000fd5b506000925061101591505060a08a018a611db2565b905011156110db5761102d60a0890160808a01611c90565b73ffffffffffffffffffffffffffffffffffffffff1663e32954eb8261105660a08c018c611db2565b6040518463ffffffff1660e01b81526004016110749392919061212a565b6000604051808303816000875af1158015611093573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526110d99190810190612258565b505b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166323b872dd3061112860408c0160208d01611c90565b60405160e084901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff928316600482015291166024820152604481018a9052606401600060405180830381600087803b15801561119c57600080fd5b505af11580156111b0573d6000803e3d6000fd5b50600192506111c891505060e08a0160c08b01611e2b565b1660ff166000146112af5773ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016637a806d6b338061122160a08d0160808e01611c90565b61122b8d8061209e565b60405160200161123c9291906123a1565b6040516020818303038152906040526040518563ffffffff1660e01b815260040161126a949392919061241d565b6020604051808303816000875af1158015611289573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ad9190611cbb565b505b60026112c160e08a0160c08b01611e2b565b1660ff166000146113835773ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663c9119941336113138b8061209e565b6040516020016113249291906123a1565b6040516020818303038152906040526040518363ffffffff1660e01b815260040161135092919061248e565b600060405180830381600087803b15801561136a57600080fd5b505af115801561137e573d6000803e3d6000fd5b505050505b505b6113956040880160208901611c90565b73ffffffffffffffffffffffffffffffffffffffff16867fc2240194853531f1ae318dcef227de79c6ad0fd9d1b0e4fe08568415be2e08a56113d78a8061209e565b89600001518a60200151878e60e001356040516113f9969594939291906124bd565b60405180910390a38334111561071257336108fc6106e88634611d7d565b6000818152600160205260409020544290611453907f000000000000000000000000000000000000000000000000000000000000000090612103565b1061148d576040517f0a059d7100000000000000000000000000000000000000000000000000000000815260048101829052602401610a1c565b6000908152600160205260409020429055565b6114a86116a5565b73ffffffffffffffffffffffffffffffffffffffff811661154b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610a1c565b61076281611726565b60408051808201909152600080825260208201526040517fd6e4fa860000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116916350e9a71591889188917f0000000000000000000000000000000000000000000000000000000000000000169063d6e4fa8690602401602060405180830381865afa158015611621573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116459190611cbb565b866040518563ffffffff1660e01b815260040161166594939291906124f6565b6040805180830381865afa158015611681573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085c919061251d565b60005473ffffffffffffffffffffffffffffffffffffffff16331461081e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a1c565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b8051600090819081905b808210156119995760008583815181106117c1576117c161256e565b01602001517fff000000000000000000000000000000000000000000000000000000000000001690507f80000000000000000000000000000000000000000000000000000000000000008110156118245761181d600184612103565b9250611986565b7fe0000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610156118795761181d600284612103565b7ff0000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610156118ce5761181d600384612103565b7ff8000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610156119235761181d600484612103565b7ffc000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610156119785761181d600584612103565b611983600684612103565b92505b50826119918161259d565b9350506117a5565b50909392505050565b60006119ae8484610865565b80156108d957506040517f96e494e8000000000000000000000000000000000000000000000000000000008152600481018390527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906396e494e890602401602060405180830381865afa158015611a40573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d99190611d90565b600060208284031215611a7657600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611aa657600080fd5b9392505050565b60008083601f840112611abf57600080fd5b50813567ffffffffffffffff811115611ad757600080fd5b602083019150836020828501011115611aef57600080fd5b9250929050565b60008060008060608587031215611b0c57600080fd5b843567ffffffffffffffff811115611b2357600080fd5b611b2f87828801611aad565b90989097506020870135966040013595509350505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611b6b57600080fd5b919050565b600080600060608486031215611b8557600080fd5b611b8e84611b47565b9250611b9c60208501611b47565b929592945050506040919091013590565b600060208284031215611bbf57600080fd5b5035919050565b600080600060408486031215611bdb57600080fd5b833567ffffffffffffffff811115611bf257600080fd5b611bfe86828701611aad565b909790965060209590950135949350505050565b60008060208385031215611c2557600080fd5b823567ffffffffffffffff811115611c3c57600080fd5b611c4885828601611aad565b90969095509350505050565b600060208284031215611c6657600080fd5b813567ffffffffffffffff811115611c7d57600080fd5b82016101008185031215611aa657600080fd5b600060208284031215611ca257600080fd5b611aa682611b47565b8183823760009101908152919050565b600060208284031215611ccd57600080fd5b5051919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b608081526000611d31608083018789611cd4565b602083019590955250604081019290925260609091015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561055e5761055e611d4e565b600060208284031215611da257600080fd5b81518015158114611aa657600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611de757600080fd5b83018035915067ffffffffffffffff821115611e0257600080fd5b6020019150600581901b3603821315611aef57600080fd5b803560ff81168114611b6b57600080fd5b600060208284031215611e3d57600080fd5b611aa682611e1a565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611e7b57600080fd5b830160208101925035905067ffffffffffffffff811115611e9b57600080fd5b803603821315611aef57600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611edf57600080fd5b830160208101925035905067ffffffffffffffff811115611eff57600080fd5b8060051b3603821315611aef57600080fd5b60008383855260208501945060208460051b8201018360005b86811015611f86577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848403018852611f638287611e46565b611f6e858284611cd4565b60209a8b019a90955093909301925050600101611f2a565b50909695505050505050565b602081526000611fa28384611e46565b6101006020850152611fb961012085018284611cd4565b91505073ffffffffffffffffffffffffffffffffffffffff611fdd60208601611b47565b166040840152600060408501359050806060850152506000606085013590508060808501525061200f60808501611b47565b73ffffffffffffffffffffffffffffffffffffffff811660a08501525061203960a0850185611eaa565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08584030160c086015261206e838284611f11565b9250505061207e60c08501611e1a565b60ff811660e08501525060e0939093013561010092909201919091525090565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126120d357600080fd5b83018035915067ffffffffffffffff8211156120ee57600080fd5b602001915036819003821315611aef57600080fd5b8082018082111561055e5761055e611d4e565b6020815260006108d9602083018486611cd4565b838152604060208201819052810182905260006060600584901b8301810190830185835b868110156121a9577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08685030183526121878289611e46565b612192868284611cd4565b95505050602092830192919091019060010161214e565b5091979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561222c5761222c6121b6565b604052919050565b60005b8381101561224f578181015183820152602001612237565b50506000910152565b60006020828403121561226a57600080fd5b815167ffffffffffffffff81111561228157600080fd5b8201601f8101841361229257600080fd5b805167ffffffffffffffff8111156122ac576122ac6121b6565b8060051b6122bc602082016121e5565b918252602081840181019290810190878411156122d857600080fd5b6020850192505b8383101561239657825167ffffffffffffffff8111156122fe57600080fd5b8501603f8101891361230f57600080fd5b602081015167ffffffffffffffff81111561232c5761232c6121b6565b61235d60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016121e5565b8181526040838301018b101561237257600080fd5b612383826020830160408601612234565b84525050602092830192909101906122df565b979650505050505050565b818382377f2e657468000000000000000000000000000000000000000000000000000000009101908152600401919050565b600081518084526123eb816020860160208601612234565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff8516815273ffffffffffffffffffffffffffffffffffffffff8416602082015273ffffffffffffffffffffffffffffffffffffffff8316604082015260806060820152600061248460808301846123d3565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006108d960408301846123d3565b60a0815260006124d160a08301888a611cd4565b9050856020830152846040830152836060830152826080830152979650505050505050565b60608152600061250a606083018688611cd4565b6020830194909452506040015292915050565b6000604082840312801561253057600080fd5b506040805190810167ffffffffffffffff81118282101715612554576125546121b6565b604052825181526020928301519281019290925250919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036125ce576125ce611d4e565b506001019056fea26469706673582212208bee915ecb306c877275eb5c18de7470963c9da7e88602549d73c9e08160d97b64736f6c634300081a0033",
  "deployedBytecode": "0x60806040526004361061016a5760003560e01c80638a95b09f116100cb578063ce1e09c01161007f578063ef9c880511610059578063ef9c880514610478578063f14fcbc81461048b578063f2fde38b146104ab57600080fd5b8063ce1e09c0146103f0578063cf7d6e0114610424578063d3419bf31461044457600080fd5b80638da5cb5b116100b05780638da5cb5b146103855780639791c097146103b0578063aeb8ce9b146103d057600080fd5b80638a95b09f1461033a5780638d839ffe1461035157600080fd5b80635d3590d51161012257806380869853116101075780638086985314610290578063839df945146102c457806383e7f6ff146102ff57600080fd5b80635d3590d51461025b578063715018a61461027b57600080fd5b80633ccfd60b116101535780633ccfd60b146101b95780633f15457f146101ce578063469bf4411461022757600080fd5b806301ffc9a71461016f57806318026ad1146101a4575b600080fd5b34801561017b57600080fd5b5061018f61018a366004611a64565b6104cb565b60405190151581526020015b60405180910390f35b6101b76101b2366004611af6565b610564565b005b3480156101c557600080fd5b506101b761071b565b3480156101da57600080fd5b506102027f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b34801561023357600080fd5b506102027f000000000000000000000000000000000000000000000000000000000000000081565b34801561026757600080fd5b506101b7610276366004611b70565b610765565b34801561028757600080fd5b506101b761080c565b34801561029c57600080fd5b506102027f000000000000000000000000000000000000000000000000000000000000000081565b3480156102d057600080fd5b506102f16102df366004611bad565b60016020526000908152604090205481565b60405190815260200161019b565b34801561030b57600080fd5b5061031f61031a366004611bc6565b610820565b6040805182518152602092830151928101929092520161019b565b34801561034657600080fd5b506102f16224ea0081565b34801561035d57600080fd5b506102f17f000000000000000000000000000000000000000000000000000000000000000081565b34801561039157600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610202565b3480156103bc57600080fd5b5061018f6103cb366004611c12565b610865565b3480156103dc57600080fd5b5061018f6103eb366004611c12565b6108b1565b3480156103fc57600080fd5b506102f17f000000000000000000000000000000000000000000000000000000000000000081565b34801561043057600080fd5b506102f161043f366004611c54565b6108e1565b34801561045057600080fd5b506102027f000000000000000000000000000000000000000000000000000000000000000081565b6101b7610486366004611c54565b610a53565b34801561049757600080fd5b506101b76104a6366004611bad565b611417565b3480156104b757600080fd5b506101b76104c6366004611c90565b6114a0565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe4f37f7900000000000000000000000000000000000000000000000000000000148061055e57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60008484604051610576929190611cab565b60405180910390209050600061058e86868487611554565b80519091503410156105cc576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fc475abff00000000000000000000000000000000000000000000000000000000815260048101839052602481018590526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063c475abff906044016020604051808303816000875af1158015610663573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106879190611cbb565b9050827ffa956c3bce4cb4b01166868ecaf0620566bc7e33fc70b0b9c6aef61e37e50b948888856000015185896040516106c5959493929190611d1d565b60405180910390a2815134111561071257815133906108fc906106e89034611d7d565b6040518115909202916000818181858888f19350505050158015610710573d6000803e3d6000fd5b505b50505050505050565b6000805460405173ffffffffffffffffffffffffffffffffffffffff909116914780156108fc02929091818181858888f19350505050158015610762573d6000803e3d6000fd5b50565b61076d6116a5565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526024820183905284169063a9059cbb906044016020604051808303816000875af11580156107e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108069190611d90565b50505050565b6108146116a5565b61081e6000611726565b565b604080518082019091526000808252602082015260008484604051610846929190611cab565b6040518091039020905061085c85858386611554565b95945050505050565b600060036108a884848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061179b92505050565b10159392505050565b60008083836040516108c4929190611cab565b604051809103902090506108d98484836119a2565b949350505050565b6000806108f160a0840184611db2565b90501180156109255750600061090d60a0840160808501611c90565b73ffffffffffffffffffffffffffffffffffffffff16145b1561095c576040517fd3f605c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61096c60e0830160c08401611e2b565b60ff16158015906109a25750600061098a60a0840160808501611c90565b73ffffffffffffffffffffffffffffffffffffffff16145b156109d9576040517f7d4a034a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6224ea0082604001351015610a2557604080517f9a71997b0000000000000000000000000000000000000000000000000000000081529083013560048201526024015b60405180910390fd5b81604051602001610a369190611f92565b604051602081830303815290604052805190602001209050919050565b6000610a5f828061209e565b604051610a6d929190611cab565b60405190819003902090506000610a92610a87848061209e565b848660400135611554565b9050600081602001518260000151610aaa9190612103565b905080341015610ae6576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610af9610af3858061209e565b856119a2565b610b3b57610b07848061209e565b6040517f477707e8000000000000000000000000000000000000000000000000000000008152600401610a1c929190612116565b6000610b46856108e1565b60008181526001602052604090205490915042610b837f000000000000000000000000000000000000000000000000000000000000000083612103565b1115610bf55781610bb47f000000000000000000000000000000000000000000000000000000000000000083612103565b6040517f74480cc900000000000000000000000000000000000000000000000000000000815260048101929092526024820152426044820152606401610a1c565b42610c207f000000000000000000000000000000000000000000000000000000000000000083612103565b11610cce5780600003610c62576040517f836588c900000000000000000000000000000000000000000000000000000000815260048101839052602401610a1c565b81610c8d7f000000000000000000000000000000000000000000000000000000000000000083612103565b6040517f256e221600000000000000000000000000000000000000000000000000000000815260048101929092526024820152426044820152606401610a1c565b600082815260016020526040812081905580610cf060a0890160808a01611c90565b73ffffffffffffffffffffffffffffffffffffffff1603610dff5773ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663fca247ac87610d5860408b0160208c01611c90565b604080517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b168152600481019390935273ffffffffffffffffffffffffffffffffffffffff90911660248301528a013560448201526064016020604051808303816000875af1158015610dd4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610df89190611cbb565b9050611385565b604080517ffca247ac000000000000000000000000000000000000000000000000000000008152600481018890523060248201529088013560448201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063fca247ac906064016020604051808303816000875af1158015610e9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ec09190611cbb565b604080517f93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae60208201529081018890529091506000906060016040516020818303038152906040528051906020012090507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663cf408823828a6020016020810190610f619190611c90565b610f7160a08d0160808e01611c90565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b168152600481019390935273ffffffffffffffffffffffffffffffffffffffff918216602484015216604482015260006064820152608401600060405180830381600087803b158015610fec57600080fd5b505af1158015611000573d6000803e3d6000fd5b506000925061101591505060a08a018a611db2565b905011156110db5761102d60a0890160808a01611c90565b73ffffffffffffffffffffffffffffffffffffffff1663e32954eb8261105660a08c018c611db2565b6040518463ffffffff1660e01b81526004016110749392919061212a565b6000604051808303816000875af1158015611093573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526110d99190810190612258565b505b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166323b872dd3061112860408c0160208d01611c90565b60405160e084901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff928316600482015291166024820152604481018a9052606401600060405180830381600087803b15801561119c57600080fd5b505af11580156111b0573d6000803e3d6000fd5b50600192506111c891505060e08a0160c08b01611e2b565b1660ff166000146112af5773ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016637a806d6b338061122160a08d0160808e01611c90565b61122b8d8061209e565b60405160200161123c9291906123a1565b6040516020818303038152906040526040518563ffffffff1660e01b815260040161126a949392919061241d565b6020604051808303816000875af1158015611289573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ad9190611cbb565b505b60026112c160e08a0160c08b01611e2b565b1660ff166000146113835773ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663c9119941336113138b8061209e565b6040516020016113249291906123a1565b6040516020818303038152906040526040518363ffffffff1660e01b815260040161135092919061248e565b600060405180830381600087803b15801561136a57600080fd5b505af115801561137e573d6000803e3d6000fd5b505050505b505b6113956040880160208901611c90565b73ffffffffffffffffffffffffffffffffffffffff16867fc2240194853531f1ae318dcef227de79c6ad0fd9d1b0e4fe08568415be2e08a56113d78a8061209e565b89600001518a60200151878e60e001356040516113f9969594939291906124bd565b60405180910390a38334111561071257336108fc6106e88634611d7d565b6000818152600160205260409020544290611453907f000000000000000000000000000000000000000000000000000000000000000090612103565b1061148d576040517f0a059d7100000000000000000000000000000000000000000000000000000000815260048101829052602401610a1c565b6000908152600160205260409020429055565b6114a86116a5565b73ffffffffffffffffffffffffffffffffffffffff811661154b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610a1c565b61076281611726565b60408051808201909152600080825260208201526040517fd6e4fa860000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116916350e9a71591889188917f0000000000000000000000000000000000000000000000000000000000000000169063d6e4fa8690602401602060405180830381865afa158015611621573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116459190611cbb565b866040518563ffffffff1660e01b815260040161166594939291906124f6565b6040805180830381865afa158015611681573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085c919061251d565b60005473ffffffffffffffffffffffffffffffffffffffff16331461081e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a1c565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b8051600090819081905b808210156119995760008583815181106117c1576117c161256e565b01602001517fff000000000000000000000000000000000000000000000000000000000000001690507f80000000000000000000000000000000000000000000000000000000000000008110156118245761181d600184612103565b9250611986565b7fe0000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610156118795761181d600284612103565b7ff0000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610156118ce5761181d600384612103565b7ff8000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610156119235761181d600484612103565b7ffc000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610156119785761181d600584612103565b611983600684612103565b92505b50826119918161259d565b9350506117a5565b50909392505050565b60006119ae8484610865565b80156108d957506040517f96e494e8000000000000000000000000000000000000000000000000000000008152600481018390527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906396e494e890602401602060405180830381865afa158015611a40573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d99190611d90565b600060208284031215611a7657600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611aa657600080fd5b9392505050565b60008083601f840112611abf57600080fd5b50813567ffffffffffffffff811115611ad757600080fd5b602083019150836020828501011115611aef57600080fd5b9250929050565b60008060008060608587031215611b0c57600080fd5b843567ffffffffffffffff811115611b2357600080fd5b611b2f87828801611aad565b90989097506020870135966040013595509350505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611b6b57600080fd5b919050565b600080600060608486031215611b8557600080fd5b611b8e84611b47565b9250611b9c60208501611b47565b929592945050506040919091013590565b600060208284031215611bbf57600080fd5b5035919050565b600080600060408486031215611bdb57600080fd5b833567ffffffffffffffff811115611bf257600080fd5b611bfe86828701611aad565b909790965060209590950135949350505050565b60008060208385031215611c2557600080fd5b823567ffffffffffffffff811115611c3c57600080fd5b611c4885828601611aad565b90969095509350505050565b600060208284031215611c6657600080fd5b813567ffffffffffffffff811115611c7d57600080fd5b82016101008185031215611aa657600080fd5b600060208284031215611ca257600080fd5b611aa682611b47565b8183823760009101908152919050565b600060208284031215611ccd57600080fd5b5051919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b608081526000611d31608083018789611cd4565b602083019590955250604081019290925260609091015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561055e5761055e611d4e565b600060208284031215611da257600080fd5b81518015158114611aa657600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611de757600080fd5b83018035915067ffffffffffffffff821115611e0257600080fd5b6020019150600581901b3603821315611aef57600080fd5b803560ff81168114611b6b57600080fd5b600060208284031215611e3d57600080fd5b611aa682611e1a565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611e7b57600080fd5b830160208101925035905067ffffffffffffffff811115611e9b57600080fd5b803603821315611aef57600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611edf57600080fd5b830160208101925035905067ffffffffffffffff811115611eff57600080fd5b8060051b3603821315611aef57600080fd5b60008383855260208501945060208460051b8201018360005b86811015611f86577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848403018852611f638287611e46565b611f6e858284611cd4565b60209a8b019a90955093909301925050600101611f2a565b50909695505050505050565b602081526000611fa28384611e46565b6101006020850152611fb961012085018284611cd4565b91505073ffffffffffffffffffffffffffffffffffffffff611fdd60208601611b47565b166040840152600060408501359050806060850152506000606085013590508060808501525061200f60808501611b47565b73ffffffffffffffffffffffffffffffffffffffff811660a08501525061203960a0850185611eaa565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08584030160c086015261206e838284611f11565b9250505061207e60c08501611e1a565b60ff811660e08501525060e0939093013561010092909201919091525090565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126120d357600080fd5b83018035915067ffffffffffffffff8211156120ee57600080fd5b602001915036819003821315611aef57600080fd5b8082018082111561055e5761055e611d4e565b6020815260006108d9602083018486611cd4565b838152604060208201819052810182905260006060600584901b8301810190830185835b868110156121a9577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08685030183526121878289611e46565b612192868284611cd4565b95505050602092830192919091019060010161214e565b5091979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561222c5761222c6121b6565b604052919050565b60005b8381101561224f578181015183820152602001612237565b50506000910152565b60006020828403121561226a57600080fd5b815167ffffffffffffffff81111561228157600080fd5b8201601f8101841361229257600080fd5b805167ffffffffffffffff8111156122ac576122ac6121b6565b8060051b6122bc602082016121e5565b918252602081840181019290810190878411156122d857600080fd5b6020850192505b8383101561239657825167ffffffffffffffff8111156122fe57600080fd5b8501603f8101891361230f57600080fd5b602081015167ffffffffffffffff81111561232c5761232c6121b6565b61235d60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016121e5565b8181526040838301018b101561237257600080fd5b612383826020830160408601612234565b84525050602092830192909101906122df565b979650505050505050565b818382377f2e657468000000000000000000000000000000000000000000000000000000009101908152600401919050565b600081518084526123eb816020860160208601612234565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff8516815273ffffffffffffffffffffffffffffffffffffffff8416602082015273ffffffffffffffffffffffffffffffffffffffff8316604082015260806060820152600061248460808301846123d3565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006108d960408301846123d3565b60a0815260006124d160a08301888a611cd4565b9050856020830152846040830152836060830152826080830152979650505050505050565b60608152600061250a606083018688611cd4565b6020830194909452506040015292915050565b6000604082840312801561253057600080fd5b506040805190810167ffffffffffffffff81118282101715612554576125546121b6565b604052825181526020928301519281019290925250919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036125ce576125ce611d4e565b506001019056fea26469706673582212208bee915ecb306c877275eb5c18de7470963c9da7e88602549d73c9e08160d97b64736f6c634300081a0033",
  "devdoc": {
    "details": "A registrar controller for registering and renewing names at fixed cost.",
    "events": {
      "NameRegistered(string,bytes32,address,uint256,uint256,uint256,bytes32)": {
        "params": {
          "baseCost": "The base cost of the name.",
          "expires": "The expiry time of the name.",
          "label": "The label of the name.",
          "labelhash": "The keccak256 hash of the label.",
          "owner": "The owner of the name.",
          "premium": "The premium cost of the name.",
          "referrer": "The referrer of the registration."
        }
      },
      "NameRenewed(string,bytes32,uint256,uint256,bytes32)": {
        "params": {
          "cost": "The cost of the name.",
          "expires": "The expiry time of the name.",
          "label": "The label of the name.",
          "labelhash": "The keccak256 hash of the label.",
          "referrer": "The referrer of the registration."
        }
      }
    },
    "kind": "dev",
    "methods": {
      "available(string)": {
        "params": {
          "label": "The label to check."
        },
        "returns": {
          "_0": "True if the label is valid and available, false otherwise."
        }
      },
      "commit(bytes32)": {
        "params": {
          "commitment": "The commitment to commit."
        }
      },
      "constructor": {
        "params": {
          "_base": "The base registrar implementation for the eth TLD.",
          "_defaultReverseRegistrar": "The registrar for default.reverse.",
          "_ens": "The ENS registry.",
          "_maxCommitmentAge": "The maximum time a commitment can exist to be valid.",
          "_minCommitmentAge": "The minimum time a commitment must exist to be valid.",
          "_prices": "The price oracle for the eth TLD.",
          "_reverseRegistrar": "The registrar for addr.reverse."
        }
      },
      "makeCommitment((string,address,uint256,bytes32,address,bytes[],uint8,bytes32))": {
        "params": {
          "registration": "The registration to make a commitment for."
        },
        "returns": {
          "commitment": "The commitment for the registration."
        }
      },
      "owner()": {
        "details": "Returns the address of the current owner."
      },
      "recoverFunds(address,address,uint256)": {
        "details": "The contract is Ownable and only the owner can call the recover function.",
        "params": {
          "_amount": "The amount of tokens to recover.",
          "_to": "The address to send the tokens to.",
          "_token": "The address of the ERC20 token to recover"
        }
      },
      "register((string,address,uint256,bytes32,address,bytes[],uint8,bytes32))": {
        "params": {
          "registration": ".referrer The referrer of the registration."
        }
      },
      "renew(string,uint256,bytes32)": {
        "params": {
          "duration": "The duration of the registration.",
          "label": "The label of the name.",
          "referrer": "The referrer of the registration."
        }
      },
      "renounceOwnership()": {
        "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner."
      },
      "rentPrice(string,uint256)": {
        "params": {
          "duration": "The duration of the registration.",
          "label": "The label of the name."
        },
        "returns": {
          "price": "The price of the registration."
        }
      },
      "supportsInterface(bytes4)": {
        "details": "Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas."
      },
      "transferOwnership(address)": {
        "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
      },
      "valid(string)": {
        "params": {
          "label": "The label to check."
        },
        "returns": {
          "_0": "True if the label is valid, false otherwise."
        }
      }
    },
    "version": 1
  },
  "userdoc": {
    "errors": {
      "CommitmentNotFound(bytes32)": [
        {
          "notice": "Thrown when a commitment is not found."
        }
      ],
      "CommitmentTooNew(bytes32,uint256,uint256)": [
        {
          "notice": "Thrown when a commitment is too new."
        }
      ],
      "CommitmentTooOld(bytes32,uint256,uint256)": [
        {
          "notice": "Thrown when a commitment is too old."
        }
      ],
      "DurationTooShort(uint256)": [
        {
          "notice": "Thrown when the duration supplied for a registration is too short."
        }
      ],
      "InsufficientValue()": [
        {
          "notice": "Thrown when the value sent for a registration is insufficient."
        }
      ],
      "MaxCommitmentAgeTooHigh()": [
        {
          "notice": "Thrown when the maximum commitment age is too high."
        }
      ],
      "MaxCommitmentAgeTooLow()": [
        {
          "notice": "Thrown when the maximum commitment age is too low."
        }
      ],
      "NameNotAvailable(string)": [
        {
          "notice": "Thrown when a name is not available to register."
        }
      ],
      "ResolverRequiredForReverseRecord()": [
        {
          "notice": "Thrown when a reverse record is requested without a resolver."
        }
      ],
      "ResolverRequiredWhenDataSupplied()": [
        {
          "notice": "Thrown when data is supplied for a registration without a resolver."
        }
      ],
      "UnexpiredCommitmentExists(bytes32)": [
        {
          "notice": "Thrown when a matching unexpired commitment exists."
        }
      ]
    },
    "events": {
      "NameRegistered(string,bytes32,address,uint256,uint256,uint256,bytes32)": {
        "notice": "Emitted when a name is registered."
      },
      "NameRenewed(string,bytes32,uint256,uint256,bytes32)": {
        "notice": "Emitted when a name is renewed."
      }
    },
    "kind": "user",
    "methods": {
      "MIN_REGISTRATION_DURATION()": {
        "notice": "The minimum duration for a registration."
      },
      "available(string)": {
        "notice": "Returns true if the label is valid and available for registration."
      },
      "commit(bytes32)": {
        "notice": "Commits a registration."
      },
      "commitments(bytes32)": {
        "notice": "A mapping of commitments to their timestamp."
      },
      "constructor": {
        "notice": "Constructor for the ETHRegistrarController."
      },
      "defaultReverseRegistrar()": {
        "notice": "The registrar for default.reverse. (i.e. fallback reverse for all EVM chains)"
      },
      "ens()": {
        "notice": "The ENS registry."
      },
      "makeCommitment((string,address,uint256,bytes32,address,bytes[],uint8,bytes32))": {
        "notice": "Returns the commitment for a registration."
      },
      "maxCommitmentAge()": {
        "notice": "The maximum time a commitment can exist to be valid."
      },
      "minCommitmentAge()": {
        "notice": "The minimum time a commitment must exist to be valid."
      },
      "prices()": {
        "notice": "The price oracle for the eth TLD."
      },
      "recoverFunds(address,address,uint256)": {
        "notice": "Recover ERC20 tokens sent to the contract by mistake."
      },
      "register((string,address,uint256,bytes32,address,bytes[],uint8,bytes32))": {
        "notice": "Registers a name."
      },
      "renew(string,uint256,bytes32)": {
        "notice": "Renews a name."
      },
      "rentPrice(string,uint256)": {
        "notice": "Returns the price of a registration for the given label and duration."
      },
      "reverseRegistrar()": {
        "notice": "The registrar for addr.reverse. (i.e. reverse for coinType 60)"
      },
      "valid(string)": {
        "notice": "Returns true if the label is valid for registration."
      },
      "withdraw()": {
        "notice": "Withdraws the balance of the contract to the owner."
      }
    },
    "version": 1
  },
  "storageLayout": {
    "storage": [
      {
        "astId": 5090,
        "contract": "contracts/ethregistrar/ETHRegistrarController.sol:ETHRegistrarController",
        "label": "_owner",
        "offset": 0,
        "slot": "0",
        "type": "t_address"
      },
      {
        "astId": 19743,
        "contract": "contracts/ethregistrar/ETHRegistrarController.sol:ETHRegistrarController",
        "label": "commitments",
        "offset": 0,
        "slot": "1",
        "type": "t_mapping(t_bytes32,t_uint256)"
      }
    ],
    "types": {
      "t_address": {
        "encoding": "inplace",
        "label": "address",
        "numberOfBytes": "20"
      },
      "t_bytes32": {
        "encoding": "inplace",
        "label": "bytes32",
        "numberOfBytes": "32"
      },
      "t_mapping(t_bytes32,t_uint256)": {
        "encoding": "mapping",
        "key": "t_bytes32",
        "label": "mapping(bytes32 => uint256)",
        "numberOfBytes": "32",
        "value": "t_uint256"
      },
      "t_uint256": {
        "encoding": "inplace",
        "label": "uint256",
        "numberOfBytes": "32"
      }
    }
  }
}