{
  "address": "0xED73a03F19e8D849E44a39252d222c6ad5217E1e",
  "abi": [
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "owner",
          "type": "address"
        },
        {
          "internalType": "contract ENS",
          "name": "ens",
          "type": "address"
        },
        {
          "internalType": "contract IGatewayProvider",
          "name": "batchGatewayProvider",
          "type": "address"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "constructor"
    },
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "dns",
          "type": "bytes"
        }
      ],
      "name": "DNSDecodingFailed",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "string",
          "name": "ens",
          "type": "string"
        }
      ],
      "name": "DNSEncodingFailed",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "EmptyAddress",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "uint16",
          "name": "status",
          "type": "uint16"
        },
        {
          "internalType": "string",
          "name": "message",
          "type": "string"
        }
      ],
      "name": "HttpError",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "InvalidBatchGatewayResponse",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "sender",
          "type": "address"
        },
        {
          "internalType": "string[]",
          "name": "urls",
          "type": "string[]"
        },
        {
          "internalType": "bytes",
          "name": "callData",
          "type": "bytes"
        },
        {
          "internalType": "bytes4",
          "name": "callbackFunction",
          "type": "bytes4"
        },
        {
          "internalType": "bytes",
          "name": "extraData",
          "type": "bytes"
        }
      ],
      "name": "OffchainLookup",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "offset",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "length",
          "type": "uint256"
        }
      ],
      "name": "OffsetOutOfBoundsError",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "errorData",
          "type": "bytes"
        }
      ],
      "name": "ResolverError",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "name",
          "type": "bytes"
        },
        {
          "internalType": "address",
          "name": "resolver",
          "type": "address"
        }
      ],
      "name": "ResolverNotContract",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "name",
          "type": "bytes"
        }
      ],
      "name": "ResolverNotFound",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "string",
          "name": "primary",
          "type": "string"
        },
        {
          "internalType": "bytes",
          "name": "primaryAddress",
          "type": "bytes"
        }
      ],
      "name": "ReverseAddressMismatch",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "bytes4",
          "name": "selector",
          "type": "bytes4"
        }
      ],
      "name": "UnsupportedResolverProfile",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "batchGatewayProvider",
      "outputs": [
        {
          "internalType": "contract IGatewayProvider",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "components": [
            {
              "components": [
                {
                  "internalType": "address",
                  "name": "target",
                  "type": "address"
                },
                {
                  "internalType": "bytes",
                  "name": "call",
                  "type": "bytes"
                },
                {
                  "internalType": "bytes",
                  "name": "data",
                  "type": "bytes"
                },
                {
                  "internalType": "uint256",
                  "name": "flags",
                  "type": "uint256"
                }
              ],
              "internalType": "struct CCIPBatcher.Lookup[]",
              "name": "lookups",
              "type": "tuple[]"
            },
            {
              "internalType": "string[]",
              "name": "gateways",
              "type": "string[]"
            }
          ],
          "internalType": "struct CCIPBatcher.Batch",
          "name": "batch",
          "type": "tuple"
        }
      ],
      "name": "ccipBatch",
      "outputs": [
        {
          "components": [
            {
              "components": [
                {
                  "internalType": "address",
                  "name": "target",
                  "type": "address"
                },
                {
                  "internalType": "bytes",
                  "name": "call",
                  "type": "bytes"
                },
                {
                  "internalType": "bytes",
                  "name": "data",
                  "type": "bytes"
                },
                {
                  "internalType": "uint256",
                  "name": "flags",
                  "type": "uint256"
                }
              ],
              "internalType": "struct CCIPBatcher.Lookup[]",
              "name": "lookups",
              "type": "tuple[]"
            },
            {
              "internalType": "string[]",
              "name": "gateways",
              "type": "string[]"
            }
          ],
          "internalType": "struct CCIPBatcher.Batch",
          "name": "",
          "type": "tuple"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "response",
          "type": "bytes"
        },
        {
          "internalType": "bytes",
          "name": "extraData",
          "type": "bytes"
        }
      ],
      "name": "ccipBatchCallback",
      "outputs": [
        {
          "components": [
            {
              "components": [
                {
                  "internalType": "address",
                  "name": "target",
                  "type": "address"
                },
                {
                  "internalType": "bytes",
                  "name": "call",
                  "type": "bytes"
                },
                {
                  "internalType": "bytes",
                  "name": "data",
                  "type": "bytes"
                },
                {
                  "internalType": "uint256",
                  "name": "flags",
                  "type": "uint256"
                }
              ],
              "internalType": "struct CCIPBatcher.Lookup[]",
              "name": "lookups",
              "type": "tuple[]"
            },
            {
              "internalType": "string[]",
              "name": "gateways",
              "type": "string[]"
            }
          ],
          "internalType": "struct CCIPBatcher.Batch",
          "name": "batch",
          "type": "tuple"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "response",
          "type": "bytes"
        },
        {
          "internalType": "bytes",
          "name": "extraData",
          "type": "bytes"
        }
      ],
      "name": "ccipReadCallback",
      "outputs": [],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "name",
          "type": "bytes"
        }
      ],
      "name": "findResolver",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        },
        {
          "internalType": "bytes32",
          "name": "",
          "type": "bytes32"
        },
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "registry",
      "outputs": [
        {
          "internalType": "contract ENS",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "name",
          "type": "bytes"
        }
      ],
      "name": "requireResolver",
      "outputs": [
        {
          "components": [
            {
              "internalType": "bytes",
              "name": "name",
              "type": "bytes"
            },
            {
              "internalType": "uint256",
              "name": "offset",
              "type": "uint256"
            },
            {
              "internalType": "bytes32",
              "name": "node",
              "type": "bytes32"
            },
            {
              "internalType": "address",
              "name": "resolver",
              "type": "address"
            },
            {
              "internalType": "bool",
              "name": "extended",
              "type": "bool"
            }
          ],
          "internalType": "struct AbstractUniversalResolver.ResolverInfo",
          "name": "info",
          "type": "tuple"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "name",
          "type": "bytes"
        },
        {
          "internalType": "bytes",
          "name": "data",
          "type": "bytes"
        }
      ],
      "name": "resolve",
      "outputs": [
        {
          "internalType": "bytes",
          "name": "",
          "type": "bytes"
        },
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "response",
          "type": "bytes"
        },
        {
          "internalType": "bytes",
          "name": "extraData",
          "type": "bytes"
        }
      ],
      "name": "resolveBatchCallback",
      "outputs": [],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "response",
          "type": "bytes"
        },
        {
          "internalType": "bytes",
          "name": "extraData",
          "type": "bytes"
        }
      ],
      "name": "resolveCallback",
      "outputs": [
        {
          "internalType": "bytes",
          "name": "",
          "type": "bytes"
        },
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "pure",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "response",
          "type": "bytes"
        },
        {
          "internalType": "bytes",
          "name": "extraData",
          "type": "bytes"
        }
      ],
      "name": "resolveDirectCallback",
      "outputs": [],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "response",
          "type": "bytes"
        },
        {
          "internalType": "bytes",
          "name": "",
          "type": "bytes"
        }
      ],
      "name": "resolveDirectCallbackError",
      "outputs": [],
      "stateMutability": "pure",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "name",
          "type": "bytes"
        },
        {
          "internalType": "bytes",
          "name": "data",
          "type": "bytes"
        },
        {
          "internalType": "string[]",
          "name": "gateways",
          "type": "string[]"
        }
      ],
      "name": "resolveWithGateways",
      "outputs": [
        {
          "internalType": "bytes",
          "name": "result",
          "type": "bytes"
        },
        {
          "internalType": "address",
          "name": "resolver",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "resolver",
          "type": "address"
        },
        {
          "internalType": "bytes",
          "name": "name",
          "type": "bytes"
        },
        {
          "internalType": "bytes",
          "name": "data",
          "type": "bytes"
        },
        {
          "internalType": "string[]",
          "name": "gateways",
          "type": "string[]"
        }
      ],
      "name": "resolveWithResolver",
      "outputs": [
        {
          "internalType": "bytes",
          "name": "",
          "type": "bytes"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "lookupAddress",
          "type": "bytes"
        },
        {
          "internalType": "uint256",
          "name": "coinType",
          "type": "uint256"
        }
      ],
      "name": "reverse",
      "outputs": [
        {
          "internalType": "string",
          "name": "",
          "type": "string"
        },
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "response",
          "type": "bytes"
        },
        {
          "internalType": "bytes",
          "name": "extraData",
          "type": "bytes"
        }
      ],
      "name": "reverseAddressCallback",
      "outputs": [
        {
          "internalType": "string",
          "name": "primary",
          "type": "string"
        },
        {
          "internalType": "address",
          "name": "resolver",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "reverseResolver",
          "type": "address"
        }
      ],
      "stateMutability": "pure",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "response",
          "type": "bytes"
        },
        {
          "internalType": "bytes",
          "name": "extraData",
          "type": "bytes"
        }
      ],
      "name": "reverseNameCallback",
      "outputs": [
        {
          "internalType": "string",
          "name": "primary",
          "type": "string"
        },
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "lookupAddress",
          "type": "bytes"
        },
        {
          "internalType": "uint256",
          "name": "coinType",
          "type": "uint256"
        },
        {
          "internalType": "string[]",
          "name": "gateways",
          "type": "string[]"
        }
      ],
      "name": "reverseWithGateways",
      "outputs": [
        {
          "internalType": "string",
          "name": "primary",
          "type": "string"
        },
        {
          "internalType": "address",
          "name": "resolver",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "reverseResolver",
          "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"
    }
  ],
  "transactionHash": "0x9cf411899e09d91b7ed7d44ba349125bab5b0c21d100257cdc7523f17944565e",
  "receipt": {
    "to": null,
    "from": "0x69420f05A11f617B4B74fFe2E04B2D300dFA556F",
    "contractAddress": "0xED73a03F19e8D849E44a39252d222c6ad5217E1e",
    "transactionIndex": 0,
    "gasUsed": "4266417",
    "logsBloom": "0x00000000400000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000010000000000080020000010000000000000040000000008000000000000200000000000000000000000000000000000000004000000000000000000000000000000000020000000000000000010000000000000000000010000000000020000000200000000000000000000000000000040000000010000000000004000000000001008000040000000000000000000000000000000800005000008000000000000000000000000000000000000000000000000000000100000000000000001000000000000000000000",
    "blockHash": "0x4f962b7ff66b5024ea0ca92f56df6d21a415ee797815525a803b0b5660b75db9",
    "transactionHash": "0x9cf411899e09d91b7ed7d44ba349125bab5b0c21d100257cdc7523f17944565e",
    "logs": [
      {
        "transactionIndex": 0,
        "blockNumber": 23085497,
        "transactionHash": "0x9cf411899e09d91b7ed7d44ba349125bab5b0c21d100257cdc7523f17944565e",
        "address": "0xa58E81fe9b61B5c3fE2AFD33CF304c454AbFc7Cb",
        "topics": [
          "0x6ada868dd3058cf77a48a74489fd7963688e5464b2b0fa957ace976243270e92",
          "0x000000000000000000000000ed73a03f19e8d849e44a39252d222c6ad5217e1e",
          "0x95614f78c09afd5900d0f8694b253a666fe04fe56b82fa8e6a132d9ac24e9e2a"
        ],
        "data": "0x",
        "logIndex": 0,
        "blockHash": "0x4f962b7ff66b5024ea0ca92f56df6d21a415ee797815525a803b0b5660b75db9"
      },
      {
        "transactionIndex": 0,
        "blockNumber": 23085497,
        "transactionHash": "0x9cf411899e09d91b7ed7d44ba349125bab5b0c21d100257cdc7523f17944565e",
        "address": "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e",
        "topics": [
          "0xce0457fe73731f824cc272376169235128c118b49d344817417c6d108d155e82",
          "0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2",
          "0xece53e3bae28cafd8df402d607d351716ca65f84c45e5e7614eae214cc1251f2"
        ],
        "data": "0x000000000000000000000000fe89cc7abb2c4183683ab71653c4cdc9b02d44b7",
        "logIndex": 1,
        "blockHash": "0x4f962b7ff66b5024ea0ca92f56df6d21a415ee797815525a803b0b5660b75db9"
      },
      {
        "transactionIndex": 0,
        "blockNumber": 23085497,
        "transactionHash": "0x9cf411899e09d91b7ed7d44ba349125bab5b0c21d100257cdc7523f17944565e",
        "address": "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e",
        "topics": [
          "0x335721b01866dc23fbee8b6b2c7b1e14d6f05c28cd35a2c934239f94095602a0",
          "0x95614f78c09afd5900d0f8694b253a666fe04fe56b82fa8e6a132d9ac24e9e2a"
        ],
        "data": "0x000000000000000000000000f29100983e058b709f3d539b0c765937b804ac15",
        "logIndex": 2,
        "blockHash": "0x4f962b7ff66b5024ea0ca92f56df6d21a415ee797815525a803b0b5660b75db9"
      }
    ],
    "blockNumber": 23085497,
    "cumulativeGasUsed": "4266417",
    "status": 1,
    "byzantium": true
  },
  "args": [
    "0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7",
    "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e",
    "0xd1E3FAc3837b85437530B8B5244E4deF43219C04"
  ],
  "numDeployments": 1,
  "solcInputHash": "13a61253e11bf590d9dd0d2301fc6969",
  "metadata": "{\"compiler\":{\"version\":\"0.8.26+commit.8a97fa7a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"contract ENS\",\"name\":\"ens\",\"type\":\"address\"},{\"internalType\":\"contract IGatewayProvider\",\"name\":\"batchGatewayProvider\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"dns\",\"type\":\"bytes\"}],\"name\":\"DNSDecodingFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"ens\",\"type\":\"string\"}],\"name\":\"DNSEncodingFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"status\",\"type\":\"uint16\"},{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"HttpError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidBatchGatewayResponse\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"string[]\",\"name\":\"urls\",\"type\":\"string[]\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"bytes4\",\"name\":\"callbackFunction\",\"type\":\"bytes4\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"OffchainLookup\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"offset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"OffsetOutOfBoundsError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorData\",\"type\":\"bytes\"}],\"name\":\"ResolverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"resolver\",\"type\":\"address\"}],\"name\":\"ResolverNotContract\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"}],\"name\":\"ResolverNotFound\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"primary\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"primaryAddress\",\"type\":\"bytes\"}],\"name\":\"ReverseAddressMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"}],\"name\":\"UnsupportedResolverProfile\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"batchGatewayProvider\",\"outputs\":[{\"internalType\":\"contract IGatewayProvider\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"call\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"flags\",\"type\":\"uint256\"}],\"internalType\":\"struct CCIPBatcher.Lookup[]\",\"name\":\"lookups\",\"type\":\"tuple[]\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"internalType\":\"struct CCIPBatcher.Batch\",\"name\":\"batch\",\"type\":\"tuple\"}],\"name\":\"ccipBatch\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"call\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"flags\",\"type\":\"uint256\"}],\"internalType\":\"struct CCIPBatcher.Lookup[]\",\"name\":\"lookups\",\"type\":\"tuple[]\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"internalType\":\"struct CCIPBatcher.Batch\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ccipBatchCallback\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"call\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"flags\",\"type\":\"uint256\"}],\"internalType\":\"struct CCIPBatcher.Lookup[]\",\"name\":\"lookups\",\"type\":\"tuple[]\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"internalType\":\"struct CCIPBatcher.Batch\",\"name\":\"batch\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ccipReadCallback\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"}],\"name\":\"findResolver\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registry\",\"outputs\":[{\"internalType\":\"contract ENS\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"}],\"name\":\"requireResolver\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"offset\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"resolver\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"extended\",\"type\":\"bool\"}],\"internalType\":\"struct AbstractUniversalResolver.ResolverInfo\",\"name\":\"info\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"resolveBatchCallback\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"resolveCallback\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"resolveDirectCallback\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"resolveDirectCallbackError\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"name\":\"resolveWithGateways\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"result\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"resolver\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"resolver\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"name\":\"resolveWithResolver\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"lookupAddress\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"coinType\",\"type\":\"uint256\"}],\"name\":\"reverse\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"reverseAddressCallback\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"primary\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"resolver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"reverseResolver\",\"type\":\"address\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"reverseNameCallback\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"primary\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"lookupAddress\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"coinType\",\"type\":\"uint256\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"name\":\"reverseWithGateways\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"primary\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"resolver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"reverseResolver\",\"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\"}],\"devdoc\":{\"errors\":{\"DNSDecodingFailed(bytes)\":[{\"details\":\"The DNS-encoded name is malformed.      Error selector: `0xba4adc23`\"}],\"DNSEncodingFailed(string)\":[{\"details\":\"A label of the ENS name has an invalid size.      Error selector: `0x9a4c3e3b`\"}],\"EmptyAddress()\":[{\"details\":\"The supplied address was `0x`.      Error selector: `0x7138356f`\"}],\"HttpError(uint16,string)\":[{\"details\":\"Error selector: `0x01800152`\"}],\"InvalidBatchGatewayResponse()\":[{\"details\":\"Error selector: `0x4a5c31ea`\"}],\"OffchainLookup(address,string[],bytes,bytes4,bytes)\":[{\"details\":\"https://eips.ethereum.org/EIPS/eip-3668 Error selector: `0x556f1830`\"}],\"OffsetOutOfBoundsError(uint256,uint256)\":[{\"details\":\"`offset` was beyond `length`.       Error selector: `0x8a3c1cfb`\"}],\"ResolverError(bytes)\":[{\"details\":\"Error selector: `0x95c0c752`\"}],\"ResolverNotContract(bytes,address)\":[{\"details\":\"Error selector: `0x1e9535f2`\"}],\"ResolverNotFound(bytes)\":[{\"details\":\"Error selector: `0x77209fe8`\"}],\"ReverseAddressMismatch(string,bytes)\":[{\"details\":\"Error selector: `0xef9c03ce`\"}],\"UnsupportedResolverProfile(bytes4)\":[{\"details\":\"Error selector: `0x7b1c461b`\"}]},\"kind\":\"dev\",\"methods\":{\"ccipBatch(((address,bytes,bytes,uint256)[],string[]))\":{\"details\":\"Use `ccipRead()` to call this function with a batch.      The callback response will be `abi.encode(batch)`.\"},\"ccipBatchCallback(bytes,bytes)\":{\"details\":\"CCIP-Read callback for `ccipBatch()`.      Updates `batch` using the batch gateway response. Reverts again if not \\\"done\\\".\",\"params\":{\"extraData\":\"The contextual data passed from `ccipBatch()`.\",\"response\":\"The response from the batch gateway.\"},\"returns\":{\"batch\":\"The batch where every lookup is \\\"done\\\".\"}},\"ccipReadCallback(bytes,bytes)\":{\"details\":\"CCIP-Read callback for `ccipRead()`.The return type of this function is polymorphic depending on the caller.\",\"params\":{\"extraData\":\"The contextual data passed from `ccipRead()`.\",\"response\":\"The response from offchain.\"}},\"findResolver(bytes)\":{\"details\":\"Find the resolver address for `name`.      Does not perform any validity checks on the resolver.\",\"params\":{\"name\":\"The name to search.\"},\"returns\":{\"_0\":\"The resolver or `address(0)` if not found.\",\"_1\":\"The namehash of `name`.\",\"_2\":\"The offset into `name` corresponding to `resolver`.\"}},\"requireResolver(bytes)\":{\"details\":\"Returns a valid resolver for `name` or reverts.\",\"params\":{\"name\":\"The name to search.\"},\"returns\":{\"info\":\"The resolver information.\"}},\"resolveBatchCallback(bytes,bytes)\":{\"details\":\"CCIP-Read callback for `_callResolver()` from calling the batch gateway successfully.\"},\"resolveCallback(bytes,bytes)\":{\"details\":\"CCIP-Read callback for `resolveWithGateways()`.\",\"params\":{\"extraData\":\"The contextual data passed from `resolveWith*()`.\",\"response\":\"The response from the resolver.\"}},\"resolveDirectCallback(bytes,bytes)\":{\"details\":\"CCIP-Read callback for `_callResolver()` from calling the resolver successfully.\"},\"resolveDirectCallbackError(bytes,bytes)\":{\"details\":\"CCIP-Read callback for `_callResolver()` from calling the resolver unsuccessfully.\"},\"resolveWithGateways(bytes,bytes,string[])\":{\"details\":\"This function executes over multiple steps.\",\"params\":{\"data\":\"The resolution data, as specified in ENSIP-10.\",\"gateways\":\"The list of batch gateway URLs to use.\",\"name\":\"The name to resolve, in normalised and DNS-encoded form.\"},\"returns\":{\"resolver\":\"The address of the resolver that supplied `result`.\",\"result\":\"The encoded response for the requested call.\"}},\"reverseAddressCallback(bytes,bytes)\":{\"details\":\"CCIP-Read callback for `reverseNameCallback()`.      Reverts `ReverseAddressMismatch`.\",\"params\":{\"extraData\":\"The contextual data passed from `reverseNameCallback()`.\",\"response\":\"The abi-encoded `addr()` response from the forward resolver.\"}},\"reverseNameCallback(bytes,bytes)\":{\"details\":\"CCIP-Read callback for `reverseWithGateways()`.\",\"params\":{\"extraData\":\"The contextual data passed from `reverseWithGateways()`.\",\"response\":\"The abi-encoded `name()` response from the reverse resolver.\"}},\"reverseWithGateways(bytes,uint256,string[])\":{\"details\":\"This function executes over multiple steps.\",\"params\":{\"coinType\":\"The coin type.\",\"gateways\":\"The list of batch gateway URLs to use.\",\"lookupAddress\":\"The input address.\"},\"returns\":{\"primary\":\"The resolved primary name.\",\"resolver\":\"The resolver address for primary name.\",\"reverseResolver\":\"The resolver address for the reverse name.\"}},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"}},\"version\":1},\"userdoc\":{\"errors\":{\"HttpError(uint16,string)\":[{\"notice\":\"An HTTP error occurred on a resolving gateway.\"}],\"InvalidBatchGatewayResponse()\":[{\"notice\":\"The batch gateway supplied an incorrect number of responses.\"}],\"ResolverError(bytes)\":[{\"notice\":\"The resolver returned an error.\"}],\"ResolverNotContract(bytes,address)\":[{\"notice\":\"The resolver is not a contract.\"}],\"ResolverNotFound(bytes)\":[{\"notice\":\"A resolver could not be found for the supplied name.\"}],\"ReverseAddressMismatch(string,bytes)\":[{\"notice\":\"The resolved address from reverse resolution does not match the supplied address.\"}],\"UnsupportedResolverProfile(bytes4)\":[{\"notice\":\"The resolver did not respond.\"}]},\"kind\":\"user\",\"methods\":{\"resolve(bytes,bytes)\":{\"notice\":\"Same as `resolveWithGateways()` but uses default batch gateways.\"},\"resolveWithGateways(bytes,bytes,string[])\":{\"notice\":\"Performs ENS resolution process for the supplied name and resolution data.         Caller should enable EIP-3668.\"},\"resolveWithResolver(address,bytes,bytes,string[])\":{\"notice\":\"Same as `resolveWithGateways()` but uses the supplied resolver.\"},\"reverse(bytes,uint256)\":{\"notice\":\"Same as `reverseWithGateways()` but uses default batch gateways.\"},\"reverseWithGateways(bytes,uint256,string[])\":{\"notice\":\"Performs ENS reverse resolution for the supplied address and coin type.         Caller should enable EIP-3668.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universalResolver/UniversalResolver.sol\":\"UniversalResolver\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@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/ERC165Checker.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/ERC165Checker.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Library used to query support of an interface declared via {IERC165}.\\n *\\n * Note that these functions return the actual result of the query: they do not\\n * `revert` if an interface is not supported. It is up to the caller to decide\\n * what to do in these cases.\\n */\\nlibrary ERC165Checker {\\n    // As per the EIP-165 spec, no interface should ever match 0xffffffff\\n    bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;\\n\\n    /**\\n     * @dev Returns true if `account` supports the {IERC165} interface.\\n     */\\n    function supportsERC165(address account) internal view returns (bool) {\\n        // Any contract that implements ERC165 must explicitly indicate support of\\n        // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid\\n        return\\n            supportsERC165InterfaceUnchecked(account, type(IERC165).interfaceId) &&\\n            !supportsERC165InterfaceUnchecked(account, _INTERFACE_ID_INVALID);\\n    }\\n\\n    /**\\n     * @dev Returns true if `account` supports the interface defined by\\n     * `interfaceId`. Support for {IERC165} itself is queried automatically.\\n     *\\n     * See {IERC165-supportsInterface}.\\n     */\\n    function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {\\n        // query support of both ERC165 as per the spec and support of _interfaceId\\n        return supportsERC165(account) && supportsERC165InterfaceUnchecked(account, interfaceId);\\n    }\\n\\n    /**\\n     * @dev Returns a boolean array where each value corresponds to the\\n     * interfaces passed in and whether they're supported or not. This allows\\n     * you to batch check interfaces for a contract where your expectation\\n     * is that some interfaces may not be supported.\\n     *\\n     * See {IERC165-supportsInterface}.\\n     *\\n     * _Available since v3.4._\\n     */\\n    function getSupportedInterfaces(\\n        address account,\\n        bytes4[] memory interfaceIds\\n    ) internal view returns (bool[] memory) {\\n        // an array of booleans corresponding to interfaceIds and whether they're supported or not\\n        bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length);\\n\\n        // query support of ERC165 itself\\n        if (supportsERC165(account)) {\\n            // query support of each interface in interfaceIds\\n            for (uint256 i = 0; i < interfaceIds.length; i++) {\\n                interfaceIdsSupported[i] = supportsERC165InterfaceUnchecked(account, interfaceIds[i]);\\n            }\\n        }\\n\\n        return interfaceIdsSupported;\\n    }\\n\\n    /**\\n     * @dev Returns true if `account` supports all the interfaces defined in\\n     * `interfaceIds`. Support for {IERC165} itself is queried automatically.\\n     *\\n     * Batch-querying can lead to gas savings by skipping repeated checks for\\n     * {IERC165} support.\\n     *\\n     * See {IERC165-supportsInterface}.\\n     */\\n    function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {\\n        // query support of ERC165 itself\\n        if (!supportsERC165(account)) {\\n            return false;\\n        }\\n\\n        // query support of each interface in interfaceIds\\n        for (uint256 i = 0; i < interfaceIds.length; i++) {\\n            if (!supportsERC165InterfaceUnchecked(account, interfaceIds[i])) {\\n                return false;\\n            }\\n        }\\n\\n        // all interfaces supported\\n        return true;\\n    }\\n\\n    /**\\n     * @notice Query if a contract implements an interface, does not check ERC165 support\\n     * @param account The address of the contract to query for support of an interface\\n     * @param interfaceId The interface identifier, as specified in ERC-165\\n     * @return true if the contract at account indicates support of the interface with\\n     * identifier interfaceId, false otherwise\\n     * @dev Assumes that account contains a contract that supports ERC165, otherwise\\n     * the behavior of this method is undefined. This precondition can be checked\\n     * with {supportsERC165}.\\n     *\\n     * Some precompiled contracts will falsely indicate support for a given interface, so caution\\n     * should be exercised when using this function.\\n     *\\n     * Interface identification is specified in ERC-165.\\n     */\\n    function supportsERC165InterfaceUnchecked(address account, bytes4 interfaceId) internal view returns (bool) {\\n        // prepare call\\n        bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId);\\n\\n        // perform static call\\n        bool success;\\n        uint256 returnSize;\\n        uint256 returnValue;\\n        assembly {\\n            success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20)\\n            returnSize := returndatasize()\\n            returnValue := mload(0x00)\\n        }\\n\\n        return success && returnSize >= 0x20 && returnValue > 0;\\n    }\\n}\\n\",\"keccak256\":\"0x5a08ad61f4e82b8a3323562661a86fb10b10190848073fdc13d4ac43710ffba5\",\"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\"},\"contracts/ccipRead/CCIPBatcher.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IBatchGateway} from \\\"./IBatchGateway.sol\\\";\\nimport {CCIPReader, EIP3668, OffchainLookup} from \\\"./CCIPReader.sol\\\";\\n\\nabstract contract CCIPBatcher is CCIPReader {\\n    /// @notice The batch gateway supplied an incorrect number of responses.\\n    /// @dev Error selector: `0x4a5c31ea`\\n    error InvalidBatchGatewayResponse();\\n\\n    uint256 constant FLAG_OFFCHAIN = 1 << 0; // the lookup reverted `OffchainLookup`\\n    uint256 constant FLAG_CALL_ERROR = 1 << 1; // the initial call or callback reverted\\n    uint256 constant FLAG_BATCH_ERROR = 1 << 2; // `OffchainLookup` failed on the batch gateway\\n    uint256 constant FLAG_EMPTY_RESPONSE = 1 << 3; // the initial call or callback returned `0x`\\n    uint256 constant FLAG_EIP140_BEFORE = 1 << 4; // does not have revert op code\\n    uint256 constant FLAG_EIP140_AFTER = 1 << 5; // has revert op code\\n    uint256 constant FLAG_DONE = 1 << 6; // the lookup has finished processing (private)\\n\\n    uint256 constant FLAGS_ANY_ERROR =\\n        FLAG_CALL_ERROR | FLAG_BATCH_ERROR | FLAG_EMPTY_RESPONSE;\\n    uint256 constant FLAGS_ANY_EIP140 = FLAG_EIP140_BEFORE | FLAG_EIP140_AFTER;\\n\\n    /// @dev An independent `OffchainLookup` session.\\n    struct Lookup {\\n        address target; // contract to call\\n        bytes call; // initial calldata\\n        bytes data; // response or error\\n        uint256 flags; // see: FLAG_*\\n    }\\n\\n    /// @dev A batch gateway session.\\n    struct Batch {\\n        Lookup[] lookups;\\n        string[] gateways;\\n    }\\n\\n    /// @dev Create a batch for a single target with multiple calls.\\n    /// @param target The target contract.\\n    /// @param calls The list of calldata.\\n    /// @param gateways The batch gateway URLs.\\n    function createBatch(\\n        address target,\\n        bytes[] memory calls,\\n        string[] memory gateways\\n    ) internal pure returns (Batch memory) {\\n        Lookup[] memory lookups = new Lookup[](calls.length);\\n        for (uint256 i; i < calls.length; ++i) {\\n            Lookup memory lu = lookups[i];\\n            lu.target = target;\\n            lu.call = calls[i];\\n        }\\n        return Batch(lookups, gateways);\\n    }\\n\\n    /// @dev Use `ccipRead()` to call this function with a batch.\\n    ///      The callback response will be `abi.encode(batch)`.\\n    function ccipBatch(\\n        Batch memory batch\\n    ) external view returns (Batch memory) {\\n        for (uint256 i; i < batch.lookups.length; ++i) {\\n            Lookup memory lu = batch.lookups[i];\\n            if ((lu.flags & FLAGS_ANY_EIP140) == 0) {\\n                uint256 flags = detectEIP140(lu.target)\\n                    ? FLAG_EIP140_AFTER\\n                    : FLAG_EIP140_BEFORE;\\n                for (uint256 j = i; j < batch.lookups.length; ++j) {\\n                    if (batch.lookups[j].target == lu.target) {\\n                        batch.lookups[j].flags |= flags;\\n                    }\\n                }\\n            }\\n            bool unsafe = (lu.flags & FLAG_EIP140_AFTER) == 0;\\n            (bool ok, bytes memory v) = safeCall(!unsafe, lu.target, lu.call);\\n            if (!ok && bytes4(v) == OffchainLookup.selector) {\\n                lu.flags |= FLAG_OFFCHAIN;\\n            } else {\\n                lu.flags |= FLAG_DONE;\\n                if (unsafe && v.length == 0) {\\n                    // unsafe contracts appear the same for throw and unimplemented fallback\\n                    // decision: interpret like an unimplemented function selector response\\n                } else if (!ok) {\\n                    lu.flags |= FLAG_CALL_ERROR;\\n                }\\n                if (v.length == 0) {\\n                    lu.flags |= FLAG_EMPTY_RESPONSE;\\n                }\\n            }\\n            lu.data = v;\\n        }\\n        _revertBatchGateway(batch); // reverts if any offchain\\n        return batch;\\n    }\\n\\n    /// @dev Check if the batch is \\\"done\\\".  If not, revert `OffchainLookup` for batch gateway.\\n    function _revertBatchGateway(Batch memory batch) internal view {\\n        IBatchGateway.Request[] memory requests = new IBatchGateway.Request[](\\n            batch.lookups.length\\n        );\\n        uint256 count;\\n        for (uint256 i; i < batch.lookups.length; ++i) {\\n            Lookup memory lu = batch.lookups[i];\\n            if ((lu.flags & FLAG_DONE) == 0) {\\n                EIP3668.Params memory p = decodeOffchainLookup(lu.data);\\n                requests[count++] = IBatchGateway.Request(\\n                    p.sender,\\n                    p.urls,\\n                    p.callData\\n                );\\n            }\\n        }\\n        if (count > 0) {\\n            assembly {\\n                mstore(requests, count) // truncate to number of offchain requests\\n            }\\n            revert OffchainLookup(\\n                address(this),\\n                batch.gateways,\\n                abi.encodeCall(IBatchGateway.query, (requests)),\\n                this.ccipBatchCallback.selector,\\n                abi.encode(batch)\\n            );\\n        }\\n    }\\n\\n    /// @dev CCIP-Read callback for `ccipBatch()`.\\n    ///      Updates `batch` using the batch gateway response. Reverts again if not \\\"done\\\".\\n    /// @param response The response from the batch gateway.\\n    /// @param extraData The contextual data passed from `ccipBatch()`.\\n    /// @return batch The batch where every lookup is \\\"done\\\".\\n    function ccipBatchCallback(\\n        bytes calldata response,\\n        bytes calldata extraData\\n    ) external view returns (Batch memory batch) {\\n        (bool[] memory failures, bytes[] memory responses) = abi.decode(\\n            response,\\n            (bool[], bytes[])\\n        );\\n        if (failures.length != responses.length) {\\n            revert InvalidBatchGatewayResponse();\\n        }\\n        batch = abi.decode(extraData, (Batch));\\n        uint256 expected;\\n        for (uint256 i; i < batch.lookups.length; ++i) {\\n            Lookup memory lu = batch.lookups[i];\\n            if ((lu.flags & FLAG_DONE) == 0) {\\n                if (expected < responses.length) {\\n                    bytes memory v = responses[expected];\\n                    if (failures[expected]) {\\n                        lu.flags |= FLAG_DONE | FLAG_BATCH_ERROR;\\n                    } else {\\n                        EIP3668.Params memory p = decodeOffchainLookup(lu.data);\\n                        bool ok;\\n                        // assumption: unsafe contracts don't revert OffchainLookup()\\n                        (ok, v) = p.sender.staticcall(\\n                            abi.encodeWithSelector(\\n                                p.callbackFunction,\\n                                v,\\n                                p.extraData\\n                            )\\n                        );\\n                        if (ok || bytes4(v) != OffchainLookup.selector) {\\n                            lu.flags |= FLAG_DONE;\\n                            // decision: promote empty response from the callback => call error\\n                            // ie. the initial function was implemented but the callback was not\\n                            // this can be detected via FLAG_OFFCHAIN\\n                            if (!ok || v.length == 0) {\\n                                lu.flags |= FLAG_CALL_ERROR;\\n                            }\\n                            if (v.length == 0) {\\n                                lu.flags |= FLAG_EMPTY_RESPONSE;\\n                            }\\n                        }\\n                    }\\n                    lu.data = v;\\n                }\\n                ++expected;\\n            }\\n        }\\n        if (expected != responses.length) {\\n            revert InvalidBatchGatewayResponse();\\n        }\\n        _revertBatchGateway(batch);\\n    }\\n}\\n\",\"keccak256\":\"0xa2650fd1dc7745ed671600d1073586abd6304d989a3e8a786f2dd69cdedd38d7\",\"license\":\"MIT\"},\"contracts/ccipRead/CCIPReader.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\n/// @author Modified from https://github.com/unruggable-labs/CCIPReader.sol/blob/341576fe7ff2b6e0c93fc08f37740cf6439f5873/contracts/CCIPReader.sol\\n\\n/// MIT License\\n/// Portions Copyright (c) 2025 Unruggable\\n/// Portions Copyright (c) 2025 ENS Labs Ltd\\n\\n/// @dev Instructions:\\n/// 1. inherit this contract\\n/// 2. call `ccipRead()` similar to `staticcall()`\\n/// 3. do not put logic after this invocation\\n/// 4. implement all response logic in callback\\n/// 5. ensure that return type of calling function == callback function\\n\\nimport {EIP3668, OffchainLookup} from \\\"./EIP3668.sol\\\";\\nimport {BytesUtils} from \\\"../utils/BytesUtils.sol\\\";\\n\\ncontract CCIPReader {\\n    /// @dev Default unsafe call gas (sufficient for legacy ENS resolver profiles).\\n    uint256 constant DEFAULT_UNSAFE_CALL_GAS = 50000;\\n\\n    /// @dev Special-purpose value for identity callback: `f(x) = x`.\\n    bytes4 constant IDENTITY_FUNCTION = bytes4(0);\\n\\n    /// @dev The gas limit for calling functions on unsafe contracts.\\n    uint256 immutable unsafeCallGas;\\n\\n    constructor(uint256 _unsafeCallGas) {\\n        unsafeCallGas = _unsafeCallGas;\\n    }\\n\\n    /// @dev A recursive CCIP-Read session.\\n    struct Context {\\n        address target;\\n        bytes4 callbackFunction;\\n        bytes extraData;\\n        bytes4 successCallbackFunction;\\n        bytes4 failureCallbackFunction;\\n        bytes myExtraData;\\n    }\\n\\n    /// @dev Same as `ccipRead()` but the callback function is the identity.\\n    function ccipRead(address target, bytes memory call) internal view {\\n        ccipRead(target, call, IDENTITY_FUNCTION, IDENTITY_FUNCTION, \\\"\\\");\\n    }\\n\\n    /// @dev Performs a CCIP-Read and handles internal recursion.\\n    ///      Reverts `OffchainLookup` if necessary.\\n    ///      Use `IDENTITY_FUNCTION` as the callback function selector for return/revert behavior.\\n    /// @param target The contract address.\\n    /// @param call The calldata to `staticcall()` on `target`.\\n    /// @param successCallbackFunction The function selector of callback on success.\\n    /// @param failureCallbackFunction The function selector of callback on failure.\\n    /// @param extraData The contextual data relayed to callback function.\\n    function ccipRead(\\n        address target,\\n        bytes memory call,\\n        bytes4 successCallbackFunction,\\n        bytes4 failureCallbackFunction,\\n        bytes memory extraData\\n    ) internal view {\\n        // We call the intended function that **could** revert with an `OffchainLookup`\\n        // We destructure the response into an execution status bool and our return bytes\\n        (bool ok, bytes memory v) = safeCall(\\n            detectEIP140(target),\\n            target,\\n            call\\n        );\\n        // IF the function reverted with an `OffchainLookup`\\n        if (!ok && bytes4(v) == OffchainLookup.selector) {\\n            // We decode the response error into a tuple\\n            // tuples allow flexibility noting stack too deep constraints\\n            EIP3668.Params memory p = decodeOffchainLookup(v);\\n            if (p.sender == target) {\\n                // We then wrap the error data in an `OffchainLookup` sent/'owned' by this contract\\n                revert OffchainLookup(\\n                    address(this),\\n                    p.urls,\\n                    p.callData,\\n                    this.ccipReadCallback.selector,\\n                    abi.encode(\\n                        Context(\\n                            target,\\n                            p.callbackFunction,\\n                            p.extraData,\\n                            successCallbackFunction,\\n                            failureCallbackFunction,\\n                            extraData\\n                        )\\n                    )\\n                );\\n            }\\n        }\\n        // IF we have gotten here, the 'real' target does not revert with an `OffchainLookup` error\\n        // figure out what callback to call\\n        bytes4 callbackFunction = ok\\n            ? successCallbackFunction\\n            : failureCallbackFunction;\\n        if (callbackFunction != IDENTITY_FUNCTION) {\\n            // The exit point of this architecture is OUR callback in the 'real'\\n            // We pass through the response to that callback\\n            (ok, v) = address(this).staticcall(\\n                abi.encodeWithSelector(callbackFunction, v, extraData)\\n            );\\n        }\\n        // OR the call to the 'real' target reverts with a different error selector\\n        // OR the call to OUR callback reverts with ANY error selector\\n        if (ok) {\\n            assembly {\\n                return(add(v, 32), mload(v))\\n            }\\n        } else {\\n            assembly {\\n                revert(add(v, 32), mload(v))\\n            }\\n        }\\n    }\\n\\n    /// @dev CCIP-Read callback for `ccipRead()`.\\n    /// @param response The response from offchain.\\n    /// @param extraData The contextual data passed from `ccipRead()`.\\n    /// @dev The return type of this function is polymorphic depending on the caller.\\n    function ccipReadCallback(\\n        bytes memory response,\\n        bytes memory extraData\\n    ) external view {\\n        Context memory ctx = abi.decode(extraData, (Context));\\n        // Since the callback can revert too (but has the same return structure)\\n        // We can reuse the calling infrastructure to call the callback\\n        ccipRead(\\n            ctx.target,\\n            abi.encodeWithSelector(\\n                ctx.callbackFunction,\\n                response,\\n                ctx.extraData\\n            ),\\n            ctx.successCallbackFunction,\\n            ctx.failureCallbackFunction,\\n            ctx.myExtraData\\n        );\\n    }\\n\\n    /// @dev Decode `OffchainLookup` error data into a struct.\\n    /// @param v The error data of the revert.\\n    /// @return p The decoded `OffchainLookup` params.\\n    function decodeOffchainLookup(\\n        bytes memory v\\n    ) internal pure returns (EIP3668.Params memory p) {\\n        p = EIP3668.decode(BytesUtils.substring(v, 4, v.length - 4));\\n    }\\n\\n    /// @dev Determine if `target` uses `revert()` instead of `invalid()`.\\n    //       Assumption: only newer contracts revert `OffchainLookup`.\\n    /// @param target The contract to test.\\n    /// @return safe True if safe to call.\\n    function detectEIP140(address target) internal view returns (bool safe) {\\n        if (target == address(this)) return true;\\n        // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-140.md\\n        assembly {\\n            let G := 5000\\n            let g := gas()\\n            pop(staticcall(G, target, 0, 0, 0, 0))\\n            safe := lt(sub(g, gas()), G)\\n        }\\n    }\\n\\n    /// @dev Same as `staticcall()` but prevents OOG when not `safe`.\\n    function safeCall(\\n        bool safe,\\n        address target,\\n        bytes memory call\\n    ) internal view returns (bool ok, bytes memory v) {\\n        (ok, v) = target.staticcall{gas: safe ? gasleft() : unsafeCallGas}(\\n            call\\n        );\\n    }\\n}\\n\",\"keccak256\":\"0xa6f483e89e779385c2b7ea6376d92cd3c05c98f91d1a3c7c43dc7422fe6b014f\",\"license\":\"MIT\"},\"contracts/ccipRead/EIP3668.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @dev https://eips.ethereum.org/EIPS/eip-3668\\n/// Error selector: `0x556f1830`\\nerror OffchainLookup(\\n    address sender,\\n    string[] urls,\\n    bytes callData,\\n    bytes4 callbackFunction,\\n    bytes extraData\\n);\\n\\n/// @dev Simple library for decoding `OffchainLookup` error data.\\n/// Avoids \\\"stack too deep\\\" issues as the natural decoding consumes 5 variables.\\nlibrary EIP3668 {\\n    /// @dev Struct with members matching `OffchainLookup`.\\n    struct Params {\\n        address sender;\\n        string[] urls;\\n        bytes callData;\\n        bytes4 callbackFunction;\\n        bytes extraData;\\n    }\\n\\n    /// @dev Decode an `OffchainLookup` into a struct from the data after the error selector.\\n    function decode(bytes memory v) internal pure returns (Params memory p) {\\n        (p.sender, p.urls, p.callData, p.callbackFunction, p.extraData) = abi\\n            .decode(v, (address, string[], bytes, bytes4, bytes));\\n    }\\n}\\n\",\"keccak256\":\"0x14619de0f3d9f085e6209767b35c2888b8d2af6d787af535f30db7b51e843bf8\",\"license\":\"MIT\"},\"contracts/ccipRead/IBatchGateway.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @notice Interface for Batch Gateway Offchain Lookup Protocol.\\n///         https://docs.ens.domains/ensip/21/\\n/// @dev Interface selector: `0xa780bab6`\\ninterface IBatchGateway {\\n    /// @notice An HTTP error occurred.\\n    /// @dev Error selector: `0x01800152`\\n    error HttpError(uint16 status, string message);\\n\\n    /// @dev Information extracted from an `OffchainLookup` revert.\\n    struct Request {\\n        address sender;\\n        string[] urls;\\n        bytes data;\\n    }\\n\\n    /// @notice Perform multiple `OffchainLookup` in parallel.\\n    ///         Callers should enable EIP-3668.\\n    /// @param requests The array of requests to lookup in parallel.\\n    /// @return failures The failure status of the corresponding request.\\n    /// @return responses The response or error data of the corresponding request.\\n    function query(\\n        Request[] memory requests\\n    ) external view returns (bool[] memory failures, bytes[] memory responses);\\n}\\n\",\"keccak256\":\"0xfd7f0c7bdc29fc732ec54da2ebaea241873e55082e484729901811bc9374d6f6\",\"license\":\"MIT\"},\"contracts/ccipRead/IGatewayProvider.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @notice Interface for shared gateway URLs.\\n/// @dev Interface selector: `0x093a86d3`\\ninterface IGatewayProvider {\\n    /// @notice Get the gateways.\\n    /// @return The gateway URLs.\\n    function gateways() external view returns (string[] memory);\\n}\\n\",\"keccak256\":\"0x7c169843cfb65657a88fb4d5f7ec44612994d7d87cb7b1a67cbfdb18758823e0\",\"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/IMulticallable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IMulticallable {\\n    function multicall(\\n        bytes[] calldata data\\n    ) external returns (bytes[] memory results);\\n\\n    function multicallWithNodeCheck(\\n        bytes32,\\n        bytes[] calldata data\\n    ) external returns (bytes[] memory results);\\n}\\n\",\"keccak256\":\"0x0334202e20bb11995997083d05963f5e8e7ed6194cba494e7f9371ab7bf4e2c3\",\"license\":\"MIT\"},\"contracts/resolvers/ResolverFeatures.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nlibrary ResolverFeatures {\\n    /// @notice Implements `resolve(multicall([...]))`.\\n    /// @dev Feature: `0x96b62db8`\\n    bytes4 constant RESOLVE_MULTICALL =\\n        bytes4(keccak256(\\\"eth.ens.resolver.extended.multicall\\\"));\\n\\n    /// @notice Returns the same records independent of name or node.\\n    /// @dev Feature: `0x86fb8da8`\\n    bytes4 constant SINGULAR = bytes4(keccak256(\\\"eth.ens.resolver.singular\\\"));\\n}\\n\",\"keccak256\":\"0x87d131fcbdd7951a17b0a94f7f02470ec3f62c6004cf91c2d2acc54098373be6\",\"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/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/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/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/reverseRegistrar/ReverseClaimer.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.17 <0.9.0;\\n\\nimport {ENS} from \\\"../registry/ENS.sol\\\";\\nimport {IReverseRegistrar} from \\\"../reverseRegistrar/IReverseRegistrar.sol\\\";\\n\\ncontract ReverseClaimer {\\n    bytes32 constant ADDR_REVERSE_NODE =\\n        0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2;\\n\\n    constructor(ENS ens, address claimant) {\\n        IReverseRegistrar reverseRegistrar = IReverseRegistrar(\\n            ens.owner(ADDR_REVERSE_NODE)\\n        );\\n        reverseRegistrar.claim(claimant);\\n    }\\n}\\n\",\"keccak256\":\"0x78a28627241535b595f6fff476a1fa7acc90c80684fe7784734920fc8af6fc22\",\"license\":\"MIT\"},\"contracts/universalResolver/AbstractUniversalResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {ERC165} from \\\"@openzeppelin/contracts/utils/introspection/ERC165.sol\\\";\\nimport {ERC165Checker} from \\\"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\\\";\\n\\nimport {IUniversalResolver} from \\\"./IUniversalResolver.sol\\\";\\nimport {CCIPBatcher, CCIPReader} from \\\"../ccipRead/CCIPBatcher.sol\\\";\\nimport {IGatewayProvider} from \\\"../ccipRead/IGatewayProvider.sol\\\";\\nimport {NameCoder} from \\\"../utils/NameCoder.sol\\\";\\nimport {BytesUtils} from \\\"../utils/BytesUtils.sol\\\";\\nimport {ENSIP19, COIN_TYPE_ETH, COIN_TYPE_DEFAULT} from \\\"../utils/ENSIP19.sol\\\";\\nimport {IFeatureSupporter} from \\\"../utils/IFeatureSupporter.sol\\\";\\nimport {ResolverFeatures} from \\\"../resolvers/ResolverFeatures.sol\\\";\\n\\n// resolver profiles\\nimport {IExtendedResolver} from \\\"../resolvers/profiles/IExtendedResolver.sol\\\";\\nimport {INameResolver} from \\\"../resolvers/profiles/INameResolver.sol\\\";\\nimport {IAddrResolver} from \\\"../resolvers/profiles/IAddrResolver.sol\\\";\\nimport {IAddressResolver} from \\\"../resolvers/profiles/IAddressResolver.sol\\\";\\nimport {IMulticallable} from \\\"../resolvers/IMulticallable.sol\\\";\\n\\nabstract contract AbstractUniversalResolver is\\n    IUniversalResolver,\\n    CCIPBatcher,\\n    ERC165\\n{\\n    /// @dev The default batch gateways.\\n    IGatewayProvider public immutable batchGatewayProvider;\\n\\n    constructor(\\n        IGatewayProvider _batchGatewayProvider\\n    ) CCIPReader(DEFAULT_UNSAFE_CALL_GAS) {\\n        batchGatewayProvider = _batchGatewayProvider;\\n    }\\n\\n    /// @inheritdoc ERC165\\n    function supportsInterface(\\n        bytes4 interfaceId\\n    ) public view virtual override(ERC165) returns (bool) {\\n        return\\n            type(IUniversalResolver).interfaceId == interfaceId ||\\n            super.supportsInterface(interfaceId);\\n    }\\n\\n    /// @inheritdoc IUniversalResolver\\n    function findResolver(\\n        bytes memory name\\n    ) public view virtual returns (address, bytes32, uint256);\\n\\n    /// @dev A valid resolver and its relevant properties.\\n    struct ResolverInfo {\\n        bytes name; // dns-encoded name (safe to decode)\\n        uint256 offset; // byte offset into name used for resolver\\n        bytes32 node; // namehash(name)\\n        address resolver;\\n        bool extended; // IExtendedResolver\\n    }\\n\\n    /// @dev Returns a valid resolver for `name` or reverts.\\n    /// @param name The name to search.\\n    /// @return info The resolver information.\\n    function requireResolver(\\n        bytes memory name\\n    ) public view returns (ResolverInfo memory info) {\\n        // https://docs.ens.domains/ensip/10\\n        (info.resolver, info.node, info.offset) = findResolver(name);\\n        info.name = name;\\n        _checkResolver(info);\\n    }\\n\\n    /// @dev Asserts that the resolver information is valid.\\n    function _checkResolver(ResolverInfo memory info) internal view {\\n        if (info.resolver == address(0)) {\\n            revert ResolverNotFound(info.name);\\n        } else if (\\n            ERC165Checker.supportsERC165InterfaceUnchecked(\\n                info.resolver,\\n                type(IExtendedResolver).interfaceId\\n            )\\n        ) {\\n            info.extended = true;\\n        } else if (info.offset != 0) {\\n            revert ResolverNotFound(info.name); // immediate resolver requires exact match\\n        } else if (info.resolver.code.length == 0) {\\n            revert ResolverNotContract(info.name, info.resolver);\\n        }\\n    }\\n\\n    /// @notice Same as `resolveWithGateways()` but uses default batch gateways.\\n    function resolve(\\n        bytes calldata name,\\n        bytes calldata data\\n    ) external view returns (bytes memory, address) {\\n        return resolveWithGateways(name, data, batchGatewayProvider.gateways());\\n    }\\n\\n    /// @notice Performs ENS resolution process for the supplied name and resolution data.\\n    ///         Caller should enable EIP-3668.\\n    /// @dev This function executes over multiple steps.\\n    /// @param name The name to resolve, in normalised and DNS-encoded form.\\n    /// @param data The resolution data, as specified in ENSIP-10.\\n    /// @param gateways The list of batch gateway URLs to use.\\n    /// @return result The encoded response for the requested call.\\n    /// @return resolver The address of the resolver that supplied `result`.\\n    function resolveWithGateways(\\n        bytes calldata name,\\n        bytes calldata data,\\n        string[] memory gateways\\n    ) public view returns (bytes memory result, address resolver) {\\n        result;\\n        resolver;\\n        ResolverInfo memory info = requireResolver(name);\\n        _callResolver(\\n            info,\\n            data,\\n            gateways,\\n            this.resolveCallback.selector, // ==> step 2\\n            abi.encode(info.resolver)\\n        );\\n    }\\n\\n    /// @notice Same as `resolveWithGateways()` but uses the supplied resolver.\\n    function resolveWithResolver(\\n        address resolver,\\n        bytes calldata name,\\n        bytes calldata data,\\n        string[] memory gateways\\n    ) external view returns (bytes memory) {\\n        ResolverInfo memory info;\\n        info.name = name;\\n        info.node = NameCoder.namehash(name, 0);\\n        info.resolver = resolver;\\n        _checkResolver(info);\\n        _callResolver(\\n            info,\\n            data,\\n            gateways,\\n            this.resolveCallback.selector, // ==> step 2\\n            abi.encode(resolver)\\n        );\\n    }\\n\\n    /// @dev CCIP-Read callback for `resolveWithGateways()`.\\n    /// @param response The response from the resolver.\\n    /// @param extraData The contextual data passed from `resolveWith*()`.\\n    function resolveCallback(\\n        bytes calldata response,\\n        bytes calldata extraData\\n    ) external pure returns (bytes memory, address) {\\n        return (response, abi.decode(extraData, (address)));\\n    }\\n\\n    /// @notice Same as `reverseWithGateways()` but uses default batch gateways.\\n    function reverse(\\n        bytes calldata lookupAddress,\\n        uint256 coinType\\n    ) external view returns (string memory, address, address) {\\n        return\\n            reverseWithGateways(\\n                lookupAddress,\\n                coinType,\\n                batchGatewayProvider.gateways()\\n            );\\n    }\\n\\n    struct ReverseArgs {\\n        bytes lookupAddress; // parsed input address\\n        uint256 coinType; // parsed coinType\\n        string[] gateways; // supplied gateways\\n        address resolver; // valid reverse resolver\\n    }\\n\\n    /// @notice Performs ENS reverse resolution for the supplied address and coin type.\\n    ///         Caller should enable EIP-3668.\\n    /// @dev This function executes over multiple steps.\\n    /// @param lookupAddress The input address.\\n    /// @param coinType The coin type.\\n    /// @param gateways The list of batch gateway URLs to use.\\n    /// @return primary The resolved primary name.\\n    /// @return resolver The resolver address for primary name.\\n    /// @return reverseResolver The resolver address for the reverse name.\\n    function reverseWithGateways(\\n        bytes calldata lookupAddress,\\n        uint256 coinType,\\n        string[] memory gateways\\n    )\\n        public\\n        view\\n        returns (\\n            string memory primary,\\n            address resolver,\\n            address reverseResolver\\n        )\\n    {\\n        primary;\\n        resolver;\\n        reverseResolver;\\n        // https://docs.ens.domains/ensip/19\\n        ResolverInfo memory info = requireResolver(\\n            NameCoder.encode(ENSIP19.reverseName(lookupAddress, coinType)) // reverts EmptyAddress\\n        );\\n        _callResolver(\\n            info,\\n            abi.encodeCall(INameResolver.name, (info.node)),\\n            gateways,\\n            this.reverseNameCallback.selector, // ==> step 2\\n            abi.encode(\\n                ReverseArgs(lookupAddress, coinType, gateways, info.resolver)\\n            )\\n        );\\n    }\\n\\n    /// @dev CCIP-Read callback for `reverseWithGateways()`.\\n    /// @param response The abi-encoded `name()` response from the reverse resolver.\\n    /// @param extraData The contextual data passed from `reverseWithGateways()`.\\n    function reverseNameCallback(\\n        bytes calldata response,\\n        bytes calldata extraData\\n    ) external view returns (string memory primary, address, address) {\\n        ReverseArgs memory args = abi.decode(extraData, (ReverseArgs));\\n        primary = abi.decode(response, (string));\\n        if (bytes(primary).length == 0) {\\n            return (\\\"\\\", address(0), args.resolver);\\n        }\\n        ResolverInfo memory info = requireResolver(NameCoder.encode(primary));\\n        _callResolver(\\n            info,\\n            args.coinType == COIN_TYPE_ETH\\n                ? abi.encodeCall(IAddrResolver.addr, (info.node))\\n                : abi.encodeCall(\\n                    IAddressResolver.addr,\\n                    (info.node, args.coinType)\\n                ),\\n            args.gateways,\\n            this.reverseAddressCallback.selector, // ==> step 3\\n            abi.encode(args, primary, info.resolver)\\n        );\\n    }\\n\\n    /// @dev CCIP-Read callback for `reverseNameCallback()`.\\n    ///      Reverts `ReverseAddressMismatch`.\\n    /// @param response The abi-encoded `addr()` response from the forward resolver.\\n    /// @param extraData The contextual data passed from `reverseNameCallback()`.\\n    function reverseAddressCallback(\\n        bytes calldata response,\\n        bytes calldata extraData\\n    )\\n        external\\n        pure\\n        returns (\\n            string memory primary,\\n            address resolver,\\n            address reverseResolver\\n        )\\n    {\\n        ReverseArgs memory args;\\n        (args, primary, resolver) = abi.decode(\\n            extraData,\\n            (ReverseArgs, string, address)\\n        );\\n        bytes memory primaryAddress;\\n        if (args.coinType == COIN_TYPE_ETH) {\\n            address addr = abi.decode(response, (address));\\n            primaryAddress = abi.encodePacked(addr);\\n        } else {\\n            primaryAddress = abi.decode(response, (bytes));\\n        }\\n        if (!BytesUtils.equals(args.lookupAddress, primaryAddress)) {\\n            revert ReverseAddressMismatch(primary, primaryAddress);\\n        }\\n        reverseResolver = args.resolver;\\n    }\\n\\n    /// @dev Efficiently call a resolver.\\n    ///      If features are supported, and not a multicall or extended w/`RESOLVE_MULTICALL`, performs a direct call.\\n    ///      Otherwise, uses the batch gateway.\\n    /// @param info The resolver to call.\\n    /// @param call The calldata.\\n    /// @param gateways The list of batch gateway URLs to use.\\n    /// @param callbackFunction The function selector to call after resolution.\\n    /// @param extraData The contextual data passed to `callbackFunction`.\\n    function _callResolver(\\n        ResolverInfo memory info,\\n        bytes memory call,\\n        string[] memory gateways,\\n        bytes4 callbackFunction,\\n        bytes memory extraData\\n    ) internal view {\\n        if (\\n            ERC165Checker.supportsERC165InterfaceUnchecked(\\n                info.resolver,\\n                type(IFeatureSupporter).interfaceId\\n            ) &&\\n            (bytes4(call) != IMulticallable.multicall.selector ||\\n                (info.extended &&\\n                    IFeatureSupporter(info.resolver).supportsFeature(\\n                        ResolverFeatures.RESOLVE_MULTICALL\\n                    )))\\n        ) {\\n            ccipRead(\\n                address(info.resolver),\\n                info.extended\\n                    ? abi.encodeCall(\\n                        IExtendedResolver.resolve,\\n                        (info.name, call)\\n                    )\\n                    : call,\\n                this.resolveDirectCallback.selector,\\n                this.resolveDirectCallbackError.selector,\\n                abi.encode(\\n                    info.extended,\\n                    bytes4(call),\\n                    callbackFunction,\\n                    extraData\\n                )\\n            );\\n        } else {\\n            bytes[] memory calls;\\n            bool multi = bytes4(call) == IMulticallable.multicall.selector;\\n            if (multi) {\\n                calls = abi.decode(\\n                    BytesUtils.substring(call, 4, call.length - 4),\\n                    (bytes[])\\n                );\\n            } else {\\n                calls = new bytes[](1);\\n                calls[0] = call;\\n            }\\n            if (info.extended) {\\n                for (uint256 i; i < calls.length; ++i) {\\n                    calls[i] = abi.encodeCall(\\n                        IExtendedResolver.resolve,\\n                        (info.name, calls[i])\\n                    );\\n                }\\n            }\\n            ccipRead(\\n                address(this),\\n                abi.encodeCall(\\n                    this.ccipBatch,\\n                    (createBatch(info.resolver, calls, gateways))\\n                ),\\n                this.resolveBatchCallback.selector,\\n                IDENTITY_FUNCTION,\\n                abi.encode(info.extended, multi, callbackFunction, extraData)\\n            );\\n        }\\n    }\\n\\n    /// @dev CCIP-Read callback for `_callResolver()` from calling the resolver successfully.\\n    function resolveDirectCallback(\\n        bytes memory response,\\n        bytes calldata extraData\\n    ) external view {\\n        (\\n            bool extended,\\n            bytes4 callSelector,\\n            bytes4 callbackFunction,\\n            bytes memory extraData_\\n        ) = abi.decode(extraData, (bool, bytes4, bytes4, bytes));\\n        if (response.length == 0) {\\n            revert UnsupportedResolverProfile(callSelector);\\n        }\\n        if (extended) {\\n            response = abi.decode(response, (bytes)); // unwrap resolve()\\n        }\\n        ccipRead(\\n            address(this),\\n            abi.encodeWithSelector(callbackFunction, response, extraData_)\\n        );\\n    }\\n\\n    /// @dev CCIP-Read callback for `_callResolver()` from calling the resolver unsuccessfully.\\n    function resolveDirectCallbackError(\\n        bytes calldata response,\\n        bytes calldata\\n    ) external pure {\\n        _propagateResolverError(response);\\n    }\\n\\n    /// @dev CCIP-Read callback for `_callResolver()` from calling the batch gateway successfully.\\n    function resolveBatchCallback(\\n        bytes calldata response,\\n        bytes calldata extraData\\n    ) external view {\\n        Lookup[] memory lookups = abi.decode(response, (Batch)).lookups;\\n        (\\n            bool extended,\\n            bool multi,\\n            bytes4 callbackFunction,\\n            bytes memory extraData_\\n        ) = abi.decode(extraData, (bool, bool, bytes4, bytes));\\n        bytes memory answer;\\n        if (multi) {\\n            bytes[] memory m = new bytes[](lookups.length);\\n            for (uint256 i; i < lookups.length; ++i) {\\n                Lookup memory lu = lookups[i];\\n                bytes memory v = lu.data;\\n                if (extended && (lu.flags & FLAGS_ANY_ERROR) == 0) {\\n                    v = abi.decode(v, (bytes)); // unwrap resolve()\\n                }\\n                m[i] = v;\\n            }\\n            answer = abi.encode(m);\\n        } else {\\n            Lookup memory lu = lookups[0];\\n            answer = lu.data;\\n            if ((lu.flags & FLAG_BATCH_ERROR) != 0) {\\n                assembly {\\n                    revert(add(answer, 32), mload(answer)) // propagate batch gateway errors\\n                }\\n            } else if ((lu.flags & FLAG_CALL_ERROR) != 0) {\\n                _propagateResolverError(answer);\\n            } else if (answer.length == 0) {\\n                revert UnsupportedResolverProfile(bytes4(lu.call));\\n            }\\n            if (extended) {\\n                answer = abi.decode(answer, (bytes)); // unwrap resolve()\\n            }\\n        }\\n        ccipRead(\\n            address(this),\\n            abi.encodeWithSelector(callbackFunction, answer, extraData_)\\n        );\\n    }\\n\\n    /// @dev Propagate the revert from the resolver.\\n    /// @param v The error data.\\n    function _propagateResolverError(bytes memory v) internal pure {\\n        if (bytes4(v) == UnsupportedResolverProfile.selector) {\\n            assembly {\\n                revert(add(v, 32), mload(v))\\n            }\\n        } else {\\n            revert ResolverError(v);\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x73948e0847c54fce7f1cdb254fd0c0969175287eb068f64a884d27d5cc5dd72d\",\"license\":\"MIT\"},\"contracts/universalResolver/IUniversalResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @notice Interface for the UniversalResolver.\\n/// @dev Interface selector: `0xcd191b34`\\ninterface IUniversalResolver {\\n    /// @notice A resolver could not be found for the supplied name.\\n    /// @dev Error selector: `0x77209fe8`\\n    error ResolverNotFound(bytes name);\\n\\n    /// @notice The resolver is not a contract.\\n    /// @dev Error selector: `0x1e9535f2`\\n    error ResolverNotContract(bytes name, address resolver);\\n\\n    /// @notice The resolver did not respond.\\n    /// @dev Error selector: `0x7b1c461b`\\n    error UnsupportedResolverProfile(bytes4 selector);\\n\\n    /// @notice The resolver returned an error.\\n    /// @dev Error selector: `0x95c0c752`\\n    error ResolverError(bytes errorData);\\n\\n    /// @notice The resolved address from reverse resolution does not match the supplied address.\\n    /// @dev Error selector: `0xef9c03ce`\\n    error ReverseAddressMismatch(string primary, bytes primaryAddress);\\n\\n    /// @notice An HTTP error occurred on a resolving gateway.\\n    /// @dev Error selector: `0x01800152`\\n    error HttpError(uint16 status, string message);\\n\\n    /// @dev Find the resolver address for `name`.\\n    ///      Does not perform any validity checks on the resolver.\\n    /// @param name The name to search.\\n    /// @return resolver The resolver or `address(0)` if not found.\\n    /// @return node The namehash of `name`.\\n    /// @return offset The offset into `name` corresponding to `resolver`.\\n    function findResolver(\\n        bytes memory name\\n    ) external view returns (address resolver, bytes32 node, uint256 offset);\\n\\n    /// @notice Performs ENS name resolution for the supplied name and resolution data.\\n    /// @notice Caller should enable EIP-3668.\\n    /// @param name The name to resolve, in normalised and DNS-encoded form.\\n    /// @param data The resolution data, as specified in ENSIP-10.\\n    ///             For a multicall, the data should be encoded as `multicall(bytes[])`.\\n    /// @return result The result of the resolution.\\n    ///                For a multicall, the result is encoded as `(bytes[])`.\\n    /// @return resolver The resolver that was used to resolve the name.\\n    function resolve(\\n        bytes calldata name,\\n        bytes calldata data\\n    ) external view returns (bytes memory result, address resolver);\\n\\n    /// @notice Performs ENS reverse resolution for the supplied address and coin type.\\n    /// @notice Caller should enable EIP-3668.\\n    /// @param lookupAddress The address to reverse resolve, in encoded form.\\n    /// @param coinType The coin type to use for the reverse resolution.\\n    ///                 For ETH, this is 60.\\n    ///                 For other EVM chains, coinType is calculated as `0x80000000 | chainId`.\\n    /// @return primary The reverse resolution result.\\n    /// @return resolver The resolver that was used to resolve the name.\\n    /// @return reverseResolver The resolver that was used to resolve the reverse name.\\n    function reverse(\\n        bytes calldata lookupAddress,\\n        uint256 coinType\\n    )\\n        external\\n        view\\n        returns (\\n            string memory primary,\\n            address resolver,\\n            address reverseResolver\\n        );\\n}\\n\",\"keccak256\":\"0x36b8a75295e7b74dff3d890e3ee19459eca878c597b791ebd726e638696e48ee\",\"license\":\"MIT\"},\"contracts/universalResolver/RegistryUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {ENS} from \\\"../registry/ENS.sol\\\";\\nimport {NameCoder} from \\\"../utils/NameCoder.sol\\\";\\n\\nlibrary RegistryUtils {\\n    /// @notice Find the resolver for `name[offset:]`.\\n    /// @dev Reverts `DNSDecodingFailed`.\\n    /// @param registry The ENS registry.\\n    /// @param name The DNS-encoded name to search.\\n    /// @param offset The offset into `name` to begin the search.\\n    /// @return resolver The resolver or `address(0)` if not found.\\n    /// @return node The namehash of `name[offset:]`.\\n    /// @return resolverOffset The offset into `name` corresponding to `resolver`.\\n    function findResolver(\\n        ENS registry,\\n        bytes memory name,\\n        uint256 offset\\n    )\\n        internal\\n        view\\n        returns (address resolver, bytes32 node, uint256 resolverOffset)\\n    {\\n        (bytes32 labelHash, uint256 next) = NameCoder.readLabel(name, offset);\\n        if (labelHash != bytes32(0)) {\\n            (\\n                address parentResolver,\\n                bytes32 parentNode,\\n                uint256 parentOffset\\n            ) = findResolver(registry, name, next);\\n            node = NameCoder.namehash(parentNode, labelHash);\\n            resolver = registry.resolver(node);\\n            return\\n                resolver != address(0)\\n                    ? (resolver, node, offset)\\n                    : (parentResolver, node, parentOffset);\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x050dd0e2823fc92df8a29f4516c5af22dcd42cd7c7fbd88d852fb330939285c7\",\"license\":\"MIT\"},\"contracts/universalResolver/UniversalResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {AbstractUniversalResolver, IGatewayProvider} from \\\"./AbstractUniversalResolver.sol\\\";\\nimport {RegistryUtils, ENS} from \\\"./RegistryUtils.sol\\\";\\nimport {ReverseClaimer} from \\\"../reverseRegistrar/ReverseClaimer.sol\\\";\\n\\ncontract UniversalResolver is AbstractUniversalResolver, ReverseClaimer {\\n    ENS public immutable registry;\\n\\n    constructor(\\n        address owner,\\n        ENS ens,\\n        IGatewayProvider batchGatewayProvider\\n    )\\n        AbstractUniversalResolver(batchGatewayProvider)\\n        ReverseClaimer(ens, owner)\\n    {\\n        registry = ens;\\n    }\\n\\n    /// @inheritdoc AbstractUniversalResolver\\n    function findResolver(\\n        bytes memory name\\n    ) public view override returns (address, bytes32, uint256) {\\n        return RegistryUtils.findResolver(registry, name, 0);\\n    }\\n}\\n\",\"keccak256\":\"0xcd631407f3b7043a6c9de7265ca6fe8e51096060c33eeba8b1c3ba848adee88c\",\"license\":\"MIT\"},\"contracts/utils/BytesUtils.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\nlibrary BytesUtils {\\n    /// @dev `offset` was beyond `length`.\\n    ///       Error selector: `0x8a3c1cfb`\\n    error OffsetOutOfBoundsError(uint256 offset, uint256 length);\\n\\n    /// @dev Assert `end` is not beyond the length of `v`.\\n    function _checkBound(bytes memory v, uint256 end) internal pure {\\n        if (end > v.length) {\\n            revert OffsetOutOfBoundsError(end, v.length);\\n        }\\n    }\\n\\n    /// @dev Compute `keccak256(v[off:off+len])`.\\n    /// @param v The source bytes.\\n    /// @param off The offset into the source.\\n    /// @param len The number of bytes to hash.\\n    /// @return ret The corresponding hash.\\n    function keccak(\\n        bytes memory v,\\n        uint256 off,\\n        uint256 len\\n    ) internal pure returns (bytes32 ret) {\\n        _checkBound(v, off + len);\\n        assembly {\\n            ret := keccak256(add(add(v, 32), off), len)\\n        }\\n    }\\n\\n    /// @dev Lexicographically compare two byte strings.\\n    /// @param vA The first bytes to compare.\\n    /// @param vB The second bytes to compare.\\n    /// @return Positive number if `A > B`, negative number if `A < B`, or zero if `A == B`.\\n    function compare(\\n        bytes memory vA,\\n        bytes memory vB\\n    ) internal pure returns (int256) {\\n        return compare(vA, 0, vA.length, vB, 0, vB.length);\\n    }\\n\\n    /// @dev Lexicographically compare two byte ranges: `A = vA[offA:offA+lenA]` and `B = vB[offB:offB+lenB]`.\\n    /// @param vA The first bytes.\\n    /// @param offA The offset of the first bytes.\\n    /// @param lenA The length of the first bytes.\\n    /// @param vB The second bytes.\\n    /// @param offB The offset of the second bytes.\\n    /// @param lenB The length of the second bytes.\\n    /// @return Positive number if `A > B`, negative number if `A < B`, or zero if `A == B`.\\n    function compare(\\n        bytes memory vA,\\n        uint256 offA,\\n        uint256 lenA,\\n        bytes memory vB,\\n        uint256 offB,\\n        uint256 lenB\\n    ) internal pure returns (int256) {\\n        _checkBound(vA, offA + lenA);\\n        _checkBound(vB, offB + lenB);\\n        uint256 ptrA;\\n        uint256 ptrB;\\n        assembly {\\n            ptrA := add(vA, offA)\\n            ptrB := add(vB, offB)\\n        }\\n        uint256 shortest = lenA < lenB ? lenA : lenB;\\n        for (uint256 i; i < shortest; i += 32) {\\n            uint256 a;\\n            uint256 b;\\n            assembly {\\n                ptrA := add(ptrA, 32)\\n                ptrB := add(ptrB, 32)\\n                a := mload(ptrA)\\n                b := mload(ptrB)\\n            }\\n            if (a != b) {\\n                uint256 rest = shortest - i;\\n                if (rest < 32) {\\n                    rest = (32 - rest) << 3; // bits to drop\\n                    a >>= rest; // shift out the\\n                    b >>= rest; // irrelevant bits\\n                }\\n                if (a < b) {\\n                    return -1;\\n                } else if (a > b) {\\n                    return 1;\\n                }\\n            }\\n        }\\n        return int256(lenA) - int256(lenB);\\n    }\\n\\n    /// @dev Determine if `a[offA:offA+len] == b[offB:offB+len]`.\\n    /// @param vA The first bytes.\\n    /// @param offA The offset into the first bytes.\\n    /// @param vB The second bytes.\\n    /// @param offB The offset into the second bytes.\\n    /// @param len The number of bytes to compare.\\n    /// @return True if the byte ranges are equal.\\n    function equals(\\n        bytes memory vA,\\n        uint256 offA,\\n        bytes memory vB,\\n        uint256 offB,\\n        uint256 len\\n    ) internal pure returns (bool) {\\n        return keccak(vA, offA, len) == keccak(vB, offB, len);\\n    }\\n\\n    /// @dev Determine if `a[offA:] == b[offB:]`.\\n    /// @param vA The first bytes.\\n    /// @param offA The offset into the first bytes.\\n    /// @param vB The second bytes.\\n    /// @param offB The offset into the second bytes.\\n    /// @return True if the byte ranges are equal.\\n    function equals(\\n        bytes memory vA,\\n        uint256 offA,\\n        bytes memory vB,\\n        uint256 offB\\n    ) internal pure returns (bool) {\\n        _checkBound(vA, offA);\\n        _checkBound(vB, offB);\\n        return\\n            keccak(vA, offA, vA.length - offA) ==\\n            keccak(vB, offB, vB.length - offB);\\n    }\\n\\n    /// @dev Determine if `a[offA:] == b`.\\n    /// @param vA The first bytes.\\n    /// @param offA The offset into the first bytes.\\n    /// @param vB The second bytes.\\n    /// @return True if the byte ranges are equal.\\n    function equals(\\n        bytes memory vA,\\n        uint256 offA,\\n        bytes memory vB\\n    ) internal pure returns (bool) {\\n        return\\n            vA.length == offA + vB.length &&\\n            keccak(vA, offA, vB.length) == keccak256(vB);\\n    }\\n\\n    /// @dev Determine if `a == b`.\\n    /// @param vA The first bytes.\\n    /// @param vB The second bytes.\\n    /// @return True if the bytes are equal.\\n    function equals(\\n        bytes memory vA,\\n        bytes memory vB\\n    ) internal pure returns (bool) {\\n        return vA.length == vB.length && keccak256(vA) == keccak256(vB);\\n    }\\n\\n    /// @dev Returns `uint8(v[off])`.\\n    /// @param v The source bytes.\\n    /// @param off The offset into the source.\\n    /// @return The corresponding `uint8`.\\n    function readUint8(\\n        bytes memory v,\\n        uint256 off\\n    ) internal pure returns (uint8) {\\n        _checkBound(v, off + 1);\\n        return uint8(v[off]);\\n    }\\n\\n    /// @dev Returns `uint16(bytes2(v[off:off+2]))`.\\n    /// @param v The source bytes.\\n    /// @param off The offset into the source.\\n    /// @return ret The corresponding `uint16`.\\n    function readUint16(\\n        bytes memory v,\\n        uint256 off\\n    ) internal pure returns (uint16 ret) {\\n        _checkBound(v, off + 2);\\n        assembly {\\n            ret := shr(240, mload(add(add(v, 32), off)))\\n        }\\n    }\\n\\n    /// @dev Returns `uint32(bytes4(v[off:off+4]))`.\\n    /// @param v The source bytes.\\n    /// @param off The offset into the source.\\n    /// @return ret The corresponding `uint32`.\\n    function readUint32(\\n        bytes memory v,\\n        uint256 off\\n    ) internal pure returns (uint32 ret) {\\n        _checkBound(v, off + 4);\\n        assembly {\\n            ret := shr(224, mload(add(add(v, 32), off)))\\n        }\\n    }\\n\\n    /// @dev Returns `bytes20(v[off:off+20])`.\\n    /// @param v The source bytes.\\n    /// @param off The offset into the source.\\n    /// @return ret The corresponding `bytes20`.\\n    function readBytes20(\\n        bytes memory v,\\n        uint256 off\\n    ) internal pure returns (bytes20 ret) {\\n        _checkBound(v, off + 20);\\n        assembly {\\n            ret := shl(96, mload(add(add(v, 20), off)))\\n        }\\n    }\\n\\n    /// @dev Returns `bytes32(v[off:off+32])`.\\n    /// @param v The source bytes.\\n    /// @param off The offset into the source.\\n    /// @return ret The corresponding `bytes32`.\\n    function readBytes32(\\n        bytes memory v,\\n        uint256 off\\n    ) internal pure returns (bytes32 ret) {\\n        _checkBound(v, off + 32);\\n        assembly {\\n            ret := mload(add(add(v, 32), off))\\n        }\\n    }\\n\\n    /// @dev Returns `bytes32(bytesN(v[off:off+len]))`.\\n    ///      Accepts 0-32 bytes or reverts.\\n    /// @param v The source bytes.\\n    /// @param off The offset into the source.\\n    /// @param len The number of bytes.\\n    /// @return ret The corresponding N-bytes left-aligned in a `bytes32`.\\n    function readBytesN(\\n        bytes memory v,\\n        uint256 off,\\n        uint256 len\\n    ) internal pure returns (bytes32 ret) {\\n        assert(len <= 32);\\n        _checkBound(v, off + len);\\n        assembly {\\n            let mask := sub(shl(shl(3, sub(32, len)), 1), 1) // <(32-N)x00><NxFF>\\n            ret := and(mload(add(add(v, 32), off)), not(mask))\\n        }\\n    }\\n\\n    /// @dev Copy `mem[src:src+len]` to `mem[dst:dst+len]`.\\n    /// @param src The source memory offset.\\n    /// @param dst The destination memory offset.\\n    /// @param len The number of bytes to copy.\\n    function unsafeMemcpy(uint256 dst, uint256 src, uint256 len) internal pure {\\n        assembly {\\n            // Copy word-length chunks while offsible\\n            // prettier-ignore\\n            for {} gt(len, 31) {} {\\n                mstore(dst, mload(src))\\n                dst := add(dst, 32)\\n                src := add(src, 32)\\n                len := sub(len, 32)\\n            }\\n            // Copy remaining bytes\\n            if len {\\n                let mask := sub(shl(shl(3, sub(32, len)), 1), 1) // see above\\n                let wSrc := and(mload(src), not(mask))\\n                let wDst := and(mload(dst), mask)\\n                mstore(dst, or(wSrc, wDst))\\n            }\\n        }\\n    }\\n\\n    /// @dev Copy `vSrc[offSrc:offSrc+len]` to `vDst[offDst:offDst:len]`.\\n    /// @param vSrc The source bytes.\\n    /// @param offSrc The offset into the source to begin the copy.\\n    /// @param vDst The destination bytes.\\n    /// @param offDst The offset into the destination to place the copy.\\n    /// @param len The number of bytes to copy.\\n    function copyBytes(\\n        bytes memory vSrc,\\n        uint256 offSrc,\\n        bytes memory vDst,\\n        uint256 offDst,\\n        uint256 len\\n    ) internal pure {\\n        _checkBound(vSrc, offSrc + len);\\n        _checkBound(vDst, offDst + len);\\n        uint256 src;\\n        uint256 dst;\\n        assembly {\\n            src := add(add(vSrc, 32), offSrc)\\n            dst := add(add(vDst, 32), offDst)\\n        }\\n        unsafeMemcpy(dst, src, len);\\n    }\\n\\n    /// @dev Copies a substring into a new byte string.\\n    /// @param vSrc The byte string to copy from.\\n    /// @param off The offset to start copying at.\\n    /// @param len The number of bytes to copy.\\n    /// @return vDst The copied substring.\\n    function substring(\\n        bytes memory vSrc,\\n        uint256 off,\\n        uint256 len\\n    ) internal pure returns (bytes memory vDst) {\\n        vDst = new bytes(len);\\n        copyBytes(vSrc, off, vDst, 0, len);\\n    }\\n\\n    /// @dev Find the first occurrence of `needle`.\\n    /// @param v The bytes to search.\\n    /// @param off The offset to start searching.\\n    /// @param len The number of bytes to search.\\n    /// @param needle The byte to search for.\\n    /// @return The offset of `needle`, or `type(uint256).max` if not found.\\n    function find(\\n        bytes memory v,\\n        uint256 off,\\n        uint256 len,\\n        bytes1 needle\\n    ) internal pure returns (uint256) {\\n        for (uint256 end = off + len; off < end; off++) {\\n            if (v[off] == needle) {\\n                return off;\\n            }\\n        }\\n        return type(uint256).max;\\n    }\\n}\\n\",\"keccak256\":\"0x573cabd76541625f8722c3d134a4c5f6398a5b794f0cab82e9ea60b023e42c03\",\"license\":\"MIT\"},\"contracts/utils/ENSIP19.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {HexUtils} from \\\"../utils/HexUtils.sol\\\";\\nimport {NameCoder} from \\\"../utils/NameCoder.sol\\\";\\n\\nuint32 constant CHAIN_ID_ETH = 1;\\n\\nuint256 constant COIN_TYPE_ETH = 60;\\nuint256 constant COIN_TYPE_DEFAULT = 1 << 31; // 0x8000_0000\\n\\nstring constant SLUG_ETH = \\\"addr\\\"; // <=> COIN_TYPE_ETH\\nstring constant SLUG_DEFAULT = \\\"default\\\"; // <=> COIN_TYPE_DEFAULT\\nstring constant TLD_REVERSE = \\\"reverse\\\";\\n\\n/// @dev Library for generating reverse names according to ENSIP-19.\\n/// https://docs.ens.domains/ensip/19\\nlibrary ENSIP19 {\\n    /// @dev The supplied address was `0x`.\\n    ///      Error selector: `0x7138356f`\\n    error EmptyAddress();\\n\\n    /// @dev Extract Chain ID from `coinType`.\\n    /// @param coinType The coin type.\\n    /// @return The Chain ID or 0 if non-EVM Chain.\\n    function chainFromCoinType(\\n        uint256 coinType\\n    ) internal pure returns (uint32) {\\n        if (coinType == COIN_TYPE_ETH) return CHAIN_ID_ETH;\\n        coinType ^= COIN_TYPE_DEFAULT;\\n        return uint32(coinType < COIN_TYPE_DEFAULT ? coinType : 0);\\n    }\\n\\n    /// @dev Determine if Coin Type is for an EVM address.\\n    /// @param coinType The coin type.\\n    /// @return True if coin type represents an EVM address.\\n    function isEVMCoinType(uint256 coinType) internal pure returns (bool) {\\n        return coinType == COIN_TYPE_DEFAULT || chainFromCoinType(coinType) > 0;\\n    }\\n\\n    /// @dev Generate Reverse Name from Address + Coin Type.\\n    ///      Reverts `EmptyAddress` if `addressBytes` is `0x`.\\n    /// @param addressBytes The input address.\\n    /// @param coinType The coin type.\\n    /// @return The ENS reverse name, eg. `1234abcd.addr.reverse`.\\n    function reverseName(\\n        bytes memory addressBytes,\\n        uint256 coinType\\n    ) internal pure returns (string memory) {\\n        if (addressBytes.length == 0) {\\n            revert EmptyAddress();\\n        }\\n        return\\n            string(\\n                abi.encodePacked(\\n                    HexUtils.bytesToHex(addressBytes),\\n                    bytes1(\\\".\\\"),\\n                    coinType == COIN_TYPE_ETH\\n                        ? SLUG_ETH\\n                        : coinType == COIN_TYPE_DEFAULT\\n                            ? SLUG_DEFAULT\\n                            : HexUtils.unpaddedUintToHex(coinType, true),\\n                    bytes1(\\\".\\\"),\\n                    TLD_REVERSE\\n                )\\n            );\\n    }\\n\\n    /// @dev Parse Reverse Name into Address + Coin Type.\\n    ///      Matches: `/^[0-9a-fA-F]+\\\\.([0-9a-f]{1,64}|addr|default)\\\\.reverse$/`.\\n    ///      Reverts `DNSDecodingFailed`.\\n    /// @param name The DNS-encoded name.\\n    /// @return addressBytes The address or empty if invalid.\\n    /// @return coinType The coin type.\\n    function parse(\\n        bytes memory name\\n    ) internal pure returns (bytes memory addressBytes, uint256 coinType) {\\n        (, uint256 offset) = NameCoder.readLabel(name, 0);\\n        bool valid;\\n        (addressBytes, valid) = HexUtils.hexToBytes(name, 1, offset);\\n        if (!valid || addressBytes.length == 0) return (\\\"\\\", 0); // addressBytes not 1+ hex\\n        (valid, coinType) = parseNamespace(name, offset);\\n        if (!valid) return (\\\"\\\", 0); // invalid namespace\\n    }\\n\\n    /// @dev Parse Reverse Namespace into Coin Type.\\n    ///      Matches: `/^([0-9a-f]{1,64}|addr|default)\\\\.reverse$/`.\\n    ///      Reverts `DNSDecodingFailed`.\\n    /// @param name The DNS-encoded name.\\n    /// @param offset The offset to begin parsing.\\n    /// @return valid True if a valid reverse namespace.\\n    /// @return coinType The coin type.\\n    function parseNamespace(\\n        bytes memory name,\\n        uint256 offset\\n    ) internal pure returns (bool valid, uint256 coinType) {\\n        (bytes32 labelHash, uint256 offsetTLD) = NameCoder.readLabel(\\n            name,\\n            offset\\n        );\\n        if (labelHash == keccak256(bytes(SLUG_ETH))) {\\n            coinType = COIN_TYPE_ETH;\\n        } else if (labelHash == keccak256(bytes(SLUG_DEFAULT))) {\\n            coinType = COIN_TYPE_DEFAULT;\\n        } else if (labelHash == bytes32(0)) {\\n            return (false, 0); // no slug\\n        } else {\\n            (bytes32 word, bool validHex) = HexUtils.hexStringToBytes32(\\n                name,\\n                1 + offset,\\n                offsetTLD\\n            );\\n            if (!validHex) return (false, 0); // invalid coinType or too long\\n            coinType = uint256(word);\\n        }\\n        (labelHash, offset) = NameCoder.readLabel(name, offsetTLD);\\n        if (labelHash != keccak256(bytes(TLD_REVERSE))) return (false, 0); // invalid tld\\n        (labelHash, ) = NameCoder.readLabel(name, offset);\\n        if (labelHash != bytes32(0)) return (false, 0); // not tld\\n        valid = true;\\n    }\\n}\\n\",\"keccak256\":\"0xd1af09b014028de4c50489bd58ae424273180bb96d95353d8eefd14845f31824\",\"license\":\"MIT\"},\"contracts/utils/HexUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\nlibrary HexUtils {\\n    /// @dev Convert `hexString[off:end]` to `bytes32`.\\n    ///      Accepts 0-64 hex-chars.\\n    ///      Uses right alignment: `1` &rarr; `0000000000000000000000000000000000000000000000000000000000000001`.\\n    /// @param hexString The string to parse.\\n    /// @param off The index to start parsing.\\n    /// @param end The (exclusive) index to stop parsing.\\n    /// @return word The parsed bytes32.\\n    /// @return valid True if the parse was successful.\\n    function hexStringToBytes32(\\n        bytes memory hexString,\\n        uint256 off,\\n        uint256 end\\n    ) internal pure returns (bytes32 word, bool valid) {\\n        if (end < off) return (\\\"\\\", false); // invalid range\\n        uint256 nibbles = end - off;\\n        if (nibbles > 64 || end > hexString.length) {\\n            return (bytes32(0), false); // too large or out of bounds\\n        }\\n        uint256 src;\\n        assembly {\\n            src := add(add(hexString, 32), off)\\n        }\\n        valid = unsafeBytes(src, 0, nibbles);\\n        assembly {\\n            let pad := sub(32, shr(1, add(nibbles, 1))) // number of bytes\\n            word := shr(shl(3, pad), mload(0)) // right align\\n        }\\n    }\\n\\n    /// @dev Convert `hexString[off:end]` to `address`.\\n    ///      Accepts exactly 40 hex-chars.\\n    /// @param hexString The string to parse.\\n    /// @param off The index to start parsing.\\n    /// @param end The (exclusive) index to stop parsing.\\n    /// @return addr The parsed address.\\n    /// @return valid True if the parse was successful.\\n    function hexToAddress(\\n        bytes memory hexString,\\n        uint256 off,\\n        uint256 end\\n    ) internal pure returns (address addr, bool valid) {\\n        if (off + 40 != end) return (address(0), false); // wrong length\\n        bytes32 word;\\n        (word, valid) = hexStringToBytes32(hexString, off, end);\\n        addr = address(uint160(uint256(word)));\\n    }\\n\\n    /// @dev Convert `hexString[off:end]` to `bytes`.\\n    ///      Accepts 0+ hex-chars.\\n    /// @param hexString The string to parse.\\n    /// @param off The index to start parsing.\\n    /// @param end The (exclusive) index to stop parsing.\\n    /// @return v The parsed bytes.\\n    /// @return valid True if the parse was successful.\\n    function hexToBytes(\\n        bytes memory hexString,\\n        uint256 off,\\n        uint256 end\\n    ) internal pure returns (bytes memory v, bool valid) {\\n        if (end < off) return (\\\"\\\", false); // invalid range\\n        uint256 nibbles = end - off;\\n        v = new bytes((1 + nibbles) >> 1); // round up\\n        uint256 src;\\n        uint256 dst;\\n        assembly {\\n            src := add(add(hexString, 32), off)\\n            dst := add(v, 32)\\n        }\\n        valid = unsafeBytes(src, dst, nibbles);\\n    }\\n\\n    /// @dev Convert arbitrary hex-encoded memory to bytes.\\n    ///      If nibbles is odd, leading hex-char is padded, eg. `F` &rarr; `0x0F`.\\n    ///      Matches: `/^[0-9a-f]*$/i`.\\n    /// @param src The memory offset of first hex-char of input.\\n    /// @param dst The memory offset of first byte of output (cannot alias `src`).\\n    /// @param nibbles The number of hex-chars to convert.\\n    /// @return valid True if all characters were hex.\\n    function unsafeBytes(\\n        uint256 src,\\n        uint256 dst,\\n        uint256 nibbles\\n    ) internal pure returns (bool valid) {\\n        assembly {\\n            function getHex(c, i) -> ascii {\\n                c := byte(i, c)\\n                // chars 48-57: 0-9\\n                if and(gt(c, 47), lt(c, 58)) {\\n                    ascii := sub(c, 48)\\n                    leave\\n                }\\n                // chars 65-70: A-F\\n                if and(gt(c, 64), lt(c, 71)) {\\n                    ascii := add(sub(c, 65), 10)\\n                    leave\\n                }\\n                // chars 97-102: a-f\\n                if and(gt(c, 96), lt(c, 103)) {\\n                    ascii := add(sub(c, 97), 10)\\n                    leave\\n                }\\n                // invalid char\\n                ascii := 0x100\\n            }\\n            valid := true\\n            let end := add(src, nibbles)\\n            if and(nibbles, 1) {\\n                let b := getHex(mload(src), 0) // \\\"f\\\" -> 15\\n                mstore8(dst, b) // write ascii byte\\n                src := add(src, 1) // update pointers\\n                dst := add(dst, 1)\\n                if gt(b, 255) {\\n                    valid := false\\n                    src := end // terminate loop\\n                }\\n            }\\n            // prettier-ignore\\n            for {} lt(src, end) {\\n                src := add(src, 2) // 2 nibbles\\n                dst := add(dst, 1) // per byte\\n            } {\\n                let word := mload(src) // read word (left aligned)\\n                let b := or(shl(4, getHex(word, 0)), getHex(word, 1)) // \\\"ff\\\" -> 255\\n                if gt(b, 255) {\\n                    valid := false\\n                    break\\n                }\\n                mstore8(dst, b) // write ascii byte\\n            }\\n        }\\n    }\\n\\n    /// @dev Format `address` as a hex string.\\n    /// @param addr The address to format.\\n    /// @return hexString The corresponding hex string w/o a 0x-prefix.\\n    function addressToHex(\\n        address addr\\n    ) internal pure returns (string memory hexString) {\\n        // return bytesToHex(abi.encodePacked(addr));\\n        hexString = new string(40);\\n        uint256 dst;\\n        assembly {\\n            mstore(0, addr)\\n            dst := add(hexString, 32)\\n        }\\n        unsafeHex(12, dst, 40);\\n    }\\n\\n    /// @dev Format `uint256` as a variable-length hex string without zero padding.\\n    /// * unpaddedUintToHex(0, true)  = \\\"0\\\"\\n    /// * unpaddedUintToHex(1, true)  = \\\"1\\\"\\n    /// * unpaddedUintToHex(0, false) = \\\"00\\\"\\n    /// * unpaddedUintToHex(1, false) = \\\"01\\\"\\n    /// @param value The number to format.\\n    /// @param dropZeroNibble If true, the leading byte will use one nibble if less than 16.\\n    /// @return hexString The corresponding hex string w/o an 0x-prefix.\\n    function unpaddedUintToHex(\\n        uint256 value,\\n        bool dropZeroNibble\\n    ) internal pure returns (string memory hexString) {\\n        uint256 temp = value;\\n        uint256 shift;\\n        for (uint256 b = 128; b >= 8; b >>= 1) {\\n            if (temp < (1 << b)) {\\n                shift += b; // number of zero upper bits\\n            } else {\\n                temp >>= b; // shift away lower half\\n            }\\n        }\\n        if (dropZeroNibble && temp < 16) shift += 4;\\n        uint256 nibbles = 64 - (shift >> 2);\\n        hexString = new string(nibbles);\\n        uint256 dst;\\n        assembly {\\n            mstore(0, shl(shift, value)) // left-align\\n            dst := add(hexString, 32)\\n        }\\n        unsafeHex(0, dst, nibbles);\\n    }\\n\\n    /// @dev Format `bytes` as a hex string.\\n    /// @param v The bytes to format.\\n    /// @return hexString The corresponding hex string w/o a 0x-prefix.\\n    function bytesToHex(\\n        bytes memory v\\n    ) internal pure returns (string memory hexString) {\\n        uint256 nibbles = v.length << 1;\\n        hexString = new string(nibbles);\\n        uint256 src;\\n        uint256 dst;\\n        assembly {\\n            src := add(v, 32)\\n            dst := add(hexString, 32)\\n        }\\n        unsafeHex(src, dst, nibbles);\\n    }\\n\\n    /// @dev Converts arbitrary memory to a hex string.\\n    /// @param src The memory offset of first nibble of input.\\n    /// @param dst The memory offset of first hex-char of output (can alias `src`).\\n    /// @param nibbles The number of nibbles to convert and the byte-length of the output.\\n    function unsafeHex(\\n        uint256 src,\\n        uint256 dst,\\n        uint256 nibbles\\n    ) internal pure {\\n        unchecked {\\n            for (uint256 end = dst + nibbles; dst < end; src += 32) {\\n                uint256 word;\\n                assembly {\\n                    word := mload(src)\\n                }\\n                for (uint256 shift = 256; dst < end && shift > 0; dst++) {\\n                    uint256 b = (word >> (shift -= 4)) & 15; // each nibble\\n                    b = b < 10 ? b + 0x30 : b + 0x57; // (\\\"a\\\" - 10) => 0x57\\n                    assembly {\\n                        mstore8(dst, b)\\n                    }\\n                }\\n            }\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0xab784cab15b7a06154be3555edf0d25bcdad8e6bf116aa2016119a233875b02b\",\"license\":\"MIT\"},\"contracts/utils/IFeatureSupporter.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @notice Interface for expressing contract features not visible from the ABI.\\n/// @dev Interface selector: `0x582de3e7`\\ninterface IFeatureSupporter {\\n    /// @notice Check if a feature is supported.\\n    /// @param feature The feature.\\n    /// @return True if the feature is supported by the contract.\\n    function supportsFeature(bytes4 feature) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x54839baa6478dea4f3985a9e9d149febd90dbfe7206f36bdcfee13a86406ebee\",\"license\":\"MIT\"},\"contracts/utils/NameCoder.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {HexUtils} from \\\"../utils/HexUtils.sol\\\";\\n\\n/// @dev Library for encoding/decoding names.\\n///\\n/// An ENS name is stop-separated labels, eg. \\\"aaa.bb.c\\\".\\n///\\n/// A DNS-encoded name is composed of byte length-prefixed labels with a terminator byte.\\n/// eg. \\\"\\\\x03aaa\\\\x02bb\\\\x01c\\\\x00\\\".\\n/// - maximum label length is 255 bytes.\\n/// - length = 0 is reserved for the terminator (root).\\n///\\n/// To encode a label larger than 255 bytes, use a hashed label.\\n/// A label of any length can be converted to a hashed label.\\n///\\n/// A hashed label is encoded as \\\"[\\\" + toHex(keccak256(label)) + \\\"]\\\".\\n/// eg. [af2caa1c2ca1d027f1ac823b529d0a67cd144264b2789fa2ea4d63a67c7103cc] = \\\"vitalik\\\".\\n/// - always 66 bytes.\\n/// - matches: `/^\\\\[[0-9a-f]{64}\\\\]$/`.\\n///\\n/// w/o hashed labels: `dns.length == 2 + ens.length` and the mapping is injective.\\n///  w/ hashed labels: `dns.length == 2 + ens.split('.').map(x => x.utf8Length).sum(n => n > 255 ? 66 : n)`.\\n///\\nlibrary NameCoder {\\n    /// @dev The DNS-encoded name is malformed.\\n    ///      Error selector: `0xba4adc23`\\n    error DNSDecodingFailed(bytes dns);\\n\\n    /// @dev A label of the ENS name has an invalid size.\\n    ///      Error selector: `0x9a4c3e3b`\\n    error DNSEncodingFailed(string ens);\\n\\n    /// @dev Read the `size` of the label at `offset`.\\n    ///      If `size = 0`, it must be the end of `name` (no junk at end).\\n    ///      Reverts `DNSDecodingFailed`.\\n    /// @param name The DNS-encoded name.\\n    /// @param offset The offset into `name` to start reading.\\n    /// @return size The size of the label in bytes.\\n    /// @return nextOffset The offset into `name` of the next label.\\n    function nextLabel(\\n        bytes memory name,\\n        uint256 offset\\n    ) internal pure returns (uint8 size, uint256 nextOffset) {\\n        assembly {\\n            size := byte(0, mload(add(add(name, 32), offset))) // uint8(name[offset])\\n            nextOffset := add(offset, add(1, size)) // offset + 1 + size\\n        }\\n        if (size > 0 ? nextOffset >= name.length : nextOffset != name.length) {\\n            revert DNSDecodingFailed(name);\\n        }\\n    }\\n\\n    /// @dev Find the offset of the label before `offset` in `name`.\\n    ///      * `prevOffset(name, 0)` reverts.\\n    ///      * `prevOffset(name, name.length + 1)` reverts.\\n    ///      * `prevOffset(name, name.length) = name.length - 1`.\\n    ///      * `prevOffset(name, name.length - 1) = <tld>`.\\n    ///      Reverts `DNSDecodingFailed`.\\n    /// @param name The DNS-encoded name.\\n    /// @param offset The offset into `name` to start reading backwards.\\n    /// @return prevOffset The offset into `name` of the previous label.\\n    function prevLabel(\\n        bytes memory name,\\n        uint256 offset\\n    ) internal pure returns (uint256 prevOffset) {\\n        while (true) {\\n            (, uint256 nextOffset) = nextLabel(name, prevOffset);\\n            if (nextOffset == offset) break;\\n            if (nextOffset > offset) {\\n                revert DNSDecodingFailed(name);\\n            }\\n            prevOffset = nextOffset;\\n        }\\n    }\\n\\n    /// @dev Compute the ENS labelhash of the label at `offset` and the offset for the next label.\\n    ///      Disallows hashed label of zero (eg. `[0..0]`) to prevent confusion with terminator.\\n    ///      Reverts `DNSDecodingFailed`.\\n    /// @param name The DNS-encoded name.\\n    /// @param offset The offset into `name` to start reading.\\n    /// @param parseHashed If true, supports hashed labels.\\n    /// @return labelHash The resulting labelhash.\\n    /// @return nextOffset The offset into `name` of the next label.\\n    /// @return size The size of the label in bytes.\\n    /// @return wasHashed If true, the label was interpreted as a hashed label.\\n    function readLabel(\\n        bytes memory name,\\n        uint256 offset,\\n        bool parseHashed\\n    )\\n        internal\\n        pure\\n        returns (\\n            bytes32 labelHash,\\n            uint256 nextOffset,\\n            uint8 size,\\n            bool wasHashed\\n        )\\n    {\\n        (size, nextOffset) = nextLabel(name, offset);\\n        if (\\n            parseHashed &&\\n            size == 66 &&\\n            name[offset + 1] == \\\"[\\\" &&\\n            name[nextOffset - 1] == \\\"]\\\"\\n        ) {\\n            (labelHash, wasHashed) = HexUtils.hexStringToBytes32(\\n                name,\\n                offset + 2,\\n                nextOffset - 1\\n            ); // will not revert\\n            if (!wasHashed || labelHash == bytes32(0)) {\\n                revert DNSDecodingFailed(name); // \\\"readLabel: malformed\\\" or null literal\\n            }\\n        } else if (size > 0) {\\n            assembly {\\n                labelHash := keccak256(add(add(name, offset), 33), size)\\n            }\\n        }\\n    }\\n\\n    /// @dev Same as `BytesUtils.namehash()` but supports hashed labels.\\n    function readLabel(\\n        bytes memory name,\\n        uint256 offset\\n    ) internal pure returns (bytes32 labelHash, uint256 nextOffset) {\\n        (labelHash, nextOffset, , ) = readLabel(name, offset, true);\\n    }\\n\\n    /// @dev Compute the ENS namehash of `name[:offset]`.\\n    ///      Supports hashed labels.\\n    ///      Reverts `DNSDecodingFailed`.\\n    /// @param name The DNS-encoded name.\\n    /// @param offset The offset into name start hashing.\\n    /// @return hash The namehash of `name[:offset]`.\\n    function namehash(\\n        bytes memory name,\\n        uint256 offset\\n    ) internal pure returns (bytes32 hash) {\\n        (hash, offset) = readLabel(name, offset);\\n        if (hash != bytes32(0)) {\\n            hash = namehash(namehash(name, offset), hash);\\n        }\\n    }\\n\\n    /// @dev Compute a child namehash from a parent namehash.\\n    /// @param parentNode The namehash of the parent.\\n    /// @param labelHash The labelhash of the child.\\n    /// @return node The namehash of the child.\\n    function namehash(\\n        bytes32 parentNode,\\n        bytes32 labelHash\\n    ) internal pure returns (bytes32 node) {\\n        // ~100 gas less than: keccak256(abi.encode(parentNode, labelHash))\\n        assembly {\\n            mstore(0, parentNode)\\n            mstore(32, labelHash)\\n            node := keccak256(0, 64)\\n        }\\n    }\\n\\n    /// @dev Convert DNS-encoded name to ENS name.\\n    ///      Reverts `DNSDecodingFailed`.\\n    /// @param dns The DNS-encoded name to convert, eg. `\\\\x03aaa\\\\x02bb\\\\x01c\\\\x00`.\\n    /// @return ens The equivalent ENS name, eg. `aaa.bb.c`.\\n    function decode(\\n        bytes memory dns\\n    ) internal pure returns (string memory ens) {\\n        unchecked {\\n            uint256 n = dns.length;\\n            if (n == 1 && dns[0] == 0) return \\\"\\\"; // only valid answer is root\\n            if (n < 3) revert DNSDecodingFailed(dns);\\n            bytes memory v = new bytes(n - 2); // always 2-shorter\\n            uint256 src;\\n            uint256 dst;\\n            while (src < n) {\\n                uint8 len = uint8(dns[src++]);\\n                if (len == 0) break;\\n                uint256 end = src + len;\\n                if (end > dns.length) revert DNSDecodingFailed(dns); // overflow\\n                if (dst > 0) v[dst++] = \\\".\\\"; // skip first stop\\n                while (src < end) {\\n                    bytes1 x = dns[src++]; // read byte\\n                    if (x == \\\".\\\") revert DNSDecodingFailed(dns); // malicious label\\n                    v[dst++] = x; // write byte\\n                }\\n            }\\n            if (src != dns.length) revert DNSDecodingFailed(dns); // junk at end\\n            return string(v);\\n        }\\n    }\\n\\n    /// @dev Convert ENS name to DNS-encoded name.\\n    ///      Hashes labels longer than 255 bytes.\\n    ///      Reverts `DNSEncodingFailed`.\\n    /// @param ens The ENS name to convert, eg. `aaa.bb.c`.\\n    /// @return dns The corresponding DNS-encoded name, eg. `\\\\x03aaa\\\\x02bb\\\\x01c\\\\x00`.\\n    function encode(\\n        string memory ens\\n    ) internal pure returns (bytes memory dns) {\\n        unchecked {\\n            uint256 n = bytes(ens).length;\\n            if (n == 0) return hex\\\"00\\\"; // root\\n            dns = new bytes(n + 2);\\n            uint256 start;\\n            assembly {\\n                start := add(dns, 32) // first byte of output\\n            }\\n            uint256 end = start; // remember position to write length\\n            for (uint256 i; i < n; i++) {\\n                bytes1 x = bytes(ens)[i]; // read byte\\n                if (x == \\\".\\\") {\\n                    start = _createHashedLabel(start, end);\\n                    if (start == 0) revert DNSEncodingFailed(ens);\\n                    end = start; // jump to next position\\n                } else {\\n                    assembly {\\n                        end := add(end, 1) // increase length\\n                        mstore(end, x) // write byte\\n                    }\\n                }\\n            }\\n            start = _createHashedLabel(start, end);\\n            if (start == 0) revert DNSEncodingFailed(ens);\\n            assembly {\\n                mstore8(start, 0) // terminal byte\\n                mstore(dns, sub(start, add(dns, 31))) // truncate length\\n            }\\n        }\\n    }\\n\\n    /// @dev Write the label length.\\n    ///      If longer than 255, writes a hashed label instead.\\n    /// @param start The memory offset of the length-prefixed label.\\n    /// @param end The memory offset at the end of the label.\\n    /// @return next The memory offset for the next label.\\n    ///              Returns 0 if label is empty (handled by caller).\\n    function _createHashedLabel(\\n        uint256 start,\\n        uint256 end\\n    ) internal pure returns (uint256 next) {\\n        uint256 size = end - start; // length of label\\n        if (size > 255) {\\n            assembly {\\n                mstore(0, keccak256(add(start, 1), size)) // compute hash of label\\n            }\\n            HexUtils.unsafeHex(0, start + 2, 64); // override label with hex(hash)\\n            assembly {\\n                mstore8(add(start, 1), 0x5B) // \\\"[\\\"\\n                mstore8(add(start, 66), 0x5D) // \\\"]\\\"\\n            }\\n            size = 66;\\n        }\\n        if (size > 0) {\\n            assembly {\\n                mstore8(start, size) // update length\\n            }\\n            next = start + 1 + size; // advance\\n        }\\n    }\\n\\n    /// @dev Find the offset of `name` that namehashes to `nodeSuffix`.\\n    /// @param name The name to search.\\n    /// @param nodeSuffix The node to match.\\n    /// @return matched True if `name` ends with the suffix.\\n    /// @return node The namehash of `name[offset:]`.\\n    /// @return prevOffset The offset into `name` of the label before the suffix, or `matchOffset` if no match or prior label.\\n    /// @return matchOffset The offset into `name` that namehashes to the `nodeSuffix`, or 0 if no match.\\n    function matchSuffix(\\n        bytes memory name,\\n        uint256 offset,\\n        bytes32 nodeSuffix\\n    )\\n        internal\\n        pure\\n        returns (\\n            bool matched,\\n            bytes32 node,\\n            uint256 prevOffset,\\n            uint256 matchOffset\\n        )\\n    {\\n        (bytes32 labelHash, uint256 next) = readLabel(name, offset);\\n        if (labelHash != bytes32(0)) {\\n            (matched, node, prevOffset, matchOffset) = matchSuffix(\\n                name,\\n                next,\\n                nodeSuffix\\n            );\\n            if (node == nodeSuffix) {\\n                matched = true;\\n                prevOffset = offset;\\n                matchOffset = next;\\n            }\\n            node = namehash(node, labelHash);\\n        }\\n        if (node == nodeSuffix) {\\n            matched = true;\\n            prevOffset = matchOffset = offset;\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x5b560dababf924922630c9dfb2cef290f16ad9ad9aec9b30419be67f7f99cd1d\",\"license\":\"MIT\"}},\"version\":1}",
  "bytecode": "0x60e060405234801561001057600080fd5b50604051614d94380380614d9483398101604081905261002f9161016c565b61c3506080526001600160a01b0381811660a0526040516302571be360e01b81527f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e26004820152839185916000918416906302571be390602401602060405180830381865afa1580156100a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100ca91906101b9565b604051630f41a04d60e11b81526001600160a01b03848116600483015291925090821690631e83409a906024016020604051808303816000875af1158015610116573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061013a91906101dd565b5050506001600160a01b0390921660c052506101f6915050565b6001600160a01b038116811461016957600080fd5b50565b60008060006060848603121561018157600080fd5b835161018c81610154565b602085015190935061019d81610154565b60408501519092506101ae81610154565b809150509250925092565b6000602082840312156101cb57600080fd5b81516101d681610154565b9392505050565b6000602082840312156101ef57600080fd5b5051919050565b60805160a05160c051614b5a61023a6000396000818161025f01526110f601526000818161018301528181610b360152610c02015260006120590152614b5a6000f3fe608060405234801561001057600080fd5b50600436106101515760003560e01c80639061b923116100cd578063b4a8580111610081578063b7d6ca6411610066578063b7d6ca6414610353578063c285238a14610366578063ef46c0b81461038657600080fd5b8063b4a858011461032d578063b536af761461034057600080fd5b80639f28e99d116100b25780639f28e99d146102b5578063a1472844146102d5578063a1cbcbaf146102e857600080fd5b80639061b9231461028157806394fbfa87146102a257600080fd5b80634a3e399411610124578063575de75011610109578063575de750146102255780635d78a217146102475780637b1039991461025a57600080fd5b80634a3e3994146101f257806355391bb81461021257600080fd5b806301ffc9a71461015657806302cf25781461017e5780633c6cbda8146101ca578063491fc4f9146101df575b600080fd5b61016961016436600461332d565b610399565b60405190151581526020015b60405180910390f35b6101a57f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610175565b6101dd6101d836600461338c565b610432565b005b6101dd6101ed36600461338c565b610477565b61020561020036600461365c565b61073d565b604051610175919061377b565b6101dd61022036600461378e565b6108a8565b61023861023336600461338c565b61095e565b604051610175939291906137fc565b61023861025536600461383c565b610b29565b6101a57f000000000000000000000000000000000000000000000000000000000000000081565b61029461028f36600461338c565b610bf5565b604051610175929190613888565b6102386102b036600461338c565b610cbe565b6102c86102c33660046138c0565b610e08565b6040516101759190613af7565b6102946102e3366004613c11565b611011565b6102fb6102f6366004613cb1565b6110ec565b6040805173ffffffffffffffffffffffffffffffffffffffff9094168452602084019290925290820152606001610175565b61029461033b36600461338c565b61112a565b6102c861034e36600461338c565b611182565b610238610361366004613ce6565b6114a4565b610379610374366004613cb1565b6115f0565b6040516101759190613d5e565b6101dd610394366004613dc6565b61165a565b60007f6cd2d09b000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061042c57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b61047184848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061172c92505050565b50505050565b6000610485848601866138c0565b519050600080808061049986880188613e3d565b9350935093509350606083156105ad576000865167ffffffffffffffff8111156104c5576104c561341f565b6040519080825280602002602001820160405280156104f857816020015b60608152602001906001900390816104e35790505b50905060005b875181101561058457600088828151811061051b5761051b613ea6565b6020026020010151905060008160400151905088801561054057506060820151600e16155b1561055c57808060200190518101906105599190613f25565b90505b8084848151811061056f5761056f613ea6565b602090810291909101015250506001016104fe565b50806040516020016105969190613f5a565b604051602081830303815290604052915050610697565b6000866000815181106105c2576105c2613ea6565b602002602001015190508060400151915060048160600151166000146105ea57815160208301fd5b606081015160021615610605576106008261172c565b610678565b815160000361067857806020015161061c90613fdd565b6040517f7b1c461b0000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000090911660048201526024015b60405180910390fd5b851561069557818060200190518101906106929190613f25565b91505b505b610731308483856040516024016106af929190614049565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526117bc565b50505050505050505050565b6040805160a0810182526060808252600060208301819052928201839052818101839052608082019290925286868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250604080516020601f89018190048102820181019092528781526107df918990899081908401838280828437600092018290525092506117e4915050565b604082015273ffffffffffffffffffffffffffffffffffffffff881660608201526108098161181e565b61089d8186868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805173ffffffffffffffffffffffffffffffffffffffff8f1660208201528993507fb4a85801000000000000000000000000000000000000000000000000000000009250015b60405160208183030381529060405261194c565b509695505050505050565b60008080806108b98587018761406e565b93509350935093508651600003610920576040517f7b1c461b0000000000000000000000000000000000000000000000000000000081527fffffffff000000000000000000000000000000000000000000000000000000008416600482015260240161066f565b831561093d578680602001905181019061093a9190613f25565b96505b610955308389846040516024016106af929190614049565b50505050505050565b60606000808061097085870187614130565b905061097e87890189613cb1565b935083516000036109a957606001516040805160208101909152600080825290945092509050610b1f565b60006109b761037486611e28565b9050610b1c81603c846020015114610a6857826040015184602001516040516024016109ed929190918252602082015260400190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167ff1cb7e0600000000000000000000000000000000000000000000000000000000179052610af6565b8260400151604051602401610a7f91815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f3b3b57de000000000000000000000000000000000000000000000000000000001790525b84604001516394fbfa8760e01b868a8760600151604051602001610889939291906141ca565b50505b9450945094915050565b6060600080610be58686867f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663093a86d36040518163ffffffff1660e01b8152600401600060405180830381865afa158015610b9f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261036191908101906142ad565b9250925092505b93509350939050565b60606000610cb1868686867f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663093a86d36040518163ffffffff1660e01b8152600401600060405180830381865afa158015610c6b573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526102e391908101906142ad565b9150915094509492505050565b6060600080610d046040518060800160405280606081526020016000815260200160608152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b610d10858701876142e2565b602083015191965094509091506060907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc401610da0576000610d54898b018b61435f565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606083901b166020820152909150603401604051602081830303815290604052915050610daf565b610dac888a018a613cb1565b90505b8151610dbb9082611fd0565b610df55784816040517fef9c03ce00000000000000000000000000000000000000000000000000000000815260040161066f929190614049565b8160600151925050509450945094915050565b604080518082019091526060808252602082015260005b82515181101561100357600083600001518281518110610e4157610e41613ea6565b602002602001015190506020601017816060015116600003610f19576000610e6c8260000151611ff5565b610e77576010610e7a565b60205b9050825b855151811015610f1657826000015173ffffffffffffffffffffffffffffffffffffffff1686600001518281518110610eb957610eb9613ea6565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610f0e578186600001518281518110610ef757610ef7613ea6565b602002602001015160600181815117915081815250505b600101610e7e565b50505b600060208260600151166000149050600080610f3f831585600001518660200151612037565b9150915081158015610f9a57507f556f183000000000000000000000000000000000000000000000000000000000610f7682613fdd565b7fffffffff0000000000000000000000000000000000000000000000000000000016145b15610faf576060840180516001179052610ff0565b6060840180516040179052828015610fc657508051155b610fdb5781610fdb5760608401805160021790525b8051600003610ff05760608401805160081790525b6040909301929092525050600101610e1f565b5061100d826120db565b5090565b606060008061105588888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506115f092505050565b90506110e18187878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050505060608401516040805173ffffffffffffffffffffffffffffffffffffffff909216602083015288917fb4a85801000000000000000000000000000000000000000000000000000000009101610889565b509550959350505050565b600080600061111d7f0000000000000000000000000000000000000000000000000000000000000000856000612352565b9250925092509193909250565b60606000858561113c8587018761435f565b82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929c939b50929950505050505050505050565b60408051808201909152606080825260208201526000806111a58688018861437c565b9150915080518251146111e4576040517f4a5c31ea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111f0848601866138c0565b92506000805b8451518110156114555760008560000151828151811061121857611218613ea6565b60200260200101519050604081606001511660000361144c57835183101561144057600084848151811061124e5761124e613ea6565b6020026020010151905085848151811061126a5761126a613ea6565b60200260200101511561128757606082018051604417905261143a565b6000611296836040015161246f565b90506000816000015173ffffffffffffffffffffffffffffffffffffffff1682606001518484608001516040516024016112d1929190614049565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090941693909317909252905161135a919061443d565b600060405180830381855afa9150503d8060008114611395576040519150601f19603f3d011682016040523d82523d6000602084013e61139a565b606091505b509350905080806113f557507f556f1830000000000000000000000000000000000000000000000000000000006113d084613fdd565b7fffffffff000000000000000000000000000000000000000000000000000000001614155b1561143757606084018051604017905280158061141157508251155b156114225760608401805160021790525b82516000036114375760608401805160081790525b50505b60408201525b61144983614488565b92505b506001016111f6565b5081518114611490576040517f4a5c31ea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611499846120db565b505050949350505050565b606060008060006114f76103746114f28a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92506124b4915050565b611e28565b90506115e581826040015160405160240161151491815260200190565b60405160208183030381529060405263691f343160e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050508763575de75060e01b60405180608001604052808e8e8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060208082018e905260408083018e905260608a81015173ffffffffffffffffffffffffffffffffffffffff1693019290925290516108899291016144c0565b509450945094915050565b6040805160a081018252606080825260006020830181905292820183905281018290526080810191909152611624826110ec565b6020840152604083015273ffffffffffffffffffffffffffffffffffffffff1660608201528181526116558161181e565b919050565b60008180602001905181019061167091906144e9565b905061172781600001518260200151858460400151604051602401611696929190614049565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526060840151608085015160a0860151612632565b505050565b7f7b1c461b0000000000000000000000000000000000000000000000000000000061175682613fdd565b7fffffffff00000000000000000000000000000000000000000000000000000000160361178557805160208201fd5b806040517f95c0c75200000000000000000000000000000000000000000000000000000000815260040161066f919061377b565b50565b6117e08282600060e01b600060e01b60405180602001604052806000815250612632565b5050565b60006117f08383612903565b92509050801561042c5761181761180784846117e4565b8260009182526020526040902090565b9392505050565b606081015173ffffffffffffffffffffffffffffffffffffffff166118725780516040517f77209fe800000000000000000000000000000000000000000000000000000000815261066f919060040161377b565b6118a081606001517f9061b9230000000000000000000000000000000000000000000000000000000061291f565b156118af576001608082015250565b6020810151156118ee5780516040517f77209fe800000000000000000000000000000000000000000000000000000000815261066f919060040161377b565b806060015173ffffffffffffffffffffffffffffffffffffffff163b6000036117b957805160608201516040517f1e9535f200000000000000000000000000000000000000000000000000000000815261066f929190600401613888565b61197a85606001517f582de3e70000000000000000000000000000000000000000000000000000000061291f565b8015611a9557507fac9650d8000000000000000000000000000000000000000000000000000000006119ab85613fdd565b7fffffffff0000000000000000000000000000000000000000000000000000000016141580611a95575084608001518015611a95575060608501516040517f582de3e70000000000000000000000000000000000000000000000000000000081527f96b62db800000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff9091169063582de3e790602401602060405180830381865afa158015611a71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a9591906145ca565b15611bbc57611bb785606001518660800151611ab15785611b3c565b8651604051611ac591908890602401614049565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f9061b923000000000000000000000000000000000000000000000000000000001790525b60808801517f55391bb800000000000000000000000000000000000000000000000000000000907f3c6cbda80000000000000000000000000000000000000000000000000000000090611b8e8a613fdd565b8888604051602001611ba394939291906145e7565b604051602081830303815290604052612632565b611e21565b606060007fac9650d800000000000000000000000000000000000000000000000000000000611bea87613fdd565b7fffffffff00000000000000000000000000000000000000000000000000000000161490508015611c4757611c2d866004808951611c28919061465c565b6129ee565b806020019051810190611c40919061466f565b9150611c93565b60408051600180825281830190925290816020015b6060815260200190600190039081611c5c5790505091508582600081518110611c8757611c87613ea6565b60200260200101819052505b866080015115611d785760005b8251811015611d76578760000151838281518110611cc057611cc0613ea6565b6020026020010151604051602401611cd9929190614049565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f9061b923000000000000000000000000000000000000000000000000000000001790528351849083908110611d6357611d63613ea6565b6020908102919091010152600101611ca0565b505b610955303073ffffffffffffffffffffffffffffffffffffffff16639f28e99d611da78b60600151878b612a44565b604051602401611db79190613af7565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505063491fc4f960e01b600060e01b8b60800151868a8a604051602001611ba3949392919061471b565b5050505050565b80516060906000819003611e52575050604080518082019091526001815260006020820152919050565b8060020167ffffffffffffffff811115611e6e57611e6e61341f565b6040519080825280601f01601f191660200182016040528015611e98576020820181803683370190505b509150602082018060005b83811015611f73576000868281518110611ebf57611ebf613ea6565b01602001517fff000000000000000000000000000000000000000000000000000000000000001690507f2e00000000000000000000000000000000000000000000000000000000000000819003611f6057611f1a8484612b78565b935083600003611f5857866040517f9a4c3e3b00000000000000000000000000000000000000000000000000000000815260040161066f919061377b565b839250611f6a565b6001830192508083525b50600101611ea3565b50611f7e8282612b78565b915081600003611fbc57846040517f9a4c3e3b00000000000000000000000000000000000000000000000000000000815260040161066f919061377b565b60008253601f840182038452505050919050565b6000815183511480156118175750508051602091820120825192909101919091201490565b60003073ffffffffffffffffffffffffffffffffffffffff83160361201c57506001919050565b6113885a6000806000808786fa50815a909103109392505050565b600060608373ffffffffffffffffffffffffffffffffffffffff168561207d577f000000000000000000000000000000000000000000000000000000000000000061207f565b5a5b8460405161208d919061443d565b6000604051808303818686fa925050503d80600081146120c9576040519150601f19603f3d011682016040523d82523d6000602084013e6120ce565b606091505b5090969095509350505050565b80515160009067ffffffffffffffff8111156120f9576120f961341f565b60405190808252806020026020018201604052801561216457816020015b6121516040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff16815260200160608152602001606081525090565b8152602001906001900390816121175790505b5090506000805b8351518110156122285760008460000151828151811061218d5761218d613ea6565b60200260200101519050604081606001511660000361221f5760006121b5826040015161246f565b90506040518060600160405280826000015173ffffffffffffffffffffffffffffffffffffffff16815260200182602001518152602001826040015181525085858061220090614488565b96508151811061221257612212613ea6565b6020026020010181905250505b5060010161216b565b50801561172757808252308360200151836040516024016122499190614766565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa780bab60000000000000000000000000000000000000000000000000000000017905290517fb536af7600000000000000000000000000000000000000000000000000000000916122f091899101613af7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f556f183000000000000000000000000000000000000000000000000000000000825261066f9594939291600401614824565b60008060008060006123648787612903565b9092509050811561246457600080600061237f8b8b86612352565b925092509250612399828660009182526020526040902090565b6040517f0178b8bf0000000000000000000000000000000000000000000000000000000081526004810182905290975073ffffffffffffffffffffffffffffffffffffffff8c1690630178b8bf90602401602060405180830381865afa158015612407573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061242b91906148ad565b975073ffffffffffffffffffffffffffffffffffffffff881661245057828782612454565b87878a5b9750975097505050505050610bec565b505093509350939050565b6040805160a081018252600080825260606020830181905292820183905282820152608081019190915261042c6124af836004808651611c28919061465c565b612bed565b606082516000036124f1576040517f7138356f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6124fa83612c7e565b7f2e00000000000000000000000000000000000000000000000000000000000000603c8414612579576380000000841461253e57612539846001612ce7565b6125b0565b6040518060400160405280600781526020017f64656661756c74000000000000000000000000000000000000000000000000008152506125b0565b6040518060400160405280600481526020017f61646472000000000000000000000000000000000000000000000000000000008152505b7f2e000000000000000000000000000000000000000000000000000000000000006040518060400160405280600781526020017f726576657273650000000000000000000000000000000000000000000000000081525060405160200161261b9594939291906148ca565b604051602081830303815290604052905092915050565b60008061264861264188611ff5565b8888612037565b91509150811580156126a357507f556f18300000000000000000000000000000000000000000000000000000000061267f82613fdd565b7fffffffff0000000000000000000000000000000000000000000000000000000016145b156127b95760006126b38261246f565b90508773ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff16036127b757308160200151826040015163ef46c0b860e01b6040518060c001604052808d73ffffffffffffffffffffffffffffffffffffffff16815260200186606001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001866080015181526020018b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020018a7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001898152506040516020016122f09190614967565b505b6000826127c657846127c8565b855b90507fffffffff000000000000000000000000000000000000000000000000000000008116156128ed573073ffffffffffffffffffffffffffffffffffffffff1681838660405160240161281d929190614049565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290516128a6919061443d565b600060405180830381855afa9150503d80600081146128e1576040519150601f19603f3d011682016040523d82523d6000602084013e6128e6565b606091505b5090935091505b82156128fb57815160208301f35b815160208301fd5b60008061291284846001612dbe565b5091969095509350505050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156129d7575060208210155b80156129e35750600081115b979650505050505050565b60608167ffffffffffffffff811115612a0957612a0961341f565b6040519080825280601f01601f191660200182016040528015612a33576020820181803683370190505b509050611817848483600086612f4d565b60408051808201909152606080825260208201526000835167ffffffffffffffff811115612a7457612a7461341f565b604051908082528060200260200182016040528015612ae657816020015b612ad36040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff1681526020016060815260200160608152602001600081525090565b815260200190600190039081612a925790505b50905060005b8451811015612b5b576000828281518110612b0957612b09613ea6565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff881681528651909150869083908110612b4457612b44613ea6565b602090810291909101810151910152600101612aec565b506040805180820190915290815260208101929092525092915050565b600080612b85848461465c565b905060ff811115612bc457806001850120600052612bb26000856002612bab9190614a62565b6040612f85565b605b6001850153605d60428501535060425b8015612be65780845380612bd9856001614a62565b612be39190614a62565b91505b5092915050565b6040805160a081018252600080825260606020830181905292820183905282820152608081019190915281806020019051810190612c2b9190614a75565b60808601527fffffffff000000000000000000000000000000000000000000000000000000001660608501526040840152602083015273ffffffffffffffffffffffffffffffffffffffff168152919050565b805160609060011b8067ffffffffffffffff811115612c9f57612c9f61341f565b6040519080825280601f01601f191660200182016040528015612cc9576020820181803683370190505b5091506020838101908301612cdf828285612f85565b505050919050565b606082600060805b60088110612d20576001811b831015612d1357612d0c8183614a62565b9150612d18565b91821c915b60011c612cef565b50838015612d2e5750601082105b15612d4157612d3e600482614a62565b90505b6000612d52600283901c604061465c565b90508067ffffffffffffffff811115612d6d57612d6d61341f565b6040519080825280601f01601f191660200182016040528015612d97576020820181803683370190505b509350600086831b600052602085019050612db460008284612f85565b5050505092915050565b600080600080612dce8787613007565b93509150848015612de257508160ff166042145b8015612e50575086612df5876001614a62565b81518110612e0557612e05613ea6565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f5b00000000000000000000000000000000000000000000000000000000000000145b8015612ebe575086612e6360018561465c565b81518110612e7357612e73613ea6565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f5d00000000000000000000000000000000000000000000000000000000000000145b15612f3057612ee287612ed2886002614a62565b612edd60018761465c565b61306c565b9094509050801580612ef2575083155b15612f2b57866040517fba4adc2300000000000000000000000000000000000000000000000000000000815260040161066f919061377b565b612f44565b60ff821615612f4457816021878901012093505b93509350935093565b612f6085612f5b8387614a62565b6130e5565b612f6e83612f5b8385614a62565b60208486018101908385010161095581838561312d565b8181015b808310156104715783516101005b8285108015612fa65750600081115b15612ffa577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc01600f82821c16600a8110612fe45780605701612fe9565b806030015b905080865350600190940193612f97565b5050602084019350612f89565b8181016020015160001a8082016001018161302657835181141561302c565b83518110155b1561306557836040517fba4adc2300000000000000000000000000000000000000000000000000000000815260040161066f919061377b565b9250929050565b60008083831015613082575060009050806130dd565b600061308e858561465c565b9050604081118061309f5750855184115b156130b15750600091508190506130dd565b8585016020016130c3816000846131b3565b92506001820160011c6020036000518160031b1c94505050505b935093915050565b81518111156117e05781516040517f8a3c1cfb00000000000000000000000000000000000000000000000000000000815261066f918391600401918252602082015260400190565b5b601f81111561316c5781518352602092830192909101907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00161312e565b80156117275790518251600160209390930360031b9290921b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199091169116179052565b600061326d565b811a6000602f8211603a831016156131f557507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd0810161042c565b6047821060408311161561322c57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc9810161042c565b6067821060608311161561326357507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa9810161042c565b5061010092915050565b506001838201828216156132a957613287600086516131ba565b80855360018601955060018501945060ff8111156132a757600092508195505b505b808510156132f75784516132be6001826131ba565b6132c96000836131ba565b60041b17905060ff8111156132e25760009250506132f7565b808553506002850194506001840193506132a9565b509392505050565b7fffffffff00000000000000000000000000000000000000000000000000000000811681146117b957600080fd5b60006020828403121561333f57600080fd5b8135611817816132ff565b60008083601f84011261335c57600080fd5b50813567ffffffffffffffff81111561337457600080fd5b60208301915083602082850101111561306557600080fd5b600080600080604085870312156133a257600080fd5b843567ffffffffffffffff8111156133b957600080fd5b6133c58782880161334a565b909550935050602085013567ffffffffffffffff8111156133e557600080fd5b6133f18782880161334a565b95989497509550505050565b73ffffffffffffffffffffffffffffffffffffffff811681146117b957600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156134715761347161341f565b60405290565b6040516080810167ffffffffffffffff811182821017156134715761347161341f565b60405160c0810167ffffffffffffffff811182821017156134715761347161341f565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156135045761350461341f565b604052919050565b600067ffffffffffffffff8211156135265761352661341f565b5060051b60200190565b600067ffffffffffffffff82111561354a5761354a61341f565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261358757600080fd5b81356020830160006135a061359b84613530565b6134bd565b90508281528583830111156135b457600080fd5b82826020830137600092810160200192909252509392505050565b600082601f8301126135e057600080fd5b81356135ee61359b8261350c565b8082825260208201915060208360051b86010192508583111561361057600080fd5b602085015b8381101561365257803567ffffffffffffffff81111561363457600080fd5b613643886020838a0101613576565b84525060209283019201613615565b5095945050505050565b6000806000806000806080878903121561367557600080fd5b8635613680816133fd565b9550602087013567ffffffffffffffff81111561369c57600080fd5b6136a889828a0161334a565b909650945050604087013567ffffffffffffffff8111156136c857600080fd5b6136d489828a0161334a565b909450925050606087013567ffffffffffffffff8111156136f457600080fd5b61370089828a016135cf565b9150509295509295509295565b60005b83811015613728578181015183820152602001613710565b50506000910152565b6000815180845261374981602086016020860161370d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006118176020830184613731565b6000806000604084860312156137a357600080fd5b833567ffffffffffffffff8111156137ba57600080fd5b6137c686828701613576565b935050602084013567ffffffffffffffff8111156137e357600080fd5b6137ef8682870161334a565b9497909650939450505050565b60608152600061380f6060830186613731565b73ffffffffffffffffffffffffffffffffffffffff94851660208401529290931660409091015292915050565b60008060006040848603121561385157600080fd5b833567ffffffffffffffff81111561386857600080fd5b6138748682870161334a565b909790965060209590950135949350505050565b60408152600061389b6040830185613731565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b6000602082840312156138d257600080fd5b813567ffffffffffffffff8111156138e957600080fd5b8201604081850312156138fb57600080fd5b61390361344e565b813567ffffffffffffffff81111561391a57600080fd5b8201601f8101861361392b57600080fd5b803561393961359b8261350c565b8082825260208201915060208360051b85010192508883111561395b57600080fd5b602084015b83811015613a4357803567ffffffffffffffff81111561397f57600080fd5b85016080818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00112156139b357600080fd5b6139bb613477565b60208201356139c9816133fd565b8152604082013567ffffffffffffffff8111156139e557600080fd5b6139f48d602083860101613576565b602083015250606082013567ffffffffffffffff811115613a1457600080fd5b613a238d602083860101613576565b604083015250608091909101356060820152835260209283019201613960565b508452505050602082013567ffffffffffffffff811115613a6357600080fd5b613a6f868285016135cf565b602083015250949350505050565b600082825180855260208501945060208160051b8301016020850160005b83811015613aeb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0858403018852613ad5838351613731565b6020988901989093509190910190600101613a9b565b50909695505050505050565b6020815260006060820183516040602085015281815180845260808601915060808160051b870101935060208301925060005b81811015613bcb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80878603018352835173ffffffffffffffffffffffffffffffffffffffff8151168652602081015160806020880152613b8e6080880182613731565b905060408201518782036040890152613ba78282613731565b60609384015198909301979097525094506020938401939290920191600101613b2a565b5050505060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152613c088282613a7d565b95945050505050565b600080600080600060608688031215613c2957600080fd5b853567ffffffffffffffff811115613c4057600080fd5b613c4c8882890161334a565b909650945050602086013567ffffffffffffffff811115613c6c57600080fd5b613c788882890161334a565b909450925050604086013567ffffffffffffffff811115613c9857600080fd5b613ca4888289016135cf565b9150509295509295909350565b600060208284031215613cc357600080fd5b813567ffffffffffffffff811115613cda57600080fd5b612be384828501613576565b60008060008060608587031215613cfc57600080fd5b843567ffffffffffffffff811115613d1357600080fd5b613d1f8782880161334a565b90955093505060208501359150604085013567ffffffffffffffff811115613d4657600080fd5b613d52878288016135cf565b91505092959194509250565b602081526000825160a06020840152613d7a60c0840182613731565b9050602084015160408401526040840151606084015273ffffffffffffffffffffffffffffffffffffffff60608501511660808401526080840151151560a08401528091505092915050565b60008060408385031215613dd957600080fd5b823567ffffffffffffffff811115613df057600080fd5b613dfc85828601613576565b925050602083013567ffffffffffffffff811115613e1957600080fd5b613e2585828601613576565b9150509250929050565b80151581146117b957600080fd5b60008060008060808587031215613e5357600080fd5b8435613e5e81613e2f565b93506020850135613e6e81613e2f565b92506040850135613e7e816132ff565b9150606085013567ffffffffffffffff811115613e9a57600080fd5b613d5287828801613576565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000613ee361359b84613530565b9050828152838383011115613ef757600080fd5b61181783602083018461370d565b600082601f830112613f1657600080fd5b61181783835160208501613ed5565b600060208284031215613f3757600080fd5b815167ffffffffffffffff811115613f4e57600080fd5b612be384828501613f05565b6000602082016020835280845180835260408501915060408160051b86010192506020860160005b82811015613fd1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0878603018452613fbc858351613731565b94506020938401939190910190600101613f82565b50929695505050505050565b805160208201517fffffffff00000000000000000000000000000000000000000000000000000000811691906004821015614042577fffffffff00000000000000000000000000000000000000000000000000000000808360040360031b1b82161692505b5050919050565b60408152600061405c6040830185613731565b8281036020840152613c088185613731565b6000806000806080858703121561408457600080fd5b843561408f81613e2f565b93506020850135613e6e816132ff565b6000608082840312156140b157600080fd5b6140b9613477565b9050813567ffffffffffffffff8111156140d257600080fd5b6140de84828501613576565b82525060208281013590820152604082013567ffffffffffffffff81111561410557600080fd5b614111848285016135cf565b6040830152506060820135614125816133fd565b606082015292915050565b60006020828403121561414257600080fd5b813567ffffffffffffffff81111561415957600080fd5b612be38482850161409f565b600081516080845261417a6080850182613731565b9050602083015160208501526040830151848203604086015261419d8282613a7d565b91505073ffffffffffffffffffffffffffffffffffffffff60608401511660608501528091505092915050565b6060815260006141dd6060830186614165565b82810360208401526141ef8186613731565b91505073ffffffffffffffffffffffffffffffffffffffff83166040830152949350505050565b600082601f83011261422757600080fd5b815161423561359b8261350c565b8082825260208201915060208360051b86010192508583111561425757600080fd5b602085015b8381101561365257805167ffffffffffffffff81111561427b57600080fd5b8601603f8101881361428c57600080fd5b61429e88602083015160408401613ed5565b8452506020928301920161425c565b6000602082840312156142bf57600080fd5b815167ffffffffffffffff8111156142d657600080fd5b612be384828501614216565b6000806000606084860312156142f757600080fd5b833567ffffffffffffffff81111561430e57600080fd5b61431a8682870161409f565b935050602084013567ffffffffffffffff81111561433757600080fd5b61434386828701613576565b9250506040840135614354816133fd565b809150509250925092565b60006020828403121561437157600080fd5b8135611817816133fd565b6000806040838503121561438f57600080fd5b823567ffffffffffffffff8111156143a657600080fd5b8301601f810185136143b757600080fd5b80356143c561359b8261350c565b8082825260208201915060208360051b8501019250878311156143e757600080fd5b6020840193505b8284101561441257833561440181613e2f565b8252602093840193909101906143ee565b9450505050602083013567ffffffffffffffff81111561443157600080fd5b613e25858286016135cf565b6000825161444f81846020870161370d565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036144b9576144b9614459565b5060010190565b6020815260006118176020830184614165565b8051611655816133fd565b8051611655816132ff565b6000602082840312156144fb57600080fd5b815167ffffffffffffffff81111561451257600080fd5b820160c0818503121561452457600080fd5b61452c61349a565b614535826144d3565b8152614543602083016144de565b6020820152604082015167ffffffffffffffff81111561456257600080fd5b61456e86828501613f05565b604083015250614580606083016144de565b6060820152614591608083016144de565b608082015260a082015167ffffffffffffffff8111156145b057600080fd5b6145bc86828501613f05565b60a083015250949350505050565b6000602082840312156145dc57600080fd5b815161181781613e2f565b84151581527fffffffff00000000000000000000000000000000000000000000000000000000841660208201527fffffffff00000000000000000000000000000000000000000000000000000000831660408201526080606082015260006146526080830184613731565b9695505050505050565b8181038181111561042c5761042c614459565b60006020828403121561468157600080fd5b815167ffffffffffffffff81111561469857600080fd5b8201601f810184136146a957600080fd5b80516146b761359b8261350c565b8082825260208201915060208360051b8501019250868311156146d957600080fd5b602084015b8381101561089d57805167ffffffffffffffff8111156146fd57600080fd5b61470c89602083890101613f05565b845250602092830192016146de565b841515815283151560208201527fffffffff00000000000000000000000000000000000000000000000000000000831660408201526080606082015260006146526080830184613731565b6000602082016020835280845180835260408501915060408160051b86010192506020860160005b82811015613fd1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0878603018452815173ffffffffffffffffffffffffffffffffffffffff81511686526020810151606060208801526147f26060880182613a7d565b905060408201519150868103604088015261480d8183613731565b96505050602093840193919091019060010161478e565b73ffffffffffffffffffffffffffffffffffffffff8616815260a06020820152600061485360a0830187613a7d565b82810360408401526148658187613731565b90507fffffffff000000000000000000000000000000000000000000000000000000008516606084015282810360808401526148a18185613731565b98975050505050505050565b6000602082840312156148bf57600080fd5b8151611817816133fd565b600086516148dc818460208b0161370d565b7fff0000000000000000000000000000000000000000000000000000000000000087169083019081528551614918816001840160208a0161370d565b7fff00000000000000000000000000000000000000000000000000000000000000861660019290910191820152835161495881600284016020880161370d565b01600201979650505050505050565b6020815273ffffffffffffffffffffffffffffffffffffffff82511660208201527fffffffff0000000000000000000000000000000000000000000000000000000060208301511660408201526000604083015160c060608401526149cf60e0840182613731565b90507fffffffff0000000000000000000000000000000000000000000000000000000060608501511660808401527fffffffff0000000000000000000000000000000000000000000000000000000060808501511660a084015260a08401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160c0850152613c088282613731565b8082018082111561042c5761042c614459565b600080600080600060a08688031215614a8d57600080fd5b8551614a98816133fd565b602087015190955067ffffffffffffffff811115614ab557600080fd5b614ac188828901614216565b945050604086015167ffffffffffffffff811115614ade57600080fd5b614aea88828901613f05565b9350506060860151614afb816132ff565b608087015190925067ffffffffffffffff811115614b1857600080fd5b613ca488828901613f0556fea264697066735822122084f9ea59b473b1991a8ef12ca16a590b7c121f1b45f67d70f9ac492af54f2bdf64736f6c634300081a0033",
  "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101515760003560e01c80639061b923116100cd578063b4a8580111610081578063b7d6ca6411610066578063b7d6ca6414610353578063c285238a14610366578063ef46c0b81461038657600080fd5b8063b4a858011461032d578063b536af761461034057600080fd5b80639f28e99d116100b25780639f28e99d146102b5578063a1472844146102d5578063a1cbcbaf146102e857600080fd5b80639061b9231461028157806394fbfa87146102a257600080fd5b80634a3e399411610124578063575de75011610109578063575de750146102255780635d78a217146102475780637b1039991461025a57600080fd5b80634a3e3994146101f257806355391bb81461021257600080fd5b806301ffc9a71461015657806302cf25781461017e5780633c6cbda8146101ca578063491fc4f9146101df575b600080fd5b61016961016436600461332d565b610399565b60405190151581526020015b60405180910390f35b6101a57f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610175565b6101dd6101d836600461338c565b610432565b005b6101dd6101ed36600461338c565b610477565b61020561020036600461365c565b61073d565b604051610175919061377b565b6101dd61022036600461378e565b6108a8565b61023861023336600461338c565b61095e565b604051610175939291906137fc565b61023861025536600461383c565b610b29565b6101a57f000000000000000000000000000000000000000000000000000000000000000081565b61029461028f36600461338c565b610bf5565b604051610175929190613888565b6102386102b036600461338c565b610cbe565b6102c86102c33660046138c0565b610e08565b6040516101759190613af7565b6102946102e3366004613c11565b611011565b6102fb6102f6366004613cb1565b6110ec565b6040805173ffffffffffffffffffffffffffffffffffffffff9094168452602084019290925290820152606001610175565b61029461033b36600461338c565b61112a565b6102c861034e36600461338c565b611182565b610238610361366004613ce6565b6114a4565b610379610374366004613cb1565b6115f0565b6040516101759190613d5e565b6101dd610394366004613dc6565b61165a565b60007f6cd2d09b000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061042c57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b61047184848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061172c92505050565b50505050565b6000610485848601866138c0565b519050600080808061049986880188613e3d565b9350935093509350606083156105ad576000865167ffffffffffffffff8111156104c5576104c561341f565b6040519080825280602002602001820160405280156104f857816020015b60608152602001906001900390816104e35790505b50905060005b875181101561058457600088828151811061051b5761051b613ea6565b6020026020010151905060008160400151905088801561054057506060820151600e16155b1561055c57808060200190518101906105599190613f25565b90505b8084848151811061056f5761056f613ea6565b602090810291909101015250506001016104fe565b50806040516020016105969190613f5a565b604051602081830303815290604052915050610697565b6000866000815181106105c2576105c2613ea6565b602002602001015190508060400151915060048160600151166000146105ea57815160208301fd5b606081015160021615610605576106008261172c565b610678565b815160000361067857806020015161061c90613fdd565b6040517f7b1c461b0000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000090911660048201526024015b60405180910390fd5b851561069557818060200190518101906106929190613f25565b91505b505b610731308483856040516024016106af929190614049565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526117bc565b50505050505050505050565b6040805160a0810182526060808252600060208301819052928201839052818101839052608082019290925286868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250604080516020601f89018190048102820181019092528781526107df918990899081908401838280828437600092018290525092506117e4915050565b604082015273ffffffffffffffffffffffffffffffffffffffff881660608201526108098161181e565b61089d8186868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805173ffffffffffffffffffffffffffffffffffffffff8f1660208201528993507fb4a85801000000000000000000000000000000000000000000000000000000009250015b60405160208183030381529060405261194c565b509695505050505050565b60008080806108b98587018761406e565b93509350935093508651600003610920576040517f7b1c461b0000000000000000000000000000000000000000000000000000000081527fffffffff000000000000000000000000000000000000000000000000000000008416600482015260240161066f565b831561093d578680602001905181019061093a9190613f25565b96505b610955308389846040516024016106af929190614049565b50505050505050565b60606000808061097085870187614130565b905061097e87890189613cb1565b935083516000036109a957606001516040805160208101909152600080825290945092509050610b1f565b60006109b761037486611e28565b9050610b1c81603c846020015114610a6857826040015184602001516040516024016109ed929190918252602082015260400190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167ff1cb7e0600000000000000000000000000000000000000000000000000000000179052610af6565b8260400151604051602401610a7f91815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f3b3b57de000000000000000000000000000000000000000000000000000000001790525b84604001516394fbfa8760e01b868a8760600151604051602001610889939291906141ca565b50505b9450945094915050565b6060600080610be58686867f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663093a86d36040518163ffffffff1660e01b8152600401600060405180830381865afa158015610b9f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261036191908101906142ad565b9250925092505b93509350939050565b60606000610cb1868686867f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663093a86d36040518163ffffffff1660e01b8152600401600060405180830381865afa158015610c6b573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526102e391908101906142ad565b9150915094509492505050565b6060600080610d046040518060800160405280606081526020016000815260200160608152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b610d10858701876142e2565b602083015191965094509091506060907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc401610da0576000610d54898b018b61435f565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606083901b166020820152909150603401604051602081830303815290604052915050610daf565b610dac888a018a613cb1565b90505b8151610dbb9082611fd0565b610df55784816040517fef9c03ce00000000000000000000000000000000000000000000000000000000815260040161066f929190614049565b8160600151925050509450945094915050565b604080518082019091526060808252602082015260005b82515181101561100357600083600001518281518110610e4157610e41613ea6565b602002602001015190506020601017816060015116600003610f19576000610e6c8260000151611ff5565b610e77576010610e7a565b60205b9050825b855151811015610f1657826000015173ffffffffffffffffffffffffffffffffffffffff1686600001518281518110610eb957610eb9613ea6565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610f0e578186600001518281518110610ef757610ef7613ea6565b602002602001015160600181815117915081815250505b600101610e7e565b50505b600060208260600151166000149050600080610f3f831585600001518660200151612037565b9150915081158015610f9a57507f556f183000000000000000000000000000000000000000000000000000000000610f7682613fdd565b7fffffffff0000000000000000000000000000000000000000000000000000000016145b15610faf576060840180516001179052610ff0565b6060840180516040179052828015610fc657508051155b610fdb5781610fdb5760608401805160021790525b8051600003610ff05760608401805160081790525b6040909301929092525050600101610e1f565b5061100d826120db565b5090565b606060008061105588888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506115f092505050565b90506110e18187878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050505060608401516040805173ffffffffffffffffffffffffffffffffffffffff909216602083015288917fb4a85801000000000000000000000000000000000000000000000000000000009101610889565b509550959350505050565b600080600061111d7f0000000000000000000000000000000000000000000000000000000000000000856000612352565b9250925092509193909250565b60606000858561113c8587018761435f565b82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929c939b50929950505050505050505050565b60408051808201909152606080825260208201526000806111a58688018861437c565b9150915080518251146111e4576040517f4a5c31ea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111f0848601866138c0565b92506000805b8451518110156114555760008560000151828151811061121857611218613ea6565b60200260200101519050604081606001511660000361144c57835183101561144057600084848151811061124e5761124e613ea6565b6020026020010151905085848151811061126a5761126a613ea6565b60200260200101511561128757606082018051604417905261143a565b6000611296836040015161246f565b90506000816000015173ffffffffffffffffffffffffffffffffffffffff1682606001518484608001516040516024016112d1929190614049565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090941693909317909252905161135a919061443d565b600060405180830381855afa9150503d8060008114611395576040519150601f19603f3d011682016040523d82523d6000602084013e61139a565b606091505b509350905080806113f557507f556f1830000000000000000000000000000000000000000000000000000000006113d084613fdd565b7fffffffff000000000000000000000000000000000000000000000000000000001614155b1561143757606084018051604017905280158061141157508251155b156114225760608401805160021790525b82516000036114375760608401805160081790525b50505b60408201525b61144983614488565b92505b506001016111f6565b5081518114611490576040517f4a5c31ea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611499846120db565b505050949350505050565b606060008060006114f76103746114f28a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92506124b4915050565b611e28565b90506115e581826040015160405160240161151491815260200190565b60405160208183030381529060405263691f343160e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050508763575de75060e01b60405180608001604052808e8e8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060208082018e905260408083018e905260608a81015173ffffffffffffffffffffffffffffffffffffffff1693019290925290516108899291016144c0565b509450945094915050565b6040805160a081018252606080825260006020830181905292820183905281018290526080810191909152611624826110ec565b6020840152604083015273ffffffffffffffffffffffffffffffffffffffff1660608201528181526116558161181e565b919050565b60008180602001905181019061167091906144e9565b905061172781600001518260200151858460400151604051602401611696929190614049565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526060840151608085015160a0860151612632565b505050565b7f7b1c461b0000000000000000000000000000000000000000000000000000000061175682613fdd565b7fffffffff00000000000000000000000000000000000000000000000000000000160361178557805160208201fd5b806040517f95c0c75200000000000000000000000000000000000000000000000000000000815260040161066f919061377b565b50565b6117e08282600060e01b600060e01b60405180602001604052806000815250612632565b5050565b60006117f08383612903565b92509050801561042c5761181761180784846117e4565b8260009182526020526040902090565b9392505050565b606081015173ffffffffffffffffffffffffffffffffffffffff166118725780516040517f77209fe800000000000000000000000000000000000000000000000000000000815261066f919060040161377b565b6118a081606001517f9061b9230000000000000000000000000000000000000000000000000000000061291f565b156118af576001608082015250565b6020810151156118ee5780516040517f77209fe800000000000000000000000000000000000000000000000000000000815261066f919060040161377b565b806060015173ffffffffffffffffffffffffffffffffffffffff163b6000036117b957805160608201516040517f1e9535f200000000000000000000000000000000000000000000000000000000815261066f929190600401613888565b61197a85606001517f582de3e70000000000000000000000000000000000000000000000000000000061291f565b8015611a9557507fac9650d8000000000000000000000000000000000000000000000000000000006119ab85613fdd565b7fffffffff0000000000000000000000000000000000000000000000000000000016141580611a95575084608001518015611a95575060608501516040517f582de3e70000000000000000000000000000000000000000000000000000000081527f96b62db800000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff9091169063582de3e790602401602060405180830381865afa158015611a71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a9591906145ca565b15611bbc57611bb785606001518660800151611ab15785611b3c565b8651604051611ac591908890602401614049565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f9061b923000000000000000000000000000000000000000000000000000000001790525b60808801517f55391bb800000000000000000000000000000000000000000000000000000000907f3c6cbda80000000000000000000000000000000000000000000000000000000090611b8e8a613fdd565b8888604051602001611ba394939291906145e7565b604051602081830303815290604052612632565b611e21565b606060007fac9650d800000000000000000000000000000000000000000000000000000000611bea87613fdd565b7fffffffff00000000000000000000000000000000000000000000000000000000161490508015611c4757611c2d866004808951611c28919061465c565b6129ee565b806020019051810190611c40919061466f565b9150611c93565b60408051600180825281830190925290816020015b6060815260200190600190039081611c5c5790505091508582600081518110611c8757611c87613ea6565b60200260200101819052505b866080015115611d785760005b8251811015611d76578760000151838281518110611cc057611cc0613ea6565b6020026020010151604051602401611cd9929190614049565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f9061b923000000000000000000000000000000000000000000000000000000001790528351849083908110611d6357611d63613ea6565b6020908102919091010152600101611ca0565b505b610955303073ffffffffffffffffffffffffffffffffffffffff16639f28e99d611da78b60600151878b612a44565b604051602401611db79190613af7565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505063491fc4f960e01b600060e01b8b60800151868a8a604051602001611ba3949392919061471b565b5050505050565b80516060906000819003611e52575050604080518082019091526001815260006020820152919050565b8060020167ffffffffffffffff811115611e6e57611e6e61341f565b6040519080825280601f01601f191660200182016040528015611e98576020820181803683370190505b509150602082018060005b83811015611f73576000868281518110611ebf57611ebf613ea6565b01602001517fff000000000000000000000000000000000000000000000000000000000000001690507f2e00000000000000000000000000000000000000000000000000000000000000819003611f6057611f1a8484612b78565b935083600003611f5857866040517f9a4c3e3b00000000000000000000000000000000000000000000000000000000815260040161066f919061377b565b839250611f6a565b6001830192508083525b50600101611ea3565b50611f7e8282612b78565b915081600003611fbc57846040517f9a4c3e3b00000000000000000000000000000000000000000000000000000000815260040161066f919061377b565b60008253601f840182038452505050919050565b6000815183511480156118175750508051602091820120825192909101919091201490565b60003073ffffffffffffffffffffffffffffffffffffffff83160361201c57506001919050565b6113885a6000806000808786fa50815a909103109392505050565b600060608373ffffffffffffffffffffffffffffffffffffffff168561207d577f000000000000000000000000000000000000000000000000000000000000000061207f565b5a5b8460405161208d919061443d565b6000604051808303818686fa925050503d80600081146120c9576040519150601f19603f3d011682016040523d82523d6000602084013e6120ce565b606091505b5090969095509350505050565b80515160009067ffffffffffffffff8111156120f9576120f961341f565b60405190808252806020026020018201604052801561216457816020015b6121516040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff16815260200160608152602001606081525090565b8152602001906001900390816121175790505b5090506000805b8351518110156122285760008460000151828151811061218d5761218d613ea6565b60200260200101519050604081606001511660000361221f5760006121b5826040015161246f565b90506040518060600160405280826000015173ffffffffffffffffffffffffffffffffffffffff16815260200182602001518152602001826040015181525085858061220090614488565b96508151811061221257612212613ea6565b6020026020010181905250505b5060010161216b565b50801561172757808252308360200151836040516024016122499190614766565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa780bab60000000000000000000000000000000000000000000000000000000017905290517fb536af7600000000000000000000000000000000000000000000000000000000916122f091899101613af7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f556f183000000000000000000000000000000000000000000000000000000000825261066f9594939291600401614824565b60008060008060006123648787612903565b9092509050811561246457600080600061237f8b8b86612352565b925092509250612399828660009182526020526040902090565b6040517f0178b8bf0000000000000000000000000000000000000000000000000000000081526004810182905290975073ffffffffffffffffffffffffffffffffffffffff8c1690630178b8bf90602401602060405180830381865afa158015612407573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061242b91906148ad565b975073ffffffffffffffffffffffffffffffffffffffff881661245057828782612454565b87878a5b9750975097505050505050610bec565b505093509350939050565b6040805160a081018252600080825260606020830181905292820183905282820152608081019190915261042c6124af836004808651611c28919061465c565b612bed565b606082516000036124f1576040517f7138356f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6124fa83612c7e565b7f2e00000000000000000000000000000000000000000000000000000000000000603c8414612579576380000000841461253e57612539846001612ce7565b6125b0565b6040518060400160405280600781526020017f64656661756c74000000000000000000000000000000000000000000000000008152506125b0565b6040518060400160405280600481526020017f61646472000000000000000000000000000000000000000000000000000000008152505b7f2e000000000000000000000000000000000000000000000000000000000000006040518060400160405280600781526020017f726576657273650000000000000000000000000000000000000000000000000081525060405160200161261b9594939291906148ca565b604051602081830303815290604052905092915050565b60008061264861264188611ff5565b8888612037565b91509150811580156126a357507f556f18300000000000000000000000000000000000000000000000000000000061267f82613fdd565b7fffffffff0000000000000000000000000000000000000000000000000000000016145b156127b95760006126b38261246f565b90508773ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff16036127b757308160200151826040015163ef46c0b860e01b6040518060c001604052808d73ffffffffffffffffffffffffffffffffffffffff16815260200186606001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001866080015181526020018b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020018a7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001898152506040516020016122f09190614967565b505b6000826127c657846127c8565b855b90507fffffffff000000000000000000000000000000000000000000000000000000008116156128ed573073ffffffffffffffffffffffffffffffffffffffff1681838660405160240161281d929190614049565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290516128a6919061443d565b600060405180830381855afa9150503d80600081146128e1576040519150601f19603f3d011682016040523d82523d6000602084013e6128e6565b606091505b5090935091505b82156128fb57815160208301f35b815160208301fd5b60008061291284846001612dbe565b5091969095509350505050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156129d7575060208210155b80156129e35750600081115b979650505050505050565b60608167ffffffffffffffff811115612a0957612a0961341f565b6040519080825280601f01601f191660200182016040528015612a33576020820181803683370190505b509050611817848483600086612f4d565b60408051808201909152606080825260208201526000835167ffffffffffffffff811115612a7457612a7461341f565b604051908082528060200260200182016040528015612ae657816020015b612ad36040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff1681526020016060815260200160608152602001600081525090565b815260200190600190039081612a925790505b50905060005b8451811015612b5b576000828281518110612b0957612b09613ea6565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff881681528651909150869083908110612b4457612b44613ea6565b602090810291909101810151910152600101612aec565b506040805180820190915290815260208101929092525092915050565b600080612b85848461465c565b905060ff811115612bc457806001850120600052612bb26000856002612bab9190614a62565b6040612f85565b605b6001850153605d60428501535060425b8015612be65780845380612bd9856001614a62565b612be39190614a62565b91505b5092915050565b6040805160a081018252600080825260606020830181905292820183905282820152608081019190915281806020019051810190612c2b9190614a75565b60808601527fffffffff000000000000000000000000000000000000000000000000000000001660608501526040840152602083015273ffffffffffffffffffffffffffffffffffffffff168152919050565b805160609060011b8067ffffffffffffffff811115612c9f57612c9f61341f565b6040519080825280601f01601f191660200182016040528015612cc9576020820181803683370190505b5091506020838101908301612cdf828285612f85565b505050919050565b606082600060805b60088110612d20576001811b831015612d1357612d0c8183614a62565b9150612d18565b91821c915b60011c612cef565b50838015612d2e5750601082105b15612d4157612d3e600482614a62565b90505b6000612d52600283901c604061465c565b90508067ffffffffffffffff811115612d6d57612d6d61341f565b6040519080825280601f01601f191660200182016040528015612d97576020820181803683370190505b509350600086831b600052602085019050612db460008284612f85565b5050505092915050565b600080600080612dce8787613007565b93509150848015612de257508160ff166042145b8015612e50575086612df5876001614a62565b81518110612e0557612e05613ea6565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f5b00000000000000000000000000000000000000000000000000000000000000145b8015612ebe575086612e6360018561465c565b81518110612e7357612e73613ea6565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f5d00000000000000000000000000000000000000000000000000000000000000145b15612f3057612ee287612ed2886002614a62565b612edd60018761465c565b61306c565b9094509050801580612ef2575083155b15612f2b57866040517fba4adc2300000000000000000000000000000000000000000000000000000000815260040161066f919061377b565b612f44565b60ff821615612f4457816021878901012093505b93509350935093565b612f6085612f5b8387614a62565b6130e5565b612f6e83612f5b8385614a62565b60208486018101908385010161095581838561312d565b8181015b808310156104715783516101005b8285108015612fa65750600081115b15612ffa577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc01600f82821c16600a8110612fe45780605701612fe9565b806030015b905080865350600190940193612f97565b5050602084019350612f89565b8181016020015160001a8082016001018161302657835181141561302c565b83518110155b1561306557836040517fba4adc2300000000000000000000000000000000000000000000000000000000815260040161066f919061377b565b9250929050565b60008083831015613082575060009050806130dd565b600061308e858561465c565b9050604081118061309f5750855184115b156130b15750600091508190506130dd565b8585016020016130c3816000846131b3565b92506001820160011c6020036000518160031b1c94505050505b935093915050565b81518111156117e05781516040517f8a3c1cfb00000000000000000000000000000000000000000000000000000000815261066f918391600401918252602082015260400190565b5b601f81111561316c5781518352602092830192909101907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00161312e565b80156117275790518251600160209390930360031b9290921b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199091169116179052565b600061326d565b811a6000602f8211603a831016156131f557507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd0810161042c565b6047821060408311161561322c57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc9810161042c565b6067821060608311161561326357507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa9810161042c565b5061010092915050565b506001838201828216156132a957613287600086516131ba565b80855360018601955060018501945060ff8111156132a757600092508195505b505b808510156132f75784516132be6001826131ba565b6132c96000836131ba565b60041b17905060ff8111156132e25760009250506132f7565b808553506002850194506001840193506132a9565b509392505050565b7fffffffff00000000000000000000000000000000000000000000000000000000811681146117b957600080fd5b60006020828403121561333f57600080fd5b8135611817816132ff565b60008083601f84011261335c57600080fd5b50813567ffffffffffffffff81111561337457600080fd5b60208301915083602082850101111561306557600080fd5b600080600080604085870312156133a257600080fd5b843567ffffffffffffffff8111156133b957600080fd5b6133c58782880161334a565b909550935050602085013567ffffffffffffffff8111156133e557600080fd5b6133f18782880161334a565b95989497509550505050565b73ffffffffffffffffffffffffffffffffffffffff811681146117b957600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156134715761347161341f565b60405290565b6040516080810167ffffffffffffffff811182821017156134715761347161341f565b60405160c0810167ffffffffffffffff811182821017156134715761347161341f565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156135045761350461341f565b604052919050565b600067ffffffffffffffff8211156135265761352661341f565b5060051b60200190565b600067ffffffffffffffff82111561354a5761354a61341f565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261358757600080fd5b81356020830160006135a061359b84613530565b6134bd565b90508281528583830111156135b457600080fd5b82826020830137600092810160200192909252509392505050565b600082601f8301126135e057600080fd5b81356135ee61359b8261350c565b8082825260208201915060208360051b86010192508583111561361057600080fd5b602085015b8381101561365257803567ffffffffffffffff81111561363457600080fd5b613643886020838a0101613576565b84525060209283019201613615565b5095945050505050565b6000806000806000806080878903121561367557600080fd5b8635613680816133fd565b9550602087013567ffffffffffffffff81111561369c57600080fd5b6136a889828a0161334a565b909650945050604087013567ffffffffffffffff8111156136c857600080fd5b6136d489828a0161334a565b909450925050606087013567ffffffffffffffff8111156136f457600080fd5b61370089828a016135cf565b9150509295509295509295565b60005b83811015613728578181015183820152602001613710565b50506000910152565b6000815180845261374981602086016020860161370d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006118176020830184613731565b6000806000604084860312156137a357600080fd5b833567ffffffffffffffff8111156137ba57600080fd5b6137c686828701613576565b935050602084013567ffffffffffffffff8111156137e357600080fd5b6137ef8682870161334a565b9497909650939450505050565b60608152600061380f6060830186613731565b73ffffffffffffffffffffffffffffffffffffffff94851660208401529290931660409091015292915050565b60008060006040848603121561385157600080fd5b833567ffffffffffffffff81111561386857600080fd5b6138748682870161334a565b909790965060209590950135949350505050565b60408152600061389b6040830185613731565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b6000602082840312156138d257600080fd5b813567ffffffffffffffff8111156138e957600080fd5b8201604081850312156138fb57600080fd5b61390361344e565b813567ffffffffffffffff81111561391a57600080fd5b8201601f8101861361392b57600080fd5b803561393961359b8261350c565b8082825260208201915060208360051b85010192508883111561395b57600080fd5b602084015b83811015613a4357803567ffffffffffffffff81111561397f57600080fd5b85016080818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00112156139b357600080fd5b6139bb613477565b60208201356139c9816133fd565b8152604082013567ffffffffffffffff8111156139e557600080fd5b6139f48d602083860101613576565b602083015250606082013567ffffffffffffffff811115613a1457600080fd5b613a238d602083860101613576565b604083015250608091909101356060820152835260209283019201613960565b508452505050602082013567ffffffffffffffff811115613a6357600080fd5b613a6f868285016135cf565b602083015250949350505050565b600082825180855260208501945060208160051b8301016020850160005b83811015613aeb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0858403018852613ad5838351613731565b6020988901989093509190910190600101613a9b565b50909695505050505050565b6020815260006060820183516040602085015281815180845260808601915060808160051b870101935060208301925060005b81811015613bcb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80878603018352835173ffffffffffffffffffffffffffffffffffffffff8151168652602081015160806020880152613b8e6080880182613731565b905060408201518782036040890152613ba78282613731565b60609384015198909301979097525094506020938401939290920191600101613b2a565b5050505060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152613c088282613a7d565b95945050505050565b600080600080600060608688031215613c2957600080fd5b853567ffffffffffffffff811115613c4057600080fd5b613c4c8882890161334a565b909650945050602086013567ffffffffffffffff811115613c6c57600080fd5b613c788882890161334a565b909450925050604086013567ffffffffffffffff811115613c9857600080fd5b613ca4888289016135cf565b9150509295509295909350565b600060208284031215613cc357600080fd5b813567ffffffffffffffff811115613cda57600080fd5b612be384828501613576565b60008060008060608587031215613cfc57600080fd5b843567ffffffffffffffff811115613d1357600080fd5b613d1f8782880161334a565b90955093505060208501359150604085013567ffffffffffffffff811115613d4657600080fd5b613d52878288016135cf565b91505092959194509250565b602081526000825160a06020840152613d7a60c0840182613731565b9050602084015160408401526040840151606084015273ffffffffffffffffffffffffffffffffffffffff60608501511660808401526080840151151560a08401528091505092915050565b60008060408385031215613dd957600080fd5b823567ffffffffffffffff811115613df057600080fd5b613dfc85828601613576565b925050602083013567ffffffffffffffff811115613e1957600080fd5b613e2585828601613576565b9150509250929050565b80151581146117b957600080fd5b60008060008060808587031215613e5357600080fd5b8435613e5e81613e2f565b93506020850135613e6e81613e2f565b92506040850135613e7e816132ff565b9150606085013567ffffffffffffffff811115613e9a57600080fd5b613d5287828801613576565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000613ee361359b84613530565b9050828152838383011115613ef757600080fd5b61181783602083018461370d565b600082601f830112613f1657600080fd5b61181783835160208501613ed5565b600060208284031215613f3757600080fd5b815167ffffffffffffffff811115613f4e57600080fd5b612be384828501613f05565b6000602082016020835280845180835260408501915060408160051b86010192506020860160005b82811015613fd1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0878603018452613fbc858351613731565b94506020938401939190910190600101613f82565b50929695505050505050565b805160208201517fffffffff00000000000000000000000000000000000000000000000000000000811691906004821015614042577fffffffff00000000000000000000000000000000000000000000000000000000808360040360031b1b82161692505b5050919050565b60408152600061405c6040830185613731565b8281036020840152613c088185613731565b6000806000806080858703121561408457600080fd5b843561408f81613e2f565b93506020850135613e6e816132ff565b6000608082840312156140b157600080fd5b6140b9613477565b9050813567ffffffffffffffff8111156140d257600080fd5b6140de84828501613576565b82525060208281013590820152604082013567ffffffffffffffff81111561410557600080fd5b614111848285016135cf565b6040830152506060820135614125816133fd565b606082015292915050565b60006020828403121561414257600080fd5b813567ffffffffffffffff81111561415957600080fd5b612be38482850161409f565b600081516080845261417a6080850182613731565b9050602083015160208501526040830151848203604086015261419d8282613a7d565b91505073ffffffffffffffffffffffffffffffffffffffff60608401511660608501528091505092915050565b6060815260006141dd6060830186614165565b82810360208401526141ef8186613731565b91505073ffffffffffffffffffffffffffffffffffffffff83166040830152949350505050565b600082601f83011261422757600080fd5b815161423561359b8261350c565b8082825260208201915060208360051b86010192508583111561425757600080fd5b602085015b8381101561365257805167ffffffffffffffff81111561427b57600080fd5b8601603f8101881361428c57600080fd5b61429e88602083015160408401613ed5565b8452506020928301920161425c565b6000602082840312156142bf57600080fd5b815167ffffffffffffffff8111156142d657600080fd5b612be384828501614216565b6000806000606084860312156142f757600080fd5b833567ffffffffffffffff81111561430e57600080fd5b61431a8682870161409f565b935050602084013567ffffffffffffffff81111561433757600080fd5b61434386828701613576565b9250506040840135614354816133fd565b809150509250925092565b60006020828403121561437157600080fd5b8135611817816133fd565b6000806040838503121561438f57600080fd5b823567ffffffffffffffff8111156143a657600080fd5b8301601f810185136143b757600080fd5b80356143c561359b8261350c565b8082825260208201915060208360051b8501019250878311156143e757600080fd5b6020840193505b8284101561441257833561440181613e2f565b8252602093840193909101906143ee565b9450505050602083013567ffffffffffffffff81111561443157600080fd5b613e25858286016135cf565b6000825161444f81846020870161370d565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036144b9576144b9614459565b5060010190565b6020815260006118176020830184614165565b8051611655816133fd565b8051611655816132ff565b6000602082840312156144fb57600080fd5b815167ffffffffffffffff81111561451257600080fd5b820160c0818503121561452457600080fd5b61452c61349a565b614535826144d3565b8152614543602083016144de565b6020820152604082015167ffffffffffffffff81111561456257600080fd5b61456e86828501613f05565b604083015250614580606083016144de565b6060820152614591608083016144de565b608082015260a082015167ffffffffffffffff8111156145b057600080fd5b6145bc86828501613f05565b60a083015250949350505050565b6000602082840312156145dc57600080fd5b815161181781613e2f565b84151581527fffffffff00000000000000000000000000000000000000000000000000000000841660208201527fffffffff00000000000000000000000000000000000000000000000000000000831660408201526080606082015260006146526080830184613731565b9695505050505050565b8181038181111561042c5761042c614459565b60006020828403121561468157600080fd5b815167ffffffffffffffff81111561469857600080fd5b8201601f810184136146a957600080fd5b80516146b761359b8261350c565b8082825260208201915060208360051b8501019250868311156146d957600080fd5b602084015b8381101561089d57805167ffffffffffffffff8111156146fd57600080fd5b61470c89602083890101613f05565b845250602092830192016146de565b841515815283151560208201527fffffffff00000000000000000000000000000000000000000000000000000000831660408201526080606082015260006146526080830184613731565b6000602082016020835280845180835260408501915060408160051b86010192506020860160005b82811015613fd1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0878603018452815173ffffffffffffffffffffffffffffffffffffffff81511686526020810151606060208801526147f26060880182613a7d565b905060408201519150868103604088015261480d8183613731565b96505050602093840193919091019060010161478e565b73ffffffffffffffffffffffffffffffffffffffff8616815260a06020820152600061485360a0830187613a7d565b82810360408401526148658187613731565b90507fffffffff000000000000000000000000000000000000000000000000000000008516606084015282810360808401526148a18185613731565b98975050505050505050565b6000602082840312156148bf57600080fd5b8151611817816133fd565b600086516148dc818460208b0161370d565b7fff0000000000000000000000000000000000000000000000000000000000000087169083019081528551614918816001840160208a0161370d565b7fff00000000000000000000000000000000000000000000000000000000000000861660019290910191820152835161495881600284016020880161370d565b01600201979650505050505050565b6020815273ffffffffffffffffffffffffffffffffffffffff82511660208201527fffffffff0000000000000000000000000000000000000000000000000000000060208301511660408201526000604083015160c060608401526149cf60e0840182613731565b90507fffffffff0000000000000000000000000000000000000000000000000000000060608501511660808401527fffffffff0000000000000000000000000000000000000000000000000000000060808501511660a084015260a08401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160c0850152613c088282613731565b8082018082111561042c5761042c614459565b600080600080600060a08688031215614a8d57600080fd5b8551614a98816133fd565b602087015190955067ffffffffffffffff811115614ab557600080fd5b614ac188828901614216565b945050604086015167ffffffffffffffff811115614ade57600080fd5b614aea88828901613f05565b9350506060860151614afb816132ff565b608087015190925067ffffffffffffffff811115614b1857600080fd5b613ca488828901613f0556fea264697066735822122084f9ea59b473b1991a8ef12ca16a590b7c121f1b45f67d70f9ac492af54f2bdf64736f6c634300081a0033",
  "devdoc": {
    "errors": {
      "DNSDecodingFailed(bytes)": [
        {
          "details": "The DNS-encoded name is malformed.      Error selector: `0xba4adc23`"
        }
      ],
      "DNSEncodingFailed(string)": [
        {
          "details": "A label of the ENS name has an invalid size.      Error selector: `0x9a4c3e3b`"
        }
      ],
      "EmptyAddress()": [
        {
          "details": "The supplied address was `0x`.      Error selector: `0x7138356f`"
        }
      ],
      "HttpError(uint16,string)": [
        {
          "details": "Error selector: `0x01800152`"
        }
      ],
      "InvalidBatchGatewayResponse()": [
        {
          "details": "Error selector: `0x4a5c31ea`"
        }
      ],
      "OffchainLookup(address,string[],bytes,bytes4,bytes)": [
        {
          "details": "https://eips.ethereum.org/EIPS/eip-3668 Error selector: `0x556f1830`"
        }
      ],
      "OffsetOutOfBoundsError(uint256,uint256)": [
        {
          "details": "`offset` was beyond `length`.       Error selector: `0x8a3c1cfb`"
        }
      ],
      "ResolverError(bytes)": [
        {
          "details": "Error selector: `0x95c0c752`"
        }
      ],
      "ResolverNotContract(bytes,address)": [
        {
          "details": "Error selector: `0x1e9535f2`"
        }
      ],
      "ResolverNotFound(bytes)": [
        {
          "details": "Error selector: `0x77209fe8`"
        }
      ],
      "ReverseAddressMismatch(string,bytes)": [
        {
          "details": "Error selector: `0xef9c03ce`"
        }
      ],
      "UnsupportedResolverProfile(bytes4)": [
        {
          "details": "Error selector: `0x7b1c461b`"
        }
      ]
    },
    "kind": "dev",
    "methods": {
      "ccipBatch(((address,bytes,bytes,uint256)[],string[]))": {
        "details": "Use `ccipRead()` to call this function with a batch.      The callback response will be `abi.encode(batch)`."
      },
      "ccipBatchCallback(bytes,bytes)": {
        "details": "CCIP-Read callback for `ccipBatch()`.      Updates `batch` using the batch gateway response. Reverts again if not \"done\".",
        "params": {
          "extraData": "The contextual data passed from `ccipBatch()`.",
          "response": "The response from the batch gateway."
        },
        "returns": {
          "batch": "The batch where every lookup is \"done\"."
        }
      },
      "ccipReadCallback(bytes,bytes)": {
        "details": "CCIP-Read callback for `ccipRead()`.The return type of this function is polymorphic depending on the caller.",
        "params": {
          "extraData": "The contextual data passed from `ccipRead()`.",
          "response": "The response from offchain."
        }
      },
      "findResolver(bytes)": {
        "details": "Find the resolver address for `name`.      Does not perform any validity checks on the resolver.",
        "params": {
          "name": "The name to search."
        },
        "returns": {
          "_0": "The resolver or `address(0)` if not found.",
          "_1": "The namehash of `name`.",
          "_2": "The offset into `name` corresponding to `resolver`."
        }
      },
      "requireResolver(bytes)": {
        "details": "Returns a valid resolver for `name` or reverts.",
        "params": {
          "name": "The name to search."
        },
        "returns": {
          "info": "The resolver information."
        }
      },
      "resolveBatchCallback(bytes,bytes)": {
        "details": "CCIP-Read callback for `_callResolver()` from calling the batch gateway successfully."
      },
      "resolveCallback(bytes,bytes)": {
        "details": "CCIP-Read callback for `resolveWithGateways()`.",
        "params": {
          "extraData": "The contextual data passed from `resolveWith*()`.",
          "response": "The response from the resolver."
        }
      },
      "resolveDirectCallback(bytes,bytes)": {
        "details": "CCIP-Read callback for `_callResolver()` from calling the resolver successfully."
      },
      "resolveDirectCallbackError(bytes,bytes)": {
        "details": "CCIP-Read callback for `_callResolver()` from calling the resolver unsuccessfully."
      },
      "resolveWithGateways(bytes,bytes,string[])": {
        "details": "This function executes over multiple steps.",
        "params": {
          "data": "The resolution data, as specified in ENSIP-10.",
          "gateways": "The list of batch gateway URLs to use.",
          "name": "The name to resolve, in normalised and DNS-encoded form."
        },
        "returns": {
          "resolver": "The address of the resolver that supplied `result`.",
          "result": "The encoded response for the requested call."
        }
      },
      "reverseAddressCallback(bytes,bytes)": {
        "details": "CCIP-Read callback for `reverseNameCallback()`.      Reverts `ReverseAddressMismatch`.",
        "params": {
          "extraData": "The contextual data passed from `reverseNameCallback()`.",
          "response": "The abi-encoded `addr()` response from the forward resolver."
        }
      },
      "reverseNameCallback(bytes,bytes)": {
        "details": "CCIP-Read callback for `reverseWithGateways()`.",
        "params": {
          "extraData": "The contextual data passed from `reverseWithGateways()`.",
          "response": "The abi-encoded `name()` response from the reverse resolver."
        }
      },
      "reverseWithGateways(bytes,uint256,string[])": {
        "details": "This function executes over multiple steps.",
        "params": {
          "coinType": "The coin type.",
          "gateways": "The list of batch gateway URLs to use.",
          "lookupAddress": "The input address."
        },
        "returns": {
          "primary": "The resolved primary name.",
          "resolver": "The resolver address for primary name.",
          "reverseResolver": "The resolver address for the reverse name."
        }
      },
      "supportsInterface(bytes4)": {
        "details": "See {IERC165-supportsInterface}."
      }
    },
    "version": 1
  },
  "userdoc": {
    "errors": {
      "HttpError(uint16,string)": [
        {
          "notice": "An HTTP error occurred on a resolving gateway."
        }
      ],
      "InvalidBatchGatewayResponse()": [
        {
          "notice": "The batch gateway supplied an incorrect number of responses."
        }
      ],
      "ResolverError(bytes)": [
        {
          "notice": "The resolver returned an error."
        }
      ],
      "ResolverNotContract(bytes,address)": [
        {
          "notice": "The resolver is not a contract."
        }
      ],
      "ResolverNotFound(bytes)": [
        {
          "notice": "A resolver could not be found for the supplied name."
        }
      ],
      "ReverseAddressMismatch(string,bytes)": [
        {
          "notice": "The resolved address from reverse resolution does not match the supplied address."
        }
      ],
      "UnsupportedResolverProfile(bytes4)": [
        {
          "notice": "The resolver did not respond."
        }
      ]
    },
    "kind": "user",
    "methods": {
      "resolve(bytes,bytes)": {
        "notice": "Same as `resolveWithGateways()` but uses default batch gateways."
      },
      "resolveWithGateways(bytes,bytes,string[])": {
        "notice": "Performs ENS resolution process for the supplied name and resolution data.         Caller should enable EIP-3668."
      },
      "resolveWithResolver(address,bytes,bytes,string[])": {
        "notice": "Same as `resolveWithGateways()` but uses the supplied resolver."
      },
      "reverse(bytes,uint256)": {
        "notice": "Same as `reverseWithGateways()` but uses default batch gateways."
      },
      "reverseWithGateways(bytes,uint256,string[])": {
        "notice": "Performs ENS reverse resolution for the supplied address and coin type.         Caller should enable EIP-3668."
      }
    },
    "version": 1
  },
  "storageLayout": {
    "storage": [],
    "types": null
  }
}