{
  "address": "0xE23c8f8aB1Cdd56D89F181c22Bf43e5b53871E08",
  "abi": [
    {
      "inputs": [],
      "stateMutability": "nonpayable",
      "type": "constructor"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "bytes32",
          "name": "node",
          "type": "bytes32"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "addr",
          "type": "address"
        }
      ],
      "name": "AddrChanged",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "bytes32",
          "name": "node",
          "type": "bytes32"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "coinType",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "bytes",
          "name": "newAddress",
          "type": "bytes"
        }
      ],
      "name": "AddressChanged",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "address",
          "name": "sender",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "guardian",
          "type": "address"
        }
      ],
      "name": "GuardianAdded",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "address",
          "name": "sender",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "guardian",
          "type": "address"
        }
      ],
      "name": "GuardianRemoved",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "address",
          "name": "initializer",
          "type": "address"
        }
      ],
      "name": "Initialized",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "bytes32",
          "name": "node",
          "type": "bytes32"
        },
        {
          "indexed": false,
          "internalType": "string",
          "name": "name",
          "type": "string"
        }
      ],
      "name": "NameChanged",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "bytes32",
          "name": "node",
          "type": "bytes32"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "owner",
          "type": "address"
        }
      ],
      "name": "NodeReleased",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "bytes32",
          "name": "node",
          "type": "bytes32"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "owner",
          "type": "address"
        }
      ],
      "name": "NodeSubmitted",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "bytes32",
          "name": "node",
          "type": "bytes32"
        }
      ],
      "name": "NodeVerified",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "bytes32",
          "name": "node",
          "type": "bytes32"
        },
        {
          "indexed": false,
          "internalType": "bytes32",
          "name": "x",
          "type": "bytes32"
        },
        {
          "indexed": false,
          "internalType": "bytes32",
          "name": "y",
          "type": "bytes32"
        }
      ],
      "name": "PubkeyChanged",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "address",
          "name": "registry",
          "type": "address"
        }
      ],
      "name": "RegistryChanged",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "bytes32",
          "name": "node",
          "type": "bytes32"
        },
        {
          "indexed": true,
          "internalType": "string",
          "name": "indexedKey",
          "type": "string"
        },
        {
          "indexed": false,
          "internalType": "string",
          "name": "key",
          "type": "string"
        }
      ],
      "name": "TextChanged",
      "type": "event"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "guardian",
          "type": "address"
        }
      ],
      "name": "addGuardian",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "node",
          "type": "bytes32"
        }
      ],
      "name": "addr",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "node",
          "type": "bytes32"
        },
        {
          "internalType": "uint256",
          "name": "coinType",
          "type": "uint256"
        }
      ],
      "name": "addr",
      "outputs": [
        {
          "internalType": "bytes",
          "name": "",
          "type": "bytes"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "chainId",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "gateway",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "components": [
            {
              "internalType": "address",
              "name": "account",
              "type": "address"
            },
            {
              "internalType": "bytes32",
              "name": "node",
              "type": "bytes32"
            },
            {
              "internalType": "bytes32",
              "name": "label",
              "type": "bytes32"
            }
          ],
          "internalType": "struct ENSController.SubNodeRegistration",
          "name": "subNodeRegistration",
          "type": "tuple"
        }
      ],
      "name": "hashSubNodeRegistration",
      "outputs": [
        {
          "internalType": "bytes32",
          "name": "",
          "type": "bytes32"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract ENSRegistry",
          "name": "registry_",
          "type": "address"
        },
        {
          "internalType": "address[]",
          "name": "guardians_",
          "type": "address[]"
        },
        {
          "internalType": "address",
          "name": "gateway_",
          "type": "address"
        }
      ],
      "name": "initialize",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "guardian",
          "type": "address"
        }
      ],
      "name": "isGuardian",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "isInitialized",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "node",
          "type": "bytes32"
        }
      ],
      "name": "name",
      "outputs": [
        {
          "internalType": "string",
          "name": "",
          "type": "string"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "",
          "type": "bytes32"
        }
      ],
      "name": "nodeOwners",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "node",
          "type": "bytes32"
        }
      ],
      "name": "pubkey",
      "outputs": [
        {
          "internalType": "bytes32",
          "name": "x",
          "type": "bytes32"
        },
        {
          "internalType": "bytes32",
          "name": "y",
          "type": "bytes32"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "node",
          "type": "bytes32"
        },
        {
          "internalType": "bytes32",
          "name": "label",
          "type": "bytes32"
        },
        {
          "internalType": "bytes",
          "name": "guardianSignature",
          "type": "bytes"
        }
      ],
      "name": "registerSubNode",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "registry",
      "outputs": [
        {
          "internalType": "contract ENSRegistry",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "node",
          "type": "bytes32"
        }
      ],
      "name": "releaseNode",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "guardian",
          "type": "address"
        }
      ],
      "name": "removeGuardian",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "node",
          "type": "bytes32"
        },
        {
          "internalType": "uint256",
          "name": "coinType",
          "type": "uint256"
        },
        {
          "internalType": "bytes",
          "name": "addr_",
          "type": "bytes"
        }
      ],
      "name": "setAddr",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "node",
          "type": "bytes32"
        },
        {
          "internalType": "address",
          "name": "addr_",
          "type": "address"
        }
      ],
      "name": "setAddr",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "node",
          "type": "bytes32"
        },
        {
          "internalType": "string",
          "name": "name",
          "type": "string"
        }
      ],
      "name": "setName",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "node",
          "type": "bytes32"
        },
        {
          "internalType": "bytes32",
          "name": "x",
          "type": "bytes32"
        },
        {
          "internalType": "bytes32",
          "name": "y",
          "type": "bytes32"
        }
      ],
      "name": "setPubkey",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract ENSRegistry",
          "name": "registry_",
          "type": "address"
        }
      ],
      "name": "setRegistry",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "node",
          "type": "bytes32"
        },
        {
          "internalType": "string",
          "name": "key",
          "type": "string"
        },
        {
          "internalType": "string",
          "name": "value",
          "type": "string"
        }
      ],
      "name": "setText",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "node",
          "type": "bytes32"
        }
      ],
      "name": "submitNode",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes4",
          "name": "interfaceID",
          "type": "bytes4"
        }
      ],
      "name": "supportsInterface",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "pure",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "node",
          "type": "bytes32"
        }
      ],
      "name": "syncAddr",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "node",
          "type": "bytes32"
        },
        {
          "internalType": "string",
          "name": "key",
          "type": "string"
        }
      ],
      "name": "text",
      "outputs": [
        {
          "internalType": "string",
          "name": "",
          "type": "string"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "messageHash",
          "type": "bytes32"
        },
        {
          "internalType": "bytes",
          "name": "signature",
          "type": "bytes"
        }
      ],
      "name": "verifyGuardianSignature",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "node",
          "type": "bytes32"
        }
      ],
      "name": "verifyNode",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    }
  ],
  "transactionHash": "0x1ffee3063052940312d55fb7c90cc30212049c49f3e4ad3f1bef334484e98472",
  "receipt": {
    "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C",
    "from": "0x326b2D4f29E19C7089D038EA5E06f090Afa6FB7f",
    "contractAddress": null,
    "transactionIndex": 1,
    "gasUsed": "4150167",
    "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "blockHash": "0x3c51cde631881561c061da4128030fd0229b05f12a92cc45294b7fc998a16c88",
    "transactionHash": "0x1ffee3063052940312d55fb7c90cc30212049c49f3e4ad3f1bef334484e98472",
    "logs": [],
    "blockNumber": 156625,
    "cumulativeGasUsed": "4150167",
    "status": 1,
    "byzantium": true
  },
  "args": [],
  "solcInputHash": "1bdf84d4bd28700579af1cc4796e2cae",
  "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"AddrChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"coinType\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newAddress\",\"type\":\"bytes\"}],\"name\":\"AddressChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guardian\",\"type\":\"address\"}],\"name\":\"GuardianAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guardian\",\"type\":\"address\"}],\"name\":\"GuardianRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"initializer\",\"type\":\"address\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NameChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"NodeReleased\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"NodeSubmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"NodeVerified\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"x\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"y\",\"type\":\"bytes32\"}],\"name\":\"PubkeyChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"registry\",\"type\":\"address\"}],\"name\":\"RegistryChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"string\",\"name\":\"indexedKey\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"key\",\"type\":\"string\"}],\"name\":\"TextChanged\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guardian\",\"type\":\"address\"}],\"name\":\"addGuardian\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"addr\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"coinType\",\"type\":\"uint256\"}],\"name\":\"addr\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"chainId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gateway\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"label\",\"type\":\"bytes32\"}],\"internalType\":\"struct ENSController.SubNodeRegistration\",\"name\":\"subNodeRegistration\",\"type\":\"tuple\"}],\"name\":\"hashSubNodeRegistration\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ENSRegistry\",\"name\":\"registry_\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"guardians_\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"gateway_\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guardian\",\"type\":\"address\"}],\"name\":\"isGuardian\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isInitialized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"nodeOwners\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"pubkey\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"x\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"y\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"label\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"guardianSignature\",\"type\":\"bytes\"}],\"name\":\"registerSubNode\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registry\",\"outputs\":[{\"internalType\":\"contract ENSRegistry\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"releaseNode\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guardian\",\"type\":\"address\"}],\"name\":\"removeGuardian\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"coinType\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"addr_\",\"type\":\"bytes\"}],\"name\":\"setAddr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}],\"name\":\"setAddr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"setName\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"x\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"y\",\"type\":\"bytes32\"}],\"name\":\"setPubkey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ENSRegistry\",\"name\":\"registry_\",\"type\":\"address\"}],\"name\":\"setRegistry\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"key\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"value\",\"type\":\"string\"}],\"name\":\"setText\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"submitNode\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceID\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"syncAddr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"key\",\"type\":\"string\"}],\"name\":\"text\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"verifyGuardianSignature\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"verifyNode\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Stanis\\u0142aw G\\u0142ogowski <stan@pillarproject.io>\",\"details\":\"The process of adding root node consists of 3 steps: 1. `submitNode` - should be called from ENS node owner, 2. Change ENS node owner in ENS registry to ENS controller, 3. `verifyNode` - should be called from previous ENS node owner, To register sub node, `msg.sender` need to send valid signature from one of guardian key. Once registration is complete `msg.sender` becoming both node owner and `addr` record value. After registration sub node cannot be replaced.\",\"events\":{\"NodeReleased(bytes32,address)\":{\"details\":\"Emitted when new node is released\",\"params\":{\"node\":\"node name hash\",\"owner\":\"owner address\"}},\"NodeSubmitted(bytes32,address)\":{\"details\":\"Emitted when new node is submitted\",\"params\":{\"node\":\"node name hash\",\"owner\":\"owner address\"}},\"NodeVerified(bytes32)\":{\"details\":\"Emitted when the existing owner is verified\",\"params\":{\"node\":\"node name hash\"}},\"RegistryChanged(address)\":{\"details\":\"Emitted when ENS registry address is changed\",\"params\":{\"registry\":\"registry address\"}}},\"kind\":\"dev\",\"methods\":{\"addGuardian(address)\":{\"params\":{\"guardian\":\"guardian address\"}},\"constructor\":{\"details\":\"Public constructor\"},\"hashSubNodeRegistration((address,bytes32,bytes32))\":{\"params\":{\"subNodeRegistration\":\"struct\"},\"returns\":{\"_0\":\"hash\"}},\"initialize(address,address[],address)\":{\"params\":{\"gateway_\":\"gateway address\",\"registry_\":\"ENS registry address\"}},\"isGuardian(address)\":{\"params\":{\"guardian\":\"guardian address\"},\"returns\":{\"_0\":\"true when guardian exists\"}},\"isInitialized()\":{\"returns\":{\"_0\":\"true when contract is initialized\"}},\"registerSubNode(bytes32,bytes32,bytes)\":{\"params\":{\"guardianSignature\":\"guardian signature\",\"label\":\"label hash\",\"node\":\"node name hash\"}},\"releaseNode(bytes32)\":{\"details\":\"Should be called from the previous ENS node owner\",\"params\":{\"node\":\"node name hash\"}},\"removeGuardian(address)\":{\"params\":{\"guardian\":\"guardian address\"}},\"setRegistry(address)\":{\"params\":{\"registry_\":\"registry address\"}},\"submitNode(bytes32)\":{\"details\":\"Should be called from the current ENS node owner\",\"params\":{\"node\":\"node name hash\"}},\"syncAddr(bytes32)\":{\"params\":{\"node\":\"node name hash\"}},\"verifyGuardianSignature(bytes32,bytes)\":{\"params\":{\"messageHash\":\"message hash\",\"signature\":\"signature\"},\"returns\":{\"_0\":\"true on correct guardian signature\"}},\"verifyNode(bytes32)\":{\"details\":\"Should be called from the previous ENS node owner\",\"params\":{\"node\":\"node name hash\"}}},\"title\":\"ENS controller\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"addGuardian(address)\":{\"notice\":\"Adds a new guardian\"},\"hashSubNodeRegistration((address,bytes32,bytes32))\":{\"notice\":\"Hashes `SubNodeRegistration` message payload\"},\"initialize(address,address[],address)\":{\"notice\":\"Initializes `ENSController` contract\"},\"isGuardian(address)\":{\"notice\":\"Check if guardian exists\"},\"isInitialized()\":{\"notice\":\"Check if contract is initialized\"},\"registerSubNode(bytes32,bytes32,bytes)\":{\"notice\":\"Registers sub node\"},\"releaseNode(bytes32)\":{\"notice\":\"Releases node\"},\"removeGuardian(address)\":{\"notice\":\"Removes the existing guardian\"},\"setRegistry(address)\":{\"notice\":\"Sets registry\"},\"submitNode(bytes32)\":{\"notice\":\"Submits node\"},\"syncAddr(bytes32)\":{\"notice\":\"Sync address\"},\"verifyGuardianSignature(bytes32,bytes)\":{\"notice\":\"Verifies guardian signature\"},\"verifyNode(bytes32)\":{\"notice\":\"Verifies node\"}},\"notice\":\"ENS subnode registrar\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/ens/ENSController.sol\":\"ENSController\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"src/common/access/Guarded.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../libs/ECDSALib.sol\\\";\\n\\n\\n/**\\n * @title Guarded\\n *\\n * @dev Contract module which provides a guardian-type control mechanism.\\n * It allows key accounts to have guardians and restricts specific methods to be accessible by guardians only.\\n *\\n * Each guardian account can remove other guardians\\n *\\n * Use `_initializeGuarded` to initialize the contract\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski <stan@pillarproject.io>\\n */\\ncontract Guarded {\\n  using ECDSALib for bytes32;\\n\\n  mapping(address => bool) private guardians;\\n\\n  // events\\n\\n  /**\\n   * @dev Emitted when a new guardian is added\\n   * @param sender sender address\\n   * @param guardian guardian address\\n   */\\n  event GuardianAdded(\\n    address sender,\\n    address guardian\\n  );\\n\\n  /**\\n   * @dev Emitted when the existing guardian is removed\\n   * @param sender sender address\\n   * @param guardian guardian address\\n   */\\n  event GuardianRemoved(\\n    address sender,\\n    address guardian\\n  );\\n\\n  // modifiers\\n\\n  /**\\n   * @dev Throws if tx.origin is not a guardian account\\n   */\\n  modifier onlyGuardian() {\\n    require(\\n      // solhint-disable-next-line avoid-tx-origin\\n      guardians[tx.origin],\\n      \\\"Guarded: tx.origin is not the guardian\\\"\\n    );\\n\\n    _;\\n  }\\n\\n  /**\\n   * @dev Internal constructor\\n   */\\n  constructor() internal {}\\n\\n  // external functions\\n\\n  /**\\n   * @notice Adds a new guardian\\n   * @param guardian guardian address\\n   */\\n  function addGuardian(\\n    address guardian\\n  )\\n    external\\n    onlyGuardian\\n  {\\n    _addGuardian(guardian);\\n  }\\n\\n  /**\\n   * @notice Removes the existing guardian\\n   * @param guardian guardian address\\n   */\\n  function removeGuardian(\\n    address guardian\\n  )\\n    external\\n    onlyGuardian\\n  {\\n    require(\\n      // solhint-disable-next-line avoid-tx-origin\\n      tx.origin != guardian,\\n      \\\"Guarded: cannot remove self\\\"\\n    );\\n\\n    require(\\n      guardians[guardian],\\n      \\\"Guarded: guardian doesn't exist\\\"\\n    );\\n\\n    guardians[guardian] = false;\\n\\n    emit GuardianRemoved(\\n      // solhint-disable-next-line avoid-tx-origin\\n      tx.origin,\\n      guardian\\n    );\\n  }\\n\\n  // external functions (views)\\n\\n  /**\\n   * @notice Check if guardian exists\\n   * @param guardian guardian address\\n   * @return true when guardian exists\\n   */\\n  function isGuardian(\\n    address guardian\\n  )\\n    external\\n    view\\n    returns (bool)\\n  {\\n    return guardians[guardian];\\n  }\\n\\n  /**\\n   * @notice Verifies guardian signature\\n   * @param messageHash message hash\\n   * @param signature signature\\n   * @return true on correct guardian signature\\n   */\\n  function verifyGuardianSignature(\\n    bytes32 messageHash,\\n    bytes calldata signature\\n  )\\n    external\\n    view\\n    returns (bool)\\n  {\\n    return _verifyGuardianSignature(\\n      messageHash,\\n      signature\\n    );\\n  }\\n\\n  // internal functions\\n\\n  /**\\n   * @notice Initializes `Guarded` contract\\n   * @dev If `guardians_` array is empty `tx.origin` is added as guardian account\\n   * @param guardians_ array of guardians addresses\\n   */\\n  function _initializeGuarded(\\n    address[] memory guardians_\\n  )\\n    internal\\n  {\\n    if (guardians_.length == 0) {\\n      // solhint-disable-next-line avoid-tx-origin\\n      _addGuardian(tx.origin);\\n    } else {\\n      uint guardiansLen = guardians_.length;\\n      for (uint i = 0; i < guardiansLen; i++) {\\n        _addGuardian(guardians_[i]);\\n      }\\n    }\\n  }\\n\\n\\n  // internal functions (views)\\n\\n  function _verifyGuardianSignature(\\n    bytes32 messageHash,\\n    bytes memory signature\\n  )\\n    internal\\n    view\\n    returns (bool)\\n  {\\n    address guardian = messageHash.recoverAddress(signature);\\n\\n    return guardians[guardian];\\n  }\\n\\n  // private functions\\n\\n  function _addGuardian(\\n    address guardian\\n  )\\n    private\\n  {\\n    require(\\n      guardian != address(0),\\n      \\\"Guarded: cannot add 0x0 guardian\\\"\\n    );\\n\\n    require(\\n      !guardians[guardian],\\n      \\\"Guarded: guardian already exists\\\"\\n    );\\n\\n    guardians[guardian] = true;\\n\\n    emit GuardianAdded(\\n      // solhint-disable-next-line avoid-tx-origin\\n      tx.origin,\\n      guardian\\n    );\\n  }\\n}\\n\",\"keccak256\":\"0x4a5f5670041362e87ea267d81c55fc3edc1a78e81f6f17524b13267f91f31458\",\"license\":\"MIT\"},\"src/common/libs/BytesLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Bytes library\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski <stan@pillarproject.io>\\n */\\nlibrary BytesLib {\\n  /**\\n   * @notice Converts bytes to address\\n   * @param data data\\n   * @return address\\n   */\\n  function toAddress(\\n    bytes memory data\\n  )\\n    internal\\n    pure\\n    returns (address)\\n  {\\n    address result;\\n\\n    require(\\n      data.length == 20,\\n      \\\"BytesLib: invalid data length\\\"\\n    );\\n\\n    // solhint-disable-next-line no-inline-assembly\\n    assembly {\\n      result := div(mload(add(data, 0x20)), 0x1000000000000000000000000)\\n    }\\n\\n    return result;\\n  }\\n}\\n\",\"keccak256\":\"0x64c84964ea91bfb1f2d859eea6c57fe5b4a6f269951a4adf5f58d306c54c7f76\",\"license\":\"MIT\"},\"src/common/libs/ECDSALib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title ECDSA library\\n *\\n * @dev Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/cryptography/ECDSA.sol#L26\\n */\\nlibrary ECDSALib {\\n  function recoverAddress(\\n    bytes32 messageHash,\\n    bytes memory signature\\n  )\\n    internal\\n    pure\\n    returns (address)\\n  {\\n    address result = address(0);\\n\\n    if (signature.length == 65) {\\n      bytes32 r;\\n      bytes32 s;\\n      uint8 v;\\n\\n      // solhint-disable-next-line no-inline-assembly\\n      assembly {\\n        r := mload(add(signature, 0x20))\\n        s := mload(add(signature, 0x40))\\n        v := byte(0, mload(add(signature, 0x60)))\\n      }\\n\\n      if (v < 27) {\\n        v += 27;\\n      }\\n\\n      if (v == 27 || v == 28) {\\n        result = ecrecover(messageHash, v, r, s);\\n      }\\n    }\\n\\n    return result;\\n  }\\n\\n  function toEthereumSignedMessageHash(\\n    bytes32 messageHash\\n  )\\n    internal\\n    pure\\n    returns (bytes32)\\n  {\\n    return keccak256(abi.encodePacked(\\n      \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\",\\n      messageHash\\n    ));\\n  }\\n}\\n\",\"keccak256\":\"0x3b1460d688302eb595268c2af147ab532f29dbced66520e013f48d498eed3cec\",\"license\":\"MIT\"},\"src/common/lifecycle/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Initializable\\n *\\n * @dev Contract module which provides access control mechanism, where\\n * there is the initializer account that can be granted exclusive access to\\n * specific functions.\\n *\\n * The initializer account will be tx.origin during contract deployment and will be removed on first use.\\n * Use `onlyInitializer` modifier on contract initialize process.\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski <stan@pillarproject.io>\\n */\\ncontract Initializable {\\n  address private initializer;\\n\\n  // events\\n\\n  /**\\n   * @dev Emitted after `onlyInitializer`\\n   * @param initializer initializer address\\n   */\\n  event Initialized(\\n    address initializer\\n  );\\n\\n  // modifiers\\n\\n  /**\\n   * @dev Throws if tx.origin is not the initializer\\n   */\\n  modifier onlyInitializer() {\\n    require(\\n      // solhint-disable-next-line avoid-tx-origin\\n      tx.origin == initializer,\\n      \\\"Initializable: tx.origin is not the initializer\\\"\\n    );\\n\\n    /// @dev removes initializer\\n    initializer = address(0);\\n\\n    _;\\n\\n    emit Initialized(\\n      // solhint-disable-next-line avoid-tx-origin\\n      tx.origin\\n    );\\n  }\\n\\n  /**\\n   * @dev Internal constructor\\n   */\\n  constructor()\\n    internal\\n  {\\n    // solhint-disable-next-line avoid-tx-origin\\n    initializer = tx.origin;\\n  }\\n\\n   // external functions (views)\\n\\n  /**\\n   * @notice Check if contract is initialized\\n   * @return true when contract is initialized\\n   */\\n  function isInitialized()\\n    external\\n    view\\n    returns (bool)\\n  {\\n    return initializer == address(0);\\n  }\\n}\\n\",\"keccak256\":\"0x3d47b2864dde5bde245917f7ac416a9e9715cdf1d226897e49838eb3186ee067\",\"license\":\"MIT\"},\"src/common/signature/SignatureValidator.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../libs/ECDSALib.sol\\\";\\n\\n/**\\n * @title Signature validator\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski <stan@pillarproject.io>\\n */\\ncontract SignatureValidator {\\n  using ECDSALib for bytes32;\\n\\n  uint256 public chainId;\\n\\n  /**\\n   * @dev internal constructor\\n   */\\n  constructor() internal {\\n    uint256 chainId_;\\n\\n    // solhint-disable-next-line no-inline-assembly\\n    assembly {\\n      chainId_ := chainid()\\n    }\\n\\n    chainId = chainId_;\\n  }\\n\\n  // internal functions\\n\\n  function _hashMessagePayload(\\n    bytes32 messagePrefix,\\n    bytes memory messagePayload\\n  )\\n    internal\\n    view\\n    returns (bytes32)\\n  {\\n    return keccak256(abi.encodePacked(\\n      chainId,\\n      address(this),\\n      messagePrefix,\\n      messagePayload\\n    )).toEthereumSignedMessageHash();\\n  }\\n}\\n\",\"keccak256\":\"0xc1168f7ccb74aea67089941dc5e4c1d1c4aa766afca47a90c0b017b8445b8acf\",\"license\":\"MIT\"},\"src/ens/ENSController.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../common/access/Guarded.sol\\\";\\nimport \\\"../common/lifecycle/Initializable.sol\\\";\\nimport \\\"../common/signature/SignatureValidator.sol\\\";\\nimport \\\"../gateway/GatewayRecipient.sol\\\";\\nimport \\\"./resolvers/ENSAddressResolver.sol\\\";\\nimport \\\"./resolvers/ENSNameResolver.sol\\\";\\nimport \\\"./resolvers/ENSPubKeyResolver.sol\\\";\\nimport \\\"./resolvers/ENSTextResolver.sol\\\";\\nimport \\\"./ENSRegistry.sol\\\";\\n\\n\\n/**\\n * @title ENS controller\\n *\\n * @notice ENS subnode registrar\\n *\\n * @dev The process of adding root node consists of 3 steps:\\n * 1. `submitNode` - should be called from ENS node owner,\\n * 2. Change ENS node owner in ENS registry to ENS controller,\\n * 3. `verifyNode` - should be called from previous ENS node owner,\\n *\\n * To register sub node, `msg.sender` need to send valid signature from one of guardian key.\\n * Once registration is complete `msg.sender` becoming both node owner and `addr` record value.\\n *\\n * After registration sub node cannot be replaced.\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski <stan@pillarproject.io>\\n */\\ncontract ENSController is Guarded, Initializable, SignatureValidator, GatewayRecipient, ENSAddressResolver, ENSNameResolver, ENSPubKeyResolver, ENSTextResolver {\\n  struct SubNodeRegistration {\\n    address account;\\n    bytes32 node;\\n    bytes32 label;\\n  }\\n\\n  bytes4 private constant INTERFACE_META_ID = bytes4(keccak256(abi.encodePacked(\\\"supportsInterface(bytes4)\\\")));\\n\\n  bytes32 private constant HASH_PREFIX_SUB_NODE_REGISTRATION = keccak256(\\n    \\\"SubNodeRegistration(address account,bytes32 node,bytes32 label)\\\"\\n  );\\n\\n  ENSRegistry public registry;\\n\\n  mapping(bytes32 => address) public nodeOwners;\\n\\n  // events\\n\\n  /**\\n   * @dev Emitted when new node is submitted\\n   * @param node node name hash\\n   * @param owner owner address\\n   */\\n  event NodeSubmitted(\\n    bytes32 node,\\n    address owner\\n  );\\n\\n  /**\\n   * @dev Emitted when the existing owner is verified\\n   * @param node node name hash\\n   */\\n  event NodeVerified(\\n    bytes32 node\\n  );\\n\\n  /**\\n   * @dev Emitted when new node is released\\n   * @param node node name hash\\n   * @param owner owner address\\n   */\\n  event NodeReleased(\\n    bytes32 node,\\n    address owner\\n  );\\n\\n  /**\\n   * @dev Emitted when ENS registry address is changed\\n   * @param registry registry address\\n   */\\n  event RegistryChanged(\\n    address registry\\n  );\\n\\n  /**\\n   * @dev Public constructor\\n   */\\n  constructor() public Guarded() Initializable() SignatureValidator() {}\\n\\n  // external functions\\n\\n  /**\\n   * @notice Initializes `ENSController` contract\\n   * @param registry_ ENS registry address\\n   * @param gateway_ gateway address\\n   */\\n  function initialize(\\n    ENSRegistry registry_,\\n    address[] calldata guardians_,\\n    address gateway_\\n  )\\n    external\\n    onlyInitializer\\n  {\\n    require(\\n      address(registry_) != address(0),\\n      \\\"ENSController: cannot set 0x0 registry\\\"\\n    );\\n\\n    registry = registry_;\\n\\n    // Guarded\\n    _initializeGuarded(guardians_);\\n\\n    // GatewayRecipient\\n    _initializeGatewayRecipient(gateway_);\\n  }\\n\\n  /**\\n   * @notice Sets registry\\n   * @param registry_ registry address\\n   */\\n  function setRegistry(\\n    ENSRegistry registry_\\n  )\\n    external\\n    onlyGuardian\\n  {\\n    require(\\n      address(registry_) != address(0),\\n      \\\"ENSController: cannot set 0x0 registry\\\"\\n    );\\n\\n    require(\\n      registry_ != registry,\\n      \\\"ENSController: registry already set\\\"\\n    );\\n\\n    registry = registry_;\\n\\n    emit RegistryChanged(\\n      address(registry)\\n    );\\n  }\\n\\n  /**\\n   * @notice Submits node\\n   * @dev Should be called from the current ENS node owner\\n   * @param node node name hash\\n   */\\n  function submitNode(\\n    bytes32 node\\n  )\\n    external\\n  {\\n    address owner = _getContextAccount();\\n\\n    require(\\n      _addr(node) == address(0),\\n      \\\"ENSController: node already exists\\\"\\n    );\\n\\n    require(\\n      nodeOwners[node] == address(0),\\n      \\\"ENSController: node already submitted\\\"\\n    );\\n\\n    require(\\n      registry.owner(node) == owner,\\n      \\\"ENSController: invalid ens node owner\\\"\\n    );\\n\\n    nodeOwners[node] = owner;\\n\\n    emit NodeSubmitted(node, owner);\\n  }\\n\\n  /**\\n   * @notice Verifies node\\n   * @dev Should be called from the previous ENS node owner\\n   * @param node node name hash\\n   */\\n  function verifyNode(\\n    bytes32 node\\n  )\\n    external\\n  {\\n    address owner = _getContextAccount();\\n\\n    require(\\n      _addr(node) == address(0),\\n      \\\"ENSController: node already exists\\\"\\n    );\\n\\n    require(\\n      nodeOwners[node] == owner,\\n      \\\"ENSController: invalid node owner\\\"\\n    );\\n\\n    require(\\n      registry.owner(node) == address(this),\\n      \\\"ENSController: invalid ens node owner\\\"\\n    );\\n\\n    _setAddr(node, address(this));\\n\\n    registry.setResolver(node, address(this));\\n\\n    emit NodeVerified(node);\\n  }\\n\\n  /**\\n   * @notice Releases node\\n   * @dev Should be called from the previous ENS node owner\\n   * @param node node name hash\\n   */\\n  function releaseNode(\\n    bytes32 node\\n  )\\n    external\\n  {\\n    address owner = _getContextAccount();\\n\\n    require(\\n      _addr(node) == address(this),\\n      \\\"ENSController: node doesn't exist\\\"\\n    );\\n\\n    require(\\n      nodeOwners[node] == owner,\\n      \\\"ENSController: invalid node owner\\\"\\n    );\\n\\n    registry.setOwner(node, owner);\\n\\n    delete nodeOwners[node];\\n\\n    emit NodeReleased(node, owner);\\n  }\\n\\n  /**\\n   * @notice Sync address\\n   * @param node node name hash\\n   */\\n  function syncAddr(\\n    bytes32 node\\n  )\\n    external\\n  {\\n    address account = _getContextAccount();\\n\\n    require(\\n      account == registry.owner(node),\\n      \\\"ENSController: caller is not the node owner\\\"\\n    );\\n\\n    require(\\n      registry.resolver(node) == address(this),\\n      \\\"ENSController: invalid node resolver\\\"\\n    );\\n\\n    require(\\n      _addr(node) == address(0),\\n      \\\"ENSController: node already in sync\\\"\\n    );\\n\\n    _setAddr(node, account);\\n  }\\n\\n  /**\\n   * @notice Registers sub node\\n   * @param node node name hash\\n   * @param label label hash\\n   * @param guardianSignature guardian signature\\n   */\\n  function registerSubNode(\\n    bytes32 node,\\n    bytes32 label,\\n    bytes calldata guardianSignature\\n  )\\n    external\\n  {\\n    address account = _getContextAccount();\\n\\n    bytes32 messageHash = _hashSubNodeRegistration(\\n      account,\\n      node,\\n      label\\n    );\\n\\n    require(\\n      _verifyGuardianSignature(messageHash, guardianSignature),\\n      \\\"ENSController: invalid guardian signature\\\"\\n    );\\n\\n    bytes32 subNode = keccak256(\\n      abi.encodePacked(\\n        node,\\n        label\\n      )\\n    );\\n\\n    require(\\n      _addr(node) == address(this),\\n      \\\"ENSController: invalid node\\\"\\n    );\\n\\n    require(\\n      _addr(subNode) == address(0),\\n      \\\"ENSController: label already taken\\\"\\n    );\\n\\n    registry.setSubnodeRecord(node, label, address(this), address(this), 0);\\n    registry.setOwner(subNode, account);\\n\\n    _setAddr(subNode, account);\\n  }\\n\\n  // external functions (pure)\\n  function supportsInterface(\\n    bytes4 interfaceID\\n  )\\n    external\\n    pure\\n    returns(bool)\\n  {\\n    return interfaceID == INTERFACE_META_ID ||\\n    interfaceID == INTERFACE_ADDR_ID ||\\n    interfaceID == INTERFACE_ADDRESS_ID ||\\n    interfaceID == INTERFACE_NAME_ID ||\\n    interfaceID == INTERFACE_PUB_KEY_ID ||\\n    interfaceID == INTERFACE_TEXT_ID;\\n  }\\n\\n  // public functions (views)\\n\\n  /**\\n   * @notice Hashes `SubNodeRegistration` message payload\\n   * @param subNodeRegistration struct\\n   * @return hash\\n   */\\n  function hashSubNodeRegistration(\\n    SubNodeRegistration memory subNodeRegistration\\n  )\\n    public\\n    view\\n    returns (bytes32)\\n  {\\n    return _hashSubNodeRegistration(\\n      subNodeRegistration.account,\\n      subNodeRegistration.node,\\n      subNodeRegistration.label\\n    );\\n  }\\n\\n  // internal functions (views)\\n\\n  function _isNodeOwner(\\n    bytes32 node\\n  )\\n    internal\\n    override\\n    view\\n    returns (bool)\\n  {\\n    return registry.owner(node) == _getContextAccount();\\n  }\\n\\n  // private functions (views)\\n\\n  function _hashSubNodeRegistration(\\n    address account,\\n    bytes32 node,\\n    bytes32 label\\n  )\\n    private\\n    view\\n    returns (bytes32)\\n  {\\n    return _hashMessagePayload(HASH_PREFIX_SUB_NODE_REGISTRATION, abi.encodePacked(\\n      account,\\n      node,\\n      label\\n    ));\\n  }\\n}\\n\",\"keccak256\":\"0x8006c066bef9625f3d103d77e8b66ff5f006187586cd4518676e73c5d3f79957\",\"license\":\"MIT\"},\"src/ens/ENSRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title ENS registry\\n *\\n * @dev Base on https://github.com/ensdomains/ens/blob/ff0f41747c05f1598973b0fe7ad0d9e09565dfcd/contracts/ENSRegistry.sol\\n */\\ncontract ENSRegistry {\\n  struct Record {\\n    address owner;\\n    address resolver;\\n    uint64 ttl;\\n  }\\n\\n  mapping (bytes32 => Record) private records;\\n  mapping (address => mapping(address => bool)) private operators;\\n\\n  // events\\n\\n  event NewOwner(\\n    bytes32 indexed node,\\n    bytes32 indexed label,\\n    address owner\\n  );\\n\\n  event Transfer(\\n    bytes32 indexed node,\\n    address owner\\n  );\\n\\n  event NewResolver(\\n    bytes32 indexed node,\\n    address resolver\\n  );\\n\\n  event NewTTL(\\n    bytes32 indexed node,\\n    uint64 ttl\\n  );\\n\\n  event ApprovalForAll(\\n    address indexed owner,\\n    address indexed operator,\\n    bool approved\\n  );\\n\\n  // modifiers\\n\\n  modifier authorised(\\n    bytes32 node\\n  )\\n  {\\n    address owner = records[node].owner;\\n\\n    require(\\n      owner == msg.sender || operators[owner][msg.sender],\\n      \\\"ENSRegistry: reverted by authorised modifier\\\"\\n    );\\n\\n    _;\\n  }\\n\\n  /**\\n   * @dev Public constructor\\n   */\\n  constructor()\\n    public\\n  {\\n    // solhint-disable-next-line avoid-tx-origin\\n    records[0x0].owner = tx.origin;\\n  }\\n\\n  // external functions\\n\\n  function setRecord(\\n    bytes32 node,\\n    address owner_,\\n    address resolver_,\\n    uint64 ttl_\\n  )\\n    external\\n  {\\n    setOwner(node, owner_);\\n\\n    _setResolverAndTTL(node, resolver_, ttl_);\\n  }\\n\\n  function setTTL(\\n    bytes32 node,\\n    uint64 ttl_\\n  )\\n    external\\n    authorised(node)\\n  {\\n    records[node].ttl = ttl_;\\n\\n    emit NewTTL(node, ttl_);\\n  }\\n\\n  function setSubnodeRecord(\\n    bytes32 node,\\n    bytes32 label,\\n    address owner_,\\n    address resolver_,\\n    uint64 ttl_\\n  )\\n    external\\n  {\\n    bytes32 subNode = setSubnodeOwner(node, label, owner_);\\n\\n    _setResolverAndTTL(subNode, resolver_, ttl_);\\n  }\\n\\n  function setApprovalForAll(\\n    address operator,\\n    bool approved\\n  )\\n    external\\n  {\\n    operators[msg.sender][operator] = approved;\\n\\n    emit ApprovalForAll(\\n      msg.sender,\\n      operator,\\n      approved\\n    );\\n  }\\n\\n  // external functions (views)\\n\\n  function owner(\\n    bytes32 node\\n  )\\n    external\\n    view\\n    returns (address)\\n  {\\n    address addr = records[node].owner;\\n\\n    if (addr == address(this)) {\\n      return address(0x0);\\n    }\\n\\n    return addr;\\n  }\\n\\n  function resolver(\\n    bytes32 node\\n  )\\n    external\\n    view\\n    returns (address)\\n  {\\n    return records[node].resolver;\\n  }\\n\\n  function ttl(\\n    bytes32 node\\n  )\\n    external\\n    view\\n    returns (uint64)\\n  {\\n    return records[node].ttl;\\n  }\\n\\n  function recordExists(\\n    bytes32 node\\n  )\\n    external\\n    view\\n    returns (bool)\\n  {\\n    return records[node].owner != address(0x0);\\n  }\\n\\n  function isApprovedForAll(\\n    address owner_,\\n    address operator\\n  )\\n    external\\n    view\\n    returns (bool)\\n  {\\n    return operators[owner_][operator];\\n  }\\n\\n  // public functions\\n\\n  function setOwner(\\n    bytes32 node,\\n    address owner_\\n  )\\n    public\\n    authorised(node)\\n  {\\n    records[node].owner = owner_;\\n\\n    emit Transfer(node, owner_);\\n  }\\n\\n  function setResolver(\\n    bytes32 node,\\n    address resolver_\\n  )\\n    public\\n    authorised(node)\\n  {\\n    records[node].resolver = resolver_;\\n\\n    emit NewResolver(node, resolver_);\\n  }\\n\\n  function setSubnodeOwner(\\n    bytes32 node,\\n    bytes32 label,\\n    address owner_\\n  )\\n    public\\n    authorised(node)\\n    returns(bytes32)\\n  {\\n    bytes32 subNode = keccak256(abi.encodePacked(node, label));\\n\\n    records[subNode].owner = owner_;\\n\\n    emit NewOwner(node, label, owner_);\\n\\n    return subNode;\\n  }\\n\\n  // private functions\\n\\n  function _setResolverAndTTL(\\n    bytes32 node,\\n    address resolver_,\\n    uint64 ttl_\\n  )\\n    private\\n  {\\n    if (resolver_ != records[node].resolver) {\\n      records[node].resolver = resolver_;\\n\\n      emit NewResolver(node, resolver_);\\n    }\\n\\n    if (ttl_ != records[node].ttl) {\\n      records[node].ttl = ttl_;\\n\\n      emit NewTTL(node, ttl_);\\n    }\\n  }\\n}\\n\",\"keccak256\":\"0xe00dbdea09d17d41c2c14266e6e1b6b95938c0d374b266bb44a91cfcf0495612\",\"license\":\"MIT\"},\"src/ens/resolvers/ENSAbstractResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title ENS abstract resolver\\n *\\n * @dev Base on https://github.com/ensdomains/resolvers/blob/f7d62ab04bfe1692a4344f6f1d31ff81315a98c3/contracts/ResolverBase.sol\\n */\\nabstract contract ENSAbstractResolver {\\n  // modifiers\\n\\n  modifier onlyNodeOwner(bytes32 node)\\n  {\\n    require(\\n      _isNodeOwner(node),\\n      \\\"ENSAbstractResolver: reverted by onlyNodeOwner modifier\\\"\\n    );\\n\\n    _;\\n  }\\n\\n  // internal functions (views)\\n\\n  function _isNodeOwner(\\n    bytes32 node\\n  )\\n    internal\\n    virtual\\n    view\\n    returns (bool);\\n}\\n\",\"keccak256\":\"0xc67d8bdd4904684e5d3388f7ca7d18c7d407058d6b548d8c591404c758a1ac60\",\"license\":\"MIT\"},\"src/ens/resolvers/ENSAddressResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"./ENSAbstractResolver.sol\\\";\\n\\n\\n/**\\n * @title ENS abstract address resolver\\n *\\n * @dev Base on https://github.com/ensdomains/resolvers/blob/f7d62ab04bfe1692a4344f6f1d31ff81315a98c3/contracts/profiles/AddrResolver.sol\\n */\\nabstract contract ENSAddressResolver is ENSAbstractResolver {\\n  bytes4 internal constant INTERFACE_ADDR_ID = bytes4(keccak256(abi.encodePacked(\\\"addr(bytes32)\\\")));\\n  bytes4 internal constant INTERFACE_ADDRESS_ID = bytes4(keccak256(abi.encodePacked(\\\"addr(bytes32,uint)\\\")));\\n\\n  uint internal constant COIN_TYPE_ETH = 60;\\n\\n  mapping(bytes32 => mapping(uint => bytes)) internal resolverAddresses;\\n\\n  // events\\n\\n  event AddrChanged(\\n    bytes32 indexed node,\\n    address addr\\n  );\\n\\n  event AddressChanged(\\n    bytes32 indexed node,\\n    uint coinType,\\n    bytes newAddress\\n  );\\n\\n  // external functions\\n\\n  function setAddr(\\n    bytes32 node,\\n    address addr_\\n  )\\n    external\\n    onlyNodeOwner(node)\\n  {\\n    _setAddr(node, addr_);\\n  }\\n\\n  function setAddr(\\n    bytes32 node,\\n    uint coinType,\\n    bytes memory addr_\\n  )\\n    external\\n    onlyNodeOwner(node)\\n  {\\n    _setAddr(node, coinType, addr_);\\n  }\\n\\n  // external functions (views)\\n\\n  function addr(\\n    bytes32 node\\n  )\\n    external\\n    view\\n    returns (address)\\n  {\\n    return _addr(node);\\n  }\\n\\n  function addr(\\n    bytes32 node,\\n    uint coinType\\n  )\\n    external\\n    view\\n    returns (bytes memory)\\n  {\\n    return resolverAddresses[node][coinType];\\n  }\\n\\n  // internal functions\\n\\n  function _setAddr(\\n    bytes32 node,\\n    address addr_\\n  )\\n    internal\\n  {\\n    _setAddr(node, COIN_TYPE_ETH, _addressToBytes(addr_));\\n  }\\n\\n  function _setAddr(\\n    bytes32 node,\\n    uint coinType,\\n    bytes memory addr_\\n  )\\n    internal\\n  {\\n    emit AddressChanged(node, coinType, addr_);\\n\\n    if(coinType == COIN_TYPE_ETH) {\\n      emit AddrChanged(node, _bytesToAddress(addr_));\\n    }\\n\\n    resolverAddresses[node][coinType] = addr_;\\n  }\\n\\n  // internal functions (views)\\n\\n  function _addr(\\n    bytes32 node\\n  )\\n    internal\\n    view\\n    returns (address)\\n  {\\n    address result;\\n\\n    bytes memory addr_ = resolverAddresses[node][COIN_TYPE_ETH];\\n\\n    if (addr_.length > 0) {\\n      result = _bytesToAddress(addr_);\\n    }\\n\\n    return result;\\n  }\\n\\n  // private function (pure)\\n\\n  function _bytesToAddress(\\n    bytes memory data\\n  )\\n    private\\n    pure\\n    returns(address payable)\\n  {\\n    address payable result;\\n\\n    require(data.length == 20);\\n\\n    // solhint-disable-next-line no-inline-assembly\\n    assembly {\\n      result := div(mload(add(data, 32)), exp(256, 12))\\n    }\\n\\n    return result;\\n  }\\n\\n  function _addressToBytes(\\n    address addr_\\n  )\\n    private\\n    pure\\n    returns(bytes memory)\\n  {\\n    bytes memory result = new bytes(20);\\n\\n    // solhint-disable-next-line no-inline-assembly\\n    assembly {\\n      mstore(add(result, 32), mul(addr_, exp(256, 12)))\\n    }\\n\\n    return result;\\n  }\\n}\\n\",\"keccak256\":\"0xd2f0c5ed5f5058755512c0916496da6bcf4cf18a0026ee8d20b4306656ce5142\",\"license\":\"MIT\"},\"src/ens/resolvers/ENSNameResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"./ENSAbstractResolver.sol\\\";\\n\\n\\n/**\\n * @title ENS abstract name resolver\\n *\\n * @dev Base on https://github.com/ensdomains/resolvers/blob/f7d62ab04bfe1692a4344f6f1d31ff81315a98c3/contracts/profiles/NameResolver.sol\\n */\\nabstract contract ENSNameResolver is ENSAbstractResolver {\\n  bytes4 internal constant INTERFACE_NAME_ID = bytes4(keccak256(abi.encodePacked(\\\"name(bytes32)\\\")));\\n\\n  mapping(bytes32 => string) internal resolverNames;\\n\\n  // events\\n\\n  event NameChanged(\\n    bytes32 indexed node,\\n    string name\\n  );\\n\\n  // external functions\\n\\n  function setName(\\n    bytes32 node,\\n    string calldata name\\n  )\\n    external\\n    onlyNodeOwner(node)\\n  {\\n    resolverNames[node] = name;\\n\\n    emit NameChanged(node, name);\\n  }\\n\\n  // external functions (views)\\n\\n  function name(\\n    bytes32 node\\n  )\\n    external\\n    view\\n    returns (string memory)\\n  {\\n    return resolverNames[node];\\n  }\\n}\\n\",\"keccak256\":\"0x1d2d4b21f59225fbefe0e5aaff87aff8f11afe5281745934d595e15770557ead\",\"license\":\"MIT\"},\"src/ens/resolvers/ENSPubKeyResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"./ENSAbstractResolver.sol\\\";\\n\\n\\n/**\\n * @title ENS abstract pub key resolver\\n *\\n * @dev Base on https://github.com/ensdomains/resolvers/blob/f7d62ab04bfe1692a4344f6f1d31ff81315a98c3/contracts/profiles/PubkeyResolver.sol\\n */\\nabstract contract ENSPubKeyResolver is ENSAbstractResolver {\\n  bytes4 internal constant INTERFACE_PUB_KEY_ID = bytes4(keccak256(abi.encodePacked(\\\"pubkey(bytes32)\\\")));\\n\\n  struct PubKey {\\n    bytes32 x;\\n    bytes32 y;\\n  }\\n\\n  mapping(bytes32 => PubKey) internal resolverPubKeys;\\n\\n  // events\\n\\n  event PubkeyChanged(\\n    bytes32 indexed node,\\n    bytes32 x,\\n    bytes32 y\\n  );\\n\\n  // external functions (views)\\n\\n  function setPubkey(\\n    bytes32 node,\\n    bytes32 x,\\n    bytes32 y\\n  )\\n    external\\n    onlyNodeOwner(node)\\n  {\\n    resolverPubKeys[node] = PubKey(x, y);\\n\\n    emit PubkeyChanged(node, x, y);\\n  }\\n\\n  // external functions (views)\\n\\n  function pubkey(\\n    bytes32 node\\n  )\\n    external\\n    view\\n    returns (bytes32 x, bytes32 y)\\n  {\\n    return (resolverPubKeys[node].x, resolverPubKeys[node].y);\\n  }\\n}\\n\",\"keccak256\":\"0x763a3403ded734b7fa9141c270a0aaaf4a3f1322ff4b197e51ed70adfbaf1fa1\",\"license\":\"MIT\"},\"src/ens/resolvers/ENSTextResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"./ENSAbstractResolver.sol\\\";\\n\\n\\n/**\\n * @title ENS abstract text resolver\\n *\\n * @dev Base on https://github.com/ensdomains/resolvers/blob/f7d62ab04bfe1692a4344f6f1d31ff81315a98c3/contracts/profiles/TextResolver.sol\\n */\\nabstract contract ENSTextResolver is ENSAbstractResolver {\\n  bytes4 internal constant INTERFACE_TEXT_ID = bytes4(keccak256(abi.encodePacked(\\\"text(bytes32,string)\\\")));\\n\\n  mapping(bytes32 => mapping(string => string)) internal resolverTexts;\\n\\n  // events\\n\\n  event TextChanged(\\n    bytes32 indexed node,\\n    string indexed indexedKey,\\n    string key\\n  );\\n\\n  // external functions (views)\\n\\n  function setText(\\n    bytes32 node,\\n    string calldata key,\\n    string calldata value\\n  )\\n    external\\n    onlyNodeOwner(node)\\n  {\\n    resolverTexts[node][key] = value;\\n\\n    emit TextChanged(node, key, key);\\n  }\\n\\n  // external functions (views)\\n\\n  function text(\\n    bytes32 node,\\n    string calldata key\\n  )\\n    external\\n    view\\n    returns (string memory)\\n  {\\n    return resolverTexts[node][key];\\n  }\\n}\\n\",\"keccak256\":\"0x6d13447ff9aa753320b3a93ba0b8a2cbb43385711d51e00809cfb9201136cff7\",\"license\":\"MIT\"},\"src/gateway/GatewayRecipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../common/libs/BytesLib.sol\\\";\\n\\n\\n/**\\n * @title Gateway recipient\\n *\\n * @notice Gateway target contract\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski <stan@pillarproject.io>\\n */\\ncontract GatewayRecipient {\\n  using BytesLib for bytes;\\n\\n  address public gateway;\\n\\n  /**\\n   * @dev internal constructor\\n   */\\n  constructor() internal {}\\n\\n  // internal functions\\n\\n  /**\\n   * @notice Initializes `GatewayRecipient` contract\\n   * @param gateway_ `Gateway` contract address\\n   */\\n  function _initializeGatewayRecipient(\\n    address gateway_\\n  )\\n    internal\\n  {\\n    gateway = gateway_;\\n  }\\n\\n  // internal functions (views)\\n\\n  /**\\n   * @notice Gets gateway context account\\n   * @return context account address\\n   */\\n  function _getContextAccount()\\n    internal\\n    view\\n    returns (address)\\n  {\\n    return _getContextAddress(40);\\n  }\\n\\n  /**\\n   * @notice Gets gateway context sender\\n   * @return context sender address\\n   */\\n  function _getContextSender()\\n    internal\\n    view\\n    returns (address)\\n  {\\n    return _getContextAddress(20);\\n  }\\n\\n  /**\\n   * @notice Gets gateway context data\\n   * @return context data\\n   */\\n  function _getContextData()\\n    internal\\n    view\\n    returns (bytes calldata)\\n  {\\n    bytes calldata result;\\n\\n    if (_isGatewaySender()) {\\n      result = msg.data[:msg.data.length - 40];\\n    } else {\\n      result = msg.data;\\n    }\\n\\n    return result;\\n  }\\n\\n  // private functions (views)\\n\\n  function _getContextAddress(\\n    uint256 offset\\n  )\\n    private\\n    view\\n    returns (address)\\n  {\\n    address result = address(0);\\n\\n    if (_isGatewaySender()) {\\n      uint from = msg.data.length - offset;\\n      result = bytes(msg.data[from:from + 20]).toAddress();\\n    } else {\\n      result = msg.sender;\\n    }\\n\\n    return result;\\n  }\\n\\n  function _isGatewaySender()\\n    private\\n    view\\n    returns (bool)\\n  {\\n    bool result;\\n\\n    if (msg.sender == gateway) {\\n      require(\\n        msg.data.length >= 44,\\n        \\\"GatewayRecipient: invalid msg.data\\\"\\n      );\\n\\n      result = true;\\n    }\\n\\n    return result;\\n  }\\n}\\n\",\"keccak256\":\"0xe3fd29479d748d67360c61a9cbaafc66eaca25f476e59a45e842472bcf5233fc\",\"license\":\"MIT\"}},\"version\":1}",
  "bytecode": "0x608060405234801561001057600080fd5b5032600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600046905080600281905550506149798061006e6000396000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c806371404156116100f9578063a91ee0dc11610097578063d0f710d611610071578063d0f710d614610512578063d5fa2b0014610542578063dc5b68a61461055e578063f1cb7e061461057a576101c4565b8063a91ee0dc146104a9578063c8690233146104c5578063c8cc2aee146104f6576101c4565b80637d0e0e7e116100d35780637d0e0e7e146104375780638b95dd71146104535780639a8a05921461046f578063a526d83b1461048d576101c4565b806371404156146103e157806377372213146103fd5780637b10399914610419576101c4565b8063392e53cd1161016657806355800f871161014057806355800f871461033557806359d1d43c14610351578063691f3431146103815780636df0cf42146103b1576101c4565b8063392e53cd146102cb5780633b3b57de146102e957806346386f7314610319576101c4565b8063116191b6116101a2578063116191b6146102455780631b3cd1421461026357806329ae6a7e1461029357806329cd62ea146102af576101c4565b806301ffc9a7146101c95780630c68ba21146101f957806310f13a8c14610229575b600080fd5b6101e360048036038101906101de91906133b4565b6105aa565b6040516101f091906141bc565b60405180910390f35b610213600480360381019061020e9190613066565b610834565b60405161022091906141bc565b60405180910390f35b610243600480360381019061023e9190613288565b610889565b005b61024d61096d565b60405161025a919061415d565b60405180910390f35b61027d600480360381019061027891906130b8565b610993565b60405161028a919061415d565b60405180910390f35b6102ad60048036038101906102a891906130b8565b6109c6565b005b6102c960048036038101906102c4919061311d565b610beb565b005b6102d3610cb3565b6040516102e091906141bc565b60405180910390f35b61030360048036038101906102fe91906130b8565b610d0b565b604051610310919061415d565b60405180910390f35b610333600480360381019061032e919061316c565b610d1d565b005b61034f600480360381019061034a91906130b8565b611017565b005b61036b60048036038101906103669190613230565b6112d8565b604051610378919061433d565b60405180910390f35b61039b600480360381019061039691906130b8565b6113ad565b6040516103a8919061433d565b60405180910390f35b6103cb60048036038101906103c69190613472565b611462565b6040516103d891906141d7565b60405180910390f35b6103fb60048036038101906103f69190613066565b611482565b005b61041760048036038101906104129190613230565b61169a565b005b610421611746565b60405161042e91906142fe565b60405180910390f35b610451600480360381019061044c91906130b8565b61176c565b005b61046d6004803603810190610468919061334d565b611a38565b005b610477611a92565b604051610484919061461f565b60405180910390f35b6104a760048036038101906104a29190613066565b611a98565b005b6104c360048036038101906104be91906133dd565b611b2f565b005b6104df60048036038101906104da91906130b8565b611d58565b6040516104ed92919061421b565b60405180910390f35b610510600480360381019061050b91906130b8565b611d92565b005b61052c600480360381019061052791906131d8565b6120a2565b60405161053991906141bc565b60405180910390f35b61055c600480360381019061055791906130e1565b6120fb565b005b61057860048036038101906105739190613406565b612153565b005b610594600480360381019061058f9190613311565b612366565b6040516105a191906142dc565b60405180910390f35b60006040516020016105bb9061406f565b604051602081830303815290604052805190602001207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061067d5750604051602001610626906140aa565b604051602081830303815290604052805190602001207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806106e95750604051602001610692906140fe565b604051602081830303815290604052805190602001207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061075557506040516020016106fe906140d4565b604051602081830303815290604052805190602001207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806107c1575060405160200161076a906140e9565b604051602081830303815290604052805190602001207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061082d57506040516020016107d6906140bf565b604051602081830303815290604052805190602001207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b846108938161242d565b6108d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c9906145df565b60405180910390fd5b82826007600089815260200190815260200160002087876040516108f7929190614056565b90815260200160405180910390209190610912929190612d39565b508484604051610923929190614056565b6040518091039020867fd8c9334b1a9c2f9da342a0a2b32629c1a229b6445dad78947f674b44444a7550878760405161095d929190614319565b60405180910390a3505050505050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60096020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006109d0612516565b90503073ffffffffffffffffffffffffffffffffffffffff166109f283612527565b73ffffffffffffffffffffffffffffffffffffffff1614610a48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a3f9061443f565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166009600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610ae9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae09061437f565b60405180910390fd5b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635b0fc9c383836040518363ffffffff1660e01b8152600401610b469291906141f2565b600060405180830381600087803b158015610b6057600080fd5b505af1158015610b74573d6000803e3d6000fd5b505050506009600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690557f7803a16d95f9ca635bdec561006625e7444d8a9f8463866643cc03af011779d38282604051610bdf9291906141f2565b60405180910390a15050565b82610bf58161242d565b610c34576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c2b906145df565b60405180910390fd5b604051806040016040528084815260200183815250600660008681526020019081526020016000206000820151816000015560208201518160010155905050837f1d6f5e03d3f63eb58751986629a5439baee5079ff04f345becb66e23eb154e468484604051610ca592919061421b565b60405180910390a250505050565b60008073ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614905090565b6000610d1682612527565b9050919050565b6000610d27612516565b90506000610d3682878761260c565b9050610d868185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612664565b610dc5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dbc9061439f565b60405180910390fd5b60008686604051602001610dda92919061402a565b6040516020818303038152906040528051906020012090503073ffffffffffffffffffffffffffffffffffffffff16610e1288612527565b73ffffffffffffffffffffffffffffffffffffffff1614610e68576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5f9061441f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16610e8982612527565b73ffffffffffffffffffffffffffffffffffffffff1614610edf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ed6906143bf565b60405180910390fd5b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635ef2c7f08888303060006040518663ffffffff1660e01b8152600401610f43959493929190614244565b600060405180830381600087803b158015610f5d57600080fd5b505af1158015610f71573d6000803e3d6000fd5b50505050600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635b0fc9c382856040518363ffffffff1660e01b8152600401610fd29291906141f2565b600060405180830381600087803b158015610fec57600080fd5b505af1158015611000573d6000803e3d6000fd5b5050505061100e81846126d1565b50505050505050565b6000611021612516565b9050600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3836040518263ffffffff1660e01b815260040161107e91906141d7565b60206040518083038186803b15801561109657600080fd5b505afa1580156110aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ce919061308f565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461113b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111329061447f565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630178b8bf846040518263ffffffff1660e01b81526004016111ad91906141d7565b60206040518083038186803b1580156111c557600080fd5b505afa1580156111d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fd919061308f565b73ffffffffffffffffffffffffffffffffffffffff1614611253576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124a9061435f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1661127483612527565b73ffffffffffffffffffffffffffffffffffffffff16146112ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112c19061451f565b60405180910390fd5b6112d482826126d1565b5050565b60606007600085815260200190815260200160002083836040516112fd929190614056565b90815260200160405180910390208054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561139f5780601f106113745761010080835404028352916020019161139f565b820191906000526020600020905b81548152906001019060200180831161138257829003601f168201915b505050505090509392505050565b6060600560008381526020019081526020016000208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156114565780601f1061142b57610100808354040283529160200191611456565b820191906000526020600020905b81548152906001019060200180831161143957829003601f168201915b50505050509050919050565b600061147b82600001518360200151846040015161260c565b9050919050565b6000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661150d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115049061449f565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff16141561157c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115739061459f565b60405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611607576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115fe9061453f565b60405180910390fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fee943cdb81826d5909c559c6b1ae6908fcaf2dbc16c4b730346736b486283e8b328260405161168f929190614193565b60405180910390a150565b826116a48161242d565b6116e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116da906145df565b60405180910390fd5b8282600560008781526020019081526020016000209190611705929190612d39565b50837fb7d29e911041e8d9b843369e890bcb72c9388692ba48b65ac54e7214c4c348f78484604051611738929190614319565b60405180910390a250505050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611776612516565b9050600073ffffffffffffffffffffffffffffffffffffffff1661179983612527565b73ffffffffffffffffffffffffffffffffffffffff16146117ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117e6906144ff565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166009600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611891576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611888906144df565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3846040518263ffffffff1660e01b815260040161190391906141d7565b60206040518083038186803b15801561191b57600080fd5b505afa15801561192f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611953919061308f565b73ffffffffffffffffffffffffffffffffffffffff16146119a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a09061455f565b60405180910390fd5b806009600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fc1e082a8c26f27c26e1bf5d0ce7ddd579ec7f6d7eb3ea90d8abd6c40991bae368282604051611a2c9291906141f2565b60405180910390a15050565b82611a428161242d565b611a81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a78906145df565b60405180910390fd5b611a8c8484846126e9565b50505050565b60025481565b6000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b1a9061449f565b60405180910390fd5b611b2c816127ab565b50565b6000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611bba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bb19061449f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611c2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c21906144bf565b60405180910390fd5b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611cbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cb2906145ff565b60405180910390fd5b80600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fdb0239c63d4033dcdd21bd44f8dd479a03efbae12f6bbe27c0a5f923d26514cc600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051611d4d919061415d565b60405180910390a150565b6000806006600084815260200190815260200160002060000154600660008581526020019081526020016000206001015491509150915091565b6000611d9c612516565b9050600073ffffffffffffffffffffffffffffffffffffffff16611dbf83612527565b73ffffffffffffffffffffffffffffffffffffffff1614611e15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e0c906144ff565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166009600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611eb6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ead9061437f565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3846040518263ffffffff1660e01b8152600401611f2891906141d7565b60206040518083038186803b158015611f4057600080fd5b505afa158015611f54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f78919061308f565b73ffffffffffffffffffffffffffffffffffffffff1614611fce576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fc59061455f565b60405180910390fd5b611fd882306126d1565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631896f70a83306040518363ffffffff1660e01b81526004016120359291906141f2565b600060405180830381600087803b15801561204f57600080fd5b505af1158015612063573d6000803e3d6000fd5b505050507fcefbe9dbadcf675eef14e23810996ff38541fc26b4dd77cd6724b0eedc96f2008260405161209691906141d7565b60405180910390a15050565b60006120f28484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612664565b90509392505050565b816121058161242d565b612144576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161213b906145df565b60405180910390fd5b61214e83836126d1565b505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff16146121e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121da906143ff565b60405180910390fd5b6000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415612295576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161228c906144bf565b60405180910390fd5b83600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550612320838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505061293a565b61232981612992565b7f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e6326040516123589190614178565b60405180910390a150505050565b60606004600084815260200190815260200160002060008381526020019081526020016000208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156124205780601f106123f557610100808354040283529160200191612420565b820191906000526020600020905b81548152906001019060200180831161240357829003601f168201915b5050505050905092915050565b6000612437612516565b73ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3846040518263ffffffff1660e01b81526004016124a891906141d7565b60206040518083038186803b1580156124c057600080fd5b505afa1580156124d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f8919061308f565b73ffffffffffffffffffffffffffffffffffffffff16149050919050565b600061252260286129d6565b905090565b6000806060600460008581526020019081526020016000206000603c81526020019081526020016000208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156125e55780601f106125ba576101008083540402835291602001916125e5565b820191906000526020600020905b8154815290600101906020018083116125c857829003601f168201915b50505050509050600081511115612602576125ff81612a6b565b91505b8192505050919050565b600061265b7f621363c539a3aa1024c8837ca1dc095db03b7f9512b3a95ecb429aae7fd953ed85858560405160200161264793929190613fed565b604051602081830303815290604052612a93565b90509392505050565b60008061267a8385612ad490919063ffffffff16565b90506000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1691505092915050565b6126e582603c6126e084612b8f565b6126e9565b5050565b827f65412581168e88a1e60c6459d7f44ae83ad0832e670826c05a4e2476b57af752838360405161271b92919061463a565b60405180910390a2603c82141561276d57827f52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd261275783612a6b565b6040516127649190614178565b60405180910390a25b8060046000858152602001908152602001600020600084815260200190815260200160002090805190602001906127a5929190612db9565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561281b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612812906143df565b60405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156128a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161289e9061457f565b60405180910390fd5b60016000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fbc3292102fa77e083913064b282926717cdfaede4d35f553d66366c0a3da755a328260405161292f929190614193565b60405180910390a150565b6000815114156129525761294d326127ab565b61298f565b60008151905060005b8181101561298c5761297f83828151811061297257fe5b60200260200101516127ab565b808060010191505061295b565b50505b50565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600090506129e5612bf6565b15612a5e576000836000369050039050612a5660003683906014850192612a0e93929190614711565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612ca3565b915050612a62565b3390505b80915050919050565b6000806014835114612a7c57600080fd5b600c6101000a602084015104905080915050919050565b6000612acc600254308585604051602001612ab19493929190614113565b60405160208183030381529060405280519060200120612d09565b905092915050565b60008060009050604183511415612b855760008060006020860151925060408601519150606086015160001a9050601b8160ff161015612b1557601b810190505b601b8160ff161480612b2a5750601c8160ff16145b15612b815760018782858560405160008152602001604052604051612b529493929190614297565b6020604051602081039080840390855afa158015612b74573d6000803e3d6000fd5b5050506020604051035193505b5050505b8091505092915050565b606080601467ffffffffffffffff81118015612baa57600080fd5b506040519080825280601f01601f191660200182016040528015612bdd5781602001600182028036833780820191505090505b509050600c6101000a8302602082015280915050919050565b600080600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415612c9c57602c60003690501015612c97576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c8e9061445f565b60405180910390fd5b600190505b8091505090565b6000806014835114612cea576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ce1906145bf565b60405180910390fd5b6c01000000000000000000000000602084015104905080915050919050565b600081604051602001612d1c9190614084565b604051602081830303815290604052805190602001209050919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10612d7a57803560ff1916838001178555612da8565b82800160010185558215612da8579182015b82811115612da7578235825591602001919060010190612d8c565b5b509050612db59190612e39565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10612dfa57805160ff1916838001178555612e28565b82800160010185558215612e28579182015b82811115612e27578251825591602001919060010190612e0c565b5b509050612e359190612e39565b5090565b5b80821115612e52576000816000905550600101612e3a565b5090565b600081359050612e65816148f9565b92915050565b600081519050612e7a816148f9565b92915050565b60008083601f840112612e9257600080fd5b8235905067ffffffffffffffff811115612eab57600080fd5b602083019150836020820283011115612ec357600080fd5b9250929050565b600081359050612ed981614910565b92915050565b600081359050612eee81614927565b92915050565b60008083601f840112612f0657600080fd5b8235905067ffffffffffffffff811115612f1f57600080fd5b602083019150836001820283011115612f3757600080fd5b9250929050565b600082601f830112612f4f57600080fd5b8135612f62612f5d82614697565b61466a565b91508082526020830160208301858383011115612f7e57600080fd5b612f89838284614861565b50505092915050565b600081359050612fa18161493e565b92915050565b60008083601f840112612fb957600080fd5b8235905067ffffffffffffffff811115612fd257600080fd5b602083019150836001820283011115612fea57600080fd5b9250929050565b60006060828403121561300357600080fd5b61300d606061466a565b9050600061301d84828501612e56565b600083015250602061303184828501612eca565b602083015250604061304584828501612eca565b60408301525092915050565b60008135905061306081614955565b92915050565b60006020828403121561307857600080fd5b600061308684828501612e56565b91505092915050565b6000602082840312156130a157600080fd5b60006130af84828501612e6b565b91505092915050565b6000602082840312156130ca57600080fd5b60006130d884828501612eca565b91505092915050565b600080604083850312156130f457600080fd5b600061310285828601612eca565b925050602061311385828601612e56565b9150509250929050565b60008060006060848603121561313257600080fd5b600061314086828701612eca565b935050602061315186828701612eca565b925050604061316286828701612eca565b9150509250925092565b6000806000806060858703121561318257600080fd5b600061319087828801612eca565b94505060206131a187828801612eca565b935050604085013567ffffffffffffffff8111156131be57600080fd5b6131ca87828801612ef4565b925092505092959194509250565b6000806000604084860312156131ed57600080fd5b60006131fb86828701612eca565b935050602084013567ffffffffffffffff81111561321857600080fd5b61322486828701612ef4565b92509250509250925092565b60008060006040848603121561324557600080fd5b600061325386828701612eca565b935050602084013567ffffffffffffffff81111561327057600080fd5b61327c86828701612fa7565b92509250509250925092565b6000806000806000606086880312156132a057600080fd5b60006132ae88828901612eca565b955050602086013567ffffffffffffffff8111156132cb57600080fd5b6132d788828901612fa7565b9450945050604086013567ffffffffffffffff8111156132f657600080fd5b61330288828901612fa7565b92509250509295509295909350565b6000806040838503121561332457600080fd5b600061333285828601612eca565b925050602061334385828601613051565b9150509250929050565b60008060006060848603121561336257600080fd5b600061337086828701612eca565b935050602061338186828701613051565b925050604084013567ffffffffffffffff81111561339e57600080fd5b6133aa86828701612f3e565b9150509250925092565b6000602082840312156133c657600080fd5b60006133d484828501612edf565b91505092915050565b6000602082840312156133ef57600080fd5b60006133fd84828501612f92565b91505092915050565b6000806000806060858703121561341c57600080fd5b600061342a87828801612f92565b945050602085013567ffffffffffffffff81111561344757600080fd5b61345387828801612e80565b9350935050604061346687828801612e56565b91505092959194509250565b60006060828403121561348457600080fd5b600061349284828501612ff1565b91505092915050565b6134a4816147f5565b82525050565b6134b381614744565b82525050565b6134ca6134c582614744565b6148a3565b82525050565b6134d981614756565b82525050565b6134e881614762565b82525050565b6134ff6134fa82614762565b6148b5565b82525050565b6000613510826146c3565b61351a81856146d9565b935061352a818560208601614870565b613533816148db565b840191505092915050565b6000613549826146c3565b61355381856146ea565b9350613563818560208601614870565b80840191505092915050565b61357881614807565b82525050565b6135878161482b565b82525050565b600061359983856146f5565b93506135a6838584614861565b6135af836148db565b840190509392505050565b60006135c68385614706565b93506135d3838584614861565b82840190509392505050565b60006135ea826146ce565b6135f481856146f5565b9350613604818560208601614870565b61360d816148db565b840191505092915050565b6000613625601983614706565b91507f737570706f727473496e746572666163652862797465733429000000000000006000830152601982019050919050565b60006136656024836146f5565b91507f454e53436f6e74726f6c6c65723a20696e76616c6964206e6f6465207265736f60008301527f6c766572000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006136cb6021836146f5565b91507f454e53436f6e74726f6c6c65723a20696e76616c6964206e6f6465206f776e6560008301527f72000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006137316029836146f5565b91507f454e53436f6e74726f6c6c65723a20696e76616c696420677561726469616e2060008301527f7369676e617475726500000000000000000000000000000000000000000000006020830152604082019050919050565b60006137976022836146f5565b91507f454e53436f6e74726f6c6c65723a206c6162656c20616c72656164792074616b60008301527f656e0000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006137fd601c83614706565b91507f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000830152601c82019050919050565b600061383d6020836146f5565b91507f477561726465643a2063616e6e6f74206164642030783020677561726469616e6000830152602082019050919050565b600061387d602f836146f5565b91507f496e697469616c697a61626c653a2074782e6f726967696e206973206e6f742060008301527f74686520696e697469616c697a657200000000000000000000000000000000006020830152604082019050919050565b60006138e3600d83614706565b91507f61646472286279746573333229000000000000000000000000000000000000006000830152600d82019050919050565b6000613923601b836146f5565b91507f454e53436f6e74726f6c6c65723a20696e76616c6964206e6f646500000000006000830152602082019050919050565b60006139636021836146f5565b91507f454e53436f6e74726f6c6c65723a206e6f646520646f65736e2774206578697360008301527f74000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006139c96022836146f5565b91507f47617465776179526563697069656e743a20696e76616c6964206d73672e646160008301527f74610000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613a2f601483614706565b91507f7465787428627974657333322c737472696e67290000000000000000000000006000830152601482019050919050565b6000613a6f600d83614706565b91507f6e616d65286279746573333229000000000000000000000000000000000000006000830152600d82019050919050565b6000613aaf602b836146f5565b91507f454e53436f6e74726f6c6c65723a2063616c6c6572206973206e6f742074686560008301527f206e6f6465206f776e65720000000000000000000000000000000000000000006020830152604082019050919050565b6000613b156026836146f5565b91507f477561726465643a2074782e6f726967696e206973206e6f742074686520677560008301527f61726469616e00000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613b7b6026836146f5565b91507f454e53436f6e74726f6c6c65723a2063616e6e6f74207365742030783020726560008301527f67697374727900000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613be16025836146f5565b91507f454e53436f6e74726f6c6c65723a206e6f646520616c7265616479207375626d60008301527f69747465640000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613c47600f83614706565b91507f7075626b657928627974657333322900000000000000000000000000000000006000830152600f82019050919050565b6000613c876022836146f5565b91507f454e53436f6e74726f6c6c65723a206e6f646520616c7265616479206578697360008301527f74730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613ced6023836146f5565b91507f454e53436f6e74726f6c6c65723a206e6f646520616c726561647920696e207360008301527f796e6300000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613d53601f836146f5565b91507f477561726465643a20677561726469616e20646f65736e2774206578697374006000830152602082019050919050565b6000613d936025836146f5565b91507f454e53436f6e74726f6c6c65723a20696e76616c696420656e73206e6f64652060008301527f6f776e65720000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613df96020836146f5565b91507f477561726465643a20677561726469616e20616c7265616479206578697374736000830152602082019050919050565b6000613e39601b836146f5565b91507f477561726465643a2063616e6e6f742072656d6f76652073656c6600000000006000830152602082019050919050565b6000613e79601d836146f5565b91507f42797465734c69623a20696e76616c69642064617461206c656e6774680000006000830152602082019050919050565b6000613eb96037836146f5565b91507f454e5341627374726163745265736f6c7665723a20726576657274656420627960008301527f206f6e6c794e6f64654f776e6572206d6f6469666965720000000000000000006020830152604082019050919050565b6000613f1f601283614706565b91507f6164647228627974657333322c75696e742900000000000000000000000000006000830152601282019050919050565b6000613f5f6023836146f5565b91507f454e53436f6e74726f6c6c65723a20726567697374727920616c72656164792060008301527f73657400000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b613fc1816147ca565b82525050565b613fd8613fd3826147ca565b6148d1565b82525050565b613fe7816147e8565b82525050565b6000613ff982866134b9565b60148201915061400982856134ee565b60208201915061401982846134ee565b602082019150819050949350505050565b600061403682856134ee565b60208201915061404682846134ee565b6020820191508190509392505050565b60006140638284866135ba565b91508190509392505050565b600061407a82613618565b9150819050919050565b600061408f826137f0565b915061409b82846134ee565b60208201915081905092915050565b60006140b5826138d6565b9150819050919050565b60006140ca82613a22565b9150819050919050565b60006140df82613a62565b9150819050919050565b60006140f482613c3a565b9150819050919050565b600061410982613f12565b9150819050919050565b600061411f8287613fc7565b60208201915061412f82866134b9565b60148201915061413f82856134ee565b60208201915061414f828461353e565b915081905095945050505050565b600060208201905061417260008301846134aa565b92915050565b600060208201905061418d600083018461349b565b92915050565b60006040820190506141a8600083018561349b565b6141b560208301846134aa565b9392505050565b60006020820190506141d160008301846134d0565b92915050565b60006020820190506141ec60008301846134df565b92915050565b600060408201905061420760008301856134df565b61421460208301846134aa565b9392505050565b600060408201905061423060008301856134df565b61423d60208301846134df565b9392505050565b600060a08201905061425960008301886134df565b61426660208301876134df565b61427360408301866134aa565b61428060608301856134aa565b61428d608083018461357e565b9695505050505050565b60006080820190506142ac60008301876134df565b6142b96020830186613fde565b6142c660408301856134df565b6142d360608301846134df565b95945050505050565b600060208201905081810360008301526142f68184613505565b905092915050565b6000602082019050614313600083018461356f565b92915050565b6000602082019050818103600083015261433481848661358d565b90509392505050565b6000602082019050818103600083015261435781846135df565b905092915050565b6000602082019050818103600083015261437881613658565b9050919050565b60006020820190508181036000830152614398816136be565b9050919050565b600060208201905081810360008301526143b881613724565b9050919050565b600060208201905081810360008301526143d88161378a565b9050919050565b600060208201905081810360008301526143f881613830565b9050919050565b6000602082019050818103600083015261441881613870565b9050919050565b6000602082019050818103600083015261443881613916565b9050919050565b6000602082019050818103600083015261445881613956565b9050919050565b60006020820190508181036000830152614478816139bc565b9050919050565b6000602082019050818103600083015261449881613aa2565b9050919050565b600060208201905081810360008301526144b881613b08565b9050919050565b600060208201905081810360008301526144d881613b6e565b9050919050565b600060208201905081810360008301526144f881613bd4565b9050919050565b6000602082019050818103600083015261451881613c7a565b9050919050565b6000602082019050818103600083015261453881613ce0565b9050919050565b6000602082019050818103600083015261455881613d46565b9050919050565b6000602082019050818103600083015261457881613d86565b9050919050565b6000602082019050818103600083015261459881613dec565b9050919050565b600060208201905081810360008301526145b881613e2c565b9050919050565b600060208201905081810360008301526145d881613e6c565b9050919050565b600060208201905081810360008301526145f881613eac565b9050919050565b6000602082019050818103600083015261461881613f52565b9050919050565b60006020820190506146346000830184613fb8565b92915050565b600060408201905061464f6000830185613fb8565b81810360208301526146618184613505565b90509392505050565b6000604051905081810181811067ffffffffffffffff8211171561468d57600080fd5b8060405250919050565b600067ffffffffffffffff8211156146ae57600080fd5b601f19601f8301169050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000808585111561472157600080fd5b8386111561472e57600080fd5b6001850283019150848603905094509492505050565b600061474f826147aa565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006147a382614744565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600067ffffffffffffffff82169050919050565b600060ff82169050919050565b60006148008261483d565b9050919050565b600061481282614819565b9050919050565b6000614824826147aa565b9050919050565b6000614836826147d4565b9050919050565b60006148488261484f565b9050919050565b600061485a826147aa565b9050919050565b82818337600083830152505050565b60005b8381101561488e578082015181840152602081019050614873565b8381111561489d576000848401525b50505050565b60006148ae826148bf565b9050919050565b6000819050919050565b60006148ca826148ec565b9050919050565b6000819050919050565b6000601f19601f8301169050919050565b60008160601b9050919050565b61490281614744565b811461490d57600080fd5b50565b61491981614762565b811461492457600080fd5b50565b6149308161476c565b811461493b57600080fd5b50565b61494781614798565b811461495257600080fd5b50565b61495e816147ca565b811461496957600080fd5b5056fea164736f6c634300060c000a",
  "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101c45760003560e01c806371404156116100f9578063a91ee0dc11610097578063d0f710d611610071578063d0f710d614610512578063d5fa2b0014610542578063dc5b68a61461055e578063f1cb7e061461057a576101c4565b8063a91ee0dc146104a9578063c8690233146104c5578063c8cc2aee146104f6576101c4565b80637d0e0e7e116100d35780637d0e0e7e146104375780638b95dd71146104535780639a8a05921461046f578063a526d83b1461048d576101c4565b806371404156146103e157806377372213146103fd5780637b10399914610419576101c4565b8063392e53cd1161016657806355800f871161014057806355800f871461033557806359d1d43c14610351578063691f3431146103815780636df0cf42146103b1576101c4565b8063392e53cd146102cb5780633b3b57de146102e957806346386f7314610319576101c4565b8063116191b6116101a2578063116191b6146102455780631b3cd1421461026357806329ae6a7e1461029357806329cd62ea146102af576101c4565b806301ffc9a7146101c95780630c68ba21146101f957806310f13a8c14610229575b600080fd5b6101e360048036038101906101de91906133b4565b6105aa565b6040516101f091906141bc565b60405180910390f35b610213600480360381019061020e9190613066565b610834565b60405161022091906141bc565b60405180910390f35b610243600480360381019061023e9190613288565b610889565b005b61024d61096d565b60405161025a919061415d565b60405180910390f35b61027d600480360381019061027891906130b8565b610993565b60405161028a919061415d565b60405180910390f35b6102ad60048036038101906102a891906130b8565b6109c6565b005b6102c960048036038101906102c4919061311d565b610beb565b005b6102d3610cb3565b6040516102e091906141bc565b60405180910390f35b61030360048036038101906102fe91906130b8565b610d0b565b604051610310919061415d565b60405180910390f35b610333600480360381019061032e919061316c565b610d1d565b005b61034f600480360381019061034a91906130b8565b611017565b005b61036b60048036038101906103669190613230565b6112d8565b604051610378919061433d565b60405180910390f35b61039b600480360381019061039691906130b8565b6113ad565b6040516103a8919061433d565b60405180910390f35b6103cb60048036038101906103c69190613472565b611462565b6040516103d891906141d7565b60405180910390f35b6103fb60048036038101906103f69190613066565b611482565b005b61041760048036038101906104129190613230565b61169a565b005b610421611746565b60405161042e91906142fe565b60405180910390f35b610451600480360381019061044c91906130b8565b61176c565b005b61046d6004803603810190610468919061334d565b611a38565b005b610477611a92565b604051610484919061461f565b60405180910390f35b6104a760048036038101906104a29190613066565b611a98565b005b6104c360048036038101906104be91906133dd565b611b2f565b005b6104df60048036038101906104da91906130b8565b611d58565b6040516104ed92919061421b565b60405180910390f35b610510600480360381019061050b91906130b8565b611d92565b005b61052c600480360381019061052791906131d8565b6120a2565b60405161053991906141bc565b60405180910390f35b61055c600480360381019061055791906130e1565b6120fb565b005b61057860048036038101906105739190613406565b612153565b005b610594600480360381019061058f9190613311565b612366565b6040516105a191906142dc565b60405180910390f35b60006040516020016105bb9061406f565b604051602081830303815290604052805190602001207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061067d5750604051602001610626906140aa565b604051602081830303815290604052805190602001207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806106e95750604051602001610692906140fe565b604051602081830303815290604052805190602001207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061075557506040516020016106fe906140d4565b604051602081830303815290604052805190602001207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806107c1575060405160200161076a906140e9565b604051602081830303815290604052805190602001207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061082d57506040516020016107d6906140bf565b604051602081830303815290604052805190602001207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b846108938161242d565b6108d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c9906145df565b60405180910390fd5b82826007600089815260200190815260200160002087876040516108f7929190614056565b90815260200160405180910390209190610912929190612d39565b508484604051610923929190614056565b6040518091039020867fd8c9334b1a9c2f9da342a0a2b32629c1a229b6445dad78947f674b44444a7550878760405161095d929190614319565b60405180910390a3505050505050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60096020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006109d0612516565b90503073ffffffffffffffffffffffffffffffffffffffff166109f283612527565b73ffffffffffffffffffffffffffffffffffffffff1614610a48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a3f9061443f565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166009600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610ae9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae09061437f565b60405180910390fd5b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635b0fc9c383836040518363ffffffff1660e01b8152600401610b469291906141f2565b600060405180830381600087803b158015610b6057600080fd5b505af1158015610b74573d6000803e3d6000fd5b505050506009600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690557f7803a16d95f9ca635bdec561006625e7444d8a9f8463866643cc03af011779d38282604051610bdf9291906141f2565b60405180910390a15050565b82610bf58161242d565b610c34576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c2b906145df565b60405180910390fd5b604051806040016040528084815260200183815250600660008681526020019081526020016000206000820151816000015560208201518160010155905050837f1d6f5e03d3f63eb58751986629a5439baee5079ff04f345becb66e23eb154e468484604051610ca592919061421b565b60405180910390a250505050565b60008073ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614905090565b6000610d1682612527565b9050919050565b6000610d27612516565b90506000610d3682878761260c565b9050610d868185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612664565b610dc5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dbc9061439f565b60405180910390fd5b60008686604051602001610dda92919061402a565b6040516020818303038152906040528051906020012090503073ffffffffffffffffffffffffffffffffffffffff16610e1288612527565b73ffffffffffffffffffffffffffffffffffffffff1614610e68576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5f9061441f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16610e8982612527565b73ffffffffffffffffffffffffffffffffffffffff1614610edf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ed6906143bf565b60405180910390fd5b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635ef2c7f08888303060006040518663ffffffff1660e01b8152600401610f43959493929190614244565b600060405180830381600087803b158015610f5d57600080fd5b505af1158015610f71573d6000803e3d6000fd5b50505050600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635b0fc9c382856040518363ffffffff1660e01b8152600401610fd29291906141f2565b600060405180830381600087803b158015610fec57600080fd5b505af1158015611000573d6000803e3d6000fd5b5050505061100e81846126d1565b50505050505050565b6000611021612516565b9050600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3836040518263ffffffff1660e01b815260040161107e91906141d7565b60206040518083038186803b15801561109657600080fd5b505afa1580156110aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ce919061308f565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461113b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111329061447f565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630178b8bf846040518263ffffffff1660e01b81526004016111ad91906141d7565b60206040518083038186803b1580156111c557600080fd5b505afa1580156111d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fd919061308f565b73ffffffffffffffffffffffffffffffffffffffff1614611253576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124a9061435f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1661127483612527565b73ffffffffffffffffffffffffffffffffffffffff16146112ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112c19061451f565b60405180910390fd5b6112d482826126d1565b5050565b60606007600085815260200190815260200160002083836040516112fd929190614056565b90815260200160405180910390208054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561139f5780601f106113745761010080835404028352916020019161139f565b820191906000526020600020905b81548152906001019060200180831161138257829003601f168201915b505050505090509392505050565b6060600560008381526020019081526020016000208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156114565780601f1061142b57610100808354040283529160200191611456565b820191906000526020600020905b81548152906001019060200180831161143957829003601f168201915b50505050509050919050565b600061147b82600001518360200151846040015161260c565b9050919050565b6000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661150d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115049061449f565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff16141561157c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115739061459f565b60405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611607576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115fe9061453f565b60405180910390fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fee943cdb81826d5909c559c6b1ae6908fcaf2dbc16c4b730346736b486283e8b328260405161168f929190614193565b60405180910390a150565b826116a48161242d565b6116e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116da906145df565b60405180910390fd5b8282600560008781526020019081526020016000209190611705929190612d39565b50837fb7d29e911041e8d9b843369e890bcb72c9388692ba48b65ac54e7214c4c348f78484604051611738929190614319565b60405180910390a250505050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611776612516565b9050600073ffffffffffffffffffffffffffffffffffffffff1661179983612527565b73ffffffffffffffffffffffffffffffffffffffff16146117ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117e6906144ff565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166009600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611891576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611888906144df565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3846040518263ffffffff1660e01b815260040161190391906141d7565b60206040518083038186803b15801561191b57600080fd5b505afa15801561192f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611953919061308f565b73ffffffffffffffffffffffffffffffffffffffff16146119a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a09061455f565b60405180910390fd5b806009600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fc1e082a8c26f27c26e1bf5d0ce7ddd579ec7f6d7eb3ea90d8abd6c40991bae368282604051611a2c9291906141f2565b60405180910390a15050565b82611a428161242d565b611a81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a78906145df565b60405180910390fd5b611a8c8484846126e9565b50505050565b60025481565b6000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b1a9061449f565b60405180910390fd5b611b2c816127ab565b50565b6000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611bba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bb19061449f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611c2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c21906144bf565b60405180910390fd5b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611cbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cb2906145ff565b60405180910390fd5b80600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fdb0239c63d4033dcdd21bd44f8dd479a03efbae12f6bbe27c0a5f923d26514cc600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051611d4d919061415d565b60405180910390a150565b6000806006600084815260200190815260200160002060000154600660008581526020019081526020016000206001015491509150915091565b6000611d9c612516565b9050600073ffffffffffffffffffffffffffffffffffffffff16611dbf83612527565b73ffffffffffffffffffffffffffffffffffffffff1614611e15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e0c906144ff565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166009600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611eb6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ead9061437f565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3846040518263ffffffff1660e01b8152600401611f2891906141d7565b60206040518083038186803b158015611f4057600080fd5b505afa158015611f54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f78919061308f565b73ffffffffffffffffffffffffffffffffffffffff1614611fce576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fc59061455f565b60405180910390fd5b611fd882306126d1565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631896f70a83306040518363ffffffff1660e01b81526004016120359291906141f2565b600060405180830381600087803b15801561204f57600080fd5b505af1158015612063573d6000803e3d6000fd5b505050507fcefbe9dbadcf675eef14e23810996ff38541fc26b4dd77cd6724b0eedc96f2008260405161209691906141d7565b60405180910390a15050565b60006120f28484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612664565b90509392505050565b816121058161242d565b612144576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161213b906145df565b60405180910390fd5b61214e83836126d1565b505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff16146121e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121da906143ff565b60405180910390fd5b6000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415612295576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161228c906144bf565b60405180910390fd5b83600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550612320838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505061293a565b61232981612992565b7f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e6326040516123589190614178565b60405180910390a150505050565b60606004600084815260200190815260200160002060008381526020019081526020016000208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156124205780601f106123f557610100808354040283529160200191612420565b820191906000526020600020905b81548152906001019060200180831161240357829003601f168201915b5050505050905092915050565b6000612437612516565b73ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3846040518263ffffffff1660e01b81526004016124a891906141d7565b60206040518083038186803b1580156124c057600080fd5b505afa1580156124d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f8919061308f565b73ffffffffffffffffffffffffffffffffffffffff16149050919050565b600061252260286129d6565b905090565b6000806060600460008581526020019081526020016000206000603c81526020019081526020016000208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156125e55780601f106125ba576101008083540402835291602001916125e5565b820191906000526020600020905b8154815290600101906020018083116125c857829003601f168201915b50505050509050600081511115612602576125ff81612a6b565b91505b8192505050919050565b600061265b7f621363c539a3aa1024c8837ca1dc095db03b7f9512b3a95ecb429aae7fd953ed85858560405160200161264793929190613fed565b604051602081830303815290604052612a93565b90509392505050565b60008061267a8385612ad490919063ffffffff16565b90506000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1691505092915050565b6126e582603c6126e084612b8f565b6126e9565b5050565b827f65412581168e88a1e60c6459d7f44ae83ad0832e670826c05a4e2476b57af752838360405161271b92919061463a565b60405180910390a2603c82141561276d57827f52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd261275783612a6b565b6040516127649190614178565b60405180910390a25b8060046000858152602001908152602001600020600084815260200190815260200160002090805190602001906127a5929190612db9565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561281b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612812906143df565b60405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156128a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161289e9061457f565b60405180910390fd5b60016000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fbc3292102fa77e083913064b282926717cdfaede4d35f553d66366c0a3da755a328260405161292f929190614193565b60405180910390a150565b6000815114156129525761294d326127ab565b61298f565b60008151905060005b8181101561298c5761297f83828151811061297257fe5b60200260200101516127ab565b808060010191505061295b565b50505b50565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600090506129e5612bf6565b15612a5e576000836000369050039050612a5660003683906014850192612a0e93929190614711565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612ca3565b915050612a62565b3390505b80915050919050565b6000806014835114612a7c57600080fd5b600c6101000a602084015104905080915050919050565b6000612acc600254308585604051602001612ab19493929190614113565b60405160208183030381529060405280519060200120612d09565b905092915050565b60008060009050604183511415612b855760008060006020860151925060408601519150606086015160001a9050601b8160ff161015612b1557601b810190505b601b8160ff161480612b2a5750601c8160ff16145b15612b815760018782858560405160008152602001604052604051612b529493929190614297565b6020604051602081039080840390855afa158015612b74573d6000803e3d6000fd5b5050506020604051035193505b5050505b8091505092915050565b606080601467ffffffffffffffff81118015612baa57600080fd5b506040519080825280601f01601f191660200182016040528015612bdd5781602001600182028036833780820191505090505b509050600c6101000a8302602082015280915050919050565b600080600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415612c9c57602c60003690501015612c97576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c8e9061445f565b60405180910390fd5b600190505b8091505090565b6000806014835114612cea576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ce1906145bf565b60405180910390fd5b6c01000000000000000000000000602084015104905080915050919050565b600081604051602001612d1c9190614084565b604051602081830303815290604052805190602001209050919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10612d7a57803560ff1916838001178555612da8565b82800160010185558215612da8579182015b82811115612da7578235825591602001919060010190612d8c565b5b509050612db59190612e39565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10612dfa57805160ff1916838001178555612e28565b82800160010185558215612e28579182015b82811115612e27578251825591602001919060010190612e0c565b5b509050612e359190612e39565b5090565b5b80821115612e52576000816000905550600101612e3a565b5090565b600081359050612e65816148f9565b92915050565b600081519050612e7a816148f9565b92915050565b60008083601f840112612e9257600080fd5b8235905067ffffffffffffffff811115612eab57600080fd5b602083019150836020820283011115612ec357600080fd5b9250929050565b600081359050612ed981614910565b92915050565b600081359050612eee81614927565b92915050565b60008083601f840112612f0657600080fd5b8235905067ffffffffffffffff811115612f1f57600080fd5b602083019150836001820283011115612f3757600080fd5b9250929050565b600082601f830112612f4f57600080fd5b8135612f62612f5d82614697565b61466a565b91508082526020830160208301858383011115612f7e57600080fd5b612f89838284614861565b50505092915050565b600081359050612fa18161493e565b92915050565b60008083601f840112612fb957600080fd5b8235905067ffffffffffffffff811115612fd257600080fd5b602083019150836001820283011115612fea57600080fd5b9250929050565b60006060828403121561300357600080fd5b61300d606061466a565b9050600061301d84828501612e56565b600083015250602061303184828501612eca565b602083015250604061304584828501612eca565b60408301525092915050565b60008135905061306081614955565b92915050565b60006020828403121561307857600080fd5b600061308684828501612e56565b91505092915050565b6000602082840312156130a157600080fd5b60006130af84828501612e6b565b91505092915050565b6000602082840312156130ca57600080fd5b60006130d884828501612eca565b91505092915050565b600080604083850312156130f457600080fd5b600061310285828601612eca565b925050602061311385828601612e56565b9150509250929050565b60008060006060848603121561313257600080fd5b600061314086828701612eca565b935050602061315186828701612eca565b925050604061316286828701612eca565b9150509250925092565b6000806000806060858703121561318257600080fd5b600061319087828801612eca565b94505060206131a187828801612eca565b935050604085013567ffffffffffffffff8111156131be57600080fd5b6131ca87828801612ef4565b925092505092959194509250565b6000806000604084860312156131ed57600080fd5b60006131fb86828701612eca565b935050602084013567ffffffffffffffff81111561321857600080fd5b61322486828701612ef4565b92509250509250925092565b60008060006040848603121561324557600080fd5b600061325386828701612eca565b935050602084013567ffffffffffffffff81111561327057600080fd5b61327c86828701612fa7565b92509250509250925092565b6000806000806000606086880312156132a057600080fd5b60006132ae88828901612eca565b955050602086013567ffffffffffffffff8111156132cb57600080fd5b6132d788828901612fa7565b9450945050604086013567ffffffffffffffff8111156132f657600080fd5b61330288828901612fa7565b92509250509295509295909350565b6000806040838503121561332457600080fd5b600061333285828601612eca565b925050602061334385828601613051565b9150509250929050565b60008060006060848603121561336257600080fd5b600061337086828701612eca565b935050602061338186828701613051565b925050604084013567ffffffffffffffff81111561339e57600080fd5b6133aa86828701612f3e565b9150509250925092565b6000602082840312156133c657600080fd5b60006133d484828501612edf565b91505092915050565b6000602082840312156133ef57600080fd5b60006133fd84828501612f92565b91505092915050565b6000806000806060858703121561341c57600080fd5b600061342a87828801612f92565b945050602085013567ffffffffffffffff81111561344757600080fd5b61345387828801612e80565b9350935050604061346687828801612e56565b91505092959194509250565b60006060828403121561348457600080fd5b600061349284828501612ff1565b91505092915050565b6134a4816147f5565b82525050565b6134b381614744565b82525050565b6134ca6134c582614744565b6148a3565b82525050565b6134d981614756565b82525050565b6134e881614762565b82525050565b6134ff6134fa82614762565b6148b5565b82525050565b6000613510826146c3565b61351a81856146d9565b935061352a818560208601614870565b613533816148db565b840191505092915050565b6000613549826146c3565b61355381856146ea565b9350613563818560208601614870565b80840191505092915050565b61357881614807565b82525050565b6135878161482b565b82525050565b600061359983856146f5565b93506135a6838584614861565b6135af836148db565b840190509392505050565b60006135c68385614706565b93506135d3838584614861565b82840190509392505050565b60006135ea826146ce565b6135f481856146f5565b9350613604818560208601614870565b61360d816148db565b840191505092915050565b6000613625601983614706565b91507f737570706f727473496e746572666163652862797465733429000000000000006000830152601982019050919050565b60006136656024836146f5565b91507f454e53436f6e74726f6c6c65723a20696e76616c6964206e6f6465207265736f60008301527f6c766572000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006136cb6021836146f5565b91507f454e53436f6e74726f6c6c65723a20696e76616c6964206e6f6465206f776e6560008301527f72000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006137316029836146f5565b91507f454e53436f6e74726f6c6c65723a20696e76616c696420677561726469616e2060008301527f7369676e617475726500000000000000000000000000000000000000000000006020830152604082019050919050565b60006137976022836146f5565b91507f454e53436f6e74726f6c6c65723a206c6162656c20616c72656164792074616b60008301527f656e0000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006137fd601c83614706565b91507f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000830152601c82019050919050565b600061383d6020836146f5565b91507f477561726465643a2063616e6e6f74206164642030783020677561726469616e6000830152602082019050919050565b600061387d602f836146f5565b91507f496e697469616c697a61626c653a2074782e6f726967696e206973206e6f742060008301527f74686520696e697469616c697a657200000000000000000000000000000000006020830152604082019050919050565b60006138e3600d83614706565b91507f61646472286279746573333229000000000000000000000000000000000000006000830152600d82019050919050565b6000613923601b836146f5565b91507f454e53436f6e74726f6c6c65723a20696e76616c6964206e6f646500000000006000830152602082019050919050565b60006139636021836146f5565b91507f454e53436f6e74726f6c6c65723a206e6f646520646f65736e2774206578697360008301527f74000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006139c96022836146f5565b91507f47617465776179526563697069656e743a20696e76616c6964206d73672e646160008301527f74610000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613a2f601483614706565b91507f7465787428627974657333322c737472696e67290000000000000000000000006000830152601482019050919050565b6000613a6f600d83614706565b91507f6e616d65286279746573333229000000000000000000000000000000000000006000830152600d82019050919050565b6000613aaf602b836146f5565b91507f454e53436f6e74726f6c6c65723a2063616c6c6572206973206e6f742074686560008301527f206e6f6465206f776e65720000000000000000000000000000000000000000006020830152604082019050919050565b6000613b156026836146f5565b91507f477561726465643a2074782e6f726967696e206973206e6f742074686520677560008301527f61726469616e00000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613b7b6026836146f5565b91507f454e53436f6e74726f6c6c65723a2063616e6e6f74207365742030783020726560008301527f67697374727900000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613be16025836146f5565b91507f454e53436f6e74726f6c6c65723a206e6f646520616c7265616479207375626d60008301527f69747465640000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613c47600f83614706565b91507f7075626b657928627974657333322900000000000000000000000000000000006000830152600f82019050919050565b6000613c876022836146f5565b91507f454e53436f6e74726f6c6c65723a206e6f646520616c7265616479206578697360008301527f74730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613ced6023836146f5565b91507f454e53436f6e74726f6c6c65723a206e6f646520616c726561647920696e207360008301527f796e6300000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613d53601f836146f5565b91507f477561726465643a20677561726469616e20646f65736e2774206578697374006000830152602082019050919050565b6000613d936025836146f5565b91507f454e53436f6e74726f6c6c65723a20696e76616c696420656e73206e6f64652060008301527f6f776e65720000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613df96020836146f5565b91507f477561726465643a20677561726469616e20616c7265616479206578697374736000830152602082019050919050565b6000613e39601b836146f5565b91507f477561726465643a2063616e6e6f742072656d6f76652073656c6600000000006000830152602082019050919050565b6000613e79601d836146f5565b91507f42797465734c69623a20696e76616c69642064617461206c656e6774680000006000830152602082019050919050565b6000613eb96037836146f5565b91507f454e5341627374726163745265736f6c7665723a20726576657274656420627960008301527f206f6e6c794e6f64654f776e6572206d6f6469666965720000000000000000006020830152604082019050919050565b6000613f1f601283614706565b91507f6164647228627974657333322c75696e742900000000000000000000000000006000830152601282019050919050565b6000613f5f6023836146f5565b91507f454e53436f6e74726f6c6c65723a20726567697374727920616c72656164792060008301527f73657400000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b613fc1816147ca565b82525050565b613fd8613fd3826147ca565b6148d1565b82525050565b613fe7816147e8565b82525050565b6000613ff982866134b9565b60148201915061400982856134ee565b60208201915061401982846134ee565b602082019150819050949350505050565b600061403682856134ee565b60208201915061404682846134ee565b6020820191508190509392505050565b60006140638284866135ba565b91508190509392505050565b600061407a82613618565b9150819050919050565b600061408f826137f0565b915061409b82846134ee565b60208201915081905092915050565b60006140b5826138d6565b9150819050919050565b60006140ca82613a22565b9150819050919050565b60006140df82613a62565b9150819050919050565b60006140f482613c3a565b9150819050919050565b600061410982613f12565b9150819050919050565b600061411f8287613fc7565b60208201915061412f82866134b9565b60148201915061413f82856134ee565b60208201915061414f828461353e565b915081905095945050505050565b600060208201905061417260008301846134aa565b92915050565b600060208201905061418d600083018461349b565b92915050565b60006040820190506141a8600083018561349b565b6141b560208301846134aa565b9392505050565b60006020820190506141d160008301846134d0565b92915050565b60006020820190506141ec60008301846134df565b92915050565b600060408201905061420760008301856134df565b61421460208301846134aa565b9392505050565b600060408201905061423060008301856134df565b61423d60208301846134df565b9392505050565b600060a08201905061425960008301886134df565b61426660208301876134df565b61427360408301866134aa565b61428060608301856134aa565b61428d608083018461357e565b9695505050505050565b60006080820190506142ac60008301876134df565b6142b96020830186613fde565b6142c660408301856134df565b6142d360608301846134df565b95945050505050565b600060208201905081810360008301526142f68184613505565b905092915050565b6000602082019050614313600083018461356f565b92915050565b6000602082019050818103600083015261433481848661358d565b90509392505050565b6000602082019050818103600083015261435781846135df565b905092915050565b6000602082019050818103600083015261437881613658565b9050919050565b60006020820190508181036000830152614398816136be565b9050919050565b600060208201905081810360008301526143b881613724565b9050919050565b600060208201905081810360008301526143d88161378a565b9050919050565b600060208201905081810360008301526143f881613830565b9050919050565b6000602082019050818103600083015261441881613870565b9050919050565b6000602082019050818103600083015261443881613916565b9050919050565b6000602082019050818103600083015261445881613956565b9050919050565b60006020820190508181036000830152614478816139bc565b9050919050565b6000602082019050818103600083015261449881613aa2565b9050919050565b600060208201905081810360008301526144b881613b08565b9050919050565b600060208201905081810360008301526144d881613b6e565b9050919050565b600060208201905081810360008301526144f881613bd4565b9050919050565b6000602082019050818103600083015261451881613c7a565b9050919050565b6000602082019050818103600083015261453881613ce0565b9050919050565b6000602082019050818103600083015261455881613d46565b9050919050565b6000602082019050818103600083015261457881613d86565b9050919050565b6000602082019050818103600083015261459881613dec565b9050919050565b600060208201905081810360008301526145b881613e2c565b9050919050565b600060208201905081810360008301526145d881613e6c565b9050919050565b600060208201905081810360008301526145f881613eac565b9050919050565b6000602082019050818103600083015261461881613f52565b9050919050565b60006020820190506146346000830184613fb8565b92915050565b600060408201905061464f6000830185613fb8565b81810360208301526146618184613505565b90509392505050565b6000604051905081810181811067ffffffffffffffff8211171561468d57600080fd5b8060405250919050565b600067ffffffffffffffff8211156146ae57600080fd5b601f19601f8301169050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000808585111561472157600080fd5b8386111561472e57600080fd5b6001850283019150848603905094509492505050565b600061474f826147aa565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006147a382614744565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600067ffffffffffffffff82169050919050565b600060ff82169050919050565b60006148008261483d565b9050919050565b600061481282614819565b9050919050565b6000614824826147aa565b9050919050565b6000614836826147d4565b9050919050565b60006148488261484f565b9050919050565b600061485a826147aa565b9050919050565b82818337600083830152505050565b60005b8381101561488e578082015181840152602081019050614873565b8381111561489d576000848401525b50505050565b60006148ae826148bf565b9050919050565b6000819050919050565b60006148ca826148ec565b9050919050565b6000819050919050565b6000601f19601f8301169050919050565b60008160601b9050919050565b61490281614744565b811461490d57600080fd5b50565b61491981614762565b811461492457600080fd5b50565b6149308161476c565b811461493b57600080fd5b50565b61494781614798565b811461495257600080fd5b50565b61495e816147ca565b811461496957600080fd5b5056fea164736f6c634300060c000a",
  "devdoc": {
    "author": "Stanisław Głogowski <stan@pillarproject.io>",
    "details": "The process of adding root node consists of 3 steps: 1. `submitNode` - should be called from ENS node owner, 2. Change ENS node owner in ENS registry to ENS controller, 3. `verifyNode` - should be called from previous ENS node owner, To register sub node, `msg.sender` need to send valid signature from one of guardian key. Once registration is complete `msg.sender` becoming both node owner and `addr` record value. After registration sub node cannot be replaced.",
    "events": {
      "NodeReleased(bytes32,address)": {
        "details": "Emitted when new node is released",
        "params": {
          "node": "node name hash",
          "owner": "owner address"
        }
      },
      "NodeSubmitted(bytes32,address)": {
        "details": "Emitted when new node is submitted",
        "params": {
          "node": "node name hash",
          "owner": "owner address"
        }
      },
      "NodeVerified(bytes32)": {
        "details": "Emitted when the existing owner is verified",
        "params": {
          "node": "node name hash"
        }
      },
      "RegistryChanged(address)": {
        "details": "Emitted when ENS registry address is changed",
        "params": {
          "registry": "registry address"
        }
      }
    },
    "kind": "dev",
    "methods": {
      "addGuardian(address)": {
        "params": {
          "guardian": "guardian address"
        }
      },
      "constructor": {
        "details": "Public constructor"
      },
      "hashSubNodeRegistration((address,bytes32,bytes32))": {
        "params": {
          "subNodeRegistration": "struct"
        },
        "returns": {
          "_0": "hash"
        }
      },
      "initialize(address,address[],address)": {
        "params": {
          "gateway_": "gateway address",
          "registry_": "ENS registry address"
        }
      },
      "isGuardian(address)": {
        "params": {
          "guardian": "guardian address"
        },
        "returns": {
          "_0": "true when guardian exists"
        }
      },
      "isInitialized()": {
        "returns": {
          "_0": "true when contract is initialized"
        }
      },
      "registerSubNode(bytes32,bytes32,bytes)": {
        "params": {
          "guardianSignature": "guardian signature",
          "label": "label hash",
          "node": "node name hash"
        }
      },
      "releaseNode(bytes32)": {
        "details": "Should be called from the previous ENS node owner",
        "params": {
          "node": "node name hash"
        }
      },
      "removeGuardian(address)": {
        "params": {
          "guardian": "guardian address"
        }
      },
      "setRegistry(address)": {
        "params": {
          "registry_": "registry address"
        }
      },
      "submitNode(bytes32)": {
        "details": "Should be called from the current ENS node owner",
        "params": {
          "node": "node name hash"
        }
      },
      "syncAddr(bytes32)": {
        "params": {
          "node": "node name hash"
        }
      },
      "verifyGuardianSignature(bytes32,bytes)": {
        "params": {
          "messageHash": "message hash",
          "signature": "signature"
        },
        "returns": {
          "_0": "true on correct guardian signature"
        }
      },
      "verifyNode(bytes32)": {
        "details": "Should be called from the previous ENS node owner",
        "params": {
          "node": "node name hash"
        }
      }
    },
    "title": "ENS controller",
    "version": 1
  },
  "userdoc": {
    "kind": "user",
    "methods": {
      "addGuardian(address)": {
        "notice": "Adds a new guardian"
      },
      "hashSubNodeRegistration((address,bytes32,bytes32))": {
        "notice": "Hashes `SubNodeRegistration` message payload"
      },
      "initialize(address,address[],address)": {
        "notice": "Initializes `ENSController` contract"
      },
      "isGuardian(address)": {
        "notice": "Check if guardian exists"
      },
      "isInitialized()": {
        "notice": "Check if contract is initialized"
      },
      "registerSubNode(bytes32,bytes32,bytes)": {
        "notice": "Registers sub node"
      },
      "releaseNode(bytes32)": {
        "notice": "Releases node"
      },
      "removeGuardian(address)": {
        "notice": "Removes the existing guardian"
      },
      "setRegistry(address)": {
        "notice": "Sets registry"
      },
      "submitNode(bytes32)": {
        "notice": "Submits node"
      },
      "syncAddr(bytes32)": {
        "notice": "Sync address"
      },
      "verifyGuardianSignature(bytes32,bytes)": {
        "notice": "Verifies guardian signature"
      },
      "verifyNode(bytes32)": {
        "notice": "Verifies node"
      }
    },
    "notice": "ENS subnode registrar",
    "version": 1
  },
  "storageLayout": {
    "storage": [
      {
        "astId": 40,
        "contract": "src/ens/ENSController.sol:ENSController",
        "label": "guardians",
        "offset": 0,
        "slot": "0",
        "type": "t_mapping(t_address,t_bool)"
      },
      {
        "astId": 1871,
        "contract": "src/ens/ENSController.sol:ENSController",
        "label": "initializer",
        "offset": 0,
        "slot": "1",
        "type": "t_address"
      },
      {
        "astId": 1935,
        "contract": "src/ens/ENSController.sol:ENSController",
        "label": "chainId",
        "offset": 0,
        "slot": "2",
        "type": "t_uint256"
      },
      {
        "astId": 5197,
        "contract": "src/ens/ENSController.sol:ENSController",
        "label": "gateway",
        "offset": 0,
        "slot": "3",
        "type": "t_address"
      },
      {
        "astId": 3850,
        "contract": "src/ens/ENSController.sol:ENSController",
        "label": "resolverAddresses",
        "offset": 0,
        "slot": "4",
        "type": "t_mapping(t_bytes32,t_mapping(t_uint256,t_bytes_storage))"
      },
      {
        "astId": 4073,
        "contract": "src/ens/ENSController.sol:ENSController",
        "label": "resolverNames",
        "offset": 0,
        "slot": "5",
        "type": "t_mapping(t_bytes32,t_string_storage)"
      },
      {
        "astId": 4140,
        "contract": "src/ens/ENSController.sol:ENSController",
        "label": "resolverPubKeys",
        "offset": 0,
        "slot": "6",
        "type": "t_mapping(t_bytes32,t_struct(PubKey)4136_storage)"
      },
      {
        "astId": 4220,
        "contract": "src/ens/ENSController.sol:ENSController",
        "label": "resolverTexts",
        "offset": 0,
        "slot": "7",
        "type": "t_mapping(t_bytes32,t_mapping(t_string_memory_ptr,t_string_storage))"
      },
      {
        "astId": 2388,
        "contract": "src/ens/ENSController.sol:ENSController",
        "label": "registry",
        "offset": 0,
        "slot": "8",
        "type": "t_contract(ENSRegistry)3564"
      },
      {
        "astId": 2392,
        "contract": "src/ens/ENSController.sol:ENSController",
        "label": "nodeOwners",
        "offset": 0,
        "slot": "9",
        "type": "t_mapping(t_bytes32,t_address)"
      }
    ],
    "types": {
      "t_address": {
        "encoding": "inplace",
        "label": "address",
        "numberOfBytes": "20"
      },
      "t_bool": {
        "encoding": "inplace",
        "label": "bool",
        "numberOfBytes": "1"
      },
      "t_bytes32": {
        "encoding": "inplace",
        "label": "bytes32",
        "numberOfBytes": "32"
      },
      "t_bytes_storage": {
        "encoding": "bytes",
        "label": "bytes",
        "numberOfBytes": "32"
      },
      "t_contract(ENSRegistry)3564": {
        "encoding": "inplace",
        "label": "contract ENSRegistry",
        "numberOfBytes": "20"
      },
      "t_mapping(t_address,t_bool)": {
        "encoding": "mapping",
        "key": "t_address",
        "label": "mapping(address => bool)",
        "numberOfBytes": "32",
        "value": "t_bool"
      },
      "t_mapping(t_bytes32,t_address)": {
        "encoding": "mapping",
        "key": "t_bytes32",
        "label": "mapping(bytes32 => address)",
        "numberOfBytes": "32",
        "value": "t_address"
      },
      "t_mapping(t_bytes32,t_mapping(t_string_memory_ptr,t_string_storage))": {
        "encoding": "mapping",
        "key": "t_bytes32",
        "label": "mapping(bytes32 => mapping(string => string))",
        "numberOfBytes": "32",
        "value": "t_mapping(t_string_memory_ptr,t_string_storage)"
      },
      "t_mapping(t_bytes32,t_mapping(t_uint256,t_bytes_storage))": {
        "encoding": "mapping",
        "key": "t_bytes32",
        "label": "mapping(bytes32 => mapping(uint256 => bytes))",
        "numberOfBytes": "32",
        "value": "t_mapping(t_uint256,t_bytes_storage)"
      },
      "t_mapping(t_bytes32,t_string_storage)": {
        "encoding": "mapping",
        "key": "t_bytes32",
        "label": "mapping(bytes32 => string)",
        "numberOfBytes": "32",
        "value": "t_string_storage"
      },
      "t_mapping(t_bytes32,t_struct(PubKey)4136_storage)": {
        "encoding": "mapping",
        "key": "t_bytes32",
        "label": "mapping(bytes32 => struct ENSPubKeyResolver.PubKey)",
        "numberOfBytes": "32",
        "value": "t_struct(PubKey)4136_storage"
      },
      "t_mapping(t_string_memory_ptr,t_string_storage)": {
        "encoding": "mapping",
        "key": "t_string_memory_ptr",
        "label": "mapping(string => string)",
        "numberOfBytes": "32",
        "value": "t_string_storage"
      },
      "t_mapping(t_uint256,t_bytes_storage)": {
        "encoding": "mapping",
        "key": "t_uint256",
        "label": "mapping(uint256 => bytes)",
        "numberOfBytes": "32",
        "value": "t_bytes_storage"
      },
      "t_string_memory_ptr": {
        "encoding": "bytes",
        "label": "string",
        "numberOfBytes": "32"
      },
      "t_string_storage": {
        "encoding": "bytes",
        "label": "string",
        "numberOfBytes": "32"
      },
      "t_struct(PubKey)4136_storage": {
        "encoding": "inplace",
        "label": "struct ENSPubKeyResolver.PubKey",
        "members": [
          {
            "astId": 4133,
            "contract": "src/ens/ENSController.sol:ENSController",
            "label": "x",
            "offset": 0,
            "slot": "0",
            "type": "t_bytes32"
          },
          {
            "astId": 4135,
            "contract": "src/ens/ENSController.sol:ENSController",
            "label": "y",
            "offset": 0,
            "slot": "1",
            "type": "t_bytes32"
          }
        ],
        "numberOfBytes": "64"
      },
      "t_uint256": {
        "encoding": "inplace",
        "label": "uint256",
        "numberOfBytes": "32"
      }
    }
  }
}