{"version":3,"sources":["src.ts/utils/keccak256.ts","src.ts/utils/properties.ts","src.ts/utils/errors.ts","src.ts/utils/secp256k1.ts","src.ts/utils/bytes.ts","src.ts/utils/bignumber.ts","src.ts/utils/rlp.ts","src.ts/utils/address.ts","src.ts/utils/utf8.ts","src.ts/utils/abi-coder.ts","src.ts/contracts/interface.ts","src.ts/wordlists/wordlist.ts","src.ts/wordlists/lang-en.ts","src.ts/utils/pbkdf2.ts","src.ts/utils/hmac.ts","src.ts/utils/sha2.ts","src.ts/wallet/hdnode.ts","src.ts/utils/random-bytes.ts","src.ts/wallet/signing-key.ts","src.ts/wallet/secret-storage.ts","src.ts/utils/hash.ts","src.ts/utils/transaction.ts","src.ts/wallet/wallet.ts","src.ts/providers/networks.ts","src.ts/providers/provider.ts","src.ts/contracts/contract.ts","src.ts/contracts/index.ts","src.ts/utils/base64.ts","src.ts/utils/web.ts","src.ts/providers/etherscan-provider.ts","src.ts/providers/fallback-provider.ts","src.ts/providers/json-rpc-provider.ts","src.ts/providers/ipc-provider.ts","src.ts/providers/infura-provider.ts","src.ts/providers/web3-provider.ts","src.ts/providers/index.ts","src.ts/utils/solidity.ts","src.ts/utils/units.ts","src.ts/utils/index.ts","src.ts/wallet/index.ts","src.ts/index.ts","src.ts/wordlists/lang-ja.ts","src.ts/wordlists/lang-ko.ts","src.ts/wordlists/lang-it.ts","src.ts/wordlists/lang-zh.ts","src.ts/wordlists/index.ts","src.ts/utils/shims.ts"],"names":[],"mappings":"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","file":"ethers.d.ts","sourcesContent":["'use strict';\n\nimport sha3 = require('js-sha3');\n\nimport { arrayify, Arrayish } from './bytes';\n\nexport function keccak256(data: Arrayish): string {\n    return '0x' + sha3.keccak_256(arrayify(data));\n}\n\n//export default keccak256;\n","'use strict';\n\nexport function defineReadOnly(object: any, name: string, value: any): void {\n    Object.defineProperty(object, name, {\n        enumerable: true,\n        value: value,\n        writable: false,\n    });\n}\n\nexport function defineFrozen(object: any, name: string, value: any): void {\n    var frozen = JSON.stringify(value);\n    Object.defineProperty(object, name, {\n        enumerable: true,\n        get: function() { return JSON.parse(frozen); }\n    });\n}\n\nexport function resolveProperties(object: any): Promise<any> {\n    let result: any = {};\n\n    let promises: Array<Promise<void>> = [];\n    Object.keys(object).forEach((key) => {\n        let value = object[key];\n        if (value instanceof Promise) {\n            promises.push(\n                value.then((value) => {\n                    result[key] = value;\n                })\n            );\n        } else {\n            result[key] = value;\n        }\n    });\n\n    return Promise.all(promises).then(() => {\n        return result;\n    });\n}\n\nexport function shallowCopy(object: any): any {\n    let result: any = {};\n    for (var key in object) { result[key] = object[key]; }\n    return result;\n}\n\nexport function jsonCopy(object: any): any {\n    return JSON.parse(JSON.stringify(object));\n}\n","'use strict';\n\n// Unknown Error\nexport const UNKNOWN_ERROR = 'UNKNOWN_ERROR';\n\n// Not implemented\nexport const NOT_IMPLEMENTED = 'NOT_IMPLEMENTED';\n\n// Missing new operator to an object\n//  - name: The name of the class\nexport const MISSING_NEW = 'MISSING_NEW';\n\n// Call exception\nexport const CALL_EXCEPTION = 'CALL_EXCEPTION';\n\n// Response from a server was invalid\n//   - response: The body of the response\n//'BAD_RESPONSE',\n\n// Invalid argument (e.g. type) to a function:\n//   - arg: The argument name that was invalid\n//   - value: The value of the argument\n//   - type: The type of the argument\n//   - expected: What was expected\nexport const INVALID_ARGUMENT = 'INVALID_ARGUMENT';\n\n// Missing argument to a function:\n//   - arg: The argument name that is required\n//   - count: The number of arguments received\n//   - expectedCount: The number of arguments expected\nexport const MISSING_ARGUMENT = 'MISSING_ARGUMENT';\n\n// Too many arguments\n//   - count: The number of arguments received\n//   - expectedCount: The number of arguments expected\nexport const UNEXPECTED_ARGUMENT = 'UNEXPECTED_ARGUMENT';\n\n// Numeric Fault\n//   - operation: the operation being executed\n//   - fault: the reason this faulted\nexport const NUMERIC_FAULT = 'NUMERIC_FAULT';\n\n\n// Unsupported operation\n//   - operation\nexport const UNSUPPORTED_OPERATION = 'UNSUPPORTED_OPERATION';\n\n// @TODO: Enum\nexport function throwError(message: string, code: string, params: any): never {\n    if (!code) { code = UNKNOWN_ERROR; }\n    if (!params) { params = {}; }\n\n    var messageDetails: Array<string> = [];\n    Object.keys(params).forEach(function(key) {\n        try {\n            messageDetails.push(key + '=' + JSON.stringify(params[key]));\n        } catch (error) {\n            messageDetails.push(key + '=' + JSON.stringify(params[key].toString()));\n        }\n    });\n    var reason = message;\n    if (messageDetails.length) {\n        message += ' (' + messageDetails.join(', ') + ')';\n    }\n\n// @TODO: Any??\n    var error: any = new Error(message);\n    error.reason = reason;\n    error.code = code\n\n    Object.keys(params).forEach(function(key) {\n        error[key] = params[key];\n    });\n\n    throw error;\n}\n\nexport function checkNew(self: any, kind: any): void {\n    if (!(self instanceof kind)) {\n        throwError('missing new', MISSING_NEW, { name: kind.name });\n    }\n}\n\n","'use strict';\n\nimport * as elliptic from 'elliptic';\nconst curve = new elliptic.ec('secp256k1');\n\nimport { getAddress } from './address';\nimport { arrayify, Arrayish, hexlify, hexZeroPad } from './bytes';\nimport { keccak256 } from './keccak256';\nimport { defineReadOnly } from './properties';\n\nimport * as errors from './errors';\n\nexport const N = '0x' + curve.n.toString(16);\n\nexport interface Signature {\n    r: string;\n    s: string;\n    recoveryParam: number;\n    v?: number;\n}\n\nexport class KeyPair {\n\n    readonly privateKey: string;\n\n    readonly publicKey: string;\n    readonly compressedPublicKey: string;\n\n    readonly publicKeyBytes: Uint8Array;\n\n    constructor(privateKey: Arrayish) {\n        let keyPair = curve.keyFromPrivate(arrayify(privateKey));\n\n        defineReadOnly(this, 'privateKey', hexlify(keyPair.priv.toArray('be', 32)));\n        defineReadOnly(this, 'publicKey', '0x' + keyPair.getPublic(false, 'hex'));\n        defineReadOnly(this, 'compressedPublicKey', '0x' + keyPair.getPublic(true, 'hex'));\n        defineReadOnly(this, 'publicKeyBytes', keyPair.getPublic().encode(null, true));\n    }\n\n    sign(digest: Arrayish): Signature {\n        let keyPair = curve.keyFromPrivate(arrayify(this.privateKey));\n        let signature = keyPair.sign(arrayify(digest), {canonical: true});\n        return {\n            recoveryParam: signature.recoveryParam,\n            r: hexZeroPad('0x' + signature.r.toString(16), 32),\n            s: hexZeroPad('0x' + signature.s.toString(16), 32),\n            v: 27 + signature.recoveryParam\n        }\n\n    }\n}\n\nexport function recoverPublicKey(digest: Arrayish, signature: Signature): string {\n    let sig = {\n        r: arrayify(signature.r),\n        s: arrayify(signature.s)\n    };\n    return '0x' + curve.recoverPubKey(arrayify(digest), sig, signature.recoveryParam).encode('hex', false);\n}\n\nexport function computePublicKey(key: Arrayish, compressed?: boolean): string {\n\n    let bytes = arrayify(key);\n\n    if (bytes.length === 32) {\n        let keyPair: KeyPair = new KeyPair(bytes);\n        if (compressed) {\n            return keyPair.compressedPublicKey;\n        }\n        return keyPair.publicKey;\n\n    } else if (bytes.length === 33) {\n        if (compressed) { return hexlify(bytes); }\n        return '0x' + curve.keyFromPublic(bytes).getPublic(false, 'hex');\n\n    } else if (bytes.length === 65) {\n        if (!compressed) { return hexlify(bytes); }\n        return '0x' + curve.keyFromPublic(bytes).getPublic(true, 'hex');\n    }\n\n    errors.throwError('invalid public or private key', errors.INVALID_ARGUMENT, { arg: 'key', value: '[REDACTED]' });\n    return null;\n}\n\nexport function recoverAddress(digest: Arrayish, signature: Signature): string {\n    return computeAddress(recoverPublicKey(digest, signature));\n}\n\nexport function computeAddress(key: string): string {\n    // Strip off the leading \"0x04\"\n    let publicKey = '0x' + computePublicKey(key).slice(4);\n    return getAddress('0x' + keccak256(publicKey).substring(26));\n}\n\n","/**\n *  Conversion Utilities\n *\n */\n\nimport { BigNumber } from './bignumber';\nimport { Signature } from './secp256k1';\n\nimport errors = require('./errors');\n\n\n\nexport type Arrayish = string | ArrayLike<number>;\n\n\nfunction isBigNumber(value: any): value is BigNumber {\n    return !!value._bn;\n}\n\nfunction addSlice(array: Uint8Array): Uint8Array {\n    if (array.slice) { return array; }\n\n    array.slice = function() {\n        var args = Array.prototype.slice.call(arguments);\n        return new Uint8Array(Array.prototype.slice.apply(array, args));\n    }\n\n    return array;\n}\n\nexport function isArrayish(value: any): boolean {\n    if (!value || parseInt(String(value.length)) != value.length || typeof(value) === 'string') {\n        return false;\n    }\n\n    for (var i = 0; i < value.length; i++) {\n        var v = value[i];\n        if (v < 0 || v >= 256 || parseInt(String(v)) != v) {\n            return false;\n        }\n    }\n\n    return true;\n}\n\nexport function arrayify(value: Arrayish | BigNumber): Uint8Array {\n    if (value == null) {\n        errors.throwError('cannot convert null value to array', errors.INVALID_ARGUMENT, { arg: 'value', value: value });\n    }\n\n    if (isBigNumber(value)) {\n        value = value.toHexString();\n    }\n\n    if (typeof(value) === 'string') {\n        let match = value.match(/^(0x)?[0-9a-fA-F]*$/);\n\n        if (!match) {\n            errors.throwError('invalid hexidecimal string', errors.INVALID_ARGUMENT, { arg: 'value', value: value });\n        }\n\n        if (match[1] !== '0x') {\n             errors.throwError('hex string must have 0x prefix', errors.INVALID_ARGUMENT, { arg: 'value', value: value });\n        }\n\n        value = value.substring(2);\n        if (value.length % 2) { value = '0' + value; }\n\n        var result = [];\n        for (var i = 0; i < value.length; i += 2) {\n            result.push(parseInt(value.substr(i, 2), 16));\n        }\n\n        return addSlice(new Uint8Array(result));\n\n    } else if (typeof(value) === 'string') {\n    }\n\n    if (isArrayish(value)) {\n        return addSlice(new Uint8Array(value));\n    }\n\n    errors.throwError('invalid arrayify value', null, { arg: 'value', value: value, type: typeof(value) });\n    return null;\n}\n\nexport function concat(objects: Array<Arrayish>): Uint8Array {\n    var arrays = [];\n    var length = 0;\n    for (var i = 0; i < objects.length; i++) {\n        var object = arrayify(objects[i])\n        arrays.push(object);\n        length += object.length;\n    }\n\n    var result = new Uint8Array(length);\n    var offset = 0;\n    for (var i = 0; i < arrays.length; i++) {\n        result.set(arrays[i], offset);\n        offset += arrays[i].length;\n    }\n\n    return addSlice(result);\n}\n\nexport function stripZeros(value: Arrayish): Uint8Array {\n    let result: Uint8Array = arrayify(value);\n\n    if (result.length === 0) { return result; }\n\n    // Find the first non-zero entry\n    var start = 0;\n    while (result[start] === 0) { start++ }\n\n    // If we started with zeros, strip them\n    if (start) {\n        result = result.slice(start);\n    }\n\n    return result;\n}\n\nexport function padZeros(value: Arrayish, length: number): Uint8Array {\n    value = arrayify(value);\n\n    if (length < value.length) { throw new Error('cannot pad'); }\n\n    var result = new Uint8Array(length);\n    result.set(value, length - value.length);\n    return addSlice(result);\n}\n\n\nexport function isHexString(value: any, length?: number): boolean {\n    if (typeof(value) !== 'string' || !value.match(/^0x[0-9A-Fa-f]*$/)) {\n        return false\n    }\n    if (length && value.length !== 2 + 2 * length) { return false; }\n    return true;\n}\n\nconst HexCharacters: string = '0123456789abcdef';\n\nexport function hexlify(value: Arrayish | BigNumber | number): string {\n\n    if (isBigNumber(value)) {\n        return value.toHexString();\n    }\n\n    if (typeof(value) === 'number') {\n        if (value < 0) {\n            errors.throwError('cannot hexlify negative value', errors.INVALID_ARGUMENT, { arg: 'value', value: value });\n        }\n\n        var hex = '';\n        while (value) {\n            hex = HexCharacters[value & 0x0f] + hex;\n            value = Math.floor(value / 16);\n        }\n\n        if (hex.length) {\n            if (hex.length % 2) { hex = '0' + hex; }\n            return '0x' + hex;\n        }\n\n        return '0x00';\n    }\n\n    if (typeof(value) === 'string') {\n        let match = value.match(/^(0x)?[0-9a-fA-F]*$/);\n\n        if (!match) {\n            errors.throwError('invalid hexidecimal string', errors.INVALID_ARGUMENT, { arg: 'value', value: value });\n        }\n\n        if (match[1] !== '0x') {\n             errors.throwError('hex string must have 0x prefix', errors.INVALID_ARGUMENT, { arg: 'value', value: value });\n        }\n\n        if (value.length % 2) {\n            value = '0x0' + value.substring(2);\n        }\n        return value;\n    }\n\n    if (isArrayish(value)) {\n        var result = [];\n        for (var i = 0; i < value.length; i++) {\n             var v = value[i];\n             result.push(HexCharacters[(v & 0xf0) >> 4] + HexCharacters[v & 0x0f]);\n        }\n        return '0x' + result.join('');\n    }\n\n    errors.throwError('invalid hexlify value', null, { arg: 'value', value: value });\n    return 'never';\n}\n\nexport function hexDataLength(data: string) {\n    if (!isHexString(data) || (data.length % 2) !== 0) {\n        return null;\n    }\n    return (data.length - 2) / 2;\n}\n\nexport function hexDataSlice(data: string, offset: number, length?: number): string {\n    if (!isHexString(data)) {\n        errors.throwError('invalid hex data', errors.INVALID_ARGUMENT, { arg: 'value', value: data });\n    }\n    if ((data.length % 2) !== 0) {\n        errors.throwError('hex data length must be even', errors.INVALID_ARGUMENT, { arg: 'value', value: data });\n    }\n    offset = 2 + 2 * offset;\n\n    if (length != null) {\n        return '0x' + data.substring(offset, offset + 2 * length);\n    }\n\n    return '0x' + data.substring(offset);\n}\n\nexport function hexStripZeros(value: string): string {\n    if (!isHexString(value)) {\n        errors.throwError('invalid hex string', errors.INVALID_ARGUMENT, { arg: 'value', value: value });\n    }\n    while (value.length > 3 && value.substring(0, 3) === '0x0') {\n        value = '0x' + value.substring(3);\n    }\n    return value;\n}\n\nexport function hexZeroPad(value: string, length: number): string {\n    if (!isHexString(value)) {\n        errors.throwError('invalid hex string', errors.INVALID_ARGUMENT, { arg: 'value', value: value });\n    }\n\n    while (value.length < 2 * length + 2) {\n        value = '0x0' + value.substring(2);\n    }\n    return value;\n}\n\nexport function splitSignature(signature: Arrayish): Signature {\n    let bytes: Uint8Array = arrayify(signature);\n    if (bytes.length !== 65) {\n        throw new Error('invalid signature');\n    }\n\n    var v = bytes[64];\n    if (v !== 27 && v !== 28) {\n        v = 27 + (v % 2);\n    }\n\n    return {\n        r: hexlify(bytes.slice(0, 32)),\n        s: hexlify(bytes.slice(32, 64)),\n        recoveryParam: (v - 27),\n        v: v\n    }\n}\n\nexport function joinSignature(signature: Signature): string {\n    return hexlify(concat([\n         hexZeroPad(signature.r, 32),\n         hexZeroPad(signature.s, 32),\n         (signature.recoveryParam ? '0x1c': '0x1b')\n    ]));\n}\n\n","'use strict';\n\n/**\n *  BigNumber\n *\n *  A wrapper around the BN.js object. We use the BN.js library\n *  because it is used by elliptic, so it is required regardles.\n *\n */\n\nimport BN from 'bn.js';\n\nimport { Arrayish, hexlify, isArrayish, isHexString } from './bytes';\nimport { defineReadOnly } from './properties';\nimport * as errors from '../utils/errors';\n\nfunction _isBigNumber(value: any): value is BigNumber {\n    return isBigNumber(value);\n}\n\nexport type BigNumberish = BigNumber | string | number | Arrayish;\n\nfunction fromBN(bn: BN.BN) {\n    let value = bn.toString(16);\n    if (value[0] === '-') {\n        return new BigNumber(\"-0x\" + value.substring(1));\n    }\n    return new BigNumber('0x' + value);\n}\n\nexport class BigNumber {\n    private readonly _bn: BN.BN;\n\n    constructor(value: BigNumberish) {\n        errors.checkNew(this, BigNumber);\n\n        if (typeof(value) === 'string') {\n            if (isHexString(value)) {\n                if (value == '0x') { value = '0x0'; }\n                defineReadOnly(this, '_bn', new BN.BN(value.substring(2), 16));\n\n            } else if (value[0] === '-' && isHexString(value.substring(1))) {\n                defineReadOnly(this, '_bn', (new BN.BN(value.substring(3), 16)).mul(ConstantNegativeOne._bn));\n\n            } else if (value.match(/^-?[0-9]*$/)) {\n                if (value == '') { value = '0'; }\n                defineReadOnly(this, '_bn', new BN.BN(value));\n            }\n\n        } else if (typeof(value) === 'number') {\n            if (parseInt(String(value)) !== value) {\n                errors.throwError('underflow', errors.NUMERIC_FAULT, { operation: 'setValue', fault: 'underflow', value: value, outputValue: parseInt(String(value)) });\n            }\n            try {\n                defineReadOnly(this, '_bn', new BN.BN(value));\n            } catch (error) {\n                errors.throwError('overflow', errors.NUMERIC_FAULT, { operation: 'setValue', fault: 'overflow', details: error.message });\n            }\n\n        } else if (_isBigNumber(value)) {\n            defineReadOnly(this, '_bn', value._bn);\n\n        } else if (isArrayish(value)) {\n            defineReadOnly(this, '_bn', new BN.BN(hexlify(value).substring(2), 16));\n\n        } else {\n            errors.throwError('invalid BigNumber value', errors.INVALID_ARGUMENT, { arg: 'value', value: value });\n        }\n    }\n\n    fromTwos(value: number): BigNumber {\n        return fromBN(this._bn.fromTwos(value));\n    }\n\n    toTwos(value: number): BigNumber {\n        return fromBN(this._bn.toTwos(value));\n    }\n\n    add(other: BigNumberish): BigNumber {\n        return fromBN(this._bn.add(bigNumberify(other)._bn));\n    }\n\n    sub(other: BigNumberish): BigNumber {\n        return fromBN(this._bn.sub(bigNumberify(other)._bn));\n    }\n\n    div(other: BigNumberish): BigNumber {\n        let o: BigNumber = bigNumberify(other);\n        if (o.isZero()) {\n            errors.throwError('division by zero', errors.NUMERIC_FAULT, { operation: 'divide', fault: 'division by zero' });\n        }\n        return fromBN(this._bn.div(o._bn));\n    }\n\n    mul(other: BigNumberish): BigNumber {\n        return fromBN(this._bn.mul(bigNumberify(other)._bn));\n    }\n\n    mod(other: BigNumberish): BigNumber {\n        return fromBN(this._bn.mod(bigNumberify(other)._bn));\n    }\n\n    pow(other: BigNumberish): BigNumber {\n        return fromBN(this._bn.pow(bigNumberify(other)._bn));\n    }\n\n    maskn(value: number): BigNumber {\n        return fromBN(this._bn.maskn(value));\n    }\n\n    eq(other: BigNumberish): boolean {\n        return this._bn.eq(bigNumberify(other)._bn);\n    }\n\n    lt(other: BigNumberish): boolean {\n        return this._bn.lt(bigNumberify(other)._bn);\n    }\n\n    lte(other: BigNumberish): boolean {\n        return this._bn.lte(bigNumberify(other)._bn);\n    }\n\n    gt(other: BigNumberish): boolean {\n        return this._bn.gt(bigNumberify(other)._bn);\n   }\n\n    gte(other: BigNumberish): boolean {\n        return this._bn.gte(bigNumberify(other)._bn);\n    }\n\n    isZero(): boolean {\n        return this._bn.isZero();\n    }\n\n    toNumber(): number {\n        try {\n            return this._bn.toNumber();\n        } catch (error) {\n            errors.throwError('overflow', errors.NUMERIC_FAULT, { operation: 'setValue', fault: 'overflow', details: error.message });\n        }\n        return null;\n    }\n\n    toString(): string {\n        return this._bn.toString(10);\n    }\n\n    toHexString(): string {\n        var hex = this._bn.toString(16);\n        if (hex.length % 2) { hex = '0' + hex; }\n        return '0x' + hex;\n    }\n}\n\nexport function isBigNumber(value: any): boolean {\n    return (value._bn && value._bn.mod);\n}\n\nexport function bigNumberify(value: BigNumberish): BigNumber {\n    if (_isBigNumber(value)) { return value; }\n    return new BigNumber(value);\n}\n\nexport const ConstantNegativeOne: BigNumber = bigNumberify(-1);\nexport const ConstantZero: BigNumber = bigNumberify(0);\nexport const ConstantOne: BigNumber = bigNumberify(1);\nexport const ConstantTwo: BigNumber = bigNumberify(2);\nexport const ConstantWeiPerEther: BigNumber = bigNumberify('1000000000000000000');\n","//See: https://github.com/ethereum/wiki/wiki/RLP\n\n\nimport { arrayify, Arrayish, hexlify } from './bytes';\n\nfunction arrayifyInteger(value: number): Array<number> {\n    var result = [];\n    while (value) {\n        result.unshift(value & 0xff);\n        value >>= 8;\n    }\n    return result;\n}\n\nfunction unarrayifyInteger(data: Uint8Array, offset: number, length: number): number {\n    var result = 0;\n    for (var i = 0; i < length; i++) {\n        result = (result * 256) + data[offset + i];\n    }\n    return result;\n}\n\nfunction _encode(object: Array<any> | string): Array<number> {\n    if (Array.isArray(object)) {\n        var payload: Array<number> = [];\n        object.forEach(function(child) {\n            payload = payload.concat(_encode(child));\n        });\n\n        if (payload.length <= 55) {\n            payload.unshift(0xc0 + payload.length)\n            return payload;\n        }\n\n        var length = arrayifyInteger(payload.length);\n        length.unshift(0xf7 + length.length);\n\n        return length.concat(payload);\n\n    }\n\n    let data: Array<number> = Array.prototype.slice.call(arrayify(object));\n\n    if (data.length === 1 && data[0] <= 0x7f) {\n        return data;\n\n    } else if (data.length <= 55) {\n        data.unshift(0x80 + data.length);\n        return data;\n    }\n\n    var length = arrayifyInteger(data.length);\n    length.unshift(0xb7 + length.length);\n\n    return length.concat(data);\n}\n\nexport function encode(object: any): string {\n    return hexlify(_encode(object));\n}\n\ntype Decoded = {\n    result: any;\n    consumed: number;\n};\n\nfunction _decodeChildren(data: Uint8Array, offset: number, childOffset: number, length: number): Decoded {\n    var result = [];\n\n    while (childOffset < offset + 1 + length) {\n        var decoded = _decode(data, childOffset);\n\n        result.push(decoded.result);\n\n        childOffset += decoded.consumed;\n        if (childOffset > offset + 1 + length) {\n            throw new Error('invalid rlp');\n        }\n    }\n\n    return {consumed: (1 + length), result: result};\n}\n\n// returns { consumed: number, result: Object }\nfunction _decode(data: Uint8Array, offset: number): { consumed: number, result: any } {\n    if (data.length === 0) { throw new Error('invalid rlp data'); }\n\n    // Array with extra length prefix\n    if (data[offset] >= 0xf8) {\n        var lengthLength = data[offset] - 0xf7;\n        if (offset + 1 + lengthLength > data.length) {\n            throw new Error('too short');\n        }\n\n        var length = unarrayifyInteger(data, offset + 1, lengthLength);\n        if (offset + 1 + lengthLength + length > data.length) {\n            throw new Error('to short');\n        }\n\n        return _decodeChildren(data, offset, offset + 1 + lengthLength, lengthLength + length);\n\n    } else if (data[offset] >= 0xc0) {\n        var length = data[offset] - 0xc0;\n        if (offset + 1 + length > data.length) {\n            throw new Error('invalid rlp data');\n        }\n\n        return _decodeChildren(data, offset, offset + 1, length);\n\n    } else if (data[offset] >= 0xb8) {\n        var lengthLength = data[offset] - 0xb7;\n        if (offset + 1 + lengthLength > data.length) {\n            throw new Error('invalid rlp data');\n        }\n\n        var length = unarrayifyInteger(data, offset + 1, lengthLength);\n        if (offset + 1 + lengthLength + length > data.length) {\n            throw new Error('invalid rlp data');\n        }\n\n        var result = hexlify(data.slice(offset + 1 + lengthLength, offset + 1 + lengthLength + length));\n        return { consumed: (1 + lengthLength + length), result: result }\n\n    } else if (data[offset] >= 0x80) {\n        var length = data[offset] - 0x80;\n        if (offset + 1 + length > data.length) {\n            throw new Error('invlaid rlp data');\n        }\n\n        var result = hexlify(data.slice(offset + 1, offset + 1 + length));\n        return { consumed: (1 + length), result: result }\n    }\n    return { consumed: 1, result: hexlify(data[offset]) };\n}\n\nexport function decode(data: Arrayish): any {\n    let bytes = arrayify(data);\n    var decoded = _decode(bytes, 0);\n    if (decoded.consumed !== bytes.length) {\n        throw new Error('invalid rlp data');\n    }\n    return decoded.result;\n}\n\n","'use strict';\n\n// We use this for base 36 maths\nimport BN from 'bn.js';\n\nimport { BigNumber } from './bignumber';\nimport { arrayify, Arrayish, stripZeros, hexlify } from './bytes';\nimport { keccak256 } from './keccak256';\nimport { encode } from './rlp';\n\nimport errors = require('./errors');\n\n\nfunction getChecksumAddress(address: string): string {\n    if (typeof(address) !== 'string' || !address.match(/^0x[0-9A-Fa-f]{40}$/)) {\n        errors.throwError('invalid address', errors.INVALID_ARGUMENT, { arg: 'address', value: address });\n    }\n\n    address = address.toLowerCase();\n\n    let chars = address.substring(2).split('');\n\n    let hashed = new Uint8Array(40);\n    for (let i = 0; i < 40; i++) {\n        hashed[i] = chars[i].charCodeAt(0);\n    }\n    hashed = arrayify(keccak256(hashed));\n\n    for (var i = 0; i < 40; i += 2) {\n        if ((hashed[i >> 1] >> 4) >= 8) {\n            chars[i] = chars[i].toUpperCase();\n        }\n        if ((hashed[i >> 1] & 0x0f) >= 8) {\n            chars[i + 1] = chars[i + 1].toUpperCase();\n        }\n    }\n\n    return '0x' + chars.join('');\n}\n\n// Shims for environments that are missing some required constants and functions\nvar MAX_SAFE_INTEGER: number = 0x1fffffffffffff;\n\nfunction log10(x: number): number {\n    if (Math.log10) { return Math.log10(x); }\n    return Math.log(x) / Math.LN10;\n}\n\n\n// See: https://en.wikipedia.org/wiki/International_Bank_Account_Number\n\n// Create lookup table\nvar ibanLookup: { [character: string]: string } = {};\nfor (var i = 0; i < 10; i++) { ibanLookup[String(i)] = String(i); }\nfor (var i = 0; i < 26; i++) { ibanLookup[String.fromCharCode(65 + i)] = String(10 + i); }\n\n// How many decimal digits can we process? (for 64-bit float, this is 15)\nvar safeDigits = Math.floor(log10(MAX_SAFE_INTEGER));\n\nfunction ibanChecksum(address: string): string {\n    address = address.toUpperCase();\n    address = address.substring(4) + address.substring(0, 2) + '00';\n\n    var expanded = '';\n    address.split('').forEach(function(c) {\n        expanded += ibanLookup[c];\n    });\n\n    // Javascript can handle integers safely up to 15 (decimal) digits\n    while (expanded.length >= safeDigits){\n        var block = expanded.substring(0, safeDigits);\n        expanded = parseInt(block, 10) % 97 + expanded.substring(block.length);\n    }\n\n    var checksum = String(98 - (parseInt(expanded, 10) % 97));\n    while (checksum.length < 2) { checksum = '0' + checksum; }\n\n    return checksum;\n};\n\nexport function getAddress(address: string): string {\n    var result = null;\n\n    if (typeof(address) !== 'string') {\n        errors.throwError('invalid address', errors.INVALID_ARGUMENT, { arg: 'address', value: address });\n    }\n\n    if (address.match(/^(0x)?[0-9a-fA-F]{40}$/)) {\n\n        // Missing the 0x prefix\n        if (address.substring(0, 2) !== '0x') { address = '0x' + address; }\n\n        result = getChecksumAddress(address);\n\n        // It is a checksummed address with a bad checksum\n        if (address.match(/([A-F].*[a-f])|([a-f].*[A-F])/) && result !== address) {\n            errors.throwError('bad address checksum', errors.INVALID_ARGUMENT, { arg: 'address', value: address });\n        }\n\n    // Maybe ICAP? (we only support direct mode)\n    } else if (address.match(/^XE[0-9]{2}[0-9A-Za-z]{30,31}$/)) {\n\n        // It is an ICAP address with a bad checksum\n        if (address.substring(2, 4) !== ibanChecksum(address)) {\n            errors.throwError('bad icap checksum', errors.INVALID_ARGUMENT, { arg: 'address', value: address });\n        }\n\n        result = (new BN.BN(address.substring(4), 36)).toString(16);\n        while (result.length < 40) { result = '0' + result; }\n        result = getChecksumAddress('0x' + result);\n\n    } else {\n        errors.throwError('invalid address', errors.INVALID_ARGUMENT, { arg: 'address', value: address });\n    }\n\n    return result;\n}\n\nexport function getIcapAddress(address: string): string {\n    var base36 = (new BN.BN(getAddress(address).substring(2), 16)).toString(36).toUpperCase();\n    while (base36.length < 30) { base36 = '0' + base36; }\n    return 'XE' + ibanChecksum('XE00' + base36) + base36;\n}\n\n// http://ethereum.stackexchange.com/questions/760/how-is-the-address-of-an-ethereum-contract-computed\nexport function getContractAddress(transaction: { from: string, nonce: Arrayish | BigNumber | number }) {\n    if (!transaction.from) { throw new Error('missing from address'); }\n    var nonce = transaction.nonce;\n\n    return getAddress('0x' + keccak256(encode([\n        getAddress(transaction.from),\n        stripZeros(hexlify(nonce))\n    ])).substring(26));\n}\n\n","'use strict';\n\nimport { arrayify, Arrayish } from './bytes';\n\nexport enum UnicodeNormalizationForm {\n    current  = '',\n    NFC      = 'NFC',\n    NFD      = 'NFD',\n    NFKC     = 'NFKC',\n    NFKD     = 'NFKD'\n};\n\n// http://stackoverflow.com/questions/18729405/how-to-convert-utf8-string-to-byte-array\nexport function toUtf8Bytes(str: string, form: UnicodeNormalizationForm = UnicodeNormalizationForm.current): Uint8Array {\n\n    if (form != UnicodeNormalizationForm.current) {\n        str = str.normalize(form);\n    }\n\n    var result = [];\n    var offset = 0;\n    for (var i = 0; i < str.length; i++) {\n        var c = str.charCodeAt(i);\n        if (c < 128) {\n            result[offset++] = c;\n        } else if (c < 2048) {\n            result[offset++] = (c >> 6) | 192;\n            result[offset++] = (c & 63) | 128;\n        } else if (((c & 0xFC00) == 0xD800) && (i + 1) < str.length && ((str.charCodeAt(i + 1) & 0xFC00) == 0xDC00)) {\n            // Surrogate Pair\n            c = 0x10000 + ((c & 0x03FF) << 10) + (str.charCodeAt(++i) & 0x03FF);\n            result[offset++] = (c >> 18) | 240;\n            result[offset++] = ((c >> 12) & 63) | 128;\n            result[offset++] = ((c >> 6) & 63) | 128;\n            result[offset++] = (c & 63) | 128;\n        } else {\n            result[offset++] = (c >> 12) | 224;\n            result[offset++] = ((c >> 6) & 63) | 128;\n            result[offset++] = (c & 63) | 128;\n        }\n    }\n\n    return arrayify(result);\n};\n\n\n// http://stackoverflow.com/questions/13356493/decode-utf-8-with-javascript#13691499\nexport function toUtf8String(bytes: Arrayish): string {\n    bytes = arrayify(bytes);\n\n    var result = '';\n    var i = 0;\n\n    // Invalid bytes are ignored\n    while(i < bytes.length) {\n        var c = bytes[i++];\n        if (c >> 7 == 0) {\n            // 0xxx xxxx\n            result += String.fromCharCode(c);\n            continue;\n        }\n\n        // Invalid starting byte\n        if (c >> 6 == 0x02) { continue; }\n\n        // Multibyte; how many bytes left for thus character?\n        var extraLength = null;\n        if (c >> 5 == 0x06) {\n            extraLength = 1;\n        } else if (c >> 4 == 0x0e) {\n            extraLength = 2;\n        } else if (c >> 3 == 0x1e) {\n            extraLength = 3;\n        } else if (c >> 2 == 0x3e) {\n            extraLength = 4;\n        } else if (c >> 1 == 0x7e) {\n            extraLength = 5;\n        } else {\n            continue;\n        }\n\n        // Do we have enough bytes in our data?\n        if (i + extraLength > bytes.length) {\n\n            // If there is an invalid unprocessed byte, try to continue\n            for (; i < bytes.length; i++) {\n                if (bytes[i] >> 6 != 0x02) { break; }\n            }\n            if (i != bytes.length) continue;\n\n            // All leftover bytes are valid.\n            return result;\n        }\n\n        // Remove the UTF-8 prefix from the char (res)\n        var res = c & ((1 << (8 - extraLength - 1)) - 1);\n\n        var count;\n        for (count = 0; count < extraLength; count++) {\n            var nextChar = bytes[i++];\n\n            // Is the char valid multibyte part?\n            if (nextChar >> 6 != 0x02) {break;};\n            res = (res << 6) | (nextChar & 0x3f);\n        }\n\n        if (count != extraLength) {\n            i--;\n            continue;\n        }\n\n        if (res <= 0xffff) {\n            result += String.fromCharCode(res);\n            continue;\n        }\n\n        res -= 0x10000;\n        result += String.fromCharCode(((res >> 10) & 0x3ff) + 0xd800, (res & 0x3ff) + 0xdc00);\n    }\n\n    return result;\n}\n\n","'use strict';\n\n// See: https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI\n\nimport { getAddress } from  './address';\nimport { bigNumberify, BigNumberish } from './bignumber';\nimport { arrayify, Arrayish, concat, hexlify, padZeros } from './bytes';\nimport { toUtf8Bytes, toUtf8String } from './utf8';\nimport { defineReadOnly, jsonCopy } from './properties';\n\nimport * as errors from './errors';\n\nconst paramTypeBytes = new RegExp(/^bytes([0-9]*)$/);\nconst paramTypeNumber = new RegExp(/^(u?int)([0-9]*)$/);\nconst paramTypeArray = new RegExp(/^(.*)\\[([0-9]*)\\]$/);\n\n// @TODO: Add enum for param types\nexport type CoerceFunc = (type: string, value: any) => any;\nexport type ParamType = { name?: string, type: string, indexed?: boolean, components?: Array<any> };\n\nexport const defaultCoerceFunc: CoerceFunc = function(type: string, value: any): any {\n    var match = type.match(paramTypeNumber)\n    if (match && parseInt(match[2]) <= 48) { return value.toNumber(); }\n    return value;\n}\n\n\n///////////////////////////////////\n// Parsing for Solidity Signatures\n\nconst regexParen = new RegExp(\"^([^)(]*)\\\\((.*)\\\\)([^)(]*)$\");\nconst regexIdentifier = new RegExp(\"^[A-Za-z_][A-Za-z0-9_]*$\");\n\nfunction verifyType(type: string): string {\n\n    // These need to be transformed to their full description\n    if (type.match(/^uint($|[^1-9])/)) {\n        type = 'uint256' + type.substring(4);\n    } else if (type.match(/^int($|[^1-9])/)) {\n        type = 'int256' + type.substring(3);\n    }\n\n    return type;\n}\n\ntype ParseState = {\n    allowArray?: boolean,\n    allowName?: boolean,\n    allowParams?: boolean,\n    allowType?: boolean,\n    readArray?: boolean,\n};\n\ntype ParseNode = {\n    parent?: any,\n    type?: string,\n    name?: string,\n    state?: ParseState,\n    indexed?: boolean,\n    components?: Array<any>\n};\n\n\nfunction parseParam(param: string, allowIndexed?: boolean): ParamType {\n    function throwError(i: number) {\n        throw new Error('unexpected character \"' + param[i] + '\" at position ' + i + ' in \"' + param + '\"');\n    }\n\n    var parent: ParseNode = { type: '', name: '', state: { allowType: true } };\n    var node = parent;\n\n    for (var i = 0; i < param.length; i++) {\n        var c = param[i];\n        switch (c) {\n            case '(':\n                if (!node.state.allowParams) { throwError(i); }\n                node.state.allowType = false;\n                node.type = verifyType(node.type);\n                node.components = [ { type: '', name: '', parent: node, state: { allowType: true } } ];\n                node = node.components[0];\n                break;\n\n            case ')':\n                delete node.state;\n                node.type = verifyType(node.type);\n\n                var child = node;\n                node = node.parent;\n                if (!node) { throwError(i); }\n                delete child.parent;\n                node.state.allowParams = false;\n                node.state.allowName = true;\n                node.state.allowArray = true;\n                break;\n\n            case ',':\n                delete node.state;\n                node.type = verifyType(node.type);\n\n                var sibling: ParseNode = { type: '', name: '', parent: node.parent, state: { allowType: true } };\n                node.parent.components.push(sibling);\n                delete node.parent;\n                node = sibling;\n                break;\n\n            // Hit a space...\n            case ' ':\n\n                // If reading type, the type is done and may read a param or name\n                if (node.state.allowType) {\n                    if (node.type !== '') {\n                        node.type = verifyType(node.type);\n                        delete node.state.allowType;\n                        node.state.allowName = true;\n                        node.state.allowParams = true;\n                    }\n                }\n\n                // If reading name, the name is done\n                if (node.state.allowName) {\n                    if (node.name !== '') {\n                        if (allowIndexed && node.name === 'indexed') {\n                            node.indexed = true;\n                            node.name = '';\n                        } else {\n                            node.state.allowName = false;\n                        }\n                    }\n                }\n\n                break;\n\n            case '[':\n                if (!node.state.allowArray) { throwError(i); }\n\n                node.type += c;\n\n                node.state.allowArray = false;\n                node.state.allowName = false;\n                node.state.readArray = true;\n                break;\n\n            case ']':\n                if (!node.state.readArray) { throwError(i); }\n\n                node.type += c;\n\n                node.state.readArray = false;\n                node.state.allowArray = true;\n                node.state.allowName = true;\n                break;\n\n            default:\n                if (node.state.allowType) {\n                    node.type += c;\n                    node.state.allowParams = true;\n                    node.state.allowArray = true;\n                } else if (node.state.allowName) {\n                    node.name += c;\n                    delete node.state.allowArray;\n                } else if (node.state.readArray) {\n                    node.type += c;\n                } else {\n                    throwError(i);\n                }\n        }\n    }\n\n    if (node.parent) { throw new Error(\"unexpected eof\"); }\n\n    delete parent.state;\n    parent.type = verifyType(parent.type);\n\n    return (<ParamType>parent);\n}\n\n// @TODO: should this just be a combined Fragment?\n\nexport type EventFragment = {\n    type: string\n    name: string,\n\n    anonymous: boolean,\n\n    inputs: Array<ParamType>,\n};\n\nexport type FunctionFragment = {\n    type: string\n    name: string,\n\n    constant: boolean,\n\n    inputs: Array<ParamType>,\n    outputs: Array<ParamType>,\n\n    payable: boolean,\n    stateMutability: string,\n};\n\n// @TODO: Better return type\nfunction parseSignatureEvent(fragment: string): EventFragment {\n\n    var abi: EventFragment = {\n        anonymous: false,\n        inputs: [],\n        name: '',\n        type: 'event'\n    }\n\n    var match = fragment.match(regexParen);\n    if (!match) { throw new Error('invalid event: ' + fragment); }\n\n    abi.name = match[1].trim();\n\n    splitNesting(match[2]).forEach(function(param) {\n        param = parseParam(param, true);\n        param.indexed = !!param.indexed;\n        abi.inputs.push(param);\n    });\n\n    match[3].split(' ').forEach(function(modifier) {\n        switch(modifier) {\n            case 'anonymous':\n                abi.anonymous = true;\n                break;\n            case '':\n                break;\n            default:\n                console.log('unknown modifier: ' + modifier);\n        }\n    });\n\n    if (abi.name && !abi.name.match(regexIdentifier)) {\n        throw new Error('invalid identifier: \"' + abi.name + '\"');\n    }\n\n    return abi;\n}\n\nfunction parseSignatureFunction(fragment: string): FunctionFragment {\n    var abi: FunctionFragment = {\n        constant: false,\n        inputs: [],\n        name: '',\n        outputs: [],\n        payable: false,\n        stateMutability: null,\n        type: 'function'\n    };\n\n    var comps = fragment.split(' returns ');\n    var left = comps[0].match(regexParen);\n    if (!left) { throw new Error('invalid signature'); }\n\n    abi.name = left[1].trim();\n    if (!abi.name.match(regexIdentifier)) {\n        throw new Error('invalid identifier: \"' + left[1] + '\"');\n    }\n\n    splitNesting(left[2]).forEach(function(param) {\n        abi.inputs.push(parseParam(param));\n    });\n\n    left[3].split(' ').forEach(function(modifier) {\n        switch (modifier) {\n            case 'constant':\n                abi.constant = true;\n                break;\n            case 'payable':\n                abi.payable = true;\n                break;\n            case 'pure':\n                abi.constant = true;\n                abi.stateMutability = 'pure';\n                break;\n            case 'view':\n                abi.constant = true;\n                abi.stateMutability = 'view';\n                break;\n            case '':\n                break;\n            default:\n                console.log('unknown modifier: ' + modifier);\n        }\n    });\n\n    // We have outputs\n    if (comps.length > 1) {\n        var right = comps[1].match(regexParen);\n        if (right[1].trim() != '' || right[3].trim() != '') {\n            throw new Error('unexpected tokens');\n        }\n\n        splitNesting(right[2]).forEach(function(param) {\n            abi.outputs.push(parseParam(param));\n        });\n    }\n\n    return abi;\n}\n\nexport function parseParamType(type: string): ParamType {\n    return parseParam(type, true);\n}\n\nexport function parseSignature(fragment: string): EventFragment | FunctionFragment {\n    if(typeof(fragment) === 'string') {\n        // Make sure the \"returns\" is surrounded by a space and all whitespace is exactly one space\n        fragment = fragment.replace(/\\(/g, ' (').replace(/\\)/g, ') ').replace(/\\s+/g, ' ');\n        fragment = fragment.trim();\n\n        if (fragment.substring(0, 6) === 'event ') {\n           return parseSignatureEvent(fragment.substring(6).trim());\n\n        } else {\n            if (fragment.substring(0, 9) === 'function ') {\n                fragment = fragment.substring(9);\n            }\n            return parseSignatureFunction(fragment.trim());\n        }\n    }\n\n    throw new Error('unknown signature');\n}\n\n\n///////////////////////////////////\n// Coders\n\ntype DecodedResult = { consumed: number, value: any };\nabstract class Coder {\n    readonly coerceFunc: CoerceFunc;\n    readonly name: string;\n    readonly type: string;\n    readonly localName: string;\n    readonly dynamic: boolean;\n    constructor(coerceFunc: CoerceFunc, name: string, type: string, localName: string, dynamic: boolean) {\n        this.coerceFunc = coerceFunc;\n        this.name = name;\n        this.type = type;\n        this.localName = localName;\n        this.dynamic = dynamic;\n    }\n\n    abstract encode(value: any): Uint8Array;\n    abstract decode(data: Uint8Array, offset: number): DecodedResult;\n}\n\nclass CoderNull extends Coder {\n    constructor(coerceFunc: CoerceFunc, localName: string) {\n        super(coerceFunc, 'null', '', localName, false);\n    }\n\n    encode(value: any): Uint8Array {\n        return arrayify([]);\n    }\n\n    decode(data: Uint8Array, offset: number): DecodedResult {\n        if (offset > data.length) { throw new Error('invalid null'); }\n        return {\n            consumed: 0,\n            value: this.coerceFunc('null', undefined)\n        }\n    }\n}\n\nclass CoderNumber extends Coder {\n    readonly size: number;\n    readonly signed: boolean;\n    constructor(coerceFunc: CoerceFunc, size: number, signed: boolean, localName: string) {\n        const name = ((signed ? 'int': 'uint') + (size * 8));\n        super(coerceFunc, name, name, localName, false);\n\n        this.size = size;\n        this.signed = signed;\n    }\n\n    encode(value: BigNumberish): Uint8Array {\n        try {\n            let v = bigNumberify(value);\n            v = v.toTwos(this.size * 8).maskn(this.size * 8);\n            //value = value.toTwos(size * 8).maskn(size * 8);\n            if (this.signed) {\n                v = v.fromTwos(this.size * 8).toTwos(256);\n            }\n            return padZeros(arrayify(v), 32);\n\n        } catch (error) {\n            errors.throwError('invalid number value', errors.INVALID_ARGUMENT, {\n                arg: this.localName,\n                type: typeof(value),\n                value: value\n            });\n        }\n        return null;\n    }\n\n    decode(data: Uint8Array, offset: number): DecodedResult {\n        if (data.length < offset + 32) {\n            errors.throwError('insufficient data for ' + this.name + ' type', errors.INVALID_ARGUMENT, {\n                arg: this.localName,\n                coderType: this.name,\n                value: hexlify(data.slice(offset, offset + 32))\n            });\n        }\n        var junkLength = 32 - this.size;\n        var value = bigNumberify(data.slice(offset + junkLength, offset + 32));\n        if (this.signed) {\n            value = value.fromTwos(this.size * 8);\n        } else {\n            value = value.maskn(this.size * 8);\n        }\n\n        return {\n            consumed: 32,\n            value: this.coerceFunc(this.name, value),\n        }\n    }\n}\nvar uint256Coder = new CoderNumber(function(type: string, value: any) { return value; }, 32, false, 'none');\n\nclass CoderBoolean extends Coder {\n    constructor(coerceFunc: CoerceFunc, localName: string) {\n        super(coerceFunc, 'bool', 'bool', localName, false);\n    }\n\n    encode(value: boolean): Uint8Array {\n        return uint256Coder.encode(!!value ? 1: 0);\n    }\n\n    decode(data: Uint8Array, offset: number): DecodedResult {\n        try {\n            var result = uint256Coder.decode(data, offset);\n        } catch (error) {\n            if (error.reason === 'insufficient data for uint256 type') {\n                errors.throwError('insufficient data for boolean type', errors.INVALID_ARGUMENT, {\n                    arg: this.localName,\n                    coderType: 'boolean',\n                    value: error.value\n                });\n            }\n            throw error;\n        }\n        return {\n            consumed: result.consumed,\n            value: this.coerceFunc('bool', !result.value.isZero())\n        }\n    }\n}\n\nclass CoderFixedBytes extends Coder {\n    readonly length: number;\n    constructor(coerceFunc: CoerceFunc, length: number, localName: string) {\n        const name = ('bytes' + length);\n        super(coerceFunc, name, name, localName, false);\n        this.length = length;\n    }\n\n    encode(value: Arrayish): Uint8Array {\n        var result = new Uint8Array(32);\n\n        try {\n            let data = arrayify(value);\n            if (data.length > 32) { throw new Error(); }\n            result.set(data);\n        } catch (error) {\n            errors.throwError('invalid ' + this.name + ' value', errors.INVALID_ARGUMENT, {\n                arg: this.localName,\n                type: typeof(value),\n                value: (error.value || value)\n            });\n        }\n\n        return result;\n    }\n\n    decode(data: Uint8Array, offset: number): DecodedResult {\n        if (data.length < offset + 32) {\n            errors.throwError('insufficient data for ' + name + ' type', errors.INVALID_ARGUMENT, {\n                arg: this.localName,\n                coderType: this.name,\n                value: hexlify(data.slice(offset, offset + 32))\n            });\n        }\n\n        return {\n            consumed: 32,\n            value: this.coerceFunc(this.name, hexlify(data.slice(offset, offset + this.length)))\n        }\n    }\n}\n\nclass CoderAddress extends Coder {\n    constructor(coerceFunc: CoerceFunc, localName: string) {\n        super(coerceFunc, 'address', 'address', localName, false);\n    }\n    encode(value: string): Uint8Array {\n        let result = new Uint8Array(32);\n        try {\n            result.set(arrayify(getAddress(value)), 12);\n        } catch (error) {\n            errors.throwError('invalid address', errors.INVALID_ARGUMENT, {\n                arg: this.localName,\n                type: typeof(value),\n                value: value\n            });\n        }\n        return result;\n    }\n    decode(data: Uint8Array, offset: number): DecodedResult {\n        if (data.length < offset + 32) {\n            errors.throwError('insufficuent data for address type', errors.INVALID_ARGUMENT, {\n                arg: this.localName,\n                coderType: 'address',\n                value: hexlify(data.slice(offset, offset + 32))\n            });\n        }\n        return {\n            consumed: 32,\n            value: this.coerceFunc('address', getAddress(hexlify(data.slice(offset + 12, offset + 32))))\n       }\n    }\n}\n\nfunction _encodeDynamicBytes(value: Uint8Array): Uint8Array {\n    var dataLength = 32 * Math.ceil(value.length / 32);\n    var padding = new Uint8Array(dataLength - value.length);\n\n    return concat([\n        uint256Coder.encode(value.length),\n        value,\n        padding\n    ]);\n}\n\nfunction _decodeDynamicBytes(data: Uint8Array, offset: number, localName: string): DecodedResult {\n    if (data.length < offset + 32) {\n        errors.throwError('insufficient data for dynamicBytes length', errors.INVALID_ARGUMENT, {\n            arg: localName,\n            coderType: 'dynamicBytes',\n            value: hexlify(data.slice(offset, offset + 32))\n        });\n    }\n\n    var length = uint256Coder.decode(data, offset).value;\n    try {\n        length = length.toNumber();\n    } catch (error) {\n        errors.throwError('dynamic bytes count too large', errors.INVALID_ARGUMENT, {\n            arg: localName,\n            coderType: 'dynamicBytes',\n            value: length.toString()\n        });\n    }\n\n    if (data.length < offset + 32 + length) {\n        errors.throwError('insufficient data for dynamicBytes type', errors.INVALID_ARGUMENT, {\n            arg: localName,\n            coderType: 'dynamicBytes',\n            value: hexlify(data.slice(offset, offset + 32 + length))\n        });\n    }\n\n    return {\n        consumed: 32 + 32 * Math.ceil(length / 32),\n        value: data.slice(offset + 32, offset + 32 + length),\n    }\n}\n\nclass CoderDynamicBytes extends Coder {\n    constructor(coerceFunc: CoerceFunc, localName: string) {\n        super(coerceFunc, 'bytes', 'bytes', localName, true);\n    }\n    encode(value: Arrayish): Uint8Array {\n        try {\n            return _encodeDynamicBytes(arrayify(value));\n        } catch (error) {\n            errors.throwError('invalid bytes value', errors.INVALID_ARGUMENT, {\n                arg: this.localName,\n                type: typeof(value),\n                value: error.value\n            });\n        }\n        return null;\n    }\n\n    decode(data: Uint8Array, offset: number): DecodedResult {\n        var result = _decodeDynamicBytes(data, offset, this.localName);\n        result.value = this.coerceFunc('bytes', hexlify(result.value));\n        return result;\n    }\n}\n\nclass CoderString extends Coder {\n    constructor(coerceFunc: CoerceFunc, localName: string) {\n        super(coerceFunc, 'string', 'string', localName, true);\n    }\n\n    encode(value: string): Uint8Array {\n        if (typeof(value) !== 'string') {\n            errors.throwError('invalid string value', errors.INVALID_ARGUMENT, {\n                arg: this.localName,\n                type: typeof(value),\n                value: value\n            });\n        }\n        return _encodeDynamicBytes(toUtf8Bytes(value));\n    }\n\n    decode(data: Uint8Array, offset: number): DecodedResult {\n        var result = _decodeDynamicBytes(data, offset, this.localName);\n        result.value = this.coerceFunc('string', toUtf8String(result.value));\n        return result;\n    }\n}\n\nfunction alignSize(size: number): number {\n    return 32 * Math.ceil(size / 32);\n}\n\nfunction pack(coders: Array<Coder>, values: Array<any>): Uint8Array {\n\n    if (Array.isArray(values)) {\n       // do nothing\n\n    } else if (values && typeof(values) === 'object') {\n        var arrayValues: Array<any> = [];\n        coders.forEach(function(coder) {\n            arrayValues.push((<any>values)[coder.localName]);\n        });\n        values = arrayValues;\n\n    } else {\n        errors.throwError('invalid tuple value', errors.INVALID_ARGUMENT, {\n            coderType: 'tuple',\n            type: typeof(values),\n            value: values\n        });\n    }\n\n    if (coders.length !== values.length) {\n        errors.throwError('types/value length mismatch', errors.INVALID_ARGUMENT, {\n            coderType: 'tuple',\n            value: values\n        });\n    }\n\n    var parts: Array<{ dynamic: boolean, value: any }> = [];\n\n    coders.forEach(function(coder, index) {\n        parts.push({ dynamic: coder.dynamic, value: coder.encode(values[index]) });\n    });\n\n    var staticSize = 0, dynamicSize = 0;\n    parts.forEach(function(part) {\n        if (part.dynamic) {\n            staticSize += 32;\n            dynamicSize += alignSize(part.value.length);\n        } else {\n            staticSize += alignSize(part.value.length);\n        }\n    });\n\n    var offset = 0, dynamicOffset = staticSize;\n    var data = new Uint8Array(staticSize + dynamicSize);\n\n    parts.forEach(function(part) {\n        if (part.dynamic) {\n            //uint256Coder.encode(dynamicOffset).copy(data, offset);\n            data.set(uint256Coder.encode(dynamicOffset), offset);\n            offset += 32;\n\n            //part.value.copy(data, dynamicOffset);  @TODO\n            data.set(part.value, dynamicOffset);\n            dynamicOffset += alignSize(part.value.length);\n        } else {\n            //part.value.copy(data, offset);  @TODO\n            data.set(part.value, offset);\n            offset += alignSize(part.value.length);\n        }\n    });\n\n    return data;\n}\n\nfunction unpack(coders: Array<Coder>, data: Uint8Array, offset: number): DecodedResult {\n    var baseOffset = offset;\n    var consumed = 0;\n    var value: any = [];\n    coders.forEach(function(coder) {\n        if (coder.dynamic) {\n            var dynamicOffset = uint256Coder.decode(data, offset);\n            var result = coder.decode(data, baseOffset + dynamicOffset.value.toNumber());\n            // The dynamic part is leap-frogged somewhere else; doesn't count towards size\n            result.consumed = dynamicOffset.consumed;\n        } else {\n            var result = coder.decode(data, offset);\n        }\n\n        if (result.value != undefined) {\n            value.push(result.value);\n        }\n\n        offset += result.consumed;\n        consumed += result.consumed;\n    });\n\n    coders.forEach(function(coder: Coder, index: number) {\n        let name: string = coder.localName;\n        if (!name) { return; }\n\n        if (name === 'length') { name = '_length'; }\n\n        if (value[name] != null) { return; }\n\n        value[name] = value[index];\n    });\n\n    return {\n        value: value,\n        consumed: consumed\n    }\n}\n\nclass CoderArray extends Coder {\n    readonly coder: Coder;\n    readonly length: number;\n    constructor(coerceFunc: CoerceFunc, coder: Coder, length: number, localName: string) {\n        const type = (coder.type + '[' + (length >= 0 ? length: '') + ']');\n        const dynamic = (length === -1 || coder.dynamic);\n        super(coerceFunc, 'array', type, localName, dynamic);\n\n        this.coder = coder;\n        this.length = length;\n    }\n\n    encode(value: Array<any>): Uint8Array {\n        if (!Array.isArray(value)) {\n            errors.throwError('expected array value', errors.INVALID_ARGUMENT, {\n                arg: this.localName,\n                coderType: 'array',\n                type: typeof(value),\n                value: value\n            });\n        }\n\n        var count = this.length;\n\n        var result = new Uint8Array(0);\n        if (count === -1) {\n            count = value.length;\n            result = uint256Coder.encode(count);\n        }\n\n        if (count !== value.length) {\n            errors.throwError('array value length mismatch', errors.INVALID_ARGUMENT, {\n                arg: this.localName,\n                coderType: 'array',\n                count: value.length,\n                expectedCount: count,\n                value: value\n            });\n        }\n\n        var coders = [];\n        for (var i = 0; i < value.length; i++) { coders.push(this.coder); }\n\n        return concat([result, pack(coders, value)]);\n    }\n\n    decode(data: Uint8Array, offset: number) {\n        // @TODO:\n        //if (data.length < offset + length * 32) { throw new Error('invalid array'); }\n\n        var consumed = 0;\n\n        var count = this.length;\n\n        if (count === -1) {\n            try {\n                var decodedLength = uint256Coder.decode(data, offset);\n            } catch (error) {\n                errors.throwError('insufficient data for dynamic array length', errors.INVALID_ARGUMENT, {\n                    arg: this.localName,\n                    coderType: 'array',\n                    value: error.value\n                });\n             }\n             try {\n                 count = decodedLength.value.toNumber();\n             } catch (error) {\n                 errors.throwError('array count too large', errors.INVALID_ARGUMENT, {\n                     arg: this.localName,\n                     coderType: 'array',\n                     value: decodedLength.value.toString()\n                 });\n             }\n             consumed += decodedLength.consumed;\n             offset += decodedLength.consumed;\n        }\n\n        var coders = [];\n        for (var i = 0; i < count; i++) { coders.push(this.coder); }\n\n        var result = unpack(coders, data, offset);\n        result.consumed += consumed;\n        result.value = this.coerceFunc(this.type, result.value);\n        return result;\n    }\n}\n\nclass CoderTuple extends Coder {\n    readonly coders: Array<Coder>;\n    constructor(coerceFunc: CoerceFunc, coders: Array<Coder>, localName: string) {\n        var dynamic = false;\n        var types: Array<string> = [];\n        coders.forEach(function(coder) {\n            if (coder.dynamic) { dynamic = true; }\n            types.push(coder.type);\n        });\n        var type = ('tuple(' + types.join(',') + ')');\n\n        super(coerceFunc, 'tuple', type, localName, dynamic);\n        this.coders = coders;\n    }\n    encode(value: Array<any>): Uint8Array {\n        return pack(this.coders, value);\n    }\n    decode(data: Uint8Array, offset: number): DecodedResult {\n        var result = unpack(this.coders, data, offset);\n        result.value = this.coerceFunc(this.type, result.value);\n        return result;\n    }\n}\n/*\nfunction getTypes(coders) {\n    var type = coderTuple(coders).type;\n    return type.substring(6, type.length - 1);\n}\n*/\nfunction splitNesting(value: string): Array<any> {\n    var result = [];\n    var accum = '';\n    var depth = 0;\n    for (var offset = 0; offset < value.length; offset++) {\n        var c = value[offset];\n        if (c === ',' && depth === 0) {\n            result.push(accum);\n            accum = '';\n        } else {\n            accum += c;\n            if (c === '(') {\n                depth++;\n            } else if (c === ')') {\n                depth--;\n                if (depth === -1) {\n                    throw new Error('unbalanced parenthsis');\n                }\n            }\n        }\n    }\n    result.push(accum);\n\n    return result;\n}\n\n// @TODO: Is there a way to return \"class\"?\nconst paramTypeSimple: { [key: string]: any } = {\n    address: CoderAddress,\n    bool: CoderBoolean,\n    string: CoderString,\n    bytes: CoderDynamicBytes,\n};\n\nfunction getTupleParamCoder(coerceFunc: CoerceFunc, components: Array<any>, localName: string): CoderTuple {\n    if (!components) { components = []; }\n    var coders: Array<Coder> = [];\n    components.forEach(function(component) {\n        coders.push(getParamCoder(coerceFunc, component));\n    });\n\n    return new CoderTuple(coerceFunc, coders, localName);\n}\n\nfunction getParamCoder(coerceFunc: CoerceFunc, param: ParamType): Coder {\n    var coder = paramTypeSimple[param.type];\n    if (coder) { return new coder(coerceFunc, param.name); }\n    var match = param.type.match(paramTypeNumber);\n    if (match) {\n        let size = parseInt(match[2] || \"256\");\n        if (size === 0 || size > 256 || (size % 8) !== 0) {\n            errors.throwError('invalid ' + match[1] + ' bit length', errors.INVALID_ARGUMENT, {\n                arg: 'param',\n                value: param\n            });\n        }\n        return new CoderNumber(coerceFunc, size / 8, (match[1] === 'int'), param.name);\n    }\n\n    var match = param.type.match(paramTypeBytes);\n    if (match) {\n        let size = parseInt(match[1]);\n        if (size === 0 || size > 32) {\n            errors.throwError('invalid bytes length', errors.INVALID_ARGUMENT, {\n                arg: 'param',\n                value: param\n            });\n        }\n        return new CoderFixedBytes(coerceFunc, size, param.name);\n    }\n\n    var match = param.type.match(paramTypeArray);\n    if (match) {\n        let size = parseInt(match[2] || \"-1\");\n        param.type = match[1];\n        return new CoderArray(coerceFunc, getParamCoder(coerceFunc, param), size, param.name);\n    }\n\n    if (param.type.substring(0, 5) === 'tuple') {\n        return getTupleParamCoder(coerceFunc, param.components, param.name);\n    }\n\n    if (param.type === '') {\n        return new CoderNull(coerceFunc, param.name);\n    }\n\n    errors.throwError('invalid type', errors.INVALID_ARGUMENT, {\n        arg: 'type',\n        value: param.type\n    });\n\n    return null;\n}\n\n\nexport class AbiCoder {\n    readonly coerceFunc: CoerceFunc;\n    constructor(coerceFunc?: CoerceFunc) {\n        errors.checkNew(this, AbiCoder);\n\n        if (!coerceFunc) { coerceFunc = defaultCoerceFunc; }\n        defineReadOnly(this, 'coerceFunc', coerceFunc);\n    }\n\n    encode(types: Array<string | ParamType>, values: Array<any>): string {\n\n        if (types.length !== values.length) {\n            errors.throwError('types/values length mismatch', errors.INVALID_ARGUMENT, {\n                count: { types: types.length, values: values.length },\n                value: { types: types, values: values }\n            });\n        }\n\n        var coders: Array<Coder> = [];\n        types.forEach(function(type) {\n            // Convert types to type objects\n            //   - \"uint foo\" => { type: \"uint\", name: \"foo\" }\n            //   - \"tuple(uint, uint)\" => { type: \"tuple\", components: [ { type: \"uint\" }, { type: \"uint\" }, ] }\n\n            let typeObject: ParamType = null;\n            if (typeof(type) === 'string') {\n                typeObject = parseParam(type);\n            } else {\n                typeObject = jsonCopy(type);\n            }\n\n            coders.push(getParamCoder(this.coerceFunc, typeObject));\n\n        }, this);\n\n        return hexlify(new CoderTuple(this.coerceFunc, coders, '_').encode(values));\n    }\n\n    decode(types: Array<string | ParamType>, data: Arrayish): any {\n\n        var coders: Array<Coder> = [];\n        types.forEach(function(type) {\n\n            // See encode for details\n            let typeObject: ParamType = null;\n            if (typeof(type) === 'string') {\n                typeObject = parseParam(type);\n            } else {\n                typeObject = jsonCopy(type);\n            }\n\n            coders.push(getParamCoder(this.coerceFunc, typeObject));\n        }, this);\n\n        return new CoderTuple(this.coerceFunc, coders, '_').decode(arrayify(data), 0).value;\n    }\n}\n\nexport const defaultAbiCoder: AbiCoder = new AbiCoder();\n","'use strict';\n\n// See: https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI\n\nimport { defaultAbiCoder, EventFragment, FunctionFragment, ParamType, parseSignature } from '../utils/abi-coder';\nimport { BigNumber, bigNumberify, BigNumberish } from '../utils/bignumber';\nimport { arrayify, concat, isHexString } from '../utils/bytes';\nimport { keccak256 } from '../utils/keccak256';\nimport { toUtf8Bytes } from '../utils/utf8';\nimport { defineReadOnly, defineFrozen } from '../utils/properties';\n\nimport * as errors from '../utils/errors';\n\n// @TODO: Replace with a new abiCode.formatSignature method\nfunction parseParams(params: Array<ParamType>): { names: Array<any>, types: Array<string> } {\n    var names: Array<any> = [];\n    var types: Array<string> = [];\n\n    params.forEach(function(param) {\n        if (param.components != null) {\n            if (param.type.substring(0, 5) !== 'tuple') {\n                throw new Error('internal error; report on GitHub');\n            }\n            var suffix = '';\n            var arrayBracket = param.type.indexOf('[');\n            if (arrayBracket >= 0) { suffix = param.type.substring(arrayBracket); }\n\n            var result = parseParams(param.components);\n            names.push({ name: (param.name || null), names: result.names });\n            types.push('tuple(' + result.types.join(',') + ')' + suffix)\n        } else {\n            names.push(param.name || null);\n            types.push(param.type);\n        }\n    });\n\n    return {\n        names: names,\n        types: types\n    }\n}\n\nexport class Description {\n    readonly type: string;\n    constructor(info: any) {\n        for (var key in info) {\n            let value = info[key];\n            if (value != null && typeof(value) === 'object') {\n                defineFrozen(this, key, info[key]);\n            } else {\n                defineReadOnly(this, key, info[key]);\n            }\n        }\n    }\n}\n\n// @TOOD: Make this a description\nexport class Indexed extends Description {\n    readonly hash: string;\n}\n\nexport class DeployDescription extends Description {\n    readonly inputs: Array<ParamType>;\n    readonly payable: boolean;\n\n    encode(bytecode: string, params: Array<any>): string {\n        if (!isHexString(bytecode)) {\n            errors.throwError('invalid contract bytecode', errors.INVALID_ARGUMENT, {\n                arg: 'bytecode',\n                type: typeof(bytecode),\n                value: bytecode\n            });\n        }\n\n        if (params.length < this.inputs.length) {\n            errors.throwError('missing constructor argument', errors.MISSING_ARGUMENT, {\n                arg: (this.inputs[params.length].name || 'unknown'),\n                count: params.length,\n                expectedCount: this.inputs.length\n            });\n\n        } else if (params.length > this.inputs.length) {\n            errors.throwError('too many constructor arguments', errors.UNEXPECTED_ARGUMENT, {\n                count: params.length,\n                expectedCount: this.inputs.length\n            });\n        }\n\n        try {\n            return (bytecode + defaultAbiCoder.encode(this.inputs, params).substring(2));\n        } catch (error) {\n            errors.throwError('invalid constructor argument', errors.INVALID_ARGUMENT, {\n                arg: error.arg,\n                reason: error.reason,\n                value: error.value\n            });\n        }\n\n        return null;\n    }\n}\n\nexport class FunctionDescription extends Description {\n    readonly name: string;\n    readonly signature: string;\n    readonly sighash: string;\n\n    readonly inputs: Array<ParamType>;\n    readonly outputs: Array<ParamType>;\n    readonly payable: boolean;\n\n    encode(params: Array<any>): string {\n        if (params.length < this.inputs.length) {\n            errors.throwError('missing input argument', errors.MISSING_ARGUMENT, {\n                arg: (this.inputs[params.length].name || 'unknown'),\n                count: params.length,\n                expectedCount: this.inputs.length,\n                name: this.name\n            });\n        } else if (params.length > this.inputs.length) {\n            errors.throwError('too many input arguments', errors.UNEXPECTED_ARGUMENT, {\n                count: params.length,\n                expectedCount: this.inputs.length\n            });\n        }\n\n        try {\n            return this.sighash + defaultAbiCoder.encode(this.inputs, params).substring(2);\n        } catch (error) {\n            errors.throwError('invalid input argument', errors.INVALID_ARGUMENT, {\n                arg: error.arg,\n                reason: error.reason,\n                value: error.value\n            });\n        }\n\n        return null;\n    }\n\n    decode(data: string): any {\n        try {\n            return defaultAbiCoder.decode(this.outputs, arrayify(data));\n        } catch(error) {\n            errors.throwError('invalid data for function output', errors.INVALID_ARGUMENT, {\n                arg: 'data',\n                errorArg: error.arg,\n                errorValue: error.value,\n                value: data,\n                reason: error.reason\n            });\n        }\n    }\n}\n\nclass Result extends Description {\n    [key: string]: any;\n    [key: number]: any;\n}\n\nexport class EventDescription extends Description {\n    readonly name: string;\n    readonly signature: string;\n\n    readonly inputs: Array<ParamType>;\n    readonly anonymous: boolean;\n    readonly topic: string;\n\n    decode(data: string, topics?: Array<string>): any {\n        // Strip the signature off of non-anonymous topics\n        if (topics != null && !this.anonymous) { topics = topics.slice(1); }\n\n        let inputIndexed: Array<ParamType> = [];\n        let inputNonIndexed: Array<ParamType> = [];\n        let inputDynamic: Array<boolean> = [];\n        this.inputs.forEach(function(param, index) {\n\n            if (param.indexed) {\n                if (param.type === 'string' || param.type === 'bytes' || param.type.indexOf('[') >= 0 || param.type.substring(0, 5) === 'tuple') {\n                    inputIndexed.push({ type: 'bytes32', name: (param.name || '')});\n                    inputDynamic.push(true);\n                } else {\n                    inputIndexed.push(param);\n                    inputDynamic.push(false);\n                }\n            } else {\n                inputNonIndexed.push(param);\n                inputDynamic.push(false);\n            }\n        });\n\n        if (topics != null) {\n            var resultIndexed = defaultAbiCoder.decode(\n                inputIndexed,\n                concat(topics)\n            );\n        }\n\n        var resultNonIndexed = defaultAbiCoder.decode(\n            inputNonIndexed,\n            arrayify(data)\n        );\n\n        var result = new Result({});\n        var nonIndexedIndex = 0, indexedIndex = 0;\n        this.inputs.forEach(function(input, index) {\n            if (input.indexed) {\n                if (topics == null) {\n                    result[index] = new Indexed({ type: 'indexed', hash: null });\n\n                } else if (inputDynamic[index]) {\n                    result[index] = new Indexed({ type: 'indexed', hash: resultIndexed[indexedIndex++] });\n                } else {\n                    result[index] = resultIndexed[indexedIndex++];\n                }\n            } else {\n                result[index] = resultNonIndexed[nonIndexedIndex++];\n            }\n            if (input.name) { result[input.name] = result[index]; }\n        });\n\n        result.length = this.inputs.length;\n\n        return result;\n    }\n}\n\nclass TransactionDescription extends Description {\n    readonly name: string;\n    readonly args: Array<any>;\n    readonly signature: string;\n    readonly sighash: string;\n    readonly decode: (data: string) => any;\n    readonly value: BigNumber;\n}\n\nclass LogDescription extends Description {\n    readonly name: string;\n    readonly signature: string;\n    readonly topic: string;\n    readonly values: Array<any>\n}\n\n\nfunction addMethod(method: any): void {\n    switch (method.type) {\n        case 'constructor': {\n            let description = new DeployDescription({\n                inputs: method.inputs,\n                payable: (method.payable == null || !!method.payable),\n                type: 'deploy'\n            });\n\n            if (!this.deployFunction) { this.deployFunction = description; }\n\n            break;\n        }\n\n        case 'function': {\n            // @TODO: See event\n            let signature = '(' + parseParams(method.inputs).types.join(',') + ')';\n            signature = signature.replace(/tuple/g, '');\n            signature = method.name + signature;\n\n            let sighash = keccak256(toUtf8Bytes(signature)).substring(0, 10);\n\n            let description = new FunctionDescription({\n                inputs: method.inputs,\n                outputs: method.outputs,\n\n                payable: (method.payable == null || !!method.payable),\n                type: ((method.constant) ? 'call': 'transaction'),\n\n                signature: signature,\n                sighash: sighash,\n            });\n\n            // Expose the first (and hopefully unique named function\n            if (method.name && this.functions[method.name] == null) {\n                defineReadOnly(this.functions, method.name, description);\n            }\n\n            // Expose all methods by their signature, for overloaded functions\n            if (this.functions[description.signature] == null) {\n                defineReadOnly(this.functions, description.signature, description);\n            }\n\n            break;\n        }\n\n        case 'event': {\n            // @TODO: method.params instead? As well? Different fomrat?\n            //let inputParams = parseParams(method.inputs);\n\n            // @TODO: Don't use parseParams (create new function in ABI, formatSignature)\n            let signature = '(' + parseParams(method.inputs).types.join(',') + ')';\n            signature = signature.replace(/tuple/g, '');\n            signature = method.name + signature;\n\n            let description = new EventDescription({\n                name: method.name,\n                signature: signature,\n\n                inputs: method.inputs,\n                topic: keccak256(toUtf8Bytes(signature)),\n                anonymous: (!!method.anonymous),\n\n                type: 'event'\n            });\n\n            // Expose the first (and hopefully unique) event name\n            if (method.name && this.events[method.name] == null) {\n                defineReadOnly(this.events, method.name, description);\n            }\n\n            // Expose all events by their signature, for overloaded functions\n            if (this.events[description.signature] == null) {\n                defineReadOnly(this.events, description.signature, description);\n            }\n\n            break;\n        }\n\n\n        case 'fallback':\n            // Nothing to do for fallback\n            break;\n\n        default:\n            console.log('WARNING: unsupported ABI type - ' + method.type);\n            break;\n    }\n}\n\nexport class Interface {\n    readonly abi: Array<EventFragment | FunctionFragment>;\n    readonly functions: { [ name: string ]: FunctionDescription };\n    readonly events: { [ name: string ]: EventDescription };\n    readonly deployFunction: DeployDescription;\n\n    constructor(abi: Array<string | ParamType> | string) {\n        errors.checkNew(this, Interface);\n\n        if (typeof(abi) === 'string') {\n            try {\n                abi = JSON.parse(abi);\n            } catch (error) {\n                errors.throwError('could not parse ABI JSON', errors.INVALID_ARGUMENT, {\n                    arg: 'abi',\n                    errorMessage: error.message,\n                    value: abi\n                });\n            }\n\n            if (!Array.isArray(abi)) {\n                errors.throwError('invalid abi', errors.INVALID_ARGUMENT, { arg: 'abi', value: abi });\n                return null;\n            }\n        }\n\n        defineReadOnly(this, 'functions', { });\n        defineReadOnly(this, 'events', { });\n\n        // Convert any supported ABI format into a standard ABI format\n        let _abi: Array<EventFragment | FunctionFragment> = [];\n        abi.forEach((fragment) => {\n            if (typeof(fragment) === 'string') {\n                fragment = parseSignature(fragment);\n            }\n            // @TODO: We should probable do some validation; create abiCoder.formatSignature for checking\n            _abi.push(<EventFragment | FunctionFragment>fragment);\n        });\n\n        defineFrozen(this, 'abi', _abi);\n\n        _abi.forEach(addMethod, this);\n\n        // If there wasn't a constructor, create the default constructor\n        if (!this.deployFunction) {\n            addMethod.call(this, {type: 'constructor', inputs: []});\n        }\n    }\n\n    parseTransaction(tx: { data: string, value?: BigNumberish }): TransactionDescription {\n        var sighash = tx.data.substring(0, 10).toLowerCase();\n        for (var name in this.functions) {\n            if (name.indexOf('(') === -1) { continue; }\n            var func = this.functions[name];\n            if (func.sighash === sighash) {\n                var result = defaultAbiCoder.decode(func.inputs, '0x' + tx.data.substring(10));\n                return new TransactionDescription({\n                    args: result,\n                    decode: func.decode,\n                    name: name,\n                    signature: func.signature,\n                    sighash: func.sighash,\n                    type: 'transaction',\n                    value: bigNumberify(tx.value || 0),\n                });\n            }\n        }\n\n        return null;\n    }\n\n    parseLog(log: { topics: Array<string>, data: string}): LogDescription {\n        for (var name in this.events) {\n            if (name.indexOf('(') === -1) { continue; }\n            var event = this.events[name];\n            if (event.anonymous) { continue; }\n            if (event.topic !== log.topics[0]) { continue; }\n\n            // @TODO: If anonymous, and the only method, and the input count matches, should we parse and return it?\n\n            return new LogDescription({\n                name: event.name,\n                signature: event.signature,\n                topic: event.topic,\n                type: 'log',\n                values: event.decode(log.data, log.topics)\n            });\n        }\n\n        return null;\n    }\n}\n","\n// This gets overriddenby gulp during bip39-XX\nvar exportWordlist = false;\n\nimport { defineReadOnly } from '../utils/properties';\n\nexport abstract class Wordlist {\n    locale: string;\n\n    constructor(locale: string) {\n        defineReadOnly(this, 'locale', locale);\n    }\n\n    abstract getWord(index: number): string;\n    abstract getWordIndex(word: string): number;\n\n    // Subclasses may override this\n    split(mnemonic: string): Array<string> {\n        return mnemonic.toLowerCase().split(/ +/g)\n    }\n\n    // Subclasses may override this\n    join(words: Array<string>): string {\n        return words.join(' ');\n    }\n}\n\nexport function register(lang: Wordlist): void {\n    if (exportWordlist) {\n        if (!(<any>global).wordlists) { defineReadOnly(global, 'wordlists', { }); }\n        defineReadOnly((<any>global).wordlists, lang.locale, lang);\n    }\n}\n","'use strict';\n\nimport { register, Wordlist } from './wordlist';\n\nconst words = \"AbandonAbilityAbleAboutAboveAbsentAbsorbAbstractAbsurdAbuseAccessAccidentAccountAccuseAchieveAcidAcousticAcquireAcrossActActionActorActressActualAdaptAddAddictAddressAdjustAdmitAdultAdvanceAdviceAerobicAffairAffordAfraidAgainAgeAgentAgreeAheadAimAirAirportAisleAlarmAlbumAlcoholAlertAlienAllAlleyAllowAlmostAloneAlphaAlreadyAlsoAlterAlwaysAmateurAmazingAmongAmountAmusedAnalystAnchorAncientAngerAngleAngryAnimalAnkleAnnounceAnnualAnotherAnswerAntennaAntiqueAnxietyAnyApartApologyAppearAppleApproveAprilArchArcticAreaArenaArgueArmArmedArmorArmyAroundArrangeArrestArriveArrowArtArtefactArtistArtworkAskAspectAssaultAssetAssistAssumeAsthmaAthleteAtomAttackAttendAttitudeAttractAuctionAuditAugustAuntAuthorAutoAutumnAverageAvocadoAvoidAwakeAwareAwayAwesomeAwfulAwkwardAxisBabyBachelorBaconBadgeBagBalanceBalconyBallBambooBananaBannerBarBarelyBargainBarrelBaseBasicBasketBattleBeachBeanBeautyBecauseBecomeBeefBeforeBeginBehaveBehindBelieveBelowBeltBenchBenefitBestBetrayBetterBetweenBeyondBicycleBidBikeBindBiologyBirdBirthBitterBlackBladeBlameBlanketBlastBleakBlessBlindBloodBlossomBlouseBlueBlurBlushBoardBoatBodyBoilBombBoneBonusBookBoostBorderBoringBorrowBossBottomBounceBoxBoyBracketBrainBrandBrassBraveBreadBreezeBrickBridgeBriefBrightBringBriskBroccoliBrokenBronzeBroomBrotherBrownBrushBubbleBuddyBudgetBuffaloBuildBulbBulkBulletBundleBunkerBurdenBurgerBurstBusBusinessBusyButterBuyerBuzzCabbageCabinCableCactusCageCakeCallCalmCameraCampCanCanalCancelCandyCannonCanoeCanvasCanyonCapableCapitalCaptainCarCarbonCardCargoCarpetCarryCartCaseCashCasinoCastleCasualCatCatalogCatchCategoryCattleCaughtCauseCautionCaveCeilingCeleryCementCensusCenturyCerealCertainChairChalkChampionChangeChaosChapterChargeChaseChatCheapCheckCheeseChefCherryChestChickenChiefChildChimneyChoiceChooseChronicChuckleChunkChurnCigarCinnamonCircleCitizenCityCivilClaimClapClarifyClawClayCleanClerkCleverClickClientCliffClimbClinicClipClockClogCloseClothCloudClownClubClumpClusterClutchCoachCoastCoconutCodeCoffeeCoilCoinCollectColorColumnCombineComeComfortComicCommonCompanyConcertConductConfirmCongressConnectConsiderControlConvinceCookCoolCopperCopyCoralCoreCornCorrectCostCottonCouchCountryCoupleCourseCousinCoverCoyoteCrackCradleCraftCramCraneCrashCraterCrawlCrazyCreamCreditCreekCrewCricketCrimeCrispCriticCropCrossCrouchCrowdCrucialCruelCruiseCrumbleCrunchCrushCryCrystalCubeCultureCupCupboardCuriousCurrentCurtainCurveCushionCustomCuteCycleDadDamageDampDanceDangerDaringDashDaughterDawnDayDealDebateDebrisDecadeDecemberDecideDeclineDecorateDecreaseDeerDefenseDefineDefyDegreeDelayDeliverDemandDemiseDenialDentistDenyDepartDependDepositDepthDeputyDeriveDescribeDesertDesignDeskDespairDestroyDetailDetectDevelopDeviceDevoteDiagramDialDiamondDiaryDiceDieselDietDifferDigitalDignityDilemmaDinnerDinosaurDirectDirtDisagreeDiscoverDiseaseDishDismissDisorderDisplayDistanceDivertDivideDivorceDizzyDoctorDocumentDogDollDolphinDomainDonateDonkeyDonorDoorDoseDoubleDoveDraftDragonDramaDrasticDrawDreamDressDriftDrillDrinkDripDriveDropDrumDryDuckDumbDuneDuringDustDutchDutyDwarfDynamicEagerEagleEarlyEarnEarthEasilyEastEasyEchoEcologyEconomyEdgeEditEducateEffortEggEightEitherElbowElderElectricElegantElementElephantElevatorEliteElseEmbarkEmbodyEmbraceEmergeEmotionEmployEmpowerEmptyEnableEnactEndEndlessEndorseEnemyEnergyEnforceEngageEngineEnhanceEnjoyEnlistEnoughEnrichEnrollEnsureEnterEntireEntryEnvelopeEpisodeEqualEquipEraEraseErodeErosionErrorEruptEscapeEssayEssenceEstateEternalEthicsEvidenceEvilEvokeEvolveExactExampleExcessExchangeExciteExcludeExcuseExecuteExerciseExhaustExhibitExileExistExitExoticExpandExpectExpireExplainExposeExpressExtendExtraEyeEyebrowFabricFaceFacultyFadeFaintFaithFallFalseFameFamilyFamousFanFancyFantasyFarmFashionFatFatalFatherFatigueFaultFavoriteFeatureFebruaryFederalFeeFeedFeelFemaleFenceFestivalFetchFeverFewFiberFictionFieldFigureFileFilmFilterFinalFindFineFingerFinishFireFirmFirstFiscalFishFitFitnessFixFlagFlameFlashFlatFlavorFleeFlightFlipFloatFlockFloorFlowerFluidFlushFlyFoamFocusFogFoilFoldFollowFoodFootForceForestForgetForkFortuneForumForwardFossilFosterFoundFoxFragileFrameFrequentFreshFriendFringeFrogFrontFrostFrownFrozenFruitFuelFunFunnyFurnaceFuryFutureGadgetGainGalaxyGalleryGameGapGarageGarbageGardenGarlicGarmentGasGaspGateGatherGaugeGazeGeneralGeniusGenreGentleGenuineGestureGhostGiantGiftGiggleGingerGiraffeGirlGiveGladGlanceGlareGlassGlideGlimpseGlobeGloomGloryGloveGlowGlueGoatGoddessGoldGoodGooseGorillaGospelGossipGovernGownGrabGraceGrainGrantGrapeGrassGravityGreatGreenGridGriefGritGroceryGroupGrowGruntGuardGuessGuideGuiltGuitarGunGymHabitHairHalfHammerHamsterHandHappyHarborHardHarshHarvestHatHaveHawkHazardHeadHealthHeartHeavyHedgehogHeightHelloHelmetHelpHenHeroHiddenHighHillHintHipHireHistoryHobbyHockeyHoldHoleHolidayHollowHomeHoneyHoodHopeHornHorrorHorseHospitalHostHotelHourHoverHubHugeHumanHumbleHumorHundredHungryHuntHurdleHurryHurtHusbandHybridIceIconIdeaIdentifyIdleIgnoreIllIllegalIllnessImageImitateImmenseImmuneImpactImposeImproveImpulseInchIncludeIncomeIncreaseIndexIndicateIndoorIndustryInfantInflictInformInhaleInheritInitialInjectInjuryInmateInnerInnocentInputInquiryInsaneInsectInsideInspireInstallIntactInterestIntoInvestInviteInvolveIronIslandIsolateIssueItemIvoryJacketJaguarJarJazzJealousJeansJellyJewelJobJoinJokeJourneyJoyJudgeJuiceJumpJungleJuniorJunkJustKangarooKeenKeepKetchupKeyKickKidKidneyKindKingdomKissKitKitchenKiteKittenKiwiKneeKnifeKnockKnowLabLabelLaborLadderLadyLakeLampLanguageLaptopLargeLaterLatinLaughLaundryLavaLawLawnLawsuitLayerLazyLeaderLeafLearnLeaveLectureLeftLegLegalLegendLeisureLemonLendLengthLensLeopardLessonLetterLevelLiarLibertyLibraryLicenseLifeLiftLightLikeLimbLimitLinkLionLiquidListLittleLiveLizardLoadLoanLobsterLocalLockLogicLonelyLongLoopLotteryLoudLoungeLoveLoyalLuckyLuggageLumberLunarLunchLuxuryLyricsMachineMadMagicMagnetMaidMailMainMajorMakeMammalManManageMandateMangoMansionManualMapleMarbleMarchMarginMarineMarketMarriageMaskMassMasterMatchMaterialMathMatrixMatterMaximumMazeMeadowMeanMeasureMeatMechanicMedalMediaMelodyMeltMemberMemoryMentionMenuMercyMergeMeritMerryMeshMessageMetalMethodMiddleMidnightMilkMillionMimicMindMinimumMinorMinuteMiracleMirrorMiseryMissMistakeMixMixedMixtureMobileModelModifyMomMomentMonitorMonkeyMonsterMonthMoonMoralMoreMorningMosquitoMotherMotionMotorMountainMouseMoveMovieMuchMuffinMuleMultiplyMuscleMuseumMushroomMusicMustMutualMyselfMysteryMythNaiveNameNapkinNarrowNastyNationNatureNearNeckNeedNegativeNeglectNeitherNephewNerveNestNetNetworkNeutralNeverNewsNextNiceNightNobleNoiseNomineeNoodleNormalNorthNoseNotableNoteNothingNoticeNovelNowNuclearNumberNurseNutOakObeyObjectObligeObscureObserveObtainObviousOccurOceanOctoberOdorOffOfferOfficeOftenOilOkayOldOliveOlympicOmitOnceOneOnionOnlineOnlyOpenOperaOpinionOpposeOptionOrangeOrbitOrchardOrderOrdinaryOrganOrientOriginalOrphanOstrichOtherOutdoorOuterOutputOutsideOvalOvenOverOwnOwnerOxygenOysterOzonePactPaddlePagePairPalacePalmPandaPanelPanicPantherPaperParadeParentParkParrotPartyPassPatchPathPatientPatrolPatternPausePavePaymentPeacePeanutPearPeasantPelicanPenPenaltyPencilPeoplePepperPerfectPermitPersonPetPhonePhotoPhrasePhysicalPianoPicnicPicturePiecePigPigeonPillPilotPinkPioneerPipePistolPitchPizzaPlacePlanetPlasticPlatePlayPleasePledgePluckPlugPlungePoemPoetPointPolarPolePolicePondPonyPoolPopularPortionPositionPossiblePostPotatoPotteryPovertyPowderPowerPracticePraisePredictPreferPreparePresentPrettyPreventPricePridePrimaryPrintPriorityPrisonPrivatePrizeProblemProcessProduceProfitProgramProjectPromoteProofPropertyProsperProtectProudProvidePublicPuddingPullPulpPulsePumpkinPunchPupilPuppyPurchasePurityPurposePursePushPutPuzzlePyramidQualityQuantumQuarterQuestionQuickQuitQuizQuoteRabbitRaccoonRaceRackRadarRadioRailRainRaiseRallyRampRanchRandomRangeRapidRareRateRatherRavenRawRazorReadyRealReasonRebelRebuildRecallReceiveRecipeRecordRecycleReduceReflectReformRefuseRegionRegretRegularRejectRelaxReleaseReliefRelyRemainRememberRemindRemoveRenderRenewRentReopenRepairRepeatReplaceReportRequireRescueResembleResistResourceResponseResultRetireRetreatReturnReunionRevealReviewRewardRhythmRibRibbonRiceRichRideRidgeRifleRightRigidRingRiotRippleRiskRitualRivalRiverRoadRoastRobotRobustRocketRomanceRoofRookieRoomRoseRotateRoughRoundRouteRoyalRubberRudeRugRuleRunRunwayRuralSadSaddleSadnessSafeSailSaladSalmonSalonSaltSaluteSameSampleSandSatisfySatoshiSauceSausageSaveSayScaleScanScareScatterSceneSchemeSchoolScienceScissorsScorpionScoutScrapScreenScriptScrubSeaSearchSeasonSeatSecondSecretSectionSecuritySeedSeekSegmentSelectSellSeminarSeniorSenseSentenceSeriesServiceSessionSettleSetupSevenShadowShaftShallowShareShedShellSheriffShieldShiftShineShipShiverShockShoeShootShopShortShoulderShoveShrimpShrugShuffleShySiblingSickSideSiegeSightSignSilentSilkSillySilverSimilarSimpleSinceSingSirenSisterSituateSixSizeSkateSketchSkiSkillSkinSkirtSkullSlabSlamSleepSlenderSliceSlideSlightSlimSloganSlotSlowSlushSmallSmartSmileSmokeSmoothSnackSnakeSnapSniffSnowSoapSoccerSocialSockSodaSoftSolarSoldierSolidSolutionSolveSomeoneSongSoonSorrySortSoulSoundSoupSourceSouthSpaceSpareSpatialSpawnSpeakSpecialSpeedSpellSpendSphereSpiceSpiderSpikeSpinSpiritSplitSpoilSponsorSpoonSportSpotSpraySpreadSpringSpySquareSqueezeSquirrelStableStadiumStaffStageStairsStampStandStartStateStaySteakSteelStemStepStereoStickStillStingStockStomachStoneStoolStoryStoveStrategyStreetStrikeStrongStruggleStudentStuffStumbleStyleSubjectSubmitSubwaySuccessSuchSuddenSufferSugarSuggestSuitSummerSunSunnySunsetSuperSupplySupremeSureSurfaceSurgeSurpriseSurroundSurveySuspectSustainSwallowSwampSwapSwarmSwearSweetSwiftSwimSwingSwitchSwordSymbolSymptomSyrupSystemTableTackleTagTailTalentTalkTankTapeTargetTaskTasteTattooTaxiTeachTeamTellTenTenantTennisTentTermTestTextThankThatThemeThenTheoryThereTheyThingThisThoughtThreeThriveThrowThumbThunderTicketTideTigerTiltTimberTimeTinyTipTiredTissueTitleToastTobaccoTodayToddlerToeTogetherToiletTokenTomatoTomorrowToneTongueTonightToolToothTopTopicToppleTorchTornadoTortoiseTossTotalTouristTowardTowerTownToyTrackTradeTrafficTragicTrainTransferTrapTrashTravelTrayTreatTreeTrendTrialTribeTrickTriggerTrimTripTrophyTroubleTruckTrueTrulyTrumpetTrustTruthTryTubeTuitionTumbleTunaTunnelTurkeyTurnTurtleTwelveTwentyTwiceTwinTwistTwoTypeTypicalUglyUmbrellaUnableUnawareUncleUncoverUnderUndoUnfairUnfoldUnhappyUniformUniqueUnitUniverseUnknownUnlockUntilUnusualUnveilUpdateUpgradeUpholdUponUpperUpsetUrbanUrgeUsageUseUsedUsefulUselessUsualUtilityVacantVacuumVagueValidValleyValveVanVanishVaporVariousVastVaultVehicleVelvetVendorVentureVenueVerbVerifyVersionVeryVesselVeteranViableVibrantViciousVictoryVideoViewVillageVintageViolinVirtualVirusVisaVisitVisualVitalVividVocalVoiceVoidVolcanoVolumeVoteVoyageWageWagonWaitWalkWallWalnutWantWarfareWarmWarriorWashWaspWasteWaterWaveWayWealthWeaponWearWeaselWeatherWebWeddingWeekendWeirdWelcomeWestWetWhaleWhatWheatWheelWhenWhereWhipWhisperWideWidthWifeWildWillWinWindowWineWingWinkWinnerWinterWireWisdomWiseWishWitnessWolfWomanWonderWoodWoolWordWorkWorldWorryWorthWrapWreckWrestleWristWriteWrongYardYearYellowYouYoungYouthZebraZeroZoneZoo\";\n\nlet wordlist: Array<string> = null;\n\n\nfunction loadWords(): void {\n    if (wordlist != null) { return; }\n    wordlist = words.replace(/([A-Z])/g, ' $1').toLowerCase().substring(1).split(' ');\n}\n\nclass LangEn extends Wordlist {\n    constructor() {\n        super('en');\n    }\n\n    getWord(index: number): string {\n        loadWords();\n        return wordlist[index];\n    }\n\n    getWordIndex(word: string): number {\n        loadWords();\n        return wordlist.indexOf(word);\n    }\n}\n\nconst langEn = new LangEn();\nregister(langEn);\n\nexport { langEn };\n","'use strict';\n\nimport { pbkdf2Sync as _pbkdf2 } from 'crypto';\n\nimport { arrayify, Arrayish } from './bytes';\n\nfunction bufferify(value: Arrayish): Buffer {\n    return new Buffer(arrayify(value));\n}\n\nexport function pbkdf2(password: Arrayish, salt: Arrayish, iterations: number, keylen: number, hashAlgorithm: string): Uint8Array {\n    return arrayify(_pbkdf2(bufferify(password), bufferify(salt), iterations, keylen, hashAlgorithm));\n}\n","'use strict';\n\nimport { createHmac } from 'crypto';\n\nimport { arrayify, Arrayish } from './bytes';\n\nimport * as errors from './errors';\n\nexport type SupportedAlgorithms = 'sha256' | 'sha512';\n\nconst supportedAlgorithms = { sha256: true, sha512: true };\nexport function computeHmac(algorithm: SupportedAlgorithms, key: Arrayish, data: Arrayish): Uint8Array {\n    if (!supportedAlgorithms[algorithm]) {\n        errors.throwError('unsupported algorithm ' + algorithm, errors.UNSUPPORTED_OPERATION, { operation: 'hmac', algorithm: algorithm });\n    }\n    //return arrayify(_hmac(_hash[algorithm], arrayify(key)).update(arrayify(data)).digest());\n    return arrayify(createHmac(algorithm, new Buffer(arrayify(key))).update(new Buffer(arrayify(data))).digest());\n}\n\n","'use strict';\n\nimport hash from 'hash.js';\n\nimport { arrayify, Arrayish } from './bytes';\n\nexport function sha256(data: Arrayish): string {\n    return '0x' + (hash.sha256().update(arrayify(data)).digest('hex'));\n}\n\nexport function sha512(data: Arrayish): string {\n    return '0x' + (hash.sha512().update(arrayify(data)).digest('hex'));\n}\n","'use strict';\n\n// See: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki\n// See: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki\n\n// The English language word list.\n// For additional word lists, please see /src.tc/wordlists/\nimport { langEn } from '../wordlists/lang-en';\n\nimport { Wordlist } from '../wordlists/wordlist';\n\nimport { arrayify, Arrayish, hexlify } from '../utils/bytes';\nimport { bigNumberify } from '../utils/bignumber';\nimport { toUtf8Bytes, UnicodeNormalizationForm } from '../utils/utf8';\nimport { pbkdf2 } from '../utils/pbkdf2';\nimport { computeHmac } from '../utils/hmac';\nimport { defineReadOnly } from '../utils/properties';\nimport { KeyPair, N } from '../utils/secp256k1';\nimport { sha256 } from '../utils/sha2';\n\nimport * as errors from '../utils/errors';\n\n// \"Bitcoin seed\"\nvar MasterSecret = toUtf8Bytes('Bitcoin seed');\n\nvar HardenedBit = 0x80000000;\n\n// Returns a byte with the MSB bits set\nfunction getUpperMask(bits: number): number {\n   return ((1 << bits) - 1) << (8 - bits);\n}\n\n// Returns a byte with the LSB bits set\nfunction getLowerMask(bits: number): number {\n   return (1 << bits) - 1;\n}\n\nexport const defaultPath = \"m/44'/60'/0'/0/0\";\n\nexport class HDNode {\n    private readonly keyPair: KeyPair;\n\n    readonly privateKey: string;\n    readonly publicKey: string;\n\n    readonly mnemonic: string;\n    readonly path: string;\n\n    readonly chainCode: string;\n\n    readonly index: number;\n    readonly depth: number;\n\n    /**\n     *  This constructor should not be called directly.\n     *\n     *  Please use:\n     *   - fromMnemonic\n     *   - fromSeed\n     */\n    constructor(privateKey: Arrayish, chainCode: Uint8Array, index: number, depth: number, mnemonic: string, path: string) {\n        errors.checkNew(this, HDNode);\n\n        defineReadOnly(this, 'keyPair', new KeyPair(privateKey));\n\n        defineReadOnly(this, 'privateKey', this.keyPair.privateKey);\n        defineReadOnly(this, 'publicKey', this.keyPair.compressedPublicKey);\n\n        defineReadOnly(this, 'chainCode', hexlify(chainCode));\n\n        defineReadOnly(this, 'index', index);\n        defineReadOnly(this, 'depth', depth);\n\n        defineReadOnly(this, 'mnemonic', mnemonic);\n        defineReadOnly(this, 'path', path);\n    }\n\n    private _derive(index: number): HDNode {\n\n        // Public parent key -> public child key\n        if (!this.privateKey) {\n            if (index >= HardenedBit) { throw new Error('cannot derive child of neutered node'); }\n            throw new Error('not implemented');\n        }\n\n        var data = new Uint8Array(37);\n\n        // Base path\n        var mnemonic = this.mnemonic;\n        var path = this.path;\n        if (path) { path += '/' + index; }\n\n        if (index & HardenedBit) {\n            // Data = 0x00 || ser_256(k_par)\n            data.set(arrayify(this.privateKey), 1);\n\n            // Hardened path\n            if (path) { path += \"'\"; }\n\n        } else {\n            // Data = ser_p(point(k_par))\n            data.set(this.keyPair.publicKeyBytes);\n        }\n\n        // Data += ser_32(i)\n        for (var i = 24; i >= 0; i -= 8) { data[33 + (i >> 3)] = ((index >> (24 - i)) & 0xff); }\n\n        var I = computeHmac('sha512', this.chainCode, data);\n        var IL = bigNumberify(I.slice(0, 32));\n        var IR = I.slice(32);\n\n        var ki = IL.add(this.keyPair.privateKey).mod(N);\n\n        return new HDNode(arrayify(ki), IR, index, this.depth + 1, mnemonic, path);\n    }\n\n    derivePath(path: string): HDNode {\n        var components = path.split('/');\n\n        if (components.length === 0 || (components[0] === 'm' && this.depth !== 0)) {\n            throw new Error('invalid path');\n        }\n\n        if (components[0] === 'm') { components.shift(); }\n\n        var result: HDNode = this;\n        for (var i = 0; i < components.length; i++) {\n            var component = components[i];\n            if (component.match(/^[0-9]+'$/)) {\n                var index = parseInt(component.substring(0, component.length - 1));\n                if (index >= HardenedBit) { throw new Error('invalid path index - ' + component); }\n                result = result._derive(HardenedBit + index);\n            } else if (component.match(/^[0-9]+$/)) {\n                var index = parseInt(component);\n                if (index >= HardenedBit) { throw new Error('invalid path index - ' + component); }\n                result = result._derive(index);\n            } else {\n                throw new Error('invlaid path component - ' + component);\n            }\n        }\n\n        return result;\n    }\n}\n\nfunction _fromSeed(seed: Arrayish, mnemonic: string): HDNode {\n    let seedArray: Uint8Array = arrayify(seed);\n    if (seedArray.length < 16 || seedArray.length > 64) { throw new Error('invalid seed'); }\n\n    var I: Uint8Array = arrayify(computeHmac('sha512', MasterSecret, seedArray));\n\n    return new HDNode(I.slice(0, 32), I.slice(32), 0, 0, mnemonic, 'm');\n}\n\nexport function fromMnemonic(mnemonic: string, wordlist?: Wordlist): HDNode {\n    // Check that the checksum s valid (will throw an error)\n    mnemonicToEntropy(mnemonic, wordlist);\n\n    return _fromSeed(mnemonicToSeed(mnemonic), mnemonic);\n}\n\nexport function fromSeed(seed: Arrayish): HDNode {\n    return _fromSeed(seed, null);\n}\n\nexport function mnemonicToSeed(mnemonic: string, password?: string): string {\n    if (!password) { password = ''; }\n\n    var salt = toUtf8Bytes('mnemonic' + password, UnicodeNormalizationForm.NFKD);\n\n    return hexlify(pbkdf2(toUtf8Bytes(mnemonic, UnicodeNormalizationForm.NFKD), salt, 2048, 64, 'sha512'));\n}\n\nexport function mnemonicToEntropy(mnemonic: string, wordlist?: Wordlist): string {\n    if (!wordlist) { wordlist = langEn; }\n\n    var words = wordlist.split(mnemonic);\n    if ((words.length % 3) !== 0) { throw new Error('invalid mnemonic'); }\n\n    var entropy = arrayify(new Uint8Array(Math.ceil(11 * words.length / 8)));\n\n    var offset = 0;\n    for (var i = 0; i < words.length; i++) {\n        var index = wordlist.getWordIndex(words[i].normalize('NFKD'));\n        if (index === -1) { throw new Error('invalid mnemonic'); }\n\n        for (var bit = 0; bit < 11; bit++) {\n            if (index & (1 << (10 - bit))) {\n                entropy[offset >> 3] |= (1 << (7 - (offset % 8)));\n            }\n            offset++;\n        }\n    }\n\n    var entropyBits = 32 * words.length / 3;\n\n    var checksumBits = words.length / 3;\n    var checksumMask = getUpperMask(checksumBits);\n\n    var checksum = arrayify(sha256(entropy.slice(0, entropyBits / 8)))[0];\n    checksum &= checksumMask;\n\n    if (checksum !== (entropy[entropy.length - 1] & checksumMask)) {\n        throw new Error('invalid checksum');\n    }\n\n    return hexlify(entropy.slice(0, entropyBits / 8));\n}\n\nexport function entropyToMnemonic(entropy: Arrayish, wordlist?: Wordlist): string {\n    entropy = arrayify(entropy);\n\n    if ((entropy.length % 4) !== 0 || entropy.length < 16 || entropy.length > 32) {\n        throw new Error('invalid entropy');\n    }\n\n    var indices: Array<number> = [ 0 ];\n\n    var remainingBits = 11;\n    for (var i = 0; i < entropy.length; i++) {\n\n        // Consume the whole byte (with still more to go)\n        if (remainingBits > 8) {\n            indices[indices.length - 1] <<= 8;\n            indices[indices.length - 1] |= entropy[i];\n\n            remainingBits -= 8;\n\n        // This byte will complete an 11-bit index\n        } else {\n            indices[indices.length - 1] <<= remainingBits;\n            indices[indices.length - 1] |= entropy[i] >> (8 - remainingBits);\n\n            // Start the next word\n            indices.push(entropy[i] & getLowerMask(8 - remainingBits));\n\n            remainingBits += 3;\n        }\n    }\n\n    // Compute the checksum bits\n    var checksum = arrayify(sha256(entropy))[0];\n    var checksumBits = entropy.length / 4;\n    checksum &= getUpperMask(checksumBits);\n\n    // Shift the checksum into the word indices\n    indices[indices.length - 1] <<= checksumBits;\n    indices[indices.length - 1] |= (checksum >> (8 - checksumBits));\n\n    if (!wordlist) { wordlist = langEn; }\n\n    return wordlist.join(indices.map((index) => wordlist.getWord(index)));\n}\n\nexport function isValidMnemonic(mnemonic: string, wordlist?: Wordlist): boolean {\n    try {\n        mnemonicToEntropy(mnemonic, wordlist);\n        return true;\n    } catch (error) { }\n    return false;\n}\n\n","'use strict';\n\nimport { arrayify } from './bytes';\n\nimport { randomBytes as _randomBytes } from 'crypto';\n\nexport function randomBytes(length: number): Uint8Array {\n    return arrayify(_randomBytes(length));\n}\n\n","'use strict';\n\n/**\n *  SigningKey\n *\n *\n */\n\nimport { getAddress } from '../utils/address';\nimport { arrayify, Arrayish, hexlify } from '../utils/bytes';\nimport { HDNode } from './hdnode';\nimport { keccak256 } from '../utils/keccak256';\nimport { defineReadOnly } from '../utils/properties';\nimport { computePublicKey, KeyPair, recoverPublicKey, Signature } from '../utils/secp256k1';\n\nimport errors = require('../utils/errors');\n\nexport class SigningKey {\n\n    readonly privateKey: string;\n    readonly publicKey: string;\n    readonly address: string;\n\n    readonly mnemonic: string;\n    readonly path: string;\n\n    private readonly keyPair: KeyPair;\n\n    constructor(privateKey: Arrayish | HDNode) {\n        errors.checkNew(this, SigningKey);\n\n        let privateKeyBytes = null;\n\n        if (privateKey instanceof HDNode) {\n            defineReadOnly(this, 'mnemonic', privateKey.mnemonic);\n            defineReadOnly(this, 'path', privateKey.path);\n            privateKeyBytes = arrayify(privateKey.privateKey);\n        } else {\n            // A lot of common tools do not prefix private keys with a 0x\n            if (typeof(privateKey) === 'string' && privateKey.match(/^[0-9a-f]*$/i) && privateKey.length === 64) {\n                privateKey = '0x' + privateKey;\n            }\n            privateKeyBytes = arrayify(privateKey);\n        }\n\n        try {\n            if (privateKeyBytes.length !== 32) {\n                errors.throwError('exactly 32 bytes required', errors.INVALID_ARGUMENT, { value: privateKey });\n            }\n        } catch(error) {\n            var params: any = { arg: 'privateKey', reason: error.reason, value: '[REDACTED]' }\n            if (error.value) {\n                if(typeof(error.value.length) === 'number') {\n                    params.length = error.value.length;\n                }\n                params.type = typeof(error.value);\n            }\n            errors.throwError('invalid private key', error.code, params);\n        }\n\n        defineReadOnly(this, 'privateKey', hexlify(privateKeyBytes));\n        defineReadOnly(this, 'keyPair', new KeyPair(privateKeyBytes));\n        defineReadOnly(this, 'publicKey', this.keyPair.publicKey);\n        defineReadOnly(this, 'address', computeAddress(this.keyPair.publicKey));\n    }\n\n    signDigest(digest: Arrayish): Signature {\n        return this.keyPair.sign(digest);\n    }\n}\n\nexport function recoverAddress(digest: Arrayish, signature: Signature): string {\n    return computeAddress(recoverPublicKey(digest, signature));\n}\n\nexport function computeAddress(key: string): string {\n    // Strip off the leading \"0x04\"\n    let publicKey = '0x' + computePublicKey(key).slice(4);\n    return getAddress('0x' + keccak256(publicKey).substring(26));\n}\n","'use strict';\n\nimport aes from 'aes-js';\nimport scrypt from 'scrypt-js';\nimport uuid from 'uuid';\n\nimport { getAddress } from '../utils/address';\nimport { arrayify, Arrayish, concat, hexlify } from '../utils/bytes';\n\nimport { pbkdf2 } from '../utils/pbkdf2';\nimport { keccak256 } from '../utils/keccak256';\nimport { toUtf8Bytes, UnicodeNormalizationForm } from '../utils/utf8';\nimport { randomBytes } from '../utils/random-bytes';\n\nimport { SigningKey } from './signing-key';\nimport * as HDNode from './hdnode';\n\n\nexport interface ProgressCallback {\n    (percent: number): void\n}\n\nfunction looseArrayify(hexString: string): Uint8Array {\n    if (typeof(hexString) === 'string' && hexString.substring(0, 2) !== '0x') {\n        hexString = '0x' + hexString;\n    }\n    return arrayify(hexString);\n}\n\nfunction zpad(value: String | number, length: number): String {\n    value = String(value);\n    while (value.length < length) { value = '0' + value; }\n    return value;\n}\n\nfunction getPassword(password: Arrayish): Uint8Array {\n    if (typeof(password) === 'string') {\n        return toUtf8Bytes(password, UnicodeNormalizationForm.NFKC);\n    }\n    return arrayify(password);\n}\n\n// Search an Object and its children recursively, caselessly.\nfunction searchPath(object: any, path: string): string {\n    var currentChild = object;\n\n    var comps = path.toLowerCase().split('/');\n    for (var i = 0; i < comps.length; i++) {\n\n        // Search for a child object with a case-insensitive matching key\n        var matchingChild = null;\n        for (var key in currentChild) {\n             if (key.toLowerCase() === comps[i]) {\n                 matchingChild = currentChild[key];\n                 break;\n             }\n        }\n\n        // Didn't find one. :'(\n        if (matchingChild === null) {\n            return null;\n        }\n\n        // Now check this child...\n        currentChild = matchingChild;\n    }\n\n    return currentChild;\n}\n\nexport function isCrowdsaleWallet(json: string): boolean {\n    try {\n        var data = JSON.parse(json);\n    } catch (error) { return false; }\n\n    return (data.encseed && data.ethaddr);\n}\n\nexport function isValidWallet(json: string): boolean {\n    try {\n        var data = JSON.parse(json);\n    } catch (error) { return false; }\n\n    if (!data.version || parseInt(data.version) !== data.version || parseInt(data.version) !== 3) {\n        return false;\n    }\n\n    // @TODO: Put more checks to make sure it has kdf, iv and all that good stuff\n    return true;\n}\n\n// @TODO: Make a type for string or arrayish\n// See: https://github.com/ethereum/pyethsaletool\nexport function decryptCrowdsale(json: string, password: Arrayish | string): SigningKey {\n    var data = JSON.parse(json);\n\n    password = getPassword(password);\n\n    // Ethereum Address\n    var ethaddr = getAddress(searchPath(data, 'ethaddr'));\n\n    // Encrypted Seed\n    var encseed = looseArrayify(searchPath(data, 'encseed'));\n    if (!encseed || (encseed.length % 16) !== 0) {\n        throw new Error('invalid encseed');\n    }\n\n    let key = pbkdf2(password, password, 2000, 32, 'sha256').slice(0, 16);\n\n    var iv = encseed.slice(0, 16);\n    var encryptedSeed = encseed.slice(16);\n\n    // Decrypt the seed\n    var aesCbc = new aes.ModeOfOperation.cbc(key, iv);\n    var seed = arrayify(aesCbc.decrypt(encryptedSeed));\n    seed = aes.padding.pkcs7.strip(seed);\n\n    // This wallet format is weird... Convert the binary encoded hex to a string.\n    var seedHex = '';\n    for (var i = 0; i < seed.length; i++) {\n        seedHex += String.fromCharCode(seed[i]);\n    }\n\n    var seedHexBytes = toUtf8Bytes(seedHex);\n\n    var signingKey = new SigningKey(keccak256(seedHexBytes));\n\n    if (signingKey.address !== ethaddr) {\n        throw new Error('corrupt crowdsale wallet');\n    }\n\n    return signingKey;\n}\n\n//@TODO: string or arrayish\nexport function decrypt(json: string, password: Arrayish, progressCallback?: ProgressCallback): Promise<SigningKey> {\n    var data = JSON.parse(json);\n\n    let passwordBytes = getPassword(password);\n\n    var decrypt = function(key: Uint8Array, ciphertext: Uint8Array): Uint8Array {\n        var cipher = searchPath(data, 'crypto/cipher');\n        if (cipher === 'aes-128-ctr') {\n            var iv = looseArrayify(searchPath(data, 'crypto/cipherparams/iv'))\n            var counter = new aes.Counter(iv);\n\n            var aesCtr = new aes.ModeOfOperation.ctr(key, counter);\n\n            return arrayify(aesCtr.decrypt(ciphertext));\n        }\n\n        return null;\n    };\n\n    var computeMAC = function(derivedHalf: Uint8Array, ciphertext: Uint8Array) {\n        return keccak256(concat([derivedHalf, ciphertext]));\n    }\n\n    var getSigningKey = function(key: Uint8Array, reject: (error?: Error) => void) {\n        var ciphertext = looseArrayify(searchPath(data, 'crypto/ciphertext'));\n\n        var computedMAC = hexlify(computeMAC(key.slice(16, 32), ciphertext)).substring(2);\n        if (computedMAC !== searchPath(data, 'crypto/mac').toLowerCase()) {\n            reject(new Error('invalid password'));\n            return null;\n        }\n\n        var privateKey = decrypt(key.slice(0, 16), ciphertext);\n        var mnemonicKey = key.slice(32, 64);\n\n        if (!privateKey) {\n            reject(new Error('unsupported cipher'));\n            return null;\n        }\n\n        var signingKey = new SigningKey(privateKey);\n        if (signingKey.address !== getAddress(data.address)) {\n            reject(new Error('address mismatch'));\n            return null;\n        }\n\n        // Version 0.1 x-ethers metadata must contain an encrypted mnemonic phrase\n        if (searchPath(data, 'x-ethers/version') === '0.1') {\n            var mnemonicCiphertext = looseArrayify(searchPath(data, 'x-ethers/mnemonicCiphertext'));\n            var mnemonicIv = looseArrayify(searchPath(data, 'x-ethers/mnemonicCounter'));\n\n            var mnemonicCounter = new aes.Counter(mnemonicIv);\n            var mnemonicAesCtr = new aes.ModeOfOperation.ctr(mnemonicKey, mnemonicCounter);\n\n            var path = searchPath(data, 'x-ethers/path') || HDNode.defaultPath;\n\n            var entropy = arrayify(mnemonicAesCtr.decrypt(mnemonicCiphertext));\n            var mnemonic = HDNode.entropyToMnemonic(entropy);\n\n            var node = HDNode.fromMnemonic(mnemonic).derivePath(path);\n            if (node.privateKey != hexlify(privateKey)) {\n                reject(new Error('mnemonic mismatch'));\n                return null;\n            }\n\n            signingKey = new SigningKey(node);\n        }\n\n        return signingKey;\n    }\n\n\n    return new Promise(function(resolve, reject) {\n        var kdf = searchPath(data, 'crypto/kdf');\n        if (kdf && typeof(kdf) === 'string') {\n            if (kdf.toLowerCase() === 'scrypt') {\n                var salt = looseArrayify(searchPath(data, 'crypto/kdfparams/salt'));\n                var N = parseInt(searchPath(data, 'crypto/kdfparams/n'));\n                var r = parseInt(searchPath(data, 'crypto/kdfparams/r'));\n                var p = parseInt(searchPath(data, 'crypto/kdfparams/p'));\n                if (!N || !r || !p) {\n                    reject(new Error('unsupported key-derivation function parameters'));\n                    return;\n                }\n\n                // Make sure N is a power of 2\n                if ((N & (N - 1)) !== 0) {\n                    reject(new Error('unsupported key-derivation function parameter value for N'));\n                    return;\n                }\n\n                var dkLen = parseInt(searchPath(data, 'crypto/kdfparams/dklen'));\n                if (dkLen !== 32) {\n                    reject( new Error('unsupported key-derivation derived-key length'));\n                    return;\n                }\n\n                scrypt(passwordBytes, salt, N, r, p, 64, function(error, progress, key) {\n                    if (error) {\n                        error.progress = progress;\n                        reject(error);\n\n                    } else if (key) {\n                        key = arrayify(key);\n\n                        var signingKey = getSigningKey(key, reject);\n                        if (!signingKey) { return; }\n\n                        if (progressCallback) { progressCallback(1); }\n                        resolve(signingKey);\n\n                    } else if (progressCallback) {\n                        return progressCallback(progress);\n                    }\n                });\n\n            } else if (kdf.toLowerCase() === 'pbkdf2') {\n                var salt = looseArrayify(searchPath(data, 'crypto/kdfparams/salt'));\n\n                var prfFunc = null;\n                var prf = searchPath(data, 'crypto/kdfparams/prf');\n                if (prf === 'hmac-sha256') {\n                    prfFunc = 'sha256';\n                } else if (prf === 'hmac-sha512') {\n                    prfFunc = 'sha512';\n                } else {\n                    reject(new Error('unsupported prf'));\n                    return;\n                }\n\n                var c = parseInt(searchPath(data, 'crypto/kdfparams/c'));\n\n                var dkLen = parseInt(searchPath(data, 'crypto/kdfparams/dklen'));\n                if (dkLen !== 32) {\n                    reject( new Error('unsupported key-derivation derived-key length'));\n                    return;\n                }\n\n                var key = pbkdf2(passwordBytes, salt, c, dkLen, prfFunc);\n\n                var signingKey = getSigningKey(key, reject);\n                if (!signingKey) { return; }\n\n                resolve(signingKey);\n\n            } else {\n                reject(new Error('unsupported key-derivation function'));\n            }\n\n        } else {\n            reject(new Error('unsupported key-derivation function'));\n        }\n    });\n}\n\nexport type EncryptOptions = {\n   iv?: Arrayish;\n   entropy?: Arrayish;\n   mnemonic?: string;\n   path?: string;\n   client?: string;\n   salt?: Arrayish;\n   uuid?: string;\n   scrypt?: {\n       N?: number;\n       r?: number;\n       p?: number;\n   }\n}\n\nexport function encrypt(privateKey: Arrayish | SigningKey, password: Arrayish | string, options?: EncryptOptions, progressCallback?: ProgressCallback): Promise<string> {\n\n    // the options are optional, so adjust the call as needed\n    if (typeof(options) === 'function' && !progressCallback) {\n        progressCallback = options;\n        options = {};\n    }\n    if (!options) { options = {}; }\n\n    // Check the private key\n    let privateKeyBytes: Uint8Array = null;\n    if (privateKey instanceof SigningKey) {\n        privateKeyBytes = arrayify(privateKey.privateKey);\n    } else {\n        privateKeyBytes = arrayify(privateKey);\n    }\n    if (privateKeyBytes.length !== 32) { throw new Error('invalid private key'); }\n\n    let passwordBytes = getPassword(password);\n\n    let entropy: Uint8Array = null\n\n    if (options.entropy) {\n        entropy = arrayify(options.entropy);\n    }\n\n    if (options.mnemonic) {\n        if (entropy) {\n            if (HDNode.entropyToMnemonic(entropy) !== options.mnemonic) {\n                throw new Error('entropy and mnemonic mismatch');\n            }\n        } else {\n            entropy = arrayify(HDNode.mnemonicToEntropy(options.mnemonic));\n        }\n    }\n\n    var path: string = options.path;\n    if (entropy && !path) {\n        path = HDNode.defaultPath;\n    }\n\n    var client = options.client;\n    if (!client) { client = \"ethers.js\"; }\n\n    // Check/generate the salt\n    let salt: Uint8Array = null;\n    if (options.salt) {\n        salt = arrayify(options.salt);\n    } else {\n        salt = randomBytes(32);;\n    }\n\n    // Override initialization vector\n    let iv: Uint8Array = null;\n    if (options.iv) {\n        iv = arrayify(options.iv);\n        if (iv.length !== 16) { throw new Error('invalid iv'); }\n    } else {\n       iv = randomBytes(16);\n    }\n\n    // Override the uuid\n    var uuidRandom: Uint8Array = null;\n    if (options.uuid) {\n        uuidRandom = arrayify(options.uuid);\n        if (uuidRandom.length !== 16) { throw new Error('invalid uuid'); }\n    } else {\n        uuidRandom = randomBytes(16);\n    }\n\n    // Override the scrypt password-based key derivation function parameters\n    var N = (1 << 17), r = 8, p = 1;\n    if (options.scrypt) {\n        if (options.scrypt.N) { N = options.scrypt.N; }\n        if (options.scrypt.r) { r = options.scrypt.r; }\n        if (options.scrypt.p) { p = options.scrypt.p; }\n    }\n\n    return new Promise(function(resolve, reject) {\n\n        // We take 64 bytes:\n        //   - 32 bytes   As normal for the Web3 secret storage (derivedKey, macPrefix)\n        //   - 32 bytes   AES key to encrypt mnemonic with (required here to be Ethers Wallet)\n        scrypt(passwordBytes, salt, N, r, p, 64, function(error, progress, key) {\n            if (error) {\n                error.progress = progress;\n                reject(error);\n\n            } else if (key) {\n                key = arrayify(key);\n\n                // This will be used to encrypt the wallet (as per Web3 secret storage)\n                var derivedKey = key.slice(0, 16);\n                var macPrefix = key.slice(16, 32);\n\n                // This will be used to encrypt the mnemonic phrase (if any)\n                var mnemonicKey = key.slice(32, 64);\n\n                // Get the address for this private key\n                var address = (new SigningKey(privateKeyBytes)).address;\n\n                // Encrypt the private key\n                var counter = new aes.Counter(iv);\n                var aesCtr = new aes.ModeOfOperation.ctr(derivedKey, counter);\n                var ciphertext = arrayify(aesCtr.encrypt(privateKeyBytes));\n\n                // Compute the message authentication code, used to check the password\n                var mac = keccak256(concat([macPrefix, ciphertext]))\n\n                // See: https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition\n                var data: { [key: string]: any } = {\n                    address: address.substring(2).toLowerCase(),\n                    id: uuid.v4({ random: uuidRandom }),\n                    version: 3,\n                    Crypto: {\n                        cipher: 'aes-128-ctr',\n                        cipherparams: {\n                            iv: hexlify(iv).substring(2),\n                        },\n                        ciphertext: hexlify(ciphertext).substring(2),\n                        kdf: 'scrypt',\n                        kdfparams: {\n                            salt: hexlify(salt).substring(2),\n                            n: N,\n                            dklen: 32,\n                            p: p,\n                            r: r\n                        },\n                        mac: mac.substring(2)\n                    }\n                };\n\n                // If we have a mnemonic, encrypt it into the JSON wallet\n                if (entropy) {\n                    var mnemonicIv = randomBytes(16);\n                    var mnemonicCounter = new aes.Counter(mnemonicIv);\n                    var mnemonicAesCtr = new aes.ModeOfOperation.ctr(mnemonicKey, mnemonicCounter);\n                    var mnemonicCiphertext = arrayify(mnemonicAesCtr.encrypt(entropy));\n                    var now = new Date();\n                    var timestamp = (now.getUTCFullYear() + '-' +\n                                     zpad(now.getUTCMonth() + 1, 2) + '-' +\n                                     zpad(now.getUTCDate(), 2) + 'T' +\n                                     zpad(now.getUTCHours(), 2) + '-' +\n                                     zpad(now.getUTCMinutes(), 2) + '-' +\n                                     zpad(now.getUTCSeconds(), 2) + '.0Z'\n                                    );\n                    data['x-ethers'] = {\n                        client: client,\n                        gethFilename: ('UTC--' + timestamp + '--' + data.address),\n                        mnemonicCounter: hexlify(mnemonicIv).substring(2),\n                        mnemonicCiphertext: hexlify(mnemonicCiphertext).substring(2),\n                        version: \"0.1\"\n                    };\n                }\n\n                if (progressCallback) { progressCallback(1); }\n                resolve(JSON.stringify(data));\n\n            } else if (progressCallback) {\n                return progressCallback(progress);\n            }\n        });\n    });\n}\n\n","'use strict';\n\nimport { Arrayish, concat, hexlify } from './bytes';\nimport { toUtf8Bytes } from './utf8';\nimport { keccak256 } from './keccak256';\n\nvar Zeros = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);\nvar Partition = new RegExp(\"^((.*)\\\\.)?([^.]+)$\");\nvar UseSTD3ASCIIRules = new RegExp(\"^[a-z0-9.-]*$\");\n\nexport function namehash(name: string): string {\n    name = name.toLowerCase();\n\n    // Supporting the full UTF-8 space requires additional (and large)\n    // libraries, so for now we simply do not support them.\n    // It should be fairly easy in the future to support systems with\n    // String.normalize, but that is future work.\n    if (!name.match(UseSTD3ASCIIRules)) {\n        throw new Error('contains invalid UseSTD3ASCIIRules characters');\n    }\n\n    var result: string | Uint8Array = Zeros;\n    while (name.length) {\n        var partition = name.match(Partition);\n        var label = toUtf8Bytes(partition[3]);\n        result = keccak256(concat([result, keccak256(label)]));\n\n        name = partition[2] || '';\n    }\n\n    return hexlify(result);\n}\n\n\nexport function id(text: string): string {\n    return keccak256(toUtf8Bytes(text));\n}\n\nexport function hashMessage(message: Arrayish | string): string {\n    var payload = concat([\n        toUtf8Bytes('\\x19Ethereum Signed Message:\\n'),\n        toUtf8Bytes(String(message.length)),\n        ((typeof(message) === 'string') ? toUtf8Bytes(message): message)\n    ]);\n    return keccak256(payload);\n}\n\n","\nimport { getAddress } from './address';\nimport { BigNumber, bigNumberify, BigNumberish,ConstantZero } from './bignumber';\nimport { arrayify, Arrayish, hexlify, hexZeroPad, stripZeros, } from './bytes';\nimport { keccak256 } from './keccak256';\nimport { recoverAddress, Signature } from './secp256k1';\nimport * as RLP from './rlp';\n\nexport type UnsignedTransaction = {\n    to?: string;\n    nonce?: number;\n\n    gasLimit?: BigNumberish;\n    gasPrice?: BigNumberish;\n\n    data?: Arrayish;\n    value?: BigNumberish;\n    chainId?: number;\n}\n\n\nexport interface Transaction {\n    hash?: string;\n\n    to?: string;\n    from?: string;\n    nonce: number;\n\n    gasLimit: BigNumber;\n    gasPrice: BigNumber;\n\n    data: string;\n    value: BigNumber;\n    chainId: number;\n\n    r?: string;\n    s?: string;\n    v?: number;\n}\n\n\nfunction handleAddress(value: string): string {\n    if (value === '0x') { return null; }\n    return getAddress(value);\n}\n\nfunction handleNumber(value: string): BigNumber {\n    if (value === '0x') { return ConstantZero; }\n    return bigNumberify(value);\n}\n\nvar transactionFields = [\n    { name: 'nonce',    maxLength: 32 },\n    { name: 'gasPrice', maxLength: 32 },\n    { name: 'gasLimit', maxLength: 32 },\n    { name: 'to',          length: 20 },\n    { name: 'value',    maxLength: 32 },\n    { name: 'data' },\n];\n\n\nexport type SignDigestFunc = (digest: Arrayish) => Signature;\n\nexport function sign(transaction: UnsignedTransaction, signDigest: SignDigestFunc): string {\n\n    var raw: Array<string | Uint8Array> = [];\n\n    transactionFields.forEach(function(fieldInfo) {\n        let value = (<any>transaction)[fieldInfo.name] || ([]);\n        value = arrayify(hexlify(value));\n\n        // Fixed-width field\n        if (fieldInfo.length && value.length !== fieldInfo.length && value.length > 0) {\n            let error: any = new Error('invalid ' + fieldInfo.name);\n            error.reason = 'wrong length';\n            error.value = value;\n            throw error;\n        }\n\n        // Variable-width (with a maximum)\n        if (fieldInfo.maxLength) {\n            value = stripZeros(value);\n            if (value.length > fieldInfo.maxLength) {\n                let error: any = new Error('invalid ' + fieldInfo.name);\n                error.reason = 'too long';\n                error.value = value;\n                throw error;\n            }\n        }\n\n        raw.push(hexlify(value));\n    });\n\n    // @TOOD:\n    /*\n    // Requesting an unsigned transation\n    if (!signDigest) {\n        let v = 27 + signature.recoveryParam\n        if (transaction.chainId) {\n            v += transaction.chainId * 2 + 8;\n        }\n        //raw.push(hexlify(transaction.chainId));\n        raw.push(hexlify(v));\n        raw.push('0x');\n        raw.push('0x');\n    }\n    */\n\n    if (transaction.chainId) {\n        raw.push(hexlify(transaction.chainId));\n        raw.push('0x');\n        raw.push('0x');\n    }\n\n    var digest = keccak256(RLP.encode(raw));\n\n    var signature = signDigest(digest);\n\n    var v = 27 + signature.recoveryParam\n    if (transaction.chainId) {\n        raw.pop();\n        raw.pop();\n        raw.pop();\n        v += transaction.chainId * 2 + 8;\n    }\n\n    raw.push(hexlify(v));\n    raw.push(stripZeros(arrayify(signature.r)));\n    raw.push(stripZeros(arrayify(signature.s)));\n\n    return RLP.encode(raw);\n}\n\nexport function parse(rawTransaction: Arrayish): Transaction {\n    var signedTransaction = RLP.decode(rawTransaction);\n    if (signedTransaction.length !== 9) { throw new Error('invalid transaction'); }\n\n    let tx: Transaction = {\n        nonce:    handleNumber(signedTransaction[0]).toNumber(),\n        gasPrice: handleNumber(signedTransaction[1]),\n        gasLimit: handleNumber(signedTransaction[2]),\n        to:       handleAddress(signedTransaction[3]),\n        value:    handleNumber(signedTransaction[4]),\n        data:     signedTransaction[5],\n        chainId:  0\n    };\n\n    var v = arrayify(signedTransaction[6]);\n    var r = arrayify(signedTransaction[7]);\n    var s = arrayify(signedTransaction[8]);\n\n    if (v.length >= 1 && r.length >= 1 && r.length <= 32 && s.length >= 1 && s.length <= 32) {\n        tx.v = bigNumberify(v).toNumber();\n        tx.r = hexZeroPad(signedTransaction[7], 32);\n        tx.s = hexZeroPad(signedTransaction[8], 32);\n\n        var chainId = (tx.v - 35) / 2;\n        if (chainId < 0) { chainId = 0; }\n        chainId = Math.floor(chainId);\n\n        tx.chainId = chainId;\n\n        var recoveryParam = tx.v - 27;\n\n        let raw = signedTransaction.slice(0, 6);\n\n        if (chainId) {\n            raw.push(hexlify(chainId));\n            raw.push('0x');\n            raw.push('0x');\n            recoveryParam -= chainId * 2 + 8;\n        }\n\n        var digest = keccak256(RLP.encode(raw));\n        try {\n            tx.from = recoverAddress(digest, { r: hexlify(r), s: hexlify(s), recoveryParam: recoveryParam });\n        } catch (error) {\n            console.log(error);\n        }\n\n        tx.hash = keccak256(rawTransaction);\n    }\n\n    return tx;\n}\n","'use strict';\n\nimport { defaultPath, entropyToMnemonic, fromMnemonic, HDNode } from './hdnode';\nimport * as secretStorage from './secret-storage';\nimport { ProgressCallback } from './secret-storage';\nimport { recoverAddress, SigningKey } from './signing-key';\n\nimport { BlockTag, Provider, TransactionRequest, TransactionResponse } from '../providers/provider';\nimport { Wordlist } from '../wordlists/wordlist';\n\nimport { BigNumber } from '../utils/bignumber';\nimport { arrayify, Arrayish, concat, hexlify, joinSignature } from '../utils/bytes';\nimport { hashMessage } from '../utils/hash';\nimport { keccak256 } from '../utils/keccak256';\nimport { defineReadOnly, resolveProperties, shallowCopy } from '../utils/properties';\nimport { randomBytes } from '../utils/random-bytes';\nimport { sign as signTransaction } from '../utils/transaction';\n\nimport * as errors from '../utils/errors';\n\nexport abstract class Signer {\n    provider?: Provider;\n\n    abstract getAddress(): Promise<string>\n\n    abstract signMessage(transaction: Arrayish | string): Promise<string>;\n    abstract sendTransaction(transaction: TransactionRequest): Promise<TransactionResponse>;\n}\n\n\nexport class Wallet extends Signer {\n\n    readonly provider: Provider;\n\n    private readonly signingKey: SigningKey;\n\n    constructor(privateKey: SigningKey | HDNode | Arrayish, provider?: Provider) {\n        super();\n        errors.checkNew(this, Wallet);\n\n        // Make sure we have a valid signing key\n        if (privateKey instanceof SigningKey) {\n            defineReadOnly(this, 'signingKey', privateKey);\n        } else {\n            defineReadOnly(this, 'signingKey', new SigningKey(privateKey));\n        }\n\n        defineReadOnly(this, 'provider', provider);\n    }\n\n    get address(): string { return this.signingKey.address; }\n\n    get mnemonic(): string { return this.signingKey.mnemonic; }\n    get path(): string { return this.signingKey.mnemonic; }\n\n    get privateKey(): string { return this.signingKey.privateKey; }\n\n\n    /**\n     *  Create a new instance of this Wallet connected to provider.\n     */\n    connect(provider: Provider): Wallet {\n        return new Wallet(this.signingKey, provider);\n    }\n\n\n    getAddress(): Promise<string> {\n        return Promise.resolve(this.address);\n    }\n\n    sign(transaction: TransactionRequest): Promise<string> {\n\n        return resolveProperties(transaction).then((tx) => {\n            return signTransaction(tx, this.signingKey.signDigest.bind(this.signingKey));\n        });\n    }\n\n    signMessage(message: Arrayish | string): Promise<string> {\n        return Promise.resolve(joinSignature(this.signingKey.signDigest(hashMessage(message))));\n    }\n\n\n    getBalance(blockTag?: BlockTag): Promise<BigNumber> {\n        if (!this.provider) { throw new Error('missing provider'); }\n        return this.provider.getBalance(this.address, blockTag);\n    }\n\n    getTransactionCount(blockTag?: BlockTag): Promise<number> {\n        if (!this.provider) { throw new Error('missing provider'); }\n        return this.provider.getTransactionCount(this.address, blockTag);\n    }\n\n    sendTransaction(transaction: TransactionRequest): Promise<TransactionResponse> {\n        if (!this.provider) { throw new Error('missing provider'); }\n\n        if (!transaction || typeof(transaction) !== 'object') {\n            throw new Error('invalid transaction object');\n        }\n\n        var tx = shallowCopy(transaction);\n\n        if (tx.to != null) {\n            tx.to = this.provider.resolveName(tx.to);\n        }\n\n        if (tx.gasLimit == null) {\n            tx.gasLimit = this.provider.estimateGas(tx);\n        }\n\n        if (tx.gasPrice == null) {\n            tx.gasPrice = this.provider.getGasPrice();\n        }\n\n        if (tx.nonce == null) {\n            tx.nonce = this.getTransactionCount();\n        }\n\n        if (tx.chainId == null) {\n            tx.chainId = this.provider.getNetwork().then((network) => network.chainId);\n        }\n\n        return this.provider.sendTransaction(this.sign(tx));\n    }\n\n    encrypt(password: Arrayish | string, options: any, progressCallback: ProgressCallback): Promise<string> {\n        if (typeof(options) === 'function' && !progressCallback) {\n            progressCallback = options;\n            options = {};\n        }\n\n        if (progressCallback && typeof(progressCallback) !== 'function') {\n            throw new Error('invalid callback');\n        }\n\n        if (!options) { options = {}; }\n\n        if (this.mnemonic) {\n            // Make sure we don't accidentally bubble the mnemonic up the call-stack\n            var safeOptions: any = {};\n            for (var key in options) { safeOptions[key] = options[key]; }\n            options = safeOptions;\n\n            // Set the mnemonic and path\n            options.mnemonic = this.mnemonic;\n            options.path = this.path\n        }\n\n        return secretStorage.encrypt(this.privateKey, password, options, progressCallback);\n    }\n\n\n    /**\n     *  Static methods to create Wallet instances.\n     */\n    static createRandom(options: any): Wallet {\n        var entropy: Uint8Array = randomBytes(16);\n\n        if (!options) { options = { }; }\n\n        if (options.extraEntropy) {\n            entropy = arrayify(keccak256(concat([entropy, options.extraEntropy])).substring(0, 34));\n        }\n\n        var mnemonic = entropyToMnemonic(entropy, options.locale);\n        return Wallet.fromMnemonic(mnemonic, options.path, options.locale);\n    }\n\n    static fromEncryptedJson(json: string, password: Arrayish, progressCallback: ProgressCallback): Promise<Wallet> {\n        if (progressCallback && typeof(progressCallback) !== 'function') {\n            throw new Error('invalid callback');\n        }\n\n        return new Promise(function(resolve, reject) {\n\n            if (secretStorage.isCrowdsaleWallet(json)) {\n                try {\n                    var privateKey = secretStorage.decryptCrowdsale(json, password);\n                    resolve(new Wallet(privateKey));\n                } catch (error) {\n                    reject(error);\n                }\n\n            } else if (secretStorage.isValidWallet(json)) {\n\n                secretStorage.decrypt(json, password, progressCallback).then(function(signingKey) {\n                    var wallet = new Wallet(signingKey);\n                    /*\n                    if (signingKey.mnemonic && signingKey.path) {\n                        wallet.mnemonic = signingKey.mnemonic;\n                        wallet.path = signingKey.path;\n                    }\n                    */\n                    resolve(wallet);\n                }, function(error) {\n                    reject(error);\n                });\n\n            } else {\n                reject('invalid wallet JSON');\n            }\n        });\n    }\n\n    static fromMnemonic(mnemonic: string, path?: string, wordlist?: Wordlist): Wallet {\n        if (!path) { path = defaultPath; }\n        return new Wallet(fromMnemonic(mnemonic, wordlist).derivePath(path));\n    }\n\n\n    /**\n     *  Determine if this is an encryped JSON wallet.\n     */\n    static isEncryptedWallet(json: string): boolean {\n        return (secretStorage.isValidWallet(json) || secretStorage.isCrowdsaleWallet(json));\n    }\n\n\n    /**\n     *  Verify a signed message, returning the address of the signer.\n     */\n    static verifyMessage(message: Arrayish | string, signature: string): string {\n        signature = hexlify(signature);\n        if (signature.length != 132) { throw new Error('invalid signature'); }\n        var digest = hashMessage(message);\n\n        var recoveryParam = parseInt(signature.substring(130), 16);\n        if (recoveryParam >= 27) { recoveryParam -= 27; }\n        if (recoveryParam < 0) { throw new Error('invalid signature'); }\n\n        return recoverAddress(\n            digest,\n            {\n                r: signature.substring(0, 66),\n                s: '0x' + signature.substring(66, 130),\n                recoveryParam: recoveryParam\n            }\n        );\n    }\n}\n","'use strict';\n\nimport * as errors from '../utils/errors';\n\nexport type Network = {\n    name: string,\n    chainId: number,\n    ensAddress?: string,\n}\n\nexport type Networkish = Network | string | number;\n\n\nconst homestead = {\n    chainId: 1,\n    ensAddress: \"0x314159265dd8dbb310642f98f50c066173c1259b\",\n    name: \"homestead\"\n};\n\nconst ropsten = {\n    chainId: 3,\n    ensAddress: \"0x112234455c3a32fd11230c42e7bccd4a84e02010\",\n    name: \"ropsten\"\n};\n\nconst networks: { [name: string]: { chainId: number, ensAddress?: string } } = {\n    unspecified: {\n        chainId: 0\n    },\n\n    homestead: homestead,\n    mainnet: homestead,\n\n    morden: {\n        chainId: 2\n    },\n\n    ropsten: ropsten,\n    testnet: ropsten,\n\n    rinkeby: {\n        chainId: 4,\n        ensAddress: \"0xe7410170f87102DF0055eB195163A03B7F2Bff4A\"\n    },\n\n    kovan: {\n        chainId: 42\n    },\n\n    classic: {\n        chainId: 61\n    }\n}\n\n/**\n *  getNetwork\n *\n *  Converts a named common networks or chain ID (network ID) to a Network\n *  and verifies a network is a valid Network..\n */\nexport function getNetwork(network: Networkish): Network {\n    // No network (null) or unspecified (chainId = 0)\n    if (!network) { return null; }\n\n    if (typeof(network) === 'number') {\n        for (var name in networks) {\n            let n = networks[name];\n            if (n.chainId === network) {\n                return {\n                    name: name,\n                    chainId: n.chainId,\n                    ensAddress: n.ensAddress\n                };\n            }\n        }\n\n        return {\n            chainId: network,\n            name: 'unknown'\n        };\n    }\n\n    if (typeof(network) === 'string') {\n        let n = networks[network];\n        if (n == null) { return null; }\n        return {\n            name: network,\n            chainId: n.chainId,\n            ensAddress: n.ensAddress\n        };\n    }\n\n    let n  = networks[network.name];\n\n    // Not a standard network; check that it is a valid network in general\n    if (!n) {\n        if (typeof(n.chainId) !== 'number') {\n            errors.throwError('invalid network chainId', errors.INVALID_ARGUMENT, { name: 'network', value: network });\n        }\n        return network;\n    }\n\n    // Make sure the chainId matches the expected network chainId (or is 0; disable EIP-155)\n    if (network.chainId !== 0 && network.chainId !== n.chainId) {\n        errors.throwError('network chainId mismatch', errors.INVALID_ARGUMENT, { name: 'network', value: network });\n    }\n\n    // Standard Network\n    return {\n        name: network.name,\n        chainId: n.chainId,\n        ensAddress: n.ensAddress\n    };\n}\n","'use strict';\n\n//import inherits = require('inherits');\n\nimport { Signer } from '../wallet/wallet';\n\nimport { getAddress, getContractAddress } from '../utils/address';\nimport { BigNumber, bigNumberify, BigNumberish } from '../utils/bignumber';\nimport { Arrayish, hexDataLength, hexDataSlice, hexlify, hexStripZeros, isHexString, joinSignature, stripZeros } from '../utils/bytes';\nimport { toUtf8String } from '../utils/utf8';\nimport { decode as rlpDecode, encode as rlpEncode } from '../utils/rlp';\nimport { hashMessage, namehash } from '../utils/hash';\nimport { getNetwork, Network, Networkish } from './networks';\nimport { defineReadOnly, resolveProperties, shallowCopy } from '../utils/properties';\nimport { parse as parseTransaction, sign as signTransaction, SignDigestFunc, Transaction } from '../utils/transaction';\n\nimport * as errors from '../utils/errors';\n\n\n//////////////////////////////\n// Exported Types\n\nexport type BlockTag = string | number;\n\nexport interface Block {\n    hash: string;\n    parentHash: string;\n    number: number;\n\n    timestamp: number;\n    nonce: string;\n    difficulty: number;\n\n    gasLimit: BigNumber;\n    gasUsed: BigNumber;\n\n    miner: string;\n    extraData: string;\n\n    transactions: Array<string>;\n}\n\nexport type TransactionRequest = {\n    to?: string | Promise<string>,\n    from?: string | Promise<string>,\n    nonce?: number | string | Promise<number | string>,\n\n    gasLimit?: BigNumberish | Promise<BigNumberish>,\n    gasPrice?: BigNumberish | Promise<BigNumberish>,\n\n    data?: Arrayish | Promise<Arrayish>,\n    value?: BigNumberish | Promise<BigNumberish>,\n    chainId?: number | Promise<number>,\n}\n\nexport interface TransactionResponse extends Transaction {\n    // Only if a transaction has been mined\n    blockNumber?: number,\n    blockHash?: string,\n    timestamp?: number,\n\n    // Not optional (as it is in Transaction)\n    from: string;\n\n    // This function waits until the transaction has been mined\n    wait: (timeout?: number) => Promise<TransactionResponse>\n};\n\nexport interface TransactionReceipt {\n    contractAddress?: string,\n    transactionIndex?: number,\n    root?: string,\n    gasUsed?: BigNumber,\n    logsBloom?: string,\n    blockHash?: string,\n    transactionHash?: string,\n    logs?: Array<Log>,\n    blockNumber?: number,\n    cumulativeGasUsed?: BigNumber,\n    byzantium: boolean,\n    status?: number  // @TOOD: Check 0 or 1?\n};\n\nexport type Filter = {\n    fromBlock?: BlockTag,\n    toBlock?: BlockTag,\n    address?: string,\n    topics?: Array<any>\n}\n\n// @TODO: Some of these are not options; force them?\nexport interface Log {\n    blockNumber?: number;\n    blockHash?: string;\n    transactionIndex?: number;\n\n    removed?: boolean;\n\n    transactionLogIndex?: number,\n\n    address: string;\n    data?: string;\n\n    topics?: Array<string>;\n\n    transactionHash?: string;\n    logIndex?: number;\n}\n\nexport type Listener = (...args: Array<any>) => void;\n\n//////////////////////////////\n// Request and Response Checking\n\n// @TODO: not any?\nfunction check(format: any, object: any): any {\n    var result: any = {};\n    for (var key in format) {\n        try {\n            var value = format[key](object[key]);\n            if (value !== undefined) { result[key] = value; }\n        } catch (error) {\n            error.checkKey = key;\n            error.checkValue = object[key];\n            throw error;\n        }\n    }\n    return result;\n}\n\ntype CheckFunc = (value: any) => any;\n\nfunction allowNull(check: CheckFunc, nullValue?: any): CheckFunc {\n    return (function(value: any) {\n        if (value == null) { return nullValue; }\n        return check(value);\n    });\n}\n\nfunction allowFalsish(check: CheckFunc, replaceValue: any): CheckFunc {\n    return (function(value) {\n        if (!value) { return replaceValue; }\n        return check(value);\n    });\n}\n\nfunction arrayOf(check: CheckFunc): CheckFunc {\n    return (function(array: any): Array<any> {\n        if (!Array.isArray(array)) { throw new Error('not an array'); }\n\n        var result: any = [];\n\n        array.forEach(function(value) {\n            result.push(check(value));\n        });\n\n        return result;\n    });\n}\n\nfunction checkHash(hash: any): string {\n    if (typeof(hash) === 'string' && hexDataLength(hash) === 32) {\n       return hash;\n    }\n    errors.throwError('invalid hash', errors.INVALID_ARGUMENT, { arg: 'hash', value: hash });\n    return null;\n}\n\nfunction checkNumber(number: any): number {\n    return bigNumberify(number).toNumber();\n}\n\n// Returns the difficulty as a number, or if too large (i.e. PoA network) null\nfunction checkDifficulty(value: BigNumberish): number {\n    let v = bigNumberify(value);\n\n    try {\n        return v.toNumber();\n    } catch (error) { }\n\n    return null;\n}\n\nfunction checkBoolean(value: any): boolean {\n    if (typeof(value) === 'boolean') { return value; }\n    if (typeof(value) === 'string') {\n        if (value === 'true') { return true; }\n        if (value === 'false') { return false; }\n    }\n    throw new Error('invaid boolean - ' + value);\n}\n\nfunction checkUint256(uint256: string): string {\n    if (!isHexString(uint256)) {\n        throw new Error('invalid uint256');\n    }\n    while (uint256.length < 66) {\n        uint256 = '0x0' + uint256.substring(2);\n    }\n    return uint256;\n}\n\n/*\nfunction checkString(string) {\n    if (typeof(string) !== 'string') { throw new Error('invalid string'); }\n    return string;\n}\n*/\n\nfunction checkBlockTag(blockTag: BlockTag): string {\n    if (blockTag == null) { return 'latest'; }\n\n    if (blockTag === 'earliest') { return '0x0'; }\n\n    if (blockTag === 'latest' || blockTag === 'pending') {\n        return blockTag;\n    }\n\n    if (typeof(blockTag) === 'number') {\n        return hexStripZeros(hexlify(blockTag));\n    }\n\n    if (isHexString(blockTag)) { return hexStripZeros(blockTag); }\n\n    throw new Error('invalid blockTag');\n}\n\nvar formatBlock = {\n    hash: checkHash,\n    parentHash: checkHash,\n    number: checkNumber,\n\n    timestamp: checkNumber,\n    nonce: allowNull(hexlify),\n    difficulty: checkDifficulty,\n\n    gasLimit: bigNumberify,\n    gasUsed: bigNumberify,\n\n    miner: getAddress,\n    extraData: hexlify,\n\n    //transactions: allowNull(arrayOf(checkTransaction)),\n    transactions: allowNull(arrayOf(checkHash)),\n\n    //transactionRoot: checkHash,\n    //stateRoot: checkHash,\n    //sha3Uncles: checkHash,\n\n    //logsBloom: hexlify,\n};\n\nfunction checkBlock(block: any): Block {\n    if (block.author != null && block.miner == null) {\n        block.miner = block.author;\n    }\n    return check(formatBlock, block);\n}\n\n\nvar formatTransaction = {\n   hash: checkHash,\n\n   blockHash: allowNull(checkHash, null),\n   blockNumber: allowNull(checkNumber, null),\n   transactionIndex: allowNull(checkNumber, null),\n\n   from: getAddress,\n\n   gasPrice: bigNumberify,\n   gasLimit: bigNumberify,\n   to: allowNull(getAddress, null),\n   value: bigNumberify,\n   nonce: checkNumber,\n   data: hexlify,\n\n   r: allowNull(checkUint256),\n   s: allowNull(checkUint256),\n   v: allowNull(checkNumber),\n\n   creates: allowNull(getAddress, null),\n\n   raw: allowNull(hexlify),\n};\n\nexport function checkTransactionResponse(transaction: any): TransactionResponse {\n\n    // Rename gas to gasLimit\n    if (transaction.gas != null && transaction.gasLimit == null) {\n        transaction.gasLimit = transaction.gas;\n    }\n\n    // Some clients (TestRPC) do strange things like return 0x0 for the\n    // 0 address; correct this to be a real address\n    if (transaction.to && bigNumberify(transaction.to).isZero()) {\n        transaction.to = '0x0000000000000000000000000000000000000000';\n    }\n\n    // Rename input to data\n    if (transaction.input != null && transaction.data == null) {\n        transaction.data = transaction.input;\n    }\n\n    // If to and creates are empty, populate the creates from the transaction\n    if (transaction.to == null && transaction.creates == null) {\n        transaction.creates = getContractAddress(transaction);\n    }\n\n    if (!transaction.raw) {\n        // Very loose providers (e.g. TestRPC) don't provide a signature or raw\n        if (transaction.v && transaction.r && transaction.s) {\n            var raw = [\n                stripZeros(hexlify(transaction.nonce)),\n                stripZeros(hexlify(transaction.gasPrice)),\n                stripZeros(hexlify(transaction.gasLimit)),\n                (transaction.to || \"0x\"),\n                stripZeros(hexlify(transaction.value || '0x')),\n                hexlify(transaction.data || '0x'),\n                stripZeros(hexlify(transaction.v || '0x')),\n                stripZeros(hexlify(transaction.r)),\n                stripZeros(hexlify(transaction.s)),\n            ];\n\n            transaction.raw = rlpEncode(raw);\n        }\n    }\n\n\n    var result = check(formatTransaction, transaction);\n\n    var networkId = transaction.networkId;\n\n    if (isHexString(networkId)) {\n        networkId = bigNumberify(networkId).toNumber();\n    }\n\n    if (typeof(networkId) !== 'number' && result.v != null) {\n        networkId = (result.v - 35) / 2;\n        if (networkId < 0) { networkId = 0; }\n        networkId = parseInt(networkId);\n    }\n\n    if (typeof(networkId) !== 'number') { networkId = 0; }\n\n    result.networkId = networkId;\n    \n    // 0x0000... should actually be null\n    if (result.blockHash && result.blockHash.replace(/0/g, '') === 'x') {\n        result.blockHash = null;\n    }\n\n    return result;\n}\n\nvar formatTransactionRequest = {\n    from: allowNull(getAddress),\n    nonce: allowNull(checkNumber),\n    gasLimit: allowNull(bigNumberify),\n    gasPrice: allowNull(bigNumberify),\n    to: allowNull(getAddress),\n    value: allowNull(bigNumberify),\n    data: allowNull(hexlify),\n};\n\nfunction checkTransactionRequest(transaction: any): any {\n    return check(formatTransactionRequest, transaction);\n}\n\nvar formatTransactionReceiptLog = {\n    transactionLogIndex: allowNull(checkNumber),\n    transactionIndex: checkNumber,\n    blockNumber: checkNumber,\n    transactionHash: checkHash,\n    address: getAddress,\n    topics: arrayOf(checkHash),\n    data: hexlify,\n    logIndex: checkNumber,\n    blockHash: checkHash,\n};\n\nfunction checkTransactionReceiptLog(log: any): any {\n    return check(formatTransactionReceiptLog, log);\n}\n\nvar formatTransactionReceipt = {\n    contractAddress: allowNull(getAddress, null),\n    transactionIndex: checkNumber,\n    root: allowNull(checkHash),\n    gasUsed: bigNumberify,\n    logsBloom: allowNull(hexlify),\n    blockHash: checkHash,\n    transactionHash: checkHash,\n    logs: arrayOf(checkTransactionReceiptLog),\n    blockNumber: checkNumber,\n    cumulativeGasUsed: bigNumberify,\n    status: allowNull(checkNumber)\n};\n\nfunction checkTransactionReceipt(transactionReceipt: any): TransactionReceipt {\n    //var status = transactionReceipt.status;\n    //var root = transactionReceipt.root;\n\n    var result: TransactionReceipt = check(formatTransactionReceipt, transactionReceipt);\n    result.logs.forEach(function(entry, index) {\n        if (entry.transactionLogIndex == null) {\n            entry.transactionLogIndex = index;\n        }\n    });\n    if (transactionReceipt.status != null) {\n        result.byzantium = true;\n    }\n    return result;\n}\n\nfunction checkTopics(topics: any): any {\n    if (Array.isArray(topics)) {\n        topics.forEach(function(topic) {\n            checkTopics(topic);\n        });\n\n    } else if (topics != null) {\n        checkHash(topics);\n    }\n\n    return topics;\n}\n\nvar formatFilter = {\n    fromBlock: allowNull(checkBlockTag, undefined),\n    toBlock: allowNull(checkBlockTag, undefined),\n    address: allowNull(getAddress, undefined),\n    topics: allowNull(checkTopics, undefined),\n};\n\nfunction checkFilter(filter: any): any {\n    return check(formatFilter, filter);\n}\n\nvar formatLog = {\n    blockNumber: allowNull(checkNumber),\n    blockHash: allowNull(checkHash),\n    transactionIndex: checkNumber,\n\n    removed: allowNull(checkBoolean),\n\n    address: getAddress,\n    data: allowFalsish(hexlify, '0x'),\n\n    topics: arrayOf(checkHash),\n\n    transactionHash: checkHash,\n    logIndex: checkNumber,\n}\n\nfunction checkLog(log: any): any {\n    return check(formatLog, log);\n}\n\n//////////////////////////////\n// Defer Promises\n\ntype AllowNullFunc = () => boolean;\ntype ExecuteFunc = () => Promise<any>\nfunction stallPromise(allowNullFunc: AllowNullFunc, executeFunc: ExecuteFunc): Promise<any> {\n    return new Promise(function(resolve, reject) {\n        var attempt = 0;\n        function check() {\n            executeFunc().then(function(result) {\n                // If we have a result, or are allowed null then we're done\n                if (result || allowNullFunc()) {\n                    resolve(result);\n\n                // Otherwise, exponential back-off (up to 10s) our next request\n                } else {\n                    attempt++;\n                    var timeout = 500 + 250 * parseInt(String(Math.random() * (1 << attempt)));\n                    if (timeout > 10000) { timeout = 10000; }\n                    setTimeout(check, timeout);\n                }\n            }, function(error) {\n                reject(error);\n            });\n        }\n        check();\n    });\n}\n\n//////////////////////////////\n// Event Serializeing\n\nfunction recurse(object: any, convertFunc: (object: any) => any): any {\n    if (Array.isArray(object)) {\n        var result: any = [];\n        object.forEach(function(object) {\n            result.push(recurse(object, convertFunc));\n        });\n        return result;\n    }\n    return convertFunc(object);\n}\n\nfunction getEventString(object: any): string {\n    try {\n        return 'address:' + getAddress(object);\n    } catch (error) { }\n\n    if (object === 'block' || object === 'pending' || object === 'error') {\n        return object;\n\n    } else if (hexDataLength(object) === 32) {\n        return 'tx:' + object;\n\n    } else if (Array.isArray(object)) {\n        // Replace null in the structure with '0x'\n        let stringified: any = recurse(object, function(object: any) {\n            if (object == null) { object = '0x'; }\n            return object;\n        });\n\n        try {\n            return 'topic:' + rlpEncode(stringified);\n        } catch (error) {\n            console.log(error);\n        }\n    }\n    try {\n        throw new Error();\n    } catch(e) {\n        console.log(e.stack);\n    }\n\n    throw new Error('invalid event - ' + object);\n}\n\nfunction parseEventString(event: string): { type: string, address?: string, hash?: string, topic?: any } {\n    if (event.substring(0, 3) === 'tx:') {\n        return { type: 'transaction', hash: event.substring(3) };\n\n    } else if (event === 'block' || event === 'pending' || event === 'error') {\n        return { type: event };\n\n    } else if (event.substring(0, 8) === 'address:') {\n        return { type: 'address', address: event.substring(8) };\n\n    } else if (event.substring(0, 6) === 'topic:') {\n        try {\n            let object = recurse(rlpDecode(event.substring(6)), function(object: any) {\n                if (object === '0x') { object = null; }\n                return object;\n            });\n            return { type: 'topic', topic: object };\n        } catch (error) {\n            console.log(error);\n        }\n    }\n\n    throw new Error('invalid event string');\n}\n//////////////////////////////\n// Provider Object\n\n\n/* @TODO:\ntype Event = {\n   eventName: string,\n   listener: any, // @TODO: Function any: any\n   type: string,\n}\n*/\n\n// @TODO: Perhaps allow a SignDigestAsyncFunc?\n\n// Enable a simple signing function and provider to provide a full Signer\nexport class ProviderSigner extends Signer {\n    readonly provider: Provider;\n    readonly signDigest: SignDigestFunc;\n\n    private _addressPromise: Promise<string>;\n\n    constructor(address: string | Promise<string>, signDigest: SignDigestFunc, provider: Provider) {\n        super();\n        errors.checkNew(this, ProviderSigner);\n        defineReadOnly(this, '_addressPromise', Promise.resolve(address));\n        defineReadOnly(this, 'signDigest', signDigest);\n        defineReadOnly(this, 'provider', provider);\n    }\n\n    getAddress(): Promise<string> {\n        return this._addressPromise;\n    }\n\n    signMessage(message: Arrayish | string): Promise<string> {\n        return Promise.resolve(joinSignature(this.signDigest(hashMessage(message))));\n    }\n\n    sendTransaction(transaction: TransactionRequest): Promise<TransactionResponse> {\n        transaction = shallowCopy(transaction);\n\n        if (transaction.chainId == null) {\n            transaction.chainId = this.provider.getNetwork().then((network) => {\n                return network.chainId;\n            });\n        }\n\n        if (transaction.from == null) {\n            transaction.from = this.getAddress();\n        }\n\n        if (transaction.gasLimit == null) {\n            transaction.gasLimit = this.provider.estimateGas(transaction);\n        }\n\n        if (transaction.gasPrice == null) {\n            transaction.gasPrice = this.provider.getGasPrice();\n        }\n\n        return resolveProperties(transaction).then((tx) => {\n            let signedTx = signTransaction(tx, this.signDigest);\n            return this._addressPromise.then((address) => {\n                if (parseTransaction(signedTx).from !== address) {\n                    errors.throwError('signing address does not match expected address', errors.UNKNOWN_ERROR, { address: parseTransaction(signedTx).from, expectedAddress: address, signedTransaction: signedTx });\n                }\n                return this.provider.sendTransaction(signedTx);\n            });\n        });\n    }\n}\n\nexport class Provider {\n    private _network: Network;\n\n    // string => Event\n    private _events: any;\n    protected _emitted: any;\n\n    private _pollingInterval: number;\n    private _poller: any; // @TODO: what does TypeScript thing setInterval returns?\n\n    private _lastBlockNumber: number;\n\n    // string => BigNumber\n    private _balances: any;\n\n\n    /**\n     *  ready\n     *\n     *  A Promise<Network> that resolves only once the provider is ready.\n     *\n     *  Sub-classes that call the super with a network without a chainId\n     *  MUST set this. Standard named networks have a known chainId.\n     *\n     */\n    protected ready: Promise<Network>;\n\n    constructor(network: Networkish | Promise<Network>) {\n        errors.checkNew(this, Provider);\n\n        if (network instanceof Promise) {\n            defineReadOnly(this, 'ready', network.then((network) => {\n                defineReadOnly(this, '_network', network);\n                return network;\n            }));\n\n        } else {\n            let knownNetwork = getNetwork((network == null) ? 'homestead': network);\n            if (knownNetwork) {\n                defineReadOnly(this, '_network', knownNetwork);\n                defineReadOnly(this, 'ready', Promise.resolve(this._network));\n\n            } else {\n                errors.throwError('invalid network', errors.INVALID_ARGUMENT, { arg: 'network', value: network });\n            }\n        }\n\n        this._lastBlockNumber = -2;\n\n        // Balances being watched for changes\n        this._balances = {};\n\n        // Events being listened to\n        this._events = {};\n\n        this._pollingInterval = 4000;\n\n        // We use this to track recent emitted events; for example, if we emit a \"block\" of 100\n        // and we get a `getBlock(100)` request which would result in null, we should retry\n        // until we get a response. This provides devs with a consistent view. Similarly for\n        // transaction hashes.\n        this._emitted = { block: this._lastBlockNumber };\n    }\n\n    private _doPoll(): void {\n        this.getBlockNumber().then((blockNumber) => {\n\n            // If the block hasn't changed, meh.\n            if (blockNumber === this._lastBlockNumber) { return; }\n\n            if (this._lastBlockNumber === -2) { this._lastBlockNumber = blockNumber - 1; }\n\n            // Notify all listener for each block that has passed\n            for (var i = this._lastBlockNumber + 1; i <= blockNumber; i++) {\n                if (this._emitted.block < i) {\n                    this._emitted.block = i;\n\n                    // Evict any transaction hashes or block hashes over 12 blocks\n                    // old, since they should not return null anyways\n                    Object.keys(this._emitted).forEach((key) => {\n                        if (key === 'block') { return; }\n\n                        if (this._emitted[key] > i + 12) {\n                            delete this._emitted[key];\n                        }\n                    });\n                }\n                this.emit('block', i);\n            }\n\n            // Sweep balances and remove addresses we no longer have events for\n            var newBalances: any = {};\n\n            // Find all transaction hashes we are waiting on\n            Object.keys(this._events).forEach((eventName) => {\n                var event = parseEventString(eventName);\n\n                if (event.type === 'transaction') {\n                    this.getTransaction(event.hash).then((transaction) => {\n                        if (!transaction || transaction.blockNumber == null) { return; }\n                        this._emitted['t:' + transaction.hash.toLowerCase()] = transaction.blockNumber;\n                        this.emit(event.hash, transaction);\n                    });\n\n                } else if (event.type === 'address') {\n                    if (this._balances[event.address]) {\n                        newBalances[event.address] = this._balances[event.address];\n                    }\n                    this.getBalance(event.address, 'latest').then(function(balance) {\n                        var lastBalance = this._balances[event.address];\n                        if (lastBalance && balance.eq(lastBalance)) { return; }\n                        this._balances[event.address] = balance;\n                        this.emit(event.address, balance);\n                    });\n\n                } else if (event.type === 'topic') {\n                    this.getLogs({\n                        fromBlock: this._lastBlockNumber + 1,\n                        toBlock: blockNumber,\n                        topics: event.topic\n                    }).then((logs) => {\n                        if (logs.length === 0) { return; }\n                        logs.forEach((log) => {\n                            this._emitted['b:' + log.blockHash.toLowerCase()] = log.blockNumber;\n                            this._emitted['t:' + log.transactionHash.toLowerCase()] = log.blockNumber;\n                            this.emit(event.topic, log);\n                        });\n                    });\n                }\n            });\n\n            this._lastBlockNumber = blockNumber;\n\n            this._balances = newBalances;\n        });\n        this.doPoll();\n    }\n\n    resetEventsBlock(blockNumber: number): void {\n        this._lastBlockNumber = this.blockNumber;\n        this._doPoll();\n    }\n\n    get network(): Network {\n        return this._network;\n    }\n\n    getNetwork(): Promise<Network> {\n        return this.ready;\n    }\n\n    get blockNumber(): number {\n        if (this._lastBlockNumber < 0) { return null; }\n        return this._lastBlockNumber;\n    }\n\n    get polling(): boolean {\n        return (this._poller != null);\n    }\n\n    set polling(value: boolean) {\n        setTimeout(() => {\n            if (value && !this._poller) {\n                this._poller = setInterval(this._doPoll.bind(this), this.pollingInterval);\n\n            } else if (!value && this._poller) {\n                clearInterval(this._poller);\n                this._poller = null;\n            }\n        }, 0);\n    }\n\n    get pollingInterval(): number {\n        return this._pollingInterval;\n    }\n\n    set pollingInterval(value: number) {\n        if (typeof(value) !== 'number' || value <= 0 || parseInt(String(value)) != value) {\n            throw new Error('invalid polling interval');\n        }\n\n        this._pollingInterval = value;\n\n        if (this._poller) {\n            clearInterval(this._poller);\n            this._poller = setInterval(() => { this._doPoll() }, this._pollingInterval);\n        }\n    }\n\n    // @TODO: Add .poller which must be an event emitter with a 'start', 'stop' and 'block' event;\n    //        this will be used once we move to the WebSocket or other alternatives to polling\n\n    waitForTransaction(transactionHash: string, timeout?: number): Promise<TransactionResponse> {\n        var self = this;\n        return new Promise(function(resolve, reject) {\n            var timer: any = null;\n\n            function complete(transaction: TransactionResponse) {\n                if (timer) { clearTimeout(timer); }\n                resolve(transaction);\n            }\n\n            self.once(transactionHash, complete);\n\n            if (typeof(timeout) === 'number' && timeout > 0) {\n                timer = setTimeout(function() {\n                    self.removeListener(transactionHash, complete);\n                    reject(new Error('timeout'));\n                }, timeout);\n            }\n        });\n    }\n\n    getBlockNumber(): Promise<number> {\n        return this.ready.then(() => {\n            return this.perform('getBlockNumber', { }).then((result) => {\n                var value = parseInt(result);\n                if (value != result) { throw new Error('invalid response - getBlockNumber'); }\n                return value;\n            });\n        });\n    }\n\n    getGasPrice(): Promise<BigNumber> {\n        return this.ready.then(() => {\n            return this.perform('getGasPrice', { }).then((result) => {\n                return bigNumberify(result);\n            });\n        });\n    }\n\n\n    getBalance(addressOrName: string | Promise<string>, blockTag?: BlockTag | Promise<BlockTag>): Promise<BigNumber> {\n        return this.ready.then(() => {\n            return resolveProperties({ addressOrName: addressOrName, blockTag: blockTag }).then(({ addressOrName, blockTag }) => {\n                return this.resolveName(addressOrName).then((address) => {\n                    var params = { address: address, blockTag: checkBlockTag(blockTag) };\n                    return this.perform('getBalance', params).then((result) => {\n                        return bigNumberify(result);\n                    });\n                });\n            });\n        });\n    }\n\n    getTransactionCount(addressOrName: string | Promise<string>, blockTag?: BlockTag | Promise<BlockTag>): Promise<number> {\n        return this.ready.then(() => {\n            return resolveProperties({ addressOrName: addressOrName, blockTag: blockTag }).then(({ addressOrName, blockTag }) => {\n                return this.resolveName(addressOrName).then((address) => {\n                    var params = { address: address, blockTag: checkBlockTag(blockTag) };\n                    return this.perform('getTransactionCount', params).then((result) => {\n                        return bigNumberify(result).toNumber();\n                    });\n                });\n            });\n        });\n    }\n\n    getCode(addressOrName: string | Promise<string>, blockTag?: BlockTag | Promise<BlockTag>): Promise<string> {\n        return this.ready.then(() => {\n            return resolveProperties({ addressOrName: addressOrName, blockTag: blockTag }).then(({ addressOrName, blockTag }) => {\n                return this.resolveName(addressOrName).then((address) => {\n                    var params = {address: address, blockTag: checkBlockTag(blockTag)};\n                    return this.perform('getCode', params).then((result) => {\n                        return hexlify(result);\n                    });\n                });\n            });\n        });\n    }\n\n    getStorageAt(addressOrName: string | Promise<string>, position: BigNumberish | Promise<BigNumberish>, blockTag?: BlockTag | Promise<BlockTag>): Promise<string> {\n        return this.ready.then(() => {\n            return resolveProperties({ addressOrName: addressOrName, position: position, blockTag: blockTag }).then(({ addressOrName, position, blockTag }) => {\n                return this.resolveName(addressOrName).then((address) => {\n                    var params = {\n                        address: address,\n                        blockTag: checkBlockTag(blockTag),\n                        position: hexStripZeros(hexlify(position)),\n                    };\n                    return this.perform('getStorageAt', params).then((result) => {\n                        return hexlify(result);\n                    });\n                });\n            });\n        });\n    }\n\n    sendTransaction(signedTransaction: string | Promise<string>): Promise<TransactionResponse> {\n        return this.ready.then(() => {\n            return resolveProperties({ signedTransaction: signedTransaction }).then(({ signedTransaction }) => {\n                var params = { signedTransaction: hexlify(signedTransaction) };\n                return this.perform('sendTransaction', params).then((hash) => {\n                    if (hexDataLength(hash) !== 32) { throw new Error('invalid response - sendTransaction'); }\n\n                    // A signed transaction always has a from (and we add wait below)\n                    var tx = <TransactionResponse>parseTransaction(signedTransaction);\n\n                    // Check the hash we expect is the same as the hash the server reported\n                    if (tx.hash !== hash) {\n                        errors.throwError('Transaction hash mismatch from Proivder.sendTransaction.', errors.UNKNOWN_ERROR, { expectedHash: tx.hash, returnedHash: hash });\n                    }\n                    this._emitted['t:' + tx.hash.toLowerCase()] = 'pending';\n                    tx.wait = (timeout?: number) => {\n                        return this.waitForTransaction(hash, timeout);\n                    };\n\n                    return tx;\n                });\n            });\n        });\n    }\n\n\n    call(transaction: TransactionRequest): Promise<string> {\n        let tx: TransactionRequest = shallowCopy(transaction);\n        return this.ready.then(() => {\n            return resolveProperties(tx).then((tx) => {\n                return this._resolveNames(tx, [ 'to', 'from' ]).then((tx) => {\n                    var params = { transaction: checkTransactionRequest(tx) };\n                    return this.perform('call', params).then((result) => {\n                        return hexlify(result);\n                    });\n                });\n            });\n        });\n    }\n\n    estimateGas(transaction: TransactionRequest) {\n        let tx: TransactionRequest = {\n            to: transaction.to,\n            from: transaction.from,\n            data: transaction.data\n        };\n\n        return this.ready.then(() => {\n            return resolveProperties(tx).then((tx) => {\n                return this._resolveNames(tx, [ 'to', 'from' ]).then((tx) => {\n                    var params = { transaction: checkTransactionRequest(tx) };\n                    return this.perform('estimateGas', params).then((result) => {\n                        return bigNumberify(result);\n                    });\n                });\n            });\n        });\n   }\n\n    getBlock(blockHashOrBlockTag: BlockTag | string | Promise<BlockTag | string>): Promise<Block> {\n        return this.ready.then(() => {\n            return resolveProperties({ blockHashOrBlockTag: blockHashOrBlockTag }).then(({ blockHashOrBlockTag }) => {\n                try {\n                    var blockHash = hexlify(blockHashOrBlockTag);\n                    if (hexDataLength(blockHash) === 32) {\n                        return stallPromise(() => {\n                            return (this._emitted['b:' + blockHash.toLowerCase()] == null);\n                        }, () => {\n                            return this.perform('getBlock', {blockHash: blockHash}).then((block) => {\n                                if (block == null) { return null; }\n                                return checkBlock(block);\n                            });\n                        });\n                    }\n                } catch (error) { }\n\n                try {\n                    var blockTag = checkBlockTag(blockHashOrBlockTag);\n                    return stallPromise(() => {\n                        if (isHexString(blockTag)) {\n                            var blockNumber = parseInt(blockTag.substring(2), 16);\n                            return blockNumber > this._emitted.block;\n                        }\n                        return true;\n                    }, () => {\n                        return this.perform('getBlock', { blockTag: blockTag }).then((block) => {\n                            if (block == null) { return null; }\n                            return checkBlock(block);\n                        });\n                    });\n                } catch (error) { }\n\n                throw new Error('invalid block hash or block tag');\n            });\n        });\n    }\n\n    getTransaction(transactionHash: string): Promise<TransactionResponse> {\n        return this.ready.then(() => {\n            return resolveProperties({ transactionHash: transactionHash }).then(({ transactionHash }) => {\n                var params = { transactionHash: checkHash(transactionHash) };\n                return stallPromise(() => {\n                    return (this._emitted['t:' + transactionHash.toLowerCase()] == null);\n                }, () => {\n                    return this.perform('getTransaction', params).then((result) => {\n                        if (result != null) { result = checkTransactionResponse(result); }\n                        return result;\n                    });\n                });\n            });\n        });\n    }\n\n    getTransactionReceipt(transactionHash: string): Promise<TransactionReceipt> {\n        return this.ready.then(() => {\n            return resolveProperties({ transactionHash: transactionHash }).then(({ transactionHash }) => {\n                var params = { transactionHash: checkHash(transactionHash) };\n                return stallPromise(() => {\n                    return (this._emitted['t:' + transactionHash.toLowerCase()] == null);\n                }, () => {\n                    return this.perform('getTransactionReceipt', params).then((result) => {\n                        if (result != null) { result = checkTransactionReceipt(result); }\n                        return result;\n                    });\n                });\n            });\n        });\n    }\n\n    getLogs(filter: Filter): Promise<Array<Log>>{\n        return this.ready.then(() => {\n            return resolveProperties(filter).then((filter) => {\n                return this._resolveNames(filter, ['address']).then((filter) => {\n                    var params = { filter: checkFilter(filter) };\n                    return this.perform('getLogs', params).then((result) => {\n                        return arrayOf(checkLog)(result);\n                    });\n                });\n            });\n        });\n    }\n\n    getEtherPrice(): Promise<number> {\n        return this.ready.then(() => {\n            return this.perform('getEtherPrice', {}).then((result) => {\n                // @TODO: Check valid float\n                return result;\n            });\n        });\n    }\n\n    // @TODO: Could probably use resolveProperties instead?\n    _resolveNames(object: any, keys: Array<string>): Promise<{ [key: string]: string }> {\n        var promises: Array<Promise<void>> = [];\n\n        var result: { [key: string ]: string } = shallowCopy(object);\n\n        keys.forEach(function(key) {\n            if (result[key] === undefined) { return; }\n            promises.push(this.resolveName(result[key]).then((address: string) => {\n                result[key] = address;\n            }));\n        }, this);\n\n        return Promise.all(promises).then(function() { return result; });\n    }\n\n    _getResolver(name: string): Promise<string> {\n        // Get the resolver from the blockchain\n        return this.getNetwork().then((network) => {\n\n            // No ENS...\n            if (!network.ensAddress) {\n                errors.throwError(\n                    'network does support ENS',\n                    errors.UNSUPPORTED_OPERATION,\n                    { operation: 'ENS', network: network.name }\n                );\n            }\n\n            // keccak256('resolver(bytes32)')\n            var data = '0x0178b8bf' + namehash(name).substring(2);\n            var transaction = { to: network.ensAddress, data: data };\n\n            return this.call(transaction).then((data) => {\n\n                // extract the address from the data\n                if (hexDataLength(data) !== 32) { return null; }\n                return getAddress(hexDataSlice(data, 12));\n            });\n        });\n    }\n\n    resolveName(name: string | Promise<string>): Promise<string> {\n\n        // If it is a promise, resolve it then recurse\n        if (name instanceof Promise) {\n            return name.then((addressOrName) => {\n                return this.resolveName(addressOrName);\n            });\n        }\n\n        // If it is already an address, nothing to resolve\n        try {\n            return Promise.resolve(getAddress(name));\n        } catch (error) { }\n\n        var self = this;\n\n        var nodeHash = namehash(name);\n\n        // Get the addr from the resovler\n        return this._getResolver(name).then(function(resolverAddress) {\n\n            // keccak256('addr(bytes32)')\n            var data = '0x3b3b57de' + nodeHash.substring(2);\n            var transaction = { to: resolverAddress, data: data };\n            return self.call(transaction);\n\n        // extract the address from the data\n        }).then(function(data) {\n            if (hexDataLength(data) !== 32) { return null; }\n            var address = getAddress(hexDataSlice(data, 12));\n            if (address === '0x0000000000000000000000000000000000000000') { return null; }\n            return address;\n        });\n    }\n\n    lookupAddress(address: string | Promise<string>): Promise<string> {\n        if (address instanceof Promise) {\n            return address.then((address) => {\n                return this.lookupAddress(address);\n            });\n        }\n\n        address = getAddress(address);\n\n        var name = address.substring(2) + '.addr.reverse'\n        var nodehash = namehash(name);\n\n        var self = this;\n\n        return this._getResolver(name).then(function(resolverAddress) {\n            if (!resolverAddress) { return null; }\n\n            // keccak('name(bytes32)')\n            var data = '0x691f3431' + nodehash.substring(2);\n            var transaction = { to: resolverAddress, data: data };\n            return self.call(transaction);\n\n        }).then(function(data) {\n            // Strip off the \"0x\"\n            data = data.substring(2);\n\n            // Strip off the dynamic string pointer (0x20)\n            if (data.length < 64) { return null; }\n            data = data.substring(64);\n\n            if (data.length < 64) { return null; }\n            var length = bigNumberify('0x' + data.substring(0, 64)).toNumber();\n            data = data.substring(64);\n\n            if (2 * length > data.length) { return null; }\n\n            var name = toUtf8String('0x' + data.substring(0, 2 * length));\n\n            // Make sure the reverse record matches the foward record\n            return self.resolveName(name).then(function(addr) {\n                if (addr != address) { return null; }\n                return name;\n            });\n\n        });\n    }\n\n    doPoll(): void {\n    }\n\n    perform(method: string, params: any): Promise<any> {\n        errors.throwError(method + ' not implemented', errors.NOT_IMPLEMENTED, { operation: method });\n        return null;\n    }\n\n    _startPending(): void {\n        console.log('WARNING: this provider does not support pending events');\n    }\n\n    _stopPending(): void {\n    }\n\n    on(eventName: any, listener: Listener): Provider {\n        var key = getEventString(eventName);\n        if (!this._events[key]) { this._events[key] = []; }\n        this._events[key].push({eventName: eventName, listener: listener, type: 'on'});\n        if (key === 'pending') { this._startPending(); }\n        this.polling = true;\n\n        return this;\n    }\n\n    once(eventName: any, listener: Listener): Provider {\n        var key = getEventString(eventName);\n        if (!this._events[key]) { this._events[key] = []; }\n        this._events[key].push({eventName: eventName, listener: listener, type: 'once'});\n        if (key === 'pending') { this._startPending(); }\n        this.polling = true;\n\n        return this;\n    }\n\n    emit(eventName: any, ...args: Array<any>): boolean {\n        let result = false;\n\n        var key = getEventString(eventName);\n\n        //var args = Array.prototype.slice.call(arguments, 1);\n        var listeners = this._events[key];\n        if (!listeners) { return result; }\n\n        for (var i = 0; i < listeners.length; i++) {\n            var listener = listeners[i];\n            if (listener.type === 'once') {\n                listeners.splice(i, 1);\n                i--;\n            }\n\n            try {\n                listener.listener.apply(this, args);\n                result = true;\n            } catch (error) {\n                console.log('Event Listener Error: ' + error.message);\n            }\n        }\n\n        if (listeners.length === 0) {\n            delete this._events[key];\n            if (key === 'pending') { this._stopPending(); }\n        }\n\n        if (this.listenerCount() === 0) { this.polling = false; }\n\n        return result;\n    }\n\n    // @TODO: type EventName\n    listenerCount(eventName?: any): number {\n        if (!eventName) {\n            var result = 0;\n            for (var key in this._events) {\n                result += this._events[key].length;\n            }\n            return result;\n        }\n\n        var listeners = this._events[getEventString(eventName)];\n        if (!listeners) { return 0; }\n        return listeners.length;\n    }\n\n    listeners(eventName: any): Array<Listener> {\n        var listeners = this._events[getEventString(eventName)];\n        if (!listeners) { return []; }\n        var result = [];\n        for (var i = 0; i < listeners.length; i++) {\n            result.push(listeners[i].listener);\n        }\n        return result;\n    }\n\n    removeAllListeners(eventName: any): Provider {\n        delete this._events[getEventString(eventName)];\n        if (this.listenerCount() === 0) { this.polling = false; }\n\n        return this;\n    }\n\n    removeListener(eventName: any, listener: Listener): Provider {\n        var eventNameString = getEventString(eventName);\n        var listeners = this._events[eventNameString];\n        if (!listeners) { return this; }\n\n        for (var i = 0; i < listeners.length; i++) {\n            if (listeners[i].listener === listener) {\n                listeners.splice(i, 1);\n                break;\n            }\n        }\n\n        if (listeners.length === 0) {\n            this.removeAllListeners(eventName);\n        }\n\n        return this;\n    }\n}\n\n/*\nfunction inheritable(parent) {\n    return function(child) {\n        inherits(child, parent);\n        defineProperty(child, 'inherits', inheritable(child));\n    }\n}\n\ndefineProperty(Provider, 'inherits', inheritable(Provider));\n*/\n/*\nfunction(child) {\n    inherits(child, Provider);\n    child.inherits = function(grandchild) {\n        inherits(grandchild, child)\n    }\n});\n*/\n","'use strict';\n\nimport { EventDescription, Interface } from './interface';\n\nimport { Provider, TransactionRequest, TransactionResponse } from '../providers/provider';\nimport { Signer } from '../wallet/wallet';\n\nimport { defaultAbiCoder } from '../utils/abi-coder';\nimport { getContractAddress } from '../utils/address';\nimport { hexDataLength, hexDataSlice, isHexString } from '../utils/bytes';\nimport { ParamType } from '../utils/abi-coder';\nimport { BigNumber, ConstantZero } from '../utils/bignumber';\nimport { defineReadOnly, shallowCopy } from '../utils/properties';\n\nimport * as errors from '../utils/errors';\n\nvar allowedTransactionKeys: { [ key: string ]: boolean } = {\n    data: true, from: true, gasLimit: true, gasPrice:true, nonce: true, to: true, value: true\n}\n\n// Recursively replaces ENS names with promises to resolve the name and\n// stalls until all promises have returned\n// @TODO: Expand this to resolve any promises too\nfunction resolveAddresses(provider: Provider, value: any, paramType: ParamType | Array<ParamType>): Promise<any> {\n    if (Array.isArray(paramType)) {\n        var promises: Array<Promise<string>> = [];\n        paramType.forEach((paramType, index) => {\n            var v = null;\n            if (Array.isArray(value)) {\n                v = value[index];\n            } else {\n                v = value[paramType.name];\n            }\n            promises.push(resolveAddresses(provider, v, paramType));\n        });\n        return Promise.all(promises);\n    }\n\n    if (paramType.type === 'address') {\n        return provider.resolveName(value);\n    }\n\n    if (paramType.components) {\n        return resolveAddresses(provider, value, paramType.components);\n    }\n\n    return Promise.resolve(value);\n}\n\n\ntype RunFunction = (...params: Array<any>) => Promise<any>;\n\nfunction runMethod(contract: Contract, functionName: string, estimateOnly: boolean): RunFunction {\n    let method = contract.interface.functions[functionName];\n    return function(...params): Promise<any> {\n        var tx: any = {}\n\n        // If 1 extra parameter was passed in, it contains overrides\n        if (params.length === method.inputs.length + 1 && typeof(params[params.length - 1]) === 'object') {\n            tx = shallowCopy(params.pop());\n\n            // Check for unexpected keys (e.g. using \"gas\" instead of \"gasLimit\")\n            for (var key in tx) {\n                if (!allowedTransactionKeys[key]) {\n                    throw new Error('unknown transaction override ' + key);\n                }\n            }\n        }\n\n        if (params.length != method.inputs.length) {\n            throw new Error('incorrect number of arguments');\n        }\n\n        // Check overrides make sense\n        ['data', 'to'].forEach(function(key) {\n            if (tx[key] != null) {\n                errors.throwError('cannot override ' + key, errors.UNSUPPORTED_OPERATION, { operation: key })\n            }\n        });\n\n        // Send to the contract address\n        tx.to = contract.addressPromise;\n\n        return resolveAddresses(contract.provider, params, method.inputs).then((params) => {\n            tx.data = method.encode(params);\n            if (method.type === 'call') {\n\n                // Call (constant functions) always cost 0 ether\n                if (estimateOnly) {\n                    return Promise.resolve(ConstantZero);\n                }\n\n                if (!contract.provider) {\n                    errors.throwError('call (constant functions) require a provider or a signer with a provider', errors.UNSUPPORTED_OPERATION, { operation: 'call' })\n                }\n\n                // Check overrides make sense\n                ['gasLimit', 'gasPrice', 'value'].forEach(function(key) {\n                    if (tx[key] != null) {\n                        throw new Error('call cannot override ' + key) ;\n                    }\n                });\n\n                if (tx.from == null && contract.signer) {\n                    tx.from = contract.signer.getAddress()\n                }\n\n                return contract.provider.call(tx).then((value) => {\n\n                    if ((hexDataLength(value) % 32) === 4 && hexDataSlice(value, 0, 4) === '0x08c379a0') {\n                        let reason = defaultAbiCoder.decode([ 'string' ], hexDataSlice(value, 4));\n                        errors.throwError('call revert exception', errors.CALL_EXCEPTION, {\n                            address: contract.address,\n                            method: method.signature,\n                            args: params,\n                            errorSignature: 'Error(string)',\n                            errorArgs: [ reason ],\n                            reason: reason\n                        });\n                    }\n\n                    try {\n                        let result = method.decode(value);\n                        if (method.outputs.length === 1) {\n                            result = result[0];\n                        }\n                        return result;\n\n                    } catch (error) {\n                        if (value === '0x' && method.outputs.length > 0) {\n                            errors.throwError('call exception', errors.CALL_EXCEPTION, {\n                                address: contract.address,\n                                method: method.signature,\n                                args: params\n                            });\n                        }\n                        throw error;\n                    }\n                });\n\n            } else if (method.type === 'transaction') {\n\n                // Only computing the transaction estimate\n                if (estimateOnly) {\n                    if (!contract.provider) {\n                        errors.throwError('estimate gas require a provider or a signer with a provider', errors.UNSUPPORTED_OPERATION, { operation: 'estimateGas' })\n                    }\n\n                    if (tx.from == null && contract.signer) {\n                        tx.from = contract.signer.getAddress()\n                    }\n\n                    return contract.provider.estimateGas(tx);\n                }\n\n                if (!contract.signer) {\n                    errors.throwError('sending a transaction require a signer', errors.UNSUPPORTED_OPERATION, { operation: 'sendTransaction' })\n                }\n\n                // Make sure they aren't overriding something they shouldn't\n                if (tx.from != null) {\n                    errors.throwError('cannot override from in a transaction', errors.UNSUPPORTED_OPERATION, { operation: 'sendTransaction' })\n                }\n\n                return contract.signer.sendTransaction(tx);\n            }\n\n            throw new Error('invalid type - ' + method.type);\n            return null;\n        });\n    }\n}\n\nexport type ContractEstimate = (...params: Array<any>) => Promise<BigNumber>;\nexport type ContractFunction = (...params: Array<any>) => Promise<any>;\nexport type ContractEvent = (...params: Array<any>) => void;\n\ninterface Bucket<T> {\n    [name: string]: T;\n}\n\nexport type ErrorCallback = (error: Error) => void;\nexport type Contractish = Array<string | ParamType> | Interface | string;\nexport class Contract {\n    readonly address: string;\n    readonly interface: Interface;\n\n    readonly signer: Signer;\n    readonly provider: Provider;\n\n    readonly estimate: Bucket<ContractEstimate>;\n    readonly functions: Bucket<ContractFunction>;\n    readonly events: Bucket<ContractEvent>;\n\n    readonly addressPromise: Promise<string>;\n\n    // This is only set if the contract was created with a call to deploy\n    readonly deployTransaction: TransactionResponse;\n\n    private _onerror: ErrorCallback;\n\n    // https://github.com/Microsoft/TypeScript/issues/5453\n    // Once this issue is resolved (there are open PR) we can do this nicer\n    // by making addressOrName default to null for 2 operand calls. :)\n\n    constructor(addressOrName: string, contractInterface: Contractish, signerOrProvider: Signer | Provider) {\n        errors.checkNew(this, Contract);\n\n        // @TODO: Maybe still check the addressOrName looks like a valid address or name?\n        //address = getAddress(address);\n        if (contractInterface instanceof Interface) {\n            defineReadOnly(this, 'interface', contractInterface);\n        } else {\n            defineReadOnly(this, 'interface', new Interface(contractInterface));\n        }\n\n        if (signerOrProvider instanceof Signer) {\n            defineReadOnly(this, 'provider', signerOrProvider.provider);\n            defineReadOnly(this, 'signer', signerOrProvider);\n        } else if (signerOrProvider instanceof Provider) {\n            defineReadOnly(this, 'provider', signerOrProvider);\n            defineReadOnly(this, 'signer', null);\n        } else {\n            errors.throwError('invalid signer or provider', errors.INVALID_ARGUMENT, { arg: 'signerOrProvider', value: signerOrProvider });\n        }\n\n        defineReadOnly(this, 'estimate', { });\n        defineReadOnly(this, 'events', { });\n        defineReadOnly(this, 'functions', { });\n\n        // Not connected to an on-chain instance, so do not connect functions and events\n        if (!addressOrName) {\n            defineReadOnly(this, 'address', null);\n            defineReadOnly(this, 'addressPromise', Promise.resolve(null));\n            return;\n        }\n\n        defineReadOnly(this, 'address', addressOrName);\n        defineReadOnly(this, 'addressPromise', this.provider.resolveName(addressOrName));\n\n        Object.keys(this.interface.functions).forEach((name) => {\n            var run = runMethod(this, name, false);\n\n            if ((<any>this)[name] == null) {\n                defineReadOnly(this, name, run);\n            } else {\n                console.log('WARNING: Multiple definitions for ' + name);\n            }\n\n            if (this.functions[name] == null) {\n                defineReadOnly(this.functions, name, run);\n                defineReadOnly(this.estimate, name, runMethod(this, name, true));\n            }\n        });\n\n        Object.keys(this.interface.events).forEach((eventName) => {\n            let eventInfo: EventDescription = this.interface.events[eventName];\n\n            type Callback = (...args: Array<any>) => void;\n            let eventCallback: Callback = null;\n\n            let contract = this;\n            function handleEvent(log: any): void {\n                contract.addressPromise.then((address) => {\n                    // Not meant for us (the topics just has the same name)\n                    if (address != log.address) { return; }\n\n                    try {\n                        let result = eventInfo.decode(log.data, log.topics);\n\n                        // Some useful things to have with the log\n                        log.args = result;\n                        log.event = eventName;\n                        log.decode = eventInfo.decode;\n                        log.removeListener = function() {\n                            contract.provider.removeListener([ eventInfo.topic ], handleEvent);\n                        }\n\n                        log.getBlock = function() { return contract.provider.getBlock(log.blockHash);; }\n                        log.getTransaction = function() { return contract.provider.getTransaction(log.transactionHash); }\n                        log.getTransactionReceipt = function() { return contract.provider.getTransactionReceipt(log.transactionHash); }\n                        log.eventSignature = eventInfo.signature;\n\n                        eventCallback.apply(log, Array.prototype.slice.call(result));\n                    } catch (error) {\n                        console.log(error);\n                        let onerror = contract._onerror;\n                        if (onerror) { setTimeout(() => { onerror(error); }); }\n                    }\n                });\n            }\n\n            var property = {\n                enumerable: true,\n                get: function() {\n                    return eventCallback;\n                },\n                set: function(value: Callback) {\n                    if (!value) { value = null; }\n\n                    if (!contract.provider) {\n                        errors.throwError('events require a provider or a signer with a provider', errors.UNSUPPORTED_OPERATION, { operation: 'events' })\n                    }\n\n                    if (!value && eventCallback) {\n                        contract.provider.removeListener([ eventInfo.topic ], handleEvent);\n\n                    } else if (value && !eventCallback) {\n                        contract.provider.on([ eventInfo.topic ], handleEvent);\n                    }\n\n                    eventCallback = value;\n                }\n            };\n\n            var propertyName = 'on' + eventName.toLowerCase();\n            if ((<any>this)[propertyName] == null) {\n                Object.defineProperty(this, propertyName, property);\n            }\n\n            Object.defineProperty(this.events, eventName, property);\n\n        }, this);\n    }\n\n    get onerror() { return this._onerror; }\n\n    set onerror(callback: ErrorCallback) {\n        this._onerror = callback;\n    }\n\n    fallback(overrides?: TransactionRequest): Promise<TransactionResponse> {\n        if (!this.signer) {\n            errors.throwError('sending a transaction require a signer', errors.UNSUPPORTED_OPERATION, { operation: 'sendTransaction(fallback)' })\n        }\n\n        var tx: TransactionRequest = shallowCopy(overrides || {});\n\n        ['from', 'to'].forEach(function(key) {\n            if (tx.to == null) { return; }\n            errors.throwError('cannot override ' + key, errors.UNSUPPORTED_OPERATION, { operation: key })\n        });\n\n        tx.to = this.addressPromise;\n        return this.signer.sendTransaction(tx);\n    }\n\n    // Reconnect to a different signer or provider\n    connect(signerOrProvider: Signer | Provider): Contract {\n        return new Contract(this.address, this.interface, signerOrProvider);\n    }\n\n    // Deploy the contract with the bytecode, resolving to the deployed address.\n    // Use contract.deployTransaction.wait() to wait until the contract has\n    // been mined.\n    deploy(bytecode: string, ...args: Array<any>): Promise<Contract> {\n        if (this.signer == null) {\n            throw new Error('missing signer'); // @TODO: errors.throwError\n        }\n\n        // A lot of common tools do not prefix bytecode with a 0x\n        if (typeof(bytecode) === 'string' && bytecode.match(/^[0-9a-f]*$/i) && (bytecode.length % 2) == 0) {\n            bytecode = '0x' + bytecode;\n        }\n\n        if (!isHexString(bytecode)) {\n            errors.throwError('bytecode must be a valid hex string', errors.INVALID_ARGUMENT, { arg: 'bytecode', value: bytecode });\n        }\n\n        if ((bytecode.length % 2) !== 0) {\n            errors.throwError('bytecode must be valid data (even length)', errors.INVALID_ARGUMENT, { arg: 'bytecode', value: bytecode });\n        }\n\n        // @TODO: overrides of args.length = this.interface.deployFunction.inputs.length + 1\n        return this.signer.sendTransaction({\n            data: this.interface.deployFunction.encode(bytecode, args)\n        }).then((tx) => {\n            let contract = new Contract(getContractAddress(tx), this.interface, this.signer || this.provider);\n            defineReadOnly(contract, 'deployTransaction', tx);\n            return contract;\n        });\n    }\n}\n","'use strict';\n\nimport { Contract } from './contract';\nimport { Interface } from './interface';\n\nexport {\n    Contract,\n    Interface\n}\n\n","'use strict';\n\nimport { arrayify, Arrayish } from './bytes';\n\ndeclare class Buffer implements ArrayLike<number> {\n    constructor(data: any, encoding?: string);\n    toString(encoding?: string): any;\n    [key: number]: number;\n    length: number;\n}\n\nexport function decode(textData: string): Uint8Array {\n    return arrayify(new Uint8Array(new Buffer(textData, 'base64')));\n};\n\nexport function encode(data: Arrayish): string {\n    return new Buffer(arrayify(data)).toString('base64');\n}\n","\nimport { XMLHttpRequest } from 'xmlhttprequest';\nimport { toUtf8Bytes } from './utf8';\nimport { encode as base64Encode } from './base64';\n\nexport type ConnectionInfo = {\n    url: string,\n    user?: string,\n    password?: string,\n    allowInsecure?: boolean\n};\n\nimport * as errors from './errors';\n\nexport type ProcessFunc = (value: any) => any;\n\ntype Header = { key: string, value: string };\n\nexport function fetchJson(connection: string | ConnectionInfo, json: string, processFunc: ProcessFunc): Promise<any> {\n    let headers: Array<Header> = [ ];\n\n    let url: string = null;\n\n    if (typeof(connection) === 'string') {\n        url = connection;\n\n    } else if (typeof(connection) === 'object') {\n        if (connection.url == null) {\n            errors.throwError('missing URL', errors.MISSING_ARGUMENT, { arg: 'url' });\n        }\n\n        url = connection.url;\n\n        if (connection.user != null && connection.password != null) {\n            if (url.substring(0, 6) !== 'https:' && connection.allowInsecure !== true) {\n                errors.throwError(\n                    'basic authentication requires a secure https url', \n                    errors.INVALID_ARGUMENT,\n                    { arg: 'url', url: url, user: connection.user, password: '[REDACTED]' }\n                );\n            }\n\n            var authorization = connection.user + ':' + connection.password;\n            headers.push({\n                key: 'Authorization',\n                value: 'Basic ' + base64Encode(toUtf8Bytes(authorization))\n            });\n        }\n    }\n\n    return new Promise(function(resolve, reject) {\n        var request = new XMLHttpRequest();\n\n        if (json) {\n            request.open('POST', url, true);\n            headers.push({ key: 'Content-Type', value: 'application/json' });\n        } else {\n            request.open('GET', url, true);\n        }\n\n        headers.forEach(function(header) {\n            request.setRequestHeader(header.key, header.value);\n        });\n\n        request.onreadystatechange = function() {\n            if (request.readyState !== 4) { return; }\n\n            try {\n                var result = JSON.parse(request.responseText);\n            } catch (error) {\n                // @TODO: not any!\n                var jsonError: any = new Error('invalid json response');\n                jsonError.orginialError = error;\n                jsonError.responseText = request.responseText;\n                jsonError.url = url;\n                reject(jsonError);\n                return;\n            }\n\n            if (processFunc) {\n                try {\n                    result = processFunc(result);\n                } catch (error) {\n                    error.url = url;\n                    error.body = json;\n                    error.responseText = request.responseText;\n                    reject(error);\n                    return;\n                }\n            }\n\n            if (request.status != 200) {\n                // @TODO: not any!\n                var error: any = new Error('invalid response - ' + request.status);\n                error.statusCode = request.status;\n                reject(error);\n                return;\n            }\n\n            resolve(result);\n        };\n\n        request.onerror = function(error) {\n            reject(error);\n        }\n\n        try {\n            if (json) {\n                request.send(json);\n            } else {\n                request.send();\n            }\n\n        } catch (error) {\n            // @TODO: not any!\n            var connectionError: any = new Error('connection error');\n            connectionError.error = error;\n            reject(connectionError);\n        }\n    });\n}\n\n","\nimport { BlockTag, checkTransactionResponse, Provider, TransactionRequest, TransactionResponse } from './provider';\nimport { Networkish } from './networks';\n\nimport { hexlify, hexStripZeros } from '../utils/bytes';\nimport { defineReadOnly } from '../utils/properties';\nimport { fetchJson } from '../utils/web';\n\nimport * as errors from '../utils/errors';\n\n// The transaction has already been sanitized by the calls in Provider\nfunction getTransactionString(transaction: TransactionRequest): string {\n    var result = [];\n    for (var key in transaction) {\n        if ((<any>transaction)[key] == null) { continue; }\n        var value = hexlify((<any>transaction)[key]);\n        if ((<any>{ gasLimit: true, gasPrice: true, nonce: true, value: true })[key]) {\n            value = hexStripZeros(value);\n        }\n        result.push(key + '=' + value);\n    }\n    return result.join('&');\n}\n\nfunction getResult(result: { status?: number, message?: string, result?: any }): any {\n    // getLogs, getHistory have weird success responses\n    if (result.status == 0 && (result.message === 'No records found' || result.message === 'No transactions found')) {\n        return result.result;\n    }\n\n    if (result.status != 1 || result.message != 'OK') {\n        // @TODO: not any\n        var error: any = new Error('invalid response');\n        error.result = JSON.stringify(result);\n        throw error;\n    }\n\n    return result.result;\n}\n\nfunction getJsonResult(result: { jsonrpc: string, result?: any, error?: { code?: number, data?: any, message?: string} } ): any {\n    if (result.jsonrpc != '2.0') {\n        // @TODO: not any\n        let error: any = new Error('invalid response');\n        error.result = JSON.stringify(result);\n        throw error;\n    }\n\n    if (result.error) {\n        // @TODO: not any\n        let error: any = new Error(result.error.message || 'unknown error');\n        if (result.error.code) { error.code = result.error.code; }\n        if (result.error.data) { error.data = result.error.data; }\n        throw error;\n    }\n\n    return result.result;\n}\n\n// The blockTag was normalized as a string by the Provider pre-perform operations\nfunction checkLogTag(blockTag: string): number | \"latest\" {\n    if (blockTag === 'pending') { throw new Error('pending not supported'); }\n    if (blockTag === 'latest') { return blockTag; }\n\n    return parseInt(blockTag.substring(2), 16);\n}\n\n\nexport class EtherscanProvider extends Provider{\n    readonly baseUrl: string;\n    readonly apiKey: string;\n    constructor(network?: Networkish, apiKey?: string) {\n        super(network);\n        errors.checkNew(this, EtherscanProvider);\n\n        let name = 'invalid';\n        if (this.network) { name = this.network.name; }\n\n        let baseUrl = null;\n        switch(name) {\n            case 'homestead':\n                baseUrl = 'https://api.etherscan.io';\n                break;\n            case 'ropsten':\n                baseUrl = 'https://api-ropsten.etherscan.io';\n                break;\n            case 'rinkeby':\n                baseUrl = 'https://api-rinkeby.etherscan.io';\n                break;\n            case 'kovan':\n                baseUrl = 'https://api-kovan.etherscan.io';\n                break;\n            default:\n                throw new Error('unsupported network');\n        }\n\n        defineReadOnly(this, 'baseUrl', baseUrl);\n        defineReadOnly(this, 'apiKey', apiKey);\n    }\n\n\n    perform(method: string, params: any) {\n        //if (!params) { params = {}; }\n\n        var url = this.baseUrl;\n\n        let apiKey = '';\n        if (this.apiKey) { apiKey += '&apikey=' + this.apiKey; }\n\n        switch (method) {\n            case 'getBlockNumber':\n                url += '/api?module=proxy&action=eth_blockNumber' + apiKey;\n            return fetchJson(url, null, getJsonResult);\n\n            case 'getGasPrice':\n                url += '/api?module=proxy&action=eth_gasPrice' + apiKey;\n                return fetchJson(url, null, getJsonResult);\n\n            case 'getBalance':\n                // Returns base-10 result\n                url += '/api?module=account&action=balance&address=' + params.address;\n                url += '&tag=' + params.blockTag + apiKey;\n                return fetchJson(url, null, getResult);\n\n            case 'getTransactionCount':\n                url += '/api?module=proxy&action=eth_getTransactionCount&address=' + params.address;\n                url += '&tag=' + params.blockTag + apiKey;\n                return fetchJson(url, null, getJsonResult);\n\n\n            case 'getCode':\n                url += '/api?module=proxy&action=eth_getCode&address=' + params.address;\n                url += '&tag=' + params.blockTag + apiKey;\n                return fetchJson(url, null, getJsonResult);\n\n            case 'getStorageAt':\n                url += '/api?module=proxy&action=eth_getStorageAt&address=' + params.address;\n                url += '&position=' + params.position;\n                url += '&tag=' + params.blockTag + apiKey;\n                return fetchJson(url, null, getJsonResult);\n\n\n            case 'sendTransaction':\n                url += '/api?module=proxy&action=eth_sendRawTransaction&hex=' + params.signedTransaction;\n                url += apiKey;\n                return fetchJson(url, null, getJsonResult);\n\n\n            case 'getBlock':\n                if (params.blockTag) {\n                    url += '/api?module=proxy&action=eth_getBlockByNumber&tag=' + params.blockTag;\n                    url += '&boolean=false';\n                    url += apiKey;\n                    return fetchJson(url, null, getJsonResult);\n                }\n                throw new Error('getBlock by blockHash not implmeneted');\n\n            case 'getTransaction':\n                url += '/api?module=proxy&action=eth_getTransactionByHash&txhash=' + params.transactionHash;\n                url += apiKey;\n                return fetchJson(url, null, getJsonResult);\n\n            case 'getTransactionReceipt':\n                url += '/api?module=proxy&action=eth_getTransactionReceipt&txhash=' + params.transactionHash;\n                url += apiKey;\n                return fetchJson(url, null, getJsonResult);\n\n\n            case 'call':\n                var transaction = getTransactionString(params.transaction);\n                if (transaction) { transaction = '&' + transaction; }\n                url += '/api?module=proxy&action=eth_call' + transaction;\n                url += apiKey;\n                return fetchJson(url, null, getJsonResult);\n\n            case 'estimateGas':\n                var transaction = getTransactionString(params.transaction);\n                if (transaction) { transaction = '&' + transaction; }\n                url += '/api?module=proxy&action=eth_estimateGas&' + transaction;\n                url += apiKey;\n                return fetchJson(url, null, getJsonResult);\n\n            case 'getLogs':\n                url += '/api?module=logs&action=getLogs';\n                try {\n                    if (params.filter.fromBlock) {\n                        url += '&fromBlock=' + checkLogTag(params.filter.fromBlock);\n                    }\n\n                    if (params.filter.toBlock) {\n                        url += '&toBlock=' + checkLogTag(params.filter.toBlock);\n                    }\n\n                    if (params.filter.address) {\n                        url += '&address=' + params.filter.address;\n                    }\n\n                    // @TODO: We can handle slightly more complicated logs using the logs API\n                    if (params.filter.topics && params.filter.topics.length > 0) {\n                        if (params.filter.topics.length > 1) {\n                            throw new Error('unsupported topic format');\n                        }\n                        var topic0 = params.filter.topics[0];\n                        if (typeof(topic0) !== 'string' || topic0.length !== 66) {\n                            throw new Error('unsupported topic0 format');\n                        }\n                        url += '&topic0=' + topic0;\n                    }\n                } catch (error) {\n                    return Promise.reject(error);\n                }\n\n                url += apiKey;\n\n                var self = this;\n                return fetchJson(url, null, getResult).then(function(logs: Array<any>) {\n                    var txs: { [hash: string]: string } = {};\n\n                    var seq = Promise.resolve();\n                    logs.forEach(function(log) {\n                        seq = seq.then(function() {\n                            if (log.blockHash != null) { return null; }\n                            log.blockHash = txs[log.transactionHash];\n                            if (log.blockHash == null) {\n                                return self.getTransaction(log.transactionHash).then(function(tx) {\n                                    txs[log.transactionHash] = tx.blockHash;\n                                    log.blockHash = tx.blockHash;\n                                });\n                            }\n                            return null;\n                        });\n                    });\n\n                    return seq.then(function() {\n                        return logs;\n                    });\n                });\n\n            case 'getEtherPrice':\n                if (this.network.name !== 'homestead') { return Promise.resolve(0.0); }\n                url += '/api?module=stats&action=ethprice';\n                url += apiKey;\n                return fetchJson(url, null, getResult).then(function(result) {\n                    return parseFloat(result.ethusd);\n                });\n\n            default:\n                break;\n         }\n\n        return super.perform(method, params);\n    }\n\n    // @TODO: Allow startBlock and endBlock to be Promises\n    getHistory(addressOrName: string | Promise<string>, startBlock?: BlockTag, endBlock?: BlockTag): Promise<Array<TransactionResponse>> {\n\n        let url = this.baseUrl;\n\n        let apiKey = '';\n        if (this.apiKey) { apiKey += '&apikey=' + this.apiKey; }\n\n        if (startBlock == null) { startBlock = 0; }\n        if (endBlock == null) { endBlock = 99999999; }\n\n        return this.resolveName(addressOrName).then((address) => {\n            url += '/api?module=account&action=txlist&address=' + address;\n            url += '&startblock=' + startBlock;\n            url += '&endblock=' + endBlock;\n            url += '&sort=asc' + apiKey;\n\n            return fetchJson(url, null, getResult).then((result: Array<any>) => {\n                var output: Array<TransactionResponse> = [];\n                result.forEach((tx) => {\n                    ['contractAddress', 'to'].forEach(function(key) {\n                        if (tx[key] == '') { delete tx[key]; }\n                    });\n                    if (tx.creates == null && tx.contractAddress != null) {\n                        tx.creates = tx.contractAddress;\n                    }\n                    let item = checkTransactionResponse(tx);\n                    if (tx.timeStamp) { item.timestamp = parseInt(tx.timeStamp); }\n                    output.push(item);\n                });\n                return output;\n            });\n        });\n    }\n}\n","'use strict';\n\nimport { Network } from './networks';\nimport { Provider } from './provider';\n\nimport * as errors from '../utils/errors';\n\n// Returns:\n//  - true is all networks match\n//  - false if any network is null\n//  - throws if any 2 networks do not match\nfunction checkNetworks(networks: Array<Network>): boolean {\n    var result = true;\n\n    let check: Network = null;\n    networks.forEach((network) => {\n\n        // Null\n        if (network == null) {\n            result = false;\n            return;\n        }\n\n        // Have nothing to compre to yet\n        if (check == null) {\n            check = network;\n            return;\n        }\n\n        // Matches!\n        if (check.name === network.name &&\n            check.chainId === network.chainId &&\n            check.ensAddress === network.ensAddress) { return; }\n\n        errors.throwError(\n            'provider mismatch',\n            errors.INVALID_ARGUMENT,\n            { arg: 'providers', networks: networks }\n        );\n    });\n\n    return result;\n}\n\nexport class FallbackProvider extends Provider {\n    private _providers: Array<Provider>;\n\n    constructor(providers: Array<Provider>) {\n\n        if (providers.length === 0) { throw new Error('no providers'); }\n\n        // All networks are ready, we can know the network for certain\n        let ready = checkNetworks(providers.map((p) => p.network));\n        if (ready) {\n            super(providers[0].network);\n\n        } else {\n            // The network won't be known until all child providers know\n            let ready = Promise.all(providers.map((p) => p.getNetwork())).then((networks) => {\n                if (!checkNetworks(networks)) {\n                    errors.throwError('getNetwork returned null', errors.UNKNOWN_ERROR, { })\n                }\n                return networks[0];\n            });\n\n            super(ready);\n        }\n        errors.checkNew(this, FallbackProvider);\n\n        // Preserve a copy, so we don't get mutated\n        this._providers = providers.slice(0);\n    }\n\n    get providers(): Array<Provider> {\n        // Return a copy, so we don't get mutated\n        return this._providers.slice(0);\n    }\n\n    perform(method: string, params: any): any {\n        // Creates a copy of the providers array\n        var providers = this.providers;\n\n        return new Promise((resolve, reject) => {\n            var firstError: Error = null;\n            function next() {\n                if (!providers.length) {\n                    reject(firstError);\n                    return;\n                }\n\n                var provider = providers.shift();\n                provider.perform(method, params).then(function(result) {\n                    resolve(result);\n                }, function (error) {\n                    if (!firstError) { firstError = error; }\n                    next();\n                });\n            }\n            next();\n        });\n    }\n}\n\n","'use strict';\n\n// See: https://github.com/ethereum/wiki/wiki/JSON-RPC\n\nimport { getNetwork, Network, Networkish } from './networks';\nimport { BlockTag, Provider, TransactionRequest, TransactionResponse } from './provider';\nimport { Signer } from '../wallet/wallet';\n\nimport { getAddress } from '../utils/address';\nimport { BigNumber } from '../utils/bignumber';\nimport { Arrayish, hexlify, hexStripZeros } from '../utils/bytes';\nimport { defineReadOnly, resolveProperties } from '../utils/properties';\nimport { toUtf8Bytes } from '../utils/utf8';\nimport { ConnectionInfo, fetchJson } from '../utils/web';\n\nimport * as errors from '../utils/errors';\n\nfunction timer(timeout: number): Promise<any> {\n    return new Promise(function(resolve) {\n        setTimeout(function() {\n            resolve();\n        }, timeout);\n    });\n}\n\nfunction getResult(payload: { error?: { code?: number, data?: any, message?: string }, result?: any }): any {\n    if (payload.error) {\n        // @TODO: not any\n        var error: any = new Error(payload.error.message);\n        error.code = payload.error.code;\n        error.data = payload.error.data;\n        throw error;\n    }\n\n    return payload.result;\n}\n\n// Convert an ethers.js transaction into a JSON-RPC transaction\n//  - gasLimit => gas\n//  - All values hexlified\n//  - All numeric values zero-striped\n// @TODO: Not any, a dictionary of string to strings\nexport function hexlifyTransaction(transaction: TransactionRequest): any {\n    var result: any = {};\n\n    // Some nodes (INFURA ropsten; INFURA mainnet is fine) don't like extra zeros.\n    ['gasLimit', 'gasPrice', 'nonce', 'value'].forEach(function(key) {\n        if ((<any>transaction)[key] == null) { return; }\n        let value = hexStripZeros(hexlify((<any>transaction)[key]));\n        if (key === 'gasLimit') { key = 'gas'; }\n        result[key] = value;\n    });\n\n    ['from', 'to', 'data'].forEach(function(key) {\n        if ((<any>transaction)[key] == null) { return; }\n        result[key] = hexlify((<any>transaction)[key]);\n    });\n\n    return result;\n}\n\nfunction getLowerCase(value: string): string {\n    if (value) { return value.toLowerCase(); }\n    return value;\n}\n\nexport class JsonRpcSigner extends Signer {\n    readonly provider: JsonRpcProvider;\n    private _address: string;\n\n    constructor(provider: JsonRpcProvider, address?: string) {\n        super();\n        errors.checkNew(this, JsonRpcSigner);\n\n        defineReadOnly(this, 'provider', provider);\n\n        // Statically attach to a given address\n        if (address) {\n            defineReadOnly(this, '_address', address);\n        }\n    }\n\n    get address(): string {\n        if (!this._address) {\n            errors.throwError('no sync sync address available; use getAddress', errors.UNSUPPORTED_OPERATION, { operation: 'address' });\n        }\n        return this._address\n    }\n\n    getAddress(): Promise<string> {\n        if (this._address) {\n            return Promise.resolve(this._address);\n        }\n\n        return this.provider.send('eth_accounts', []).then((accounts) => {\n            if (accounts.length === 0) {\n                errors.throwError('no accounts', errors.UNSUPPORTED_OPERATION, { operation: 'getAddress' });\n            }\n            return getAddress(accounts[0]);\n        });\n    }\n\n    getBalance(blockTag?: BlockTag): Promise<BigNumber> {\n        return this.provider.getBalance(this.getAddress(), blockTag);\n    }\n\n    getTransactionCount(blockTag?: BlockTag): Promise<number> {\n        return this.provider.getTransactionCount(this.getAddress(), blockTag);\n    }\n\n    sendTransaction(transaction: TransactionRequest): Promise<TransactionResponse> {\n        let tx = hexlifyTransaction(transaction);\n\n        if (tx.from == null) {\n            tx.from = this.getAddress().then((address) => {\n                if (!address) { return null; }\n                return address.toLowerCase();\n            });\n        }\n\n        return resolveProperties(tx).then((tx) => {\n            return this.provider.send('eth_sendTransaction', [ transaction ]);\n        });\n    }\n\n    signMessage(message: Arrayish | string): Promise<string> {\n        var data = ((typeof(message) === 'string') ? toUtf8Bytes(message): message);\n        return this.getAddress().then((address) => {\n\n            // https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign\n            return this.provider.send('eth_sign', [ address.toLowerCase(), hexlify(data) ]);\n        });\n    }\n\n    unlock(password: string): Promise<boolean> {\n        var provider = this.provider;\n\n        return this.getAddress().then(function(address) {\n            return provider.send('personal_unlockAccount', [ address.toLowerCase(), password, null ]);\n        });\n    }\n}\n\nexport class JsonRpcProvider extends Provider {\n    readonly connection: ConnectionInfo;\n\n    private _pendingFilter: Promise<number>;\n\n    constructor(url?: ConnectionInfo | string, network?: Networkish) {\n\n        // One parameter, but it is a network name, so swap it with the URL\n        if (typeof(url) === 'string') {\n            if (network === null && getNetwork(url)) {\n                network = url;\n                url = null;\n            }\n        }\n\n        if (network) {\n            // The network has been specified explicitly, we can use it\n            super(network);\n\n        } else {\n\n            // The network is unknown, query the JSON-RPC for it\n            let ready: Promise<Network> = new Promise((resolve, reject) => {\n                setTimeout(() => {\n                    this.send('net_version', [ ]).then((result) => {\n                        let chainId = parseInt(result);\n\n                        resolve(getNetwork(chainId));\n                    });\n                });\n            });\n            super(ready);\n        }\n\n        errors.checkNew(this, JsonRpcProvider);\n\n        // Default URL\n        if (!url) { url = 'http://localhost:8545'; }\n\n        if (typeof(url) === 'string') {\n            this.connection = {\n                url: url\n            };\n        } else {\n            this.connection = url;\n        }\n\n    }\n\n    getSigner(address: string): JsonRpcSigner {\n        return new JsonRpcSigner(this, address);\n    }\n\n    listAccounts(): Promise<Array<string>> {\n        return this.send('eth_accounts', []).then((accounts: Array<string>) => {\n            return accounts.map((a) => getAddress(a));\n        });\n    }\n\n    send(method: string, params: any): Promise<any> {\n        var request = {\n            method: method,\n            params: params,\n            id: 42,\n            jsonrpc: \"2.0\"\n        };\n\n        return fetchJson(this.connection, JSON.stringify(request), getResult);\n    }\n\n    perform(method: string, params: any): Promise<any> {\n        switch (method) {\n            case 'getBlockNumber':\n                return this.send('eth_blockNumber', []);\n\n            case 'getGasPrice':\n                return this.send('eth_gasPrice', []);\n\n            case 'getBalance':\n                return this.send('eth_getBalance', [ getLowerCase(params.address), params.blockTag ]);\n\n            case 'getTransactionCount':\n                return this.send('eth_getTransactionCount', [ getLowerCase(params.address), params.blockTag ]);\n\n            case 'getCode':\n                return this.send('eth_getCode', [ getLowerCase(params.address), params.blockTag ]);\n\n            case 'getStorageAt':\n                return this.send('eth_getStorageAt', [ getLowerCase(params.address), params.position, params.blockTag ]);\n\n            case 'sendTransaction':\n                return this.send('eth_sendRawTransaction', [ params.signedTransaction ]);\n\n            case 'getBlock':\n                if (params.blockTag) {\n                    return this.send('eth_getBlockByNumber', [ params.blockTag, false ]);\n                } else if (params.blockHash) {\n                    return this.send('eth_getBlockByHash', [ params.blockHash, false ]);\n                }\n                return Promise.reject(new Error('invalid block tag or block hash'));\n\n            case 'getTransaction':\n                return this.send('eth_getTransactionByHash', [ params.transactionHash ]);\n\n            case 'getTransactionReceipt':\n                return this.send('eth_getTransactionReceipt', [ params.transactionHash ]);\n\n            case 'call':\n                return this.send('eth_call', [ hexlifyTransaction(params.transaction), 'latest' ]);\n\n            case 'estimateGas':\n                return this.send('eth_estimateGas', [ hexlifyTransaction(params.transaction) ]);\n\n            case 'getLogs':\n                if (params.filter && params.filter.address != null) {\n                    params.filter.address = getLowerCase(params.filter.address);\n                }\n                return this.send('eth_getLogs', [ params.filter ]);\n\n            default:\n                break;\n        }\n\n        errors.throwError(method + ' not implemented', errors.NOT_IMPLEMENTED, { operation: method });\n        return null;\n    }\n\n    _startPending(): void {\n        if (this._pendingFilter != null) { return; }\n        var self = this;\n\n        var pendingFilter: Promise<number> = this.send('eth_newPendingTransactionFilter', []);\n        this._pendingFilter = pendingFilter;\n\n        pendingFilter.then(function(filterId) {\n            function poll() {\n                self.send('eth_getFilterChanges', [ filterId ]).then(function(hashes: Array<string>) {\n                    if (self._pendingFilter != pendingFilter) { return null; }\n\n                    var seq = Promise.resolve();\n                    hashes.forEach(function(hash) {\n                        self._emitted['t:' + hash.toLowerCase()] = 'pending';\n                        seq = seq.then(function() {\n                            return self.getTransaction(hash).then(function(tx) {\n                                self.emit('pending', tx);\n                            });\n                        });\n                    });\n\n                    return seq.then(function() {\n                        return timer(1000);\n                    });\n                }).then(function() {\n                    if (self._pendingFilter != pendingFilter) {\n                        self.send('eth_uninstallFilter', [ filterId ]);\n                        return;\n                    }\n                    setTimeout(function() { poll(); }, 0);\n                });\n            }\n            poll();\n\n            return filterId;\n        });\n    }\n\n    _stopPending(): void {\n        this._pendingFilter = null;\n    }\n}\n","\nimport net from 'net';\n\nimport { JsonRpcProvider } from './json-rpc-provider';\nimport { Networkish } from './networks';\n\nimport { defineReadOnly } from '../utils/properties';\n\nimport * as errors from '../utils/errors';\n\nexport class IpcProvider extends JsonRpcProvider {\n    readonly path: string;\n\n    constructor(path: string, network?: Networkish) {\n        if (path == null) {\n            errors.throwError('missing path', errors.MISSING_ARGUMENT, { arg: 'path' });\n        }\n\n        super('ipc://' + path, network);\n        errors.checkNew(this, IpcProvider);\n\n        defineReadOnly(this, 'path', path);\n    }\n\n    // @TODO: Create a connection to the IPC path and use filters instead of polling for block\n\n    send(method: string, params: any): Promise<any> {\n        // This method is very simple right now. We create a new socket\n        // connection each time, which may be slower, but the main\n        // advantage we are aiming for now is security. This simplifies\n        // multiplexing requests (since we do not need to multiplex).\n\n        var payload = JSON.stringify({\n            method: method,\n            params: params,\n            id: 42,\n            jsonrpc: \"2.0\"\n        });\n\n        return new Promise((resolve, reject) => {\n            var stream = net.connect(this.path);\n            stream.on('data', function(data) {\n                try {\n                    resolve(JSON.parse(data.toString('utf8')).result);\n                    // @TODO: Better pull apart the error\n                    stream.destroy();\n                } catch (error) {\n                    reject(error);\n                    stream.destroy();\n                }\n            });\n\n            stream.on('end', function() {\n                stream.destroy();\n            });\n\n            stream.on('error', function(error) {\n                reject(error);\n                stream.destroy();\n            });\n            stream.write(payload);\n            stream.end();\n        });\n    }\n}\n","'use strict';\n\nimport { JsonRpcProvider, JsonRpcSigner } from './json-rpc-provider';\nimport { getNetwork, Networkish } from './networks';\n\nimport { defineReadOnly } from '../utils/properties';\n\nimport * as errors from '../utils/errors';\n\nexport class InfuraProvider extends JsonRpcProvider {\n    readonly apiAccessToken: string;\n\n    constructor(network?: Networkish, apiAccessToken?: string) {\n        network = getNetwork((network == null) ? 'homestead': network);\n\n        var host = null;\n        switch(network.name) {\n            case 'homestead':\n                host = 'mainnet.infura.io';\n                break;\n            case 'ropsten':\n                host = 'ropsten.infura.io';\n                break;\n            case 'rinkeby':\n                host = 'rinkeby.infura.io';\n                break;\n            case 'kovan':\n                host = 'kovan.infura.io';\n                break;\n            default:\n                throw new Error('unsupported network');\n        }\n\n        super('https://' + host + '/' + (apiAccessToken || ''), network);\n        errors.checkNew(this, InfuraProvider);\n\n        defineReadOnly(this, 'apiAccessToken', apiAccessToken || null);\n    }\n\n    _startPending(): void {\n        console.log('WARNING: INFURA does not support pending filters');\n    }\n\n    getSigner(address?: string): JsonRpcSigner {\n        errors.throwError(\n            'INFURA does not support signing',\n            errors.UNSUPPORTED_OPERATION,\n            { operation: 'getSigner' }\n        );\n        return null;\n    }\n\n    listAccounts(): Promise<Array<string>> {\n        return Promise.resolve([]);\n    }\n}\n","'use strict';\n\nimport { Networkish } from './networks';\nimport { JsonRpcProvider } from './json-rpc-provider';\n\nimport { defineReadOnly } from '../utils/properties';\n\nimport * as errors from '../utils/errors';\n\n/*\n@TODO\nutils.defineProperty(Web3Signer, 'onchange', {\n\n});\n*/\n\nexport type Callback = (error: any, response: any) => void;\n\nexport type AsyncProvider = {\n    isMetaMask: boolean;\n    host?: string;\n    path?: string;\n    sendAsync: (request: any, callback: Callback) => void\n}\n\nexport class Web3Provider extends JsonRpcProvider {\n    readonly _web3Provider: AsyncProvider;\n\n    constructor(web3Provider: AsyncProvider, network?: Networkish) {\n\n        if (!web3Provider || !web3Provider.sendAsync) {\n            errors.throwError(\n                'invalid web3Provider',\n                errors.INVALID_ARGUMENT,\n                { arg: 'web3Provider', value: web3Provider }\n            );\n        }\n\n        // HTTP has a host; IPC has a path.\n        var url = web3Provider.host || web3Provider.path || 'unknown';\n\n        super(url, network);\n        errors.checkNew(this, Web3Provider);\n\n        defineReadOnly(this, '_web3Provider', web3Provider);\n    }\n\n    send(method: string, params: any): Promise<any> {\n\n        // Metamask complains about eth_sign (and on some versions hangs)\n        if (method == 'eth_sign' && this._web3Provider.isMetaMask) {\n            // https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_sign\n            method = 'personal_sign';\n            params = [ params[1], params[0] ];\n        }\n\n        return new Promise((resolve, reject) => {\n            var request = {\n                method: method,\n                params: params,\n                id: 42,\n                jsonrpc: \"2.0\"\n            };\n\n            this._web3Provider.sendAsync(request, function(error, result) {\n                if (error) {\n                    reject(error);\n                    return;\n                }\n\n                if (result.error) {\n                    // @TODO: not any\n                    var error: any = new Error(result.error.message);\n                    error.code = result.error.code;\n                    error.data = result.error.data;\n                    reject(error);\n                    return;\n                }\n\n                resolve(result.result);\n            });\n        });\n    }\n}\n","'use strict';\n\nimport { Provider, ProviderSigner } from './provider';\n\nimport { Network } from './networks';\n\nimport { EtherscanProvider } from './etherscan-provider';\nimport { FallbackProvider } from './fallback-provider';\nimport { IpcProvider } from './ipc-provider';\nimport { InfuraProvider } from './infura-provider';\nimport { JsonRpcProvider } from './json-rpc-provider';\nimport { Web3Provider } from './web3-provider';\n\nfunction getDefaultProvider(network?: Network | string): FallbackProvider {\n    return new FallbackProvider([\n        new InfuraProvider(network),\n        new EtherscanProvider(network),\n    ]);\n}\n\nexport {\n    Provider,\n    getDefaultProvider,\n\n    ProviderSigner,\n\n    FallbackProvider,\n\n    EtherscanProvider,\n    InfuraProvider,\n    JsonRpcProvider,\n    Web3Provider,\n\n    IpcProvider\n};\n","'use strict';\n\nimport { bigNumberify } from './bignumber';\nimport { arrayify, concat, hexlify, padZeros} from './bytes';\nimport { toUtf8Bytes } from './utf8';\n\nimport { keccak256 as hashKeccak256 } from './keccak256';\nimport { sha256 as hashSha256 } from './sha2';\n\nvar regexBytes = new RegExp(\"^bytes([0-9]+)$\");\nvar regexNumber = new RegExp(\"^(u?int)([0-9]*)$\");\nvar regexArray = new RegExp(\"^(.*)\\\\[([0-9]*)\\\\]$\");\n\nvar Zeros = '0000000000000000000000000000000000000000000000000000000000000000';\n\nfunction _pack(type: string, value: any, isArray?: boolean): Uint8Array {\n    switch(type) {\n        case 'address':\n            if (isArray) { return padZeros(value, 32); }\n            return arrayify(value);\n        case 'string':\n            return toUtf8Bytes(value);\n        case 'bytes':\n            return arrayify(value);\n        case 'bool':\n            value = (value ? '0x01': '0x00');\n            if (isArray) { return padZeros(value, 32); }\n            return arrayify(value);\n    }\n\n    var match =  type.match(regexNumber);\n    if (match) {\n        //var signed = (match[1] === 'int')\n        let size = parseInt(match[2] || \"256\")\n        if ((size % 8 != 0) || size === 0 || size > 256) {\n            throw new Error('invalid number type - ' + type);\n        }\n\n        if (isArray) { size = 256; }\n\n        value = bigNumberify(value).toTwos(size);\n\n        return padZeros(value, size / 8);\n    }\n\n    match = type.match(regexBytes);\n    if (match) {\n        let size = parseInt(match[1]);\n        if (String(size) != match[1] || size === 0 || size > 32) {\n            throw new Error('invalid number type - ' + type);\n        }\n        if (arrayify(value).byteLength !== size) { throw new Error('invalid value for ' + type); }\n        if (isArray) { return arrayify((value + Zeros).substring(0, 66)); }\n        return value;\n    }\n\n    match = type.match(regexArray);\n    if (match && Array.isArray(value)) {\n        var baseType = match[1];\n        var count = parseInt(match[2] || String(value.length));\n        if (count != value.length) { throw new Error('invalid value for ' + type); }\n        var result: Array<Uint8Array> = [];\n        value.forEach(function(value) {\n            result.push(_pack(baseType, value, true));\n        });\n        return concat(result);\n    }\n\n    throw new Error('unknown type - ' + type);\n}\n\n// @TODO: Array Enum\n\nexport function pack(types: Array<string>, values: Array<any>) {\n    if (types.length != values.length) { throw new Error('type/value count mismatch'); }\n    var tight: Array<Uint8Array> = [];\n    types.forEach(function(type, index) {\n        tight.push(_pack(type, values[index]));\n    });\n    return hexlify(concat(tight));\n}\n\nexport function keccak256(types: Array<string>, values: Array<any>) {\n    return hashKeccak256(pack(types, values));\n}\n\nexport function sha256(types: Array<string>, values: Array<any>) {\n    return hashSha256(pack(types, values));\n}\n","'use strict';\n\nimport { BigNumber, bigNumberify, BigNumberish, ConstantZero, ConstantNegativeOne } from './bignumber';\n\nimport * as errors from './errors';\n\nconst names = [\n    'wei',\n    'kwei',\n    'Mwei',\n    'Gwei',\n    'szabo',\n    'finny',\n    'ether',\n];\n\ntype UnitInfo = {\n    decimals: number;\n    tenPower: BigNumber;\n};\n\nvar unitInfos: { [key: string]: UnitInfo } = {};\n\nfunction _getUnitInfo(value: string): UnitInfo {\n    return {\n        decimals: value.length - 1,\n        tenPower: bigNumberify(value)\n    };\n}\n\n// Build cache of common units\n(function() {\n\n    // Cache the common units\n    let value = '1';\n    names.forEach(function(name) {\n        let info = _getUnitInfo(value);\n        unitInfos[name.toLowerCase()] = info;\n        unitInfos[String(info.decimals)] = info;\n        value += '000';\n    });\n})();\n\nfunction getUnitInfo(name: string | number): UnitInfo {\n\n    // Try the cache\n    var info = unitInfos[String(name).toLowerCase()];\n\n    if (!info && typeof(name) === 'number' && parseInt(String(name)) == name && name >= 0 && name <= 256) {\n        var value = '1';\n        for (var i = 0; i < name; i++) { value += '0'; }\n        info = _getUnitInfo(value);\n    }\n\n    // Make sure we got something\n    if (!info) {\n        errors.throwError(\n            'invalid unitType',\n            errors.INVALID_ARGUMENT,\n            { arg: 'name', value: name }\n       );\n    }\n\n    return info;\n}\n\nexport function formatUnits(value: BigNumberish, unitType?: string | number, options?: any): string {\n    /*\n    if (typeof(unitType) === 'object' && !options) {\n        options = unitType;\n        unitType = undefined;\n    }\n    if (unitType == null) { unitType = 18; }\n    */\n\n    if (!options) { options = {}; }\n\n    var unitInfo = getUnitInfo(unitType);\n\n    // Make sure wei is a big number (convert as necessary)\n    value = bigNumberify(value);\n\n    var negative = value.lt(ConstantZero);\n    if (negative) { value = value.mul(ConstantNegativeOne); }\n\n    var fraction = value.mod(unitInfo.tenPower).toString();\n    while (fraction.length < unitInfo.decimals) { fraction = '0' + fraction; }\n\n    // Strip off trailing zeros (but keep one if would otherwise be bare decimal point)\n    if (!options.pad) {\n        fraction = fraction.match(/^([0-9]*[1-9]|0)(0*)/)[1];\n    }\n\n    var whole = value.div(unitInfo.tenPower).toString();\n\n    if (options.commify) {\n        whole = whole.replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\")\n    }\n\n    value = whole + '.' + fraction;\n\n    if (negative) { value = '-' + value; }\n\n    return value;\n}\n\nexport function parseUnits(value: string, unitType?: string | number): BigNumber {\n    if (unitType == null) { unitType = 18; }\n    var unitInfo = getUnitInfo(unitType);\n\n    if (typeof(value) !== 'string' || !value.match(/^-?[0-9.,]+$/)) {\n        errors.throwError('invalid decimal value', errors.INVALID_ARGUMENT, { arg: 'value', value: value });\n    }\n\n    // Remove commas\n    var value = value.replace(/,/g,'');\n\n    // Is it negative?\n    var negative = (value.substring(0, 1) === '-');\n    if (negative) { value = value.substring(1); }\n\n    if (value === '.') {\n        errors.throwError('missing value', errors.INVALID_ARGUMENT, { arg: 'value', value: value });\n    }\n\n    // Split it into a whole and fractional part\n    let comps = value.split('.');\n    if (comps.length > 2) {\n        errors.throwError('too many decimal points', errors.INVALID_ARGUMENT, { arg: 'value', value: value });\n    }\n\n    let whole = comps[0], fraction = comps[1];\n    if (!whole) { whole = '0'; }\n    if (!fraction) { fraction = '0'; }\n\n    // Prevent underflow\n    if (fraction.length > unitInfo.decimals) {\n        errors.throwError(\n            'underflow occurred',\n            errors.NUMERIC_FAULT,\n            { operation: 'division', fault: \"underflow\" }\n        );\n    }\n\n    // Fully pad the string with zeros to get to wei\n    while (fraction.length < unitInfo.decimals) { fraction += '0'; }\n\n    let wholeValue = bigNumberify(whole);\n    let fractionValue = bigNumberify(fraction);\n\n    let wei = (wholeValue.mul(unitInfo.tenPower)).add(fractionValue);\n\n    if (negative) { wei = wei.mul(ConstantNegativeOne); }\n\n    return wei;\n}\n\nexport function formatEther(wei: BigNumberish, options: any): string {\n    return formatUnits(wei, 18, options);\n}\n\nexport function parseEther(ether: string): BigNumber {\n    return parseUnits(ether, 18);\n}\n\n","'use strict';\n\n// This is SUPER useful, but adds 140kb (even zipped, adds 40kb)\n//var unorm = require('unorm');\n\nimport { getAddress, getContractAddress, getIcapAddress } from './address';\nimport { AbiCoder, defaultAbiCoder, parseSignature, parseParamType } from './abi-coder';\nimport * as base64 from './base64';\nimport { BigNumber, bigNumberify } from './bignumber';\nimport { arrayify, concat, hexlify, joinSignature, padZeros, splitSignature, stripZeros } from './bytes';\nimport { hashMessage, id, namehash } from './hash';\nimport { keccak256 } from './keccak256';\nimport { sha256 } from './sha2';\nimport { keccak256 as solidityKeccak256, pack as solidityPack, sha256 as soliditySha256 } from './solidity';\nimport { randomBytes } from './random-bytes';\nimport { defineFrozen, defineReadOnly, resolveProperties, shallowCopy } from './properties';\nimport * as RLP from './rlp';\nimport { toUtf8Bytes, toUtf8String } from './utf8';\nimport { formatEther, parseEther, formatUnits, parseUnits } from './units';\nimport { fetchJson } from './web';\nimport { parse as parseTransaction } from './transaction';\n\nimport * as errors from './errors';\n\n// NFKD (decomposed)\n//const etherSymbol = '\\uD835\\uDF63';\n\n// NFKC (composed)\nconst etherSymbol = '\\u039e';\n\nexport {\n    AbiCoder,\n    defaultAbiCoder,\n    parseSignature,\n    parseParamType,\n\n    RLP,\n\n    fetchJson,\n\n    defineReadOnly,\n    defineFrozen,\n    resolveProperties,\n    shallowCopy,\n\n    etherSymbol,\n\n    arrayify,\n\n    concat,\n    padZeros,\n    stripZeros,\n\n    base64,\n\n    bigNumberify,\n    BigNumber,\n\n    hexlify,\n\n    toUtf8Bytes,\n    toUtf8String,\n\n    hashMessage,\n    namehash,\n    id,\n\n    getAddress,\n    getIcapAddress,\n    getContractAddress,\n\n    formatEther,\n    parseEther,\n\n    formatUnits,\n    parseUnits,\n\n    keccak256,\n    sha256,\n\n    randomBytes,\n\n    solidityPack,\n    solidityKeccak256,\n    soliditySha256,\n\n    splitSignature,\n    joinSignature,\n\n    parseTransaction,\n\n    errors\n}\n","'use strict';\n\nimport { Wallet } from './wallet';\nimport * as HDNode from './hdnode';\nimport { SigningKey } from './signing-key';\n\nexport { HDNode, SigningKey, Wallet };\n\n/*\n\n// Exporting\nexport = {\n    HDNode: HDNode,\n    Wallet: Wallet,\n\n    SigningKey: SigningKey\n};\n\n// Default TypeScript\nexport default exporting;\n\n// Node exports\ndeclare var module: any;\n(module).exports = exporting;\n*/\n","'use strict';\n\n// This is empty in node, and used by browserify to inject extra goodies\nimport './utils/shims';\n\nimport { Contract, Interface } from './contracts';\nimport * as providers from './providers';\nimport * as errors from './utils/errors';\nimport { getNetwork } from './providers/networks';\nimport * as utils from './utils';\nimport { HDNode, SigningKey, Wallet } from './wallet';\n\n// @TODO:\n//import info from '../package.json';\nconsole.log(\"@TODO: Get version\");\nconst version = \"4.0.0\";\n\nexport {\n    Wallet,\n\n    HDNode,\n    SigningKey,\n\n    Contract,\n    Interface,\n\n    getNetwork,\n    providers,\n\n    errors,\n    utils,\n\n    version\n};\n\nexport default {\n    Wallet: Wallet,\n\n    HDNode: HDNode,\n    SigningKey: SigningKey,\n\n    Contract: Contract,\n    Interface: Interface,\n\n    providers: providers,\n\n    errors: errors,\n    utils: utils,\n\n//    version: version,\n}\n","\nimport { register, Wordlist } from './wordlist';\n\nimport { toUtf8String } from '../utils/utf8';\n\nimport * as errors from '../utils/errors';\n\nconst data = [\n\n    // 4-kana words\n    'AQRASRAGBAGUAIRAHBAghAURAdBAdcAnoAMEAFBAFCBKFBQRBSFBCXBCDBCHBGFBEQBpBBpQBIkBHNBeOBgFBVCBhBBhNBmOBmRBiHBiFBUFBZDBvFBsXBkFBlcBjYBwDBMBBTBBTRBWBBWXXaQXaRXQWXSRXCFXYBXpHXOQXHRXhRXuRXmXXbRXlXXwDXTRXrCXWQXWGaBWaKcaYgasFadQalmaMBacAKaRKKBKKXKKjKQRKDRKCYKCRKIDKeVKHcKlXKjHKrYNAHNBWNaRNKcNIBNIONmXNsXNdXNnBNMBNRBNrXNWDNWMNFOQABQAHQBrQXBQXFQaRQKXQKDQKOQKFQNBQNDQQgQCXQCDQGBQGDQGdQYXQpBQpQQpHQLXQHuQgBQhBQhCQuFQmXQiDQUFQZDQsFQdRQkHQbRQlOQlmQPDQjDQwXQMBQMDQcFQTBQTHQrDDXQDNFDGBDGQDGRDpFDhFDmXDZXDbRDMYDRdDTRDrXSAhSBCSBrSGQSEQSHBSVRShYShkSyQSuFSiBSdcSoESocSlmSMBSFBSFKSFNSFdSFcCByCaRCKcCSBCSRCCrCGbCEHCYXCpBCpQCIBCIHCeNCgBCgFCVECVcCmkCmwCZXCZFCdRClOClmClFCjDCjdCnXCwBCwXCcRCFQCFjGXhGNhGDEGDMGCDGCHGIFGgBGVXGVEGVRGmXGsXGdYGoSGbRGnXGwXGwDGWRGFNGFLGFOGFdGFkEABEBDEBFEXOEaBEKSENBENDEYXEIgEIkEgBEgQEgHEhFEudEuFEiBEiHEiFEZDEvBEsXEsFEdXEdREkFEbBEbRElFEPCEfkEFNYAEYAhYBNYQdYDXYSRYCEYYoYgQYgRYuRYmCYZTYdBYbEYlXYjQYRbYWRpKXpQopQnpSFpCXpIBpISphNpdBpdRpbRpcZpFBpFNpFDpFopFrLADLBuLXQLXcLaFLCXLEhLpBLpFLHXLeVLhILdHLdRLoDLbRLrXIABIBQIBCIBsIBoIBMIBRIXaIaRIKYIKRINBINuICDIGBIIDIIkIgRIxFIyQIiHIdRIbYIbRIlHIwRIMYIcRIRVITRIFBIFNIFQOABOAFOBQOaFONBONMOQFOSFOCDOGBOEQOpBOLXOIBOIFOgQOgFOyQOycOmXOsXOdIOkHOMEOMkOWWHBNHXNHXWHNXHDuHDRHSuHSRHHoHhkHmRHdRHkQHlcHlRHwBHWcgAEgAggAkgBNgBQgBEgXOgYcgLXgHjgyQgiBgsFgdagMYgWSgFQgFEVBTVXEVKBVKNVKDVKYVKRVNBVNYVDBVDxVSBVSRVCjVGNVLXVIFVhBVhcVsXVdRVbRVlRhBYhKYhDYhGShxWhmNhdahdkhbRhjohMXhTRxAXxXSxKBxNBxEQxeNxeQxhXxsFxdbxlHxjcxFBxFNxFQxFOxFoyNYyYoybcyMYuBQuBRuBruDMuCouHBudQukkuoBulVuMXuFEmCYmCRmpRmeDmiMmjdmTFmFQiADiBOiaRiKRiNBiNRiSFiGkiGFiERipRiLFiIFihYibHijBijEiMXiWBiFBiFCUBQUXFUaRUNDUNcUNRUNFUDBUSHUCDUGBUGFUEqULNULoUIRUeEUeYUgBUhFUuRUiFUsXUdFUkHUbBUjSUjYUwXUMDUcHURdUTBUrBUrXUrQZAFZXZZaRZKFZNBZQFZCXZGBZYdZpBZLDZIFZHXZHNZeQZVRZVFZmXZiBZvFZdFZkFZbHZbFZwXZcCZcRZRBvBQvBGvBLvBWvCovMYsAFsBDsaRsKFsNFsDrsSHsSFsCXsCRsEBsEHsEfspBsLBsLDsIgsIRseGsbRsFBsFQsFSdNBdSRdCVdGHdYDdHcdVbdySduDdsXdlRdwXdWYdWcdWRkBMkXOkaRkNIkNFkSFkCFkYBkpRkeNkgBkhVkmXksFklVkMBkWDkFNoBNoaQoaFoNBoNXoNaoNEoSRoEroYXoYCoYbopRopFomXojkowXorFbBEbEIbdBbjYlaRlDElMXlFDjKjjSRjGBjYBjYkjpRjLXjIBjOFjeVjbRjwBnXQnSHnpFnLXnINnMBnTRwXBwXNwXYwNFwQFwSBwGFwLXwLDweNwgBwuHwjDwnXMBXMpFMIBMeNMTHcaQcNBcDHcSFcCXcpBcLXcLDcgFcuFcnXcwXccDcTQcrFTQErXNrCHrpFrgFrbFrTHrFcWNYWNbWEHWMXWTR',\n\n    // 5-kana words\n    'ABGHABIJAEAVAYJQALZJAIaRAHNXAHdcAHbRAZJMAZJRAZTRAdVJAklmAbcNAjdRAMnRAMWYAWpRAWgRAFgBAFhBAFdcBNJBBNJDBQKBBQhcBQlmBDEJBYJkBYJTBpNBBpJFBIJBBIJDBIcABOKXBOEJBOVJBOiJBOZJBepBBeLXBeIFBegBBgGJBVJXBuocBiJRBUJQBlXVBlITBwNFBMYVBcqXBTlmBWNFBWiJBWnRBFGHBFwXXKGJXNJBXNZJXDTTXSHSXSVRXSlHXCJDXGQJXEhXXYQJXYbRXOfXXeNcXVJFXhQJXhEJXdTRXjdXXMhBXcQTXRGBXTEBXTnQXFCXXFOFXFgFaBaFaBNJaBCJaBpBaBwXaNJKaNJDaQIBaDpRaEPDaHMFamDJalEJaMZJaFaFaFNBaFQJaFLDaFVHKBCYKBEBKBHDKXaFKXGdKXEJKXpHKXIBKXZDKXwXKKwLKNacKNYJKNJoKNWcKDGdKDTRKChXKGaRKGhBKGbRKEBTKEaRKEPTKLMDKLWRKOHDKVJcKdBcKlIBKlOPKFSBKFEPKFpFNBNJNJBQNBGHNBEPNBHXNBgFNBVXNBZDNBsXNBwXNNaRNNJDNNJENNJkNDCJNDVDNGJRNJiDNZJNNsCJNJFNNFSBNFCXNFEPNFLXNFIFQJBFQCaRQJEQQLJDQLJFQIaRQOqXQHaFQHHQQVJXQVJDQhNJQmEIQZJFQsJXQJrFQWbRDJABDBYJDXNFDXCXDXLXDXZDDXsJDQqXDSJFDJCXDEPkDEqXDYmQDpSJDOCkDOGQDHEIDVJDDuDuDWEBDJFgSBNDSBSFSBGHSBIBSBTQSKVYSJQNSJQiSJCXSEqXSJYVSIiJSOMYSHAHSHaQSeCFSepQSegBSHdHSHrFShSJSJuHSJUFSkNRSrSrSWEBSFaHSJFQSFCXSFGDSFYXSFODSFgBSFVXSFhBSFxFSFkFSFbBSFMFCADdCJXBCXaFCXKFCXNFCXCXCXGBCXEJCXYBCXLDCXIBCXOPCXHXCXgBCXhBCXiBCXlDCXcHCJNBCJNFCDCJCDGBCDVXCDhBCDiDCDJdCCmNCpJFCIaRCOqXCHCHCHZJCViJCuCuCmddCJiFCdNBCdHhClEJCnUJCreSCWlgCWTRCFBFCFNBCFYBCFVFCFhFCFdSCFTBCFWDGBNBGBQFGJBCGBEqGBpBGBgQGNBEGNJYGNkOGNJRGDUFGJpQGHaBGJeNGJeEGVBlGVKjGiJDGvJHGsVJGkEBGMIJGWjNGFBFGFCXGFGBGFYXGFpBGFMFEASJEAWpEJNFECJVEIXSEIQJEOqXEOcFEeNcEHEJEHlFEJgFEhlmEmDJEmZJEiMBEUqXEoSREPBFEPXFEPKFEPSFEPEFEPpFEPLXEPIBEJPdEPcFEPTBEJnXEqlHEMpREFCXEFODEFcFYASJYJAFYBaBYBVXYXpFYDhBYCJBYJGFYYbRYeNcYJeVYiIJYZJcYvJgYvJRYJsXYsJFYMYMYreVpBNHpBEJpBwXpQxFpYEJpeNDpJeDpeSFpeCHpHUJpHbBpHcHpmUJpiiJpUJrpsJuplITpFaBpFQqpFGBpFEfpFYBpFpBpFLJpFIDpFgBpFVXpFyQpFuFpFlFpFjDpFnXpFwXpJFMpFTBLXCJLXEFLXhFLXUJLXbFLalmLNJBLSJQLCLCLGJBLLDJLHaFLeNFLeSHLeCXLepFLhaRLZsJLsJDLsJrLocaLlLlLMdbLFNBLFSBLFEHLFkFIBBFIBXFIBaQIBKXIBSFIBpHIBLXIBgBIBhBIBuHIBmXIBiFIBZXIBvFIBbFIBjQIBwXIBWFIKTRIQUJIDGFICjQIYSRIINXIJeCIVaRImEkIZJFIvJRIsJXIdCJIJoRIbBQIjYBIcqXITFVIreVIFKFIFSFIFCJIFGFIFLDIFIBIJFOIFgBIFVXIJFhIFxFIFmXIFdHIFbBIJFrIJFWOBGBOQfXOOKjOUqXOfXBOqXEOcqXORVJOFIBOFlDHBIOHXiFHNTRHCJXHIaRHHJDHHEJHVbRHZJYHbIBHRsJHRkDHWlmgBKFgBSBgBCDgBGHgBpBgBIBgBVJgBuBgBvFgKDTgQVXgDUJgGSJgOqXgmUMgZIJgTUJgWIEgFBFgFNBgFDJgFSFgFGBgFYXgJFOgFgQgFVXgFhBgFbHgJFWVJABVQKcVDgFVOfXVeDFVhaRVmGdViJYVMaRVFNHhBNDhBCXhBEqhBpFhBLXhNJBhSJRheVXhhKEhxlmhZIJhdBQhkIJhbMNhMUJhMZJxNJgxQUJxDEkxDdFxSJRxplmxeSBxeCXxeGFxeYXxepQxegBxWVcxFEQxFLXxFIBxFgBxFxDxFZtxFdcxFbBxFwXyDJXyDlcuASJuDJpuDIBuCpJuGSJuIJFueEFuZIJusJXudWEuoIBuWGJuFBcuFKEuFNFuFQFuFDJuFGJuFVJuFUtuFdHuFTBmBYJmNJYmQhkmLJDmLJomIdXmiJYmvJRmsJRmklmmMBymMuCmclmmcnQiJABiJBNiJBDiBSFiBCJiBEFiBYBiBpFiBLXiBTHiJNciDEfiCZJiECJiJEqiOkHiHKFieNDiHJQieQcieDHieSFieCXieGFieEFieIHiegFihUJixNoioNXiFaBiFKFiFNDiFEPiFYXitFOitFHiFgBiFVEiFmXiFitiFbBiFMFiFrFUCXQUIoQUIJcUHQJUeCEUHwXUUJDUUqXUdWcUcqXUrnQUFNDUFSHUFCFUFEfUFLXUtFOZBXOZXSBZXpFZXVXZEQJZEJkZpDJZOqXZeNHZeCDZUqXZFBQZFEHZFLXvBAFvBKFvBCXvBEPvBpHvBIDvBgFvBuHvQNJvFNFvFGBvFIBvJFcsXCDsXLXsXsXsXlFsXcHsQqXsJQFsEqXseIFsFEHsFjDdBxOdNpRdNJRdEJbdpJRdhZJdnSJdrjNdFNJdFQHdFhNkNJDkYaRkHNRkHSRkVbRkuMRkjSJkcqDoSJFoEiJoYZJoOfXohEBoMGQocqXbBAFbBXFbBaFbBNDbBGBbBLXbBTBbBWDbGJYbIJHbFQqbFpQlDgQlOrFlVJRjGEBjZJRnXvJnXbBnEfHnOPDngJRnxfXnUJWwXEJwNpJwDpBwEfXwrEBMDCJMDGHMDIJMLJDcQGDcQpHcqXccqNFcqCXcFCJRBSBRBGBRBEJRBpQTBNFTBQJTBpBTBVXTFABTFSBTFCFTFGBTFMDrXCJrXLDrDNJrEfHrFQJrFitWNjdWNTR',\n\n    // 6-kana words\n    'AKLJMANOPFASNJIAEJWXAYJNRAIIbRAIcdaAeEfDAgidRAdjNYAMYEJAMIbRAFNJBAFpJFBBIJYBDZJFBSiJhBGdEBBEJfXBEJqXBEJWRBpaUJBLXrXBIYJMBOcfXBeEfFBestXBjNJRBcDJOBFEqXXNvJRXDMBhXCJNYXOAWpXONJWXHDEBXeIaRXhYJDXZJSJXMDJOXcASJXFVJXaBQqXaBZJFasXdQaFSJQaFEfXaFpJHaFOqXKBNSRKXvJBKQJhXKEJQJKEJGFKINJBKIJjNKgJNSKVElmKVhEBKiJGFKlBgJKjnUJKwsJYKMFIJKFNJDKFIJFKFOfXNJBSFNJBCXNBpJFNJBvQNJBMBNJLJXNJOqXNJeCXNJeGFNdsJCNbTKFNwXUJQNFEPQDiJcQDMSJQSFpBQGMQJQJeOcQyCJEQUJEBQJFBrQFEJqDXDJFDJXpBDJXIMDGiJhDIJGRDJeYcDHrDJDVXgFDkAWpDkIgRDjDEqDMvJRDJFNFDJFIBSKclmSJQOFSJQVHSJQjDSJGJBSJGJFSECJoSHEJqSJHTBSJVJDSViJYSZJNBSJsJDSFSJFSFEfXSJFLXCBUJVCJXSBCJXpBCXVJXCJXsXCJXdFCJNJHCLIJgCHiJFCVNJMChCJhCUHEJCsJTRCJdYcCoQJCCFEfXCFIJgCFUJxCFstFGJBaQGJBIDGQJqXGYJNRGJHKFGeQqDGHEJFGJeLXGHIiJGHdBlGUJEBGkIJTGFQPDGJFEqEAGegEJIJBEJVJXEhQJTEiJNcEJZJFEJoEqEjDEqEPDsXEPGJBEPOqXEPeQFEfDiDEJfEFEfepQEfMiJEqXNBEqDIDEqeSFEqVJXEMvJRYXNJDYXEJHYKVJcYYJEBYJeEcYJUqXYFpJFYFstXpAZJMpBSJFpNBNFpeQPDpHLJDpHIJFpHgJFpeitFpHZJFpJFADpFSJFpJFCJpFOqXpFitBpJFZJLXIJFLIJgRLVNJWLVHJMLwNpJLFGJBLFLJDLFOqXLJFUJIBDJXIBGJBIJBYQIJBIBIBOqXIBcqDIEGJFILNJTIIJEBIOiJhIJeNBIJeIBIhiJIIWoTRIJFAHIJFpBIJFuHIFUtFIJFTHOSBYJOEcqXOHEJqOvBpFOkVJrObBVJOncqDOcNJkHhNJRHuHJuHdMhBgBUqXgBsJXgONJBgHNJDgHHJQgJeitgHsJXgJyNagyDJBgZJDrgsVJQgkEJNgkjSJgJFAHgFCJDgFZtMVJXNFVXQfXVJXDJVXoQJVQVJQVDEfXVDvJHVEqNFVeQfXVHpJFVHxfXVVJSRVVmaRVlIJOhCXVJhHjYkhxCJVhWVUJhWiJcxBNJIxeEqDxfXBFxcFEPxFSJFxFYJXyBDQJydaUJyFOPDuYCJYuLvJRuHLJXuZJLDuFOPDuFZJHuFcqXmKHJdmCQJcmOsVJiJAGFitLCFieOfXiestXiZJMEikNJQirXzFiFQqXiFIJFiFZJFiFvtFUHpJFUteIcUteOcUVCJkUhdHcUbEJEUJqXQUMNJhURjYkUFitFZDGJHZJIxDZJVJXZJFDJZJFpQvBNJBvBSJFvJxBrseQqDsVFVJdFLJDkEJNBkmNJYkFLJDoQJOPoGsJRoEAHBoEJfFbBQqDbBZJHbFVJXlFIJBjYIrXjeitcjjCEBjWMNBwXQfXwXOaFwDsJXwCJTRwrCZJMDNJQcDDJFcqDOPRYiJFTBsJXTQIJBTFEfXTFLJDrXEJFrEJXMrFZJFWEJdEWYTlm',\n\n    // 7-kana words\n    'ABCDEFACNJTRAMBDJdAcNJVXBLNJEBXSIdWRXErNJkXYDJMBXZJCJaXMNJaYKKVJKcKDEJqXKDcNJhKVJrNYKbgJVXKFVJSBNBYBwDNJeQfXNJeEqXNhGJWENJFiJRQlIJbEQJfXxDQqXcfXQFNDEJQFwXUJDYcnUJDJIBgQDIUJTRDJFEqDSJQSJFSJQIJFSOPeZtSJFZJHCJXQfXCTDEqFGJBSJFGJBOfXGJBcqXGJHNJDGJRLiJEJfXEqEJFEJPEFpBEJYJBZJFYBwXUJYiJMEBYJZJyTYTONJXpQMFXFpeGIDdpJFstXpJFcPDLBVSJRLHQJqXLJFZJFIJBNJDIJBUqXIBkFDJIJEJPTIYJGWRIJeQPDIJeEfHIJFsJXOqGDSFHXEJqXgJCsJCgGQJqXgdQYJEgFMFNBgJFcqDVJwXUJVJFZJchIgJCCxOEJqXxOwXUJyDJBVRuscisciJBiJBieUtqXiJFDJkiFsJXQUGEZJcUJFsJXZtXIrXZDZJDrZJFNJDZJFstXvJFQqXvJFCJEsJXQJqkhkNGBbDJdTRbYJMEBlDwXUJMEFiJFcfXNJDRcNJWMTBLJXC',\n\n    // 8-kana words\n    'BraFUtHBFSJFdbNBLJXVJQoYJNEBSJBEJfHSJHwXUJCJdAZJMGjaFVJXEJPNJBlEJfFiJFpFbFEJqIJBVJCrIBdHiJhOPFChvJVJZJNJWxGFNIFLueIBQJqUHEJfUFstOZJDrlXEASJRlXVJXSFwVJNJWD',\n\n    // 9-kana words\n    'QJEJNNJDQJEJIBSFQJEJxegBQJEJfHEPSJBmXEJFSJCDEJqXLXNJFQqXIcQsFNJFIFEJqXUJgFsJXIJBUJEJfHNFvJxEqXNJnXUJFQqD',\n\n    // 10-kana words\n    'IJBEJqXZJ'\n];\n\n// Maps each character into its kana value (the index)\nconst mapping = \"~~AzB~X~a~KN~Q~D~S~C~G~E~Y~p~L~I~O~eH~g~V~hxyumi~~U~~Z~~v~~s~~dkoblPjfnqwMcRTr~W~~~F~~~~~Jt\"\n\nlet words: Array<string> = null;\n\nfunction loadWords() {\n    if (words !== null) { return; }\n    words = [];\n\n    // Transforms for normalizing (sort is a not quite UTF-8)\n    var transform: { [key: string]: string | boolean } = {};\n\n    // Delete the diacritic marks\n    transform[toUtf8String([227, 130, 154])] = false;\n    transform[toUtf8String([227, 130, 153])] = false;\n\n    // Some simple transforms that sort out most of the order\n    transform[toUtf8String([227, 130, 133])] = toUtf8String([227, 130, 134]);\n    transform[toUtf8String([227, 129, 163])] = toUtf8String([227, 129, 164]);\n    transform[toUtf8String([227, 130, 131])] = toUtf8String([227, 130, 132]);\n    transform[toUtf8String([227, 130, 135])] = toUtf8String([227, 130, 136]);\n\n\n    // Normalize words using the transform\n    function normalize(word: string) {\n        var result = '';\n        for (var i = 0; i < word.length; i++) {\n            let kana = word[i];\n            var target = transform[kana];\n            if (target === false) { continue; }\n            if (target) { kana = <string>target; }\n            result += kana;\n        }\n        return result;\n    }\n\n    // Sort how the Japanese list is sorted\n    function sortJapanese(a: string, b: string) {\n        a = normalize(a);\n        b = normalize(b);\n        if (a < b) { return -1; }\n        if (a > b) { return 1; }\n        return 0;\n    }\n\n    // Load all the words\n    for (let length = 3; length <= 9; length++) {\n        let d = data[length - 3];\n        for (let offset = 0; offset < d.length; offset += length) {\n            let word = [];\n            for (let i = 0; i < length; i++) {\n                 let k = mapping.indexOf(d[offset + i]);\n                 word.push(227);\n                 word.push((k & 0x40) ? 130: 129);\n                 word.push((k & 0x3f) + 128);\n            }\n            words.push(toUtf8String(word));\n        }\n    }\n    words.sort(sortJapanese);\n\n    // For some reason kyoku and kiyoku are flipped; we'll just manually fix it\n    let kyoku = words[442];\n    words[442] = words[443];\n    words[443] = kyoku;\n}\n\n/*\nvar fs = require('fs');\nfs.readFileSync('lang-ja.txt').toString().split('\\x0a').forEach(function(d, i) {\n    if (d !== words[i]) { console.log(d, words[i], i, toUtf8Bytes(d)); }\n});\n*/\n\n\nclass LangJa extends Wordlist {\n    constructor() {\n        super('ja');\n    }\n\n    getWord(index: number): string {\n        loadWords();\n        return words[index];\n    }\n\n    getWordIndex(word: string): number {\n        loadWords();\n        return words.indexOf(word);\n    }\n\n    split(mnemonic: string): Array<string> {\n        if (!mnemonic.normalize) {\n            errors.throwError('Japanese is unsupported on this platform; missing String.prototype.normalize', errors.UNSUPPORTED_OPERATION, { operation: 'String.prototype.normalize' });\n        }\n        return mnemonic.split(/(?:\\u3000| )+/g);\n    }\n\n    join(words: Array<string>): string {\n        return words.join('\\u3000');\n    }\n}\n\nconst langJa = new LangJa();\nregister(langJa);\n\nexport { langJa };\n\n","\nimport { register, Wordlist } from './wordlist';\n\nimport { toUtf8String } from '../utils/utf8';\n\nconst data = [\n    'OYAa',\n    'ATAZoATBl3ATCTrATCl8ATDloATGg3ATHT8ATJT8ATJl3ATLlvATLn4ATMT8ATMX8ATMboATMgoAToLbAToMTATrHgATvHnAT3AnAT3JbAT3MTAT8DbAT8JTAT8LmAT8MYAT8MbAT#LnAUHT8AUHZvAUJXrAUJX8AULnrAXJnvAXLUoAXLgvAXMn6AXRg3AXrMbAX3JTAX3QbAYLn3AZLgvAZrSUAZvAcAZ8AaAZ8AbAZ8AnAZ8HnAZ8LgAZ8MYAZ8MgAZ8OnAaAboAaDTrAaFTrAaJTrAaJboAaLVoAaMXvAaOl8AaSeoAbAUoAbAg8AbAl4AbGnrAbMT8AbMXrAbMn4AbQb8AbSV8AbvRlAb8AUAb8AnAb8HgAb8JTAb8NTAb8RbAcGboAcLnvAcMT8AcMX8AcSToAcrAaAcrFnAc8AbAc8MgAfGgrAfHboAfJnvAfLV8AfLkoAfMT8AfMnoAfQb8AfScrAfSgrAgAZ8AgFl3AgGX8AgHZvAgHgrAgJXoAgJX8AgJboAgLZoAgLn4AgOX8AgoATAgoAnAgoCUAgoJgAgoLXAgoMYAgoSeAgrDUAgrJTAhrFnAhrLjAhrQgAjAgoAjJnrAkMX8AkOnoAlCTvAlCV8AlClvAlFg4AlFl6AlFn3AloSnAlrAXAlrAfAlrFUAlrFbAlrGgAlrOXAlvKnAlvMTAl3AbAl3MnAnATrAnAcrAnCZ3AnCl8AnDg8AnFboAnFl3AnHX4AnHbrAnHgrAnIl3AnJgvAnLXoAnLX4AnLbrAnLgrAnLhrAnMXoAnMgrAnOn3AnSbrAnSeoAnvLnAn3OnCTGgvCTSlvCTvAUCTvKnCTvNTCT3CZCT3GUCT3MTCT8HnCUCZrCULf8CULnvCU3HnCU3JUCY6NUCbDb8CbFZoCbLnrCboOTCboScCbrFnCbvLnCb8AgCb8HgCb$LnCkLfoClBn3CloDUDTHT8DTLl3DTSU8DTrAaDTrLXDTrLjDTrOYDTrOgDTvFXDTvFnDT3HUDT3LfDUCT9DUDT4DUFVoDUFV8DUFkoDUGgrDUJnrDULl8DUMT8DUMXrDUMX4DUMg8DUOUoDUOgvDUOg8DUSToDUSZ8DbDXoDbDgoDbGT8DbJn3DbLg3DbLn4DbMXrDbMg8DbOToDboJXGTClvGTDT8GTFZrGTLVoGTLlvGTLl3GTMg8GTOTvGTSlrGToCUGTrDgGTrJYGTrScGTtLnGTvAnGTvQgGUCZrGUDTvGUFZoGUHXrGULnvGUMT8GUoMgGXoLnGXrMXGXrMnGXvFnGYLnvGZOnvGZvOnGZ8LaGZ8LmGbAl3GbDYvGbDlrGbHX3GbJl4GbLV8GbLn3GbMn4GboJTGboRfGbvFUGb3GUGb4JnGgDX3GgFl$GgJlrGgLX6GgLZoGgLf8GgOXoGgrAgGgrJXGgrMYGgrScGgvATGgvOYGnAgoGnJgvGnLZoGnLg3GnLnrGnQn8GnSbrGnrMgHTClvHTDToHTFT3HTQT8HToJTHToJgHTrDUHTrMnHTvFYHTvRfHT8MnHT8SUHUAZ8HUBb4HUDTvHUoMYHXFl6HXJX6HXQlrHXrAUHXrMnHXrSbHXvFYHXvKXHX3LjHX3MeHYvQlHZrScHZvDbHbAcrHbFT3HbFl3HbJT8HbLTrHbMT8HbMXrHbMbrHbQb8HbSX3HboDbHboJTHbrFUHbrHgHbrJTHb8JTHb8MnHb8QgHgAlrHgDT3HgGgrHgHgrHgJTrHgJT8HgLX@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!Ln$CTGXMnCToLZ4CTrHT8CT3JTrCT3RZrCT#GTvCU6GgvCU8Db8CU8GZrCU8HT8CboLl3CbrGgrCbrMU8Cb8DT3Cb8GnrCb8LX4Cb8MT8Cb8ObrCgrGgvCgrKX4Cl8FZoDTrAbvDTrDboDTrGT6DTrJgrDTrMX3DTrRZrDTrRg8DTvAVvDTvFZoDT3DT8DT3Ln3DT4HZrDT4MT8DT8AlrDT8MT8DUAkGbDUDbJnDYLnQlDbDUOYDbMTAnDbMXSnDboAT3DboFn4DboLnvDj6JTrGTCgFTGTGgFnGTJTMnGTLnPlGToJT8GTrCT3GTrLVoGTrLnvGTrMX3GTrMboGTvKl3GZClFnGZrDT3GZ8DTrGZ8FZ8GZ8MXvGZ8On8GZ8ST3GbCnQXGbMbFnGboFboGboJg3GboMXoGb3JTvGb3JboGb3Mn6Gb3Qb8GgDXLjGgMnAUGgrDloGgrHX4GgrSToGgvAXrGgvAZvGgvFbrGgvLl3GgvMnvGnDnLXGnrATrGnrMboGnuLl3HTATMnHTAgCnHTCTCTHTrGTvHTrHTvHTrJX8HTrLl8HTrMT8HTrMgoHTrOTrHTuOn3HTvAZrHTvDTvHTvGboHTvJU8HTvLl3HTvMXrHTvQb4HT4GT6HT4JT8HT4Jb#HT8Al3HT8GZrHT8GgrHT8HX4HT8Jb8HT8JnoHT8LTrHT8LgvHT8SToHT8SV8HUoJUoHUoJX8HUoLnrHXrLZoHXvAl3HX3LnrHX4FkvHX4LhrHX4MXoHX4OnoHZrAZ8HZrDb8HZrGZ8HZrJnrHZvGZ8HZvLnvHZ8JnvHZ8LhrHbCXJlHbMTAnHboJl4HbpLl3HbrJX8HbrLnrHbrMnvHbvRYrHgoSTrHgrFV8HgrGZ8HgrJXoHgrRnvHgvBb!HgvGTrHgvHX4HgvHn!HgvLTrHgvSU8HnDnLbHnFbJbHnvDn8Hn6GgvHn!BTvJTCTLnJTQgFnJTrAnvJTrLX4JTrOUoJTvFn3JTvLnrJTvNToJT3AgoJT3Jn4JT3LhvJT3ObrJT8AcrJT8Al3JT8JT8JT8JnoJT8LX4JT8LnrJT8MX3JT8Rg3JT8Sc8JUoBTvJU8AToJU8GZ8JU8GgvJU8JTrJU8JXrJU8JnrJU8LnvJU8ScvJXHnJlJXrGgvJXrJU8JXrLhrJXrMT8JXrMXrJXrQUoJXvCTvJXvGZ8JXvGgrJXvQT8JX8Ab8JX8DT8JX8GZ8JX8HZvJX8LnrJX8MT8JX8MXoJX8MnvJX8ST3JYGnCTJbAkGbJbCTAnJbLTAcJboDT3JboLb6JbrAnvJbrCn3JbrDl8JbrGboJbrIZoJbrJnvJbrMnvJbrQb4Jb8RZrJeAbAnJgJnFbJgScAnJgrATrJgvHZ8JgvMn4JlJlFbJlLiQXJlLjOnJlRbOlJlvNXoJlvRl3Jl4AcrJl8AUoJl8MnrJnFnMlJnHgGbJnoDT8JnoFV8JnoGgvJnoIT8JnoQToJnoRg3JnrCZ3JnrGgrJnrHTvJnrLf8JnrOX8JnvAT3JnvFZoJnvGT8JnvJl4JnvMT8JnvMX8JnvOXrJnvPX6JnvSX3JnvSZrJn3MT8Jn3MX8Jn3RTrLTATKnLTJnLTLTMXKnLTRTQlLToGb8LTrAZ8LTrCZ8LTrDb8LTrHT8LT3PX6LT4FZoLT$CTvLT$GgrLUvHX3LVoATrLVoAgoLVoJboLVoMX3LVoRg3LV8CZ3LV8FZoLV8GTvLXrDXoLXrFbrLXvAgvLXvFlrLXvLl3LXvRn6LX4Mb8LX8GT8LYCXMnLYrMnrLZoSTvLZrAZvLZrAloLZrFToLZrJXvLZrJboLZrJl4LZrLnrLZrMT8LZrOgvLZrRnvLZrST4LZvMX8LZvSlvLZ8AgoLZ8CT3LZ8JT8LZ8LV8LZ8LZoLZ8Lg8LZ8SV8LZ8SbrLZ$HT8LZ$Mn4La6CTvLbFbMnLbRYFTLbSnFZLboJT8LbrAT9LbrGb3LbrQb8LcrJX8LcrMXrLerHTvLerJbrLerNboLgrDb8LgrGZ8LgrHTrLgrMXrLgrSU8LgvJTrLgvLl3Lg6Ll3LhrLnrLhrMT8LhvAl4LiLnQXLkoAgrLkoJT8LkoJn4LlrSU8Ll3FZoLl3HTrLl3JX8Ll3JnoLl3LToLmLeFbLnDUFbLnLVAnLnrATrLnrAZoLnrAb8LnrAlrLnrGgvLnrJU8LnrLZrLnrLhrLnrMb8LnrOXrLnrSZ8LnvAb4LnvDTrLnvDl8LnvHTrLnvHbrLnvJT8LnvJU8LnvJbrLnvLhvLnvMX8LnvMb8LnvNnoLnvSU8Ln3Al3Ln4FZoLn4GT6Ln4JgvLn4LhrLn4MT8Ln4SToMToCZrMToJX8MToLX4MToLf8MToRg3MTrEloMTvGb6MT3BTrMT3Lb6MT8AcrMT8AgrMT8GZrMT8JnoMT8LnrMT8MX3MUOUAnMXAbFnMXoAloMXoJX8MXoLf8MXoLl8MXrAb8MXrDTvMXrGT8MXrGgrMXrHTrMXrLf8MXrMU8MXrOXvMXrQb8MXvGT8MXvHTrMXvLVoMX3AX3MX3Jn3MX3LhrMX3MX3MX4AlrMX4OboMX8GTvMX8GZrMX8GgrMX8JT8MX8JX8MX8LhrMX8MT8MYDUFbMYMgDbMbGnFfMbvLX4MbvLl3Mb8Mb8Mb8ST4MgGXCnMg8ATrMg8AgoMg8CZrMg8DTrMg8DboMg8HTrMg8JgrMg8LT8MloJXoMl8AhrMl8JT8MnLgAUMnoJXrMnoLX4MnoLhrMnoMT8MnrAl4MnrDb8MnrOTvMnrOgvMnrQb8MnrSU8MnvGgrMnvHZ8Mn3MToMn4DTrMn4LTrMn4Mg8NnBXAnOTFTFnOToAToOTrGgvOTrJX8OT3JXoOT6MTrOT8GgrOT8HTpOT8MToOUoHT8OUoJT8OUoLn3OXrAgoOXrDg8OXrMT8OXvSToOX6CTvOX8CZrOX8OgrOb6HgvOb8AToOb8MT8OcvLZ8OgvAlrOgvHTvOgvJTrOgvJnrOgvLZrOgvLn4OgvMT8OgvRTrOg8AZoOg8DbvOnrOXoOnvJn4OnvLhvOnvRTrOn3GgoOn3JnvOn6JbvOn8OTrPTGYFTPbBnFnPbGnDnPgDYQTPlrAnvPlrETvPlrLnvPlrMXvPlvFX4QTMTAnQTrJU8QYCnJlQYJlQlQbGTQbQb8JnrQb8LZoQb8LnvQb8MT8Qb8Ml8Qb8ST4QloAl4QloHZvQloJX8QloMn8QnJZOlRTrAZvRTrDTrRTvJn4RTvLhvRT4Jb8RZrAZrRZ8AkrRZ8JU8RZ8LV8RZ8LnvRbJlQXRg3GboRg3MnvRg8AZ8Rg8JboRg8Jl4RnLTCbRnvFl3RnvQb8SToAl4SToCZrSToFZoSToHXrSToJU8SToJgvSToJl4SToLhrSToMX3STrAlvSTrCT9STrCgrSTrGgrSTrHXrSTrHboSTrJnoSTrNboSTvLnrST4AZoST8Ab8ST8JT8SUoJn3SU6HZ#SU6JTvSU8Db8SU8HboSU8LgrSV8JT8SZrAcrSZrAl3SZrJT8SZrJnvSZrMT8SZvLUoSZ4FZoSZ8JnoSZ8RZrScoLnrScoMT8ScoMX8ScrAT4ScrAZ8ScrLZ8ScrLkvScvDb8ScvLf8ScvNToSgrFZrShvKnrSloHUoSloLnrSlrMXoSl8HgrSmrJUoSn3BX6',\n    'ATFlOn3ATLgrDYAT4MTAnAT8LTMnAYJnRTrAbGgJnrAbLV8LnAbvNTAnAeFbLg3AgOYMXoAlQbFboAnDboAfAnJgoJTBToDgAnBUJbAl3BboDUAnCTDlvLnCTFTrSnCYoQTLnDTwAbAnDUDTrSnDUHgHgrDX8LXFnDbJXAcrETvLTLnGTFTQbrGTMnGToGT3DUFbGUJlPX3GbQg8LnGboJbFnGb3GgAYGgAg8ScGgMbAXrGgvAbAnGnJTLnvGnvATFgHTDT6ATHTrDlJnHYLnMn8HZrSbJTHZ8LTFnHbFTJUoHgSeMT8HgrLjAnHgvAbAnHlFUrDlHnDgvAnHnHTFT3HnQTGnrJTAaMXvJTGbCn3JTOgrAnJXvAXMnJbMg8SnJbMnRg3Jb8LTMnJnAl3OnJnGYrQlJnJlQY3LTDlCn3LTJjLg3LTLgvFXLTMg3GTLV8HUOgLXFZLg3LXNXrMnLX8QXFnLX9AlMYLYLXPXrLZAbJU8LZDUJU8LZMXrSnLZ$AgFnLaPXrDULbFYrMnLbMn8LXLboJgJgLeFbLg3LgLZrSnLgOYAgoLhrRnJlLkCTrSnLkOnLhrLnFX%AYLnFZoJXLnHTvJbLnLloAbMTATLf8MTHgJn3MTMXrAXMT3MTFnMUITvFnMXFX%AYMXMXvFbMXrFTDbMYAcMX3MbLf8SnMb8JbFnMgMXrMTMgvAXFnMgvGgCmMnAloSnMnFnJTrOXvMXSnOX8HTMnObJT8ScObLZFl3ObMXCZoPTLgrQXPUFnoQXPU3RXJlPX3RkQXPbrJXQlPlrJbFnQUAhrDbQXGnCXvQYLnHlvQbLfLnvRTOgvJbRXJYrQlRYLnrQlRbLnrQlRlFT8JlRlFnrQXSTClCn3STHTrAnSTLZQlrSTMnGTrSToHgGbSTrGTDnSTvGXCnST3HgFbSU3HXAXSbAnJn3SbFT8LnScLfLnv',\n    'AT3JgJX8AT8FZoSnAT8JgFV8AT8LhrDbAZ8JT8DbAb8GgLhrAb8SkLnvAe8MT8SnAlMYJXLVAl3GYDTvAl3LfLnvBUDTvLl3CTOn3HTrCT3DUGgrCU8MT8AbCbFTrJUoCgrDb8MTDTLV8JX8DTLnLXQlDT8LZrSnDUQb8FZ8DUST4JnvDb8ScOUoDj6GbJl4GTLfCYMlGToAXvFnGboAXvLnGgAcrJn3GgvFnSToGnLf8JnvGn#HTDToHTLnFXJlHTvATFToHTvHTDToHTvMTAgoHT3STClvHT4AlFl6HT8HTDToHUoDgJTrHUoScMX3HbRZrMXoHboJg8LTHgDb8JTrHgMToLf8HgvLnLnoHnHn3HT4Hn6MgvAnJTJU8ScvJT3AaQT8JT8HTrAnJXrRg8AnJbAloMXoJbrATFToJbvMnoSnJgDb6GgvJgDb8MXoJgSX3JU8JguATFToJlPYLnQlJlQkDnLbJlQlFYJlJl8Lf8OTJnCTFnLbJnLTHXMnJnLXGXCnJnoFfRg3JnrMYRg3Jn3HgFl3KT8Dg8LnLTRlFnPTLTvPbLbvLVoSbrCZLXMY6HT3LXNU7DlrLXNXDTATLX8DX8LnLZDb8JU8LZMnoLhrLZSToJU8LZrLaLnrLZvJn3SnLZ8LhrSnLaJnoMT8LbFlrHTvLbrFTLnrLbvATLlvLb6OTFn3LcLnJZOlLeAT6Mn4LeJT3ObrLg6LXFlrLhrJg8LnLhvDlPX4LhvLfLnvLj6JTFT3LnFbrMXoLnQluCTvLnrQXCY6LnvLfLnvLnvMgLnvLnvSeLf8MTMbrJn3MT3JgST3MT8AnATrMT8LULnrMUMToCZrMUScvLf8MXoDT8SnMX6ATFToMX8AXMT8MX8FkMT8MX8HTrDUMX8ScoSnMYJT6CTvMgAcrMXoMg8SToAfMlvAXLg3MnFl3AnvOT3AnFl3OUoATHT8OU3RnLXrOXrOXrSnObPbvFn6Og8HgrSnOg8OX8DbPTvAgoJgPU3RYLnrPXrDnJZrPb8CTGgvPlrLTDlvPlvFUJnoQUvFXrQlQeMnoAl3QlrQlrSnRTFTrJUoSTDlLiLXSTFg6HT3STJgoMn4STrFTJTrSTrLZFl3ST4FnMXoSUrDlHUoScvHTvSnSfLkvMXo',\n    'AUoAcrMXoAZ8HboAg8AbOg6ATFgAg8AloMXoAl3AT8JTrAl8MX8MXoCT3SToJU8Cl8Db8MXoDT8HgrATrDboOT8MXoGTOTrATMnGT8LhrAZ8GnvFnGnQXHToGgvAcrHTvAXvLl3HbrAZoMXoHgBlFXLg3HgMnFXrSnHgrSb8JUoHn6HT8LgvITvATrJUoJUoLZrRnvJU8HT8Jb8JXvFX8QT8JXvLToJTrJYrQnGnQXJgrJnoATrJnoJU8ScvJnvMnvMXoLTCTLgrJXLTJlRTvQlLbRnJlQYvLbrMb8LnvLbvFn3RnoLdCVSTGZrLeSTvGXCnLg3MnoLn3MToLlrETvMT8SToAl3MbrDU6GTvMb8LX4LhrPlrLXGXCnSToLf8Rg3STrDb8LTrSTvLTHXMnSb3RYLnMnSgOg6ATFg',\n    'HUDlGnrQXrJTrHgLnrAcJYMb8DULc8LTvFgGnCk3Mg8JbAnLX4QYvFYHnMXrRUoJnGnvFnRlvFTJlQnoSTrBXHXrLYSUJgLfoMT8Se8DTrHbDb',\n    'AbDl8SToJU8An3RbAb8ST8DUSTrGnrAgoLbFU6Db8LTrMg8AaHT8Jb8ObDl8SToJU8Pb3RlvFYoJl'\n]\n\nvar codes = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*'\n\nfunction getHangul(code: number): string {\n    if (code >= 40) {\n        code = code + 168 - 40;\n    } else if (code >= 19) {\n        code = code + 97 - 19;\n    }\n\n    return toUtf8String([ 225, (code >> 6) + 132, (code & 0x3f) + 128]);\n}\n\nlet wordlist: Array<string> = null;\n\nfunction loadWords(): void {\n    if (wordlist != null) { return; }\n\n    wordlist = [];\n\n    data.forEach((data, length) => {\n        length += 4;\n        for (let i = 0; i < data.length; i += length) {\n            let word = '';\n            for (let j = 0; j < length; j++) {\n                word += getHangul(codes.indexOf(data[i + j]));\n            }\n            wordlist.push(word)\n        }\n    });\n\n    wordlist.sort();\n}\nloadWords();\n\n\n\nclass LangKo extends Wordlist {\n    constructor() {\n        super('ko');\n    }\n\n    getWord(index: number): string {\n        loadWords();\n        return wordlist[index];\n    }\n\n    getWordIndex(word: string): number {\n        loadWords();\n        return wordlist.indexOf(word);\n    }\n}\n\nconst langKo = new LangKo();\nregister(langKo);\n\nexport { langKo }\n","\nimport { register, Wordlist } from './wordlist';\n\nconst words = \"AbacoAbbaglioAbbinatoAbeteAbissoAbolireAbrasivoAbrogatoAccadereAccennoAccusatoAcetoneAchilleAcidoAcquaAcreAcrilicoAcrobataAcutoAdagioAddebitoAddomeAdeguatoAderireAdipeAdottareAdulareAffabileAffettoAffissoAffrantoAforismaAfosoAfricanoAgaveAgenteAgevoleAggancioAgireAgitareAgonismoAgricoloAgrumetoAguzzoAlabardaAlatoAlbatroAlberatoAlboAlbumeAlceAlcolicoAlettoneAlfaAlgebraAlianteAlibiAlimentoAllagatoAllegroAllievoAllodolaAllusivoAlmenoAlogenoAlpacaAlpestreAltalenaAlternoAlticcioAltroveAlunnoAlveoloAlzareAmalgamaAmanitaAmarenaAmbitoAmbratoAmebaAmericaAmetistaAmicoAmmassoAmmendaAmmirareAmmonitoAmoreAmpioAmpliareAmuletoAnacardoAnagrafeAnalistaAnarchiaAnatraAncaAncellaAncoraAndareAndreaAnelloAngeloAngolareAngustoAnimaAnnegareAnnidatoAnnoAnnuncioAnonimoAnticipoAnziApaticoAperturaApodeApparireAppetitoAppoggioApprodoAppuntoAprileArabicaArachideAragostaAraldicaArancioAraturaArazzoArbitroArchivioArditoArenileArgentoArgineArgutoAriaArmoniaArneseArredatoArringaArrostoArsenicoArsoArteficeArzilloAsciuttoAscoltoAsepsiAsetticoAsfaltoAsinoAsolaAspiratoAsproAssaggioAsseAssolutoAssurdoAstaAstenutoAsticeAstrattoAtavicoAteismoAtomicoAtonoAttesaAttivareAttornoAttritoAttualeAusilioAustriaAutistaAutonomoAutunnoAvanzatoAvereAvvenireAvvisoAvvolgereAzioneAzotoAzzimoAzzurroBabeleBaccanoBacinoBacoBadessaBadilataBagnatoBaitaBalconeBaldoBalenaBallataBalzanoBambinoBandireBaraondaBarbaroBarcaBaritonoBarlumeBaroccoBasilicoBassoBatostaBattutoBauleBavaBavosaBeccoBeffaBelgioBelvaBendaBenevoleBenignoBenzinaBereBerlinaBetaBibitaBiciBidoneBifidoBigaBilanciaBimboBinocoloBiologoBipedeBipolareBirbanteBirraBiscottoBisestoBisnonnoBisonteBisturiBizzarroBlandoBlattaBollitoBonificoBordoBoscoBotanicoBottinoBozzoloBraccioBradipoBramaBrancaBravuraBretellaBrevettoBrezzaBrigliaBrillanteBrindareBroccoloBrodoBronzinaBrulloBrunoBubboneBucaBudinoBuffoneBuioBulboBuonoBurloneBurrascaBussolaBustaCadettoCaducoCalamaroCalcoloCalesseCalibroCalmoCaloriaCambusaCamerataCamiciaCamminoCamolaCampaleCanapaCandelaCaneCaninoCanottoCantinaCapaceCapelloCapitoloCapogiroCapperoCapraCapsulaCarapaceCarcassaCardoCarismaCarovanaCarrettoCartolinaCasaccioCascataCasermaCasoCassoneCastelloCasualeCatastaCatenaCatrameCautoCavilloCedibileCedrataCefaloCelebreCellulareCenaCenoneCentesimoCeramicaCercareCertoCerumeCervelloCesoiaCespoCetoChelaChiaroChiccaChiedereChimeraChinaChirurgoChitarraCiaoCiclismoCifrareCignoCilindroCiottoloCircaCirrosiCitricoCittadinoCiuffoCivettaCivileClassicoClinicaCloroCoccoCodardoCodiceCoerenteCognomeCollareColmatoColoreColposoColtivatoColzaComaCometaCommandoComodoComputerComuneConcisoCondurreConfermaCongelareConiugeConnessoConoscereConsumoContinuoConvegnoCopertoCopioneCoppiaCopricapoCorazzaCordataCoricatoCorniceCorollaCorpoCorredoCorsiaCorteseCosmicoCostanteCotturaCovatoCratereCravattaCreatoCredereCremosoCrescitaCretaCricetoCrinaleCrisiCriticoCroceCronacaCrostataCrucialeCruscaCucireCuculoCuginoCullatoCupolaCuratoreCursoreCurvoCuscinoCustodeDadoDainoDalmataDamerinoDanielaDannosoDanzareDatatoDavantiDavveroDebuttoDecennioDecisoDeclinoDecolloDecretoDedicatoDefinitoDeformeDegnoDelegareDelfinoDelirioDeltaDemenzaDenotatoDentroDepositoDerapataDerivareDerogaDescrittoDesertoDesiderioDesumereDetersivoDevotoDiametroDicembreDiedroDifesoDiffusoDigerireDigitaleDiluvioDinamicoDinnanziDipintoDiplomaDipoloDiradareDireDirottoDirupoDisagioDiscretoDisfareDisgeloDispostoDistanzaDisumanoDitoDivanoDiveltoDividereDivoratoDobloneDocenteDoganaleDogmaDolceDomatoDomenicaDominareDondoloDonoDormireDoteDottoreDovutoDozzinaDragoDruidoDubbioDubitareDucaleDunaDuomoDupliceDuraturoEbanoEccessoEccoEclissiEconomiaEderaEdicolaEdileEditoriaEducareEgemoniaEgliEgoismoEgregioElaboratoElargireEleganteElencatoElettoElevareElficoElicaElmoElsaElusoEmanatoEmblemaEmessoEmiroEmotivoEmozioneEmpiricoEmuloEndemicoEnduroEnergiaEnfasiEnotecaEntrareEnzimaEpatiteEpilogoEpisodioEpocaleEppureEquatoreErarioErbaErbosoEredeEremitaErigereErmeticoEroeErosivoErranteEsagonoEsameEsanimeEsaudireEscaEsempioEsercitoEsibitoEsigenteEsistereEsitoEsofagoEsortatoEsosoEspansoEspressoEssenzaEssoEstesoEstimareEstoniaEstrosoEsultareEtilicoEtnicoEtruscoEttoEuclideoEuropaEvasoEvidenzaEvitatoEvolutoEvvivaFabbricaFaccendaFachiroFalcoFamigliaFanaleFanfaraFangoFantasmaFareFarfallaFarinosoFarmacoFasciaFastosoFasulloFaticareFatoFavolosoFebbreFecolaFedeFegatoFelpaFeltroFemminaFendereFenomenoFermentoFerroFertileFessuraFestivoFettaFeudoFiabaFiduciaFifaFiguratoFiloFinanzaFinestraFinireFioreFiscaleFisicoFiumeFlaconeFlamencoFleboFlemmaFloridoFluenteFluoroFobicoFocacciaFocosoFoderatoFoglioFolataFolcloreFolgoreFondenteFoneticoFoniaFontanaForbitoForchettaForestaFormicaFornaioForoFortezzaForzareFosfatoFossoFracassoFranaFrassinoFratelloFreccettaFrenataFrescoFrigoFrollinoFrondeFrugaleFruttaFucilataFucsiaFuggenteFulmineFulvoFumanteFumettoFumosoFuneFunzioneFuocoFurboFurgoneFuroreFusoFutileGabbianoGaffeGalateoGallinaGaloppoGamberoGammaGaranziaGarboGarofanoGarzoneGasdottoGasolioGastricoGattoGaudioGazeboGazzellaGecoGelatinaGelsoGemelloGemmatoGeneGenitoreGennaioGenotipoGergoGhepardoGhiaccioGhisaGialloGildaGineproGiocareGioielloGiornoGioveGiratoGironeGittataGiudizioGiuratoGiustoGlobuloGlutineGnomoGobbaGolfGomitoGommoneGonfioGonnaGovernoGracileGradoGraficoGrammoGrandeGrattareGravosoGraziaGrecaGreggeGrifoneGrigioGrinzaGrottaGruppoGuadagnoGuaioGuantoGuardareGufoGuidareIbernatoIconaIdenticoIdillioIdoloIdraIdricoIdrogenoIgieneIgnaroIgnoratoIlareIllesoIllogicoIlludereImballoImbevutoImboccoImbutoImmaneImmersoImmolatoImpaccoImpetoImpiegoImportoImprontaInalareInarcareInattivoIncantoIncendioInchinoIncisivoInclusoIncontroIncrocioIncuboIndagineIndiaIndoleIneditoInfattiInfilareInflittoIngaggioIngegnoIngleseIngordoIngrossoInnescoInodoreInoltrareInondatoInsanoInsettoInsiemeInsonniaInsulinaIntasatoInteroIntonacoIntuitoInumidireInvalidoInveceInvitoIperboleIpnoticoIpotesiIppicaIrideIrlandaIronicoIrrigatoIrrorareIsolatoIsotopoIstericoIstitutoIstriceItaliaIterareLabbroLabirintoLaccaLaceratoLacrimaLacunaLaddoveLagoLampoLancettaLanternaLardosoLargaLaringeLastraLatenzaLatinoLattugaLavagnaLavoroLegaleLeggeroLemboLentezzaLenzaLeoneLepreLesivoLessatoLestoLetteraleLevaLevigatoLiberoLidoLievitoLillaLimaturaLimitareLimpidoLineareLinguaLiquidoLiraLiricaLiscaLiteLitigioLivreaLocandaLodeLogicaLombareLondraLongevoLoquaceLorenzoLotoLotteriaLuceLucidatoLumacaLuminosoLungoLupoLuppoloLusingaLussoLuttoMacabroMacchinaMaceroMacinatoMadamaMagicoMagliaMagneteMagroMaiolicaMalafedeMalgradoMalintesoMalsanoMaltoMalumoreManaManciaMandorlaMangiareManifestoMannaroManovraMansardaMantideManubrioMappaMaratonaMarcireMarettaMarmoMarsupioMascheraMassaiaMastinoMaterassoMatricolaMattoneMaturoMazurcaMeandroMeccanicoMecenateMedesimoMeditareMegaMelassaMelisMelodiaMeningeMenoMensolaMercurioMerendaMerloMeschinoMeseMessereMestoloMetalloMetodoMettereMiagolareMicaMicelioMicheleMicroboMidolloMieleMiglioreMilanoMiliteMimosaMineraleMiniMinoreMirinoMirtilloMiscelaMissivaMistoMisurareMitezzaMitigareMitraMittenteMnemonicoModelloModificaModuloMoganoMogioMoleMolossoMonasteroMoncoMondinaMonetarioMonileMonotonoMonsoneMontatoMonvisoMoraMordereMorsicatoMostroMotivatoMotosegaMottoMovenzaMovimentoMozzoMuccaMucosaMuffaMughettoMugnaioMulattoMulinelloMultiploMummiaMuntoMuovereMuraleMusaMuscoloMusicaMutevoleMutoNababboNaftaNanometroNarcisoNariceNarratoNascereNastrareNaturaleNauticaNaviglioNebulosaNecrosiNegativoNegozioNemmenoNeofitaNerettoNervoNessunoNettunoNeutraleNeveNevroticoNicchiaNinfaNitidoNobileNocivoNodoNomeNominaNordicoNormaleNorvegeseNostranoNotareNotiziaNotturnoNovellaNucleoNullaNumeroNuovoNutrireNuvolaNuzialeOasiObbedireObbligoObeliscoOblioOboloObsoletoOccasioneOcchioOccidenteOccorrereOccultareOcraOculatoOdiernoOdorareOffertaOffrireOffuscatoOggettoOggiOgnunoOlandeseOlfattoOliatoOlivaOlogrammaOltreOmaggioOmbelicoOmbraOmegaOmissioneOndosoOnereOniceOnnivoroOnorevoleOntaOperatoOpinioneOppostoOracoloOrafoOrdineOrecchinoOreficeOrfanoOrganicoOrigineOrizzonteOrmaOrmeggioOrnativoOrologioOrrendoOrribileOrtensiaOrticaOrzataOrzoOsareOscurareOsmosiOspedaleOspiteOssaOssidareOstacoloOsteOtiteOtreOttagonoOttimoOttobreOvaleOvestOvinoOviparoOvocitoOvunqueOvviareOzioPacchettoPacePacificoPadellaPadronePaesePagaPaginaPalazzinaPalesarePallidoPaloPaludePandoroPannelloPaoloPaonazzoPapricaParabolaParcellaParerePargoloPariParlatoParolaPartireParvenzaParzialePassivoPasticcaPataccaPatologiaPattumePavonePeccatoPedalarePedonalePeggioPelosoPenarePendicePenisolaPennutoPenombraPensarePentolaPepePepitaPerbenePercorsoPerdonatoPerforarePergamenaPeriodoPermessoPernoPerplessoPersuasoPertugioPervasoPesatorePesistaPesoPestiferoPetaloPettinePetulantePezzoPiacerePiantaPiattinoPiccinoPicozzaPiegaPietraPifferoPigiamaPigolioPigroPilaPiliferoPillolaPilotaPimpantePinetaPinnaPinoloPioggiaPiomboPiramidePireticoPiritePirolisiPitonePizzicoPlaceboPlanarePlasmaPlatanoPlenarioPochezzaPoderosoPodismoPoesiaPoggiarePolentaPoligonoPollicePolmonitePolpettaPolsoPoltronaPolverePomicePomodoroPontePopolosoPorfidoPorosoPorporaPorrePortataPosaPositivoPossessoPostulatoPotassioPoterePranzoPrassiPraticaPreclusoPredicaPrefissoPregiatoPrelievoPremerePrenotarePreparatoPresenzaPretestoPrevalsoPrimaPrincipePrivatoProblemaProcuraProdurreProfumoProgettoProlungaPromessaPronomePropostaProrogaProtesoProvaPrudentePrugnaPruritoPsichePubblicoPudicaPugilatoPugnoPulcePulitoPulsantePuntarePupazzoPupillaPuroQuadroQualcosaQuasiQuerelaQuotaRaccoltoRaddoppioRadicaleRadunatoRafficaRagazzoRagioneRagnoRamarroRamingoRamoRandagioRantolareRapatoRapinaRappresoRasaturaRaschiatoRasenteRassegnaRastrelloRataRavvedutoRealeRecepireRecintoReclutaReconditoRecuperoRedditoRedimereRegalatoRegistroRegolaRegressoRelazioneRemareRemotoRennaReplicaReprimereReputareResaResidenteResponsoRestauroReteRetinaRetoricaRettificaRevocatoRiassuntoRibadireRibelleRibrezzoRicaricaRiccoRicevereRiciclatoRicordoRicredutoRidicoloRidurreRifasareRiflessoRiformaRifugioRigareRigettatoRighelloRilassatoRilevatoRimanereRimbalzoRimedioRimorchioRinascitaRincaroRinforzoRinnovoRinomatoRinsavitoRintoccoRinunciaRinvenireRiparatoRipetutoRipienoRiportareRipresaRipulireRisataRischioRiservaRisibileRisoRispettoRistoroRisultatoRisvoltoRitardoRitegnoRitmicoRitrovoRiunioneRivaRiversoRivincitaRivoltoRizomaRobaRoboticoRobustoRocciaRocoRodaggioRodereRoditoreRogitoRollioRomanticoRompereRonzioRosolareRospoRotanteRotondoRotulaRovescioRubizzoRubricaRugaRullinoRumineRumorosoRuoloRupeRussareRusticoSabatoSabbiareSabotatoSagomaSalassoSaldaturaSalgemmaSalivareSalmoneSaloneSaltareSalutoSalvoSapereSapidoSaporitoSaracenoSarcasmoSartoSassosoSatelliteSatiraSatolloSaturnoSavanaSavioSaziatoSbadiglioSbalzoSbancatoSbarraSbattereSbavareSbendareSbirciareSbloccatoSbocciatoSbrinareSbruffoneSbuffareScabrosoScadenzaScalaScambiareScandaloScapolaScarsoScatenareScavatoSceltoScenicoScettroSchedaSchienaSciarpaScienzaScindereScippoSciroppoScivoloSclerareScodellaScolpitoScompartoSconfortoScoprireScortaScossoneScozzeseScribaScrollareScrutinioScuderiaScultoreScuolaScuroScusareSdebitareSdoganareSeccaturaSecondoSedanoSeggiolaSegnalatoSegregatoSeguitoSelciatoSelettivoSellaSelvaggioSemaforoSembrareSemeSeminatoSempreSensoSentireSepoltoSequenzaSerataSerbatoSerenoSerioSerpenteSerraglioServireSestinaSetolaSettimanaSfaceloSfaldareSfamatoSfarzosoSfaticatoSferaSfidaSfilatoSfingeSfocatoSfoderareSfogoSfoltireSforzatoSfrattoSfruttatoSfuggitoSfumareSfusoSgabelloSgarbatoSgonfiareSgorbioSgrassatoSguardoSibiloSiccomeSierraSiglaSignoreSilenzioSillabaSimboloSimpaticoSimulatoSinfoniaSingoloSinistroSinoSintesiSinusoideSiparioSismaSistoleSituatoSlittaSlogaturaSlovenoSmarritoSmemoratoSmentitoSmeraldoSmilzoSmontareSmottatoSmussatoSnellireSnervatoSnodoSobbalzoSobrioSoccorsoSocialeSodaleSoffittoSognoSoldatoSolenneSolidoSollazzoSoloSolubileSolventeSomaticoSommaSondaSonettoSonniferoSopireSoppesoSopraSorgereSorpassoSorrisoSorsoSorteggioSorvolatoSospiroSostaSottileSpadaSpallaSpargereSpatolaSpaventoSpazzolaSpecieSpedireSpegnereSpelaturaSperanzaSpessoreSpettraleSpezzatoSpiaSpigolosoSpillatoSpinosoSpiraleSplendidoSportivoSposoSprangaSprecareSpronatoSpruzzoSpuntinoSquilloSradicareSrotolatoStabileStaccoStaffaStagnareStampatoStantioStarnutoStaseraStatutoSteloSteppaSterzoStilettoStimaStirpeStivaleStizzosoStonatoStoricoStrappoStregatoStriduloStrozzareStruttoStuccareStufoStupendoSubentroSuccosoSudoreSuggeritoSugoSultanoSuonareSuperboSupportoSurgelatoSurrogatoSussurroSuturaSvagareSvedeseSveglioSvelareSvenutoSveziaSviluppoSvistaSvizzeraSvoltaSvuotareTabaccoTabulatoTacciareTaciturnoTaleTalismanoTamponeTanninoTaraTardivoTargatoTariffaTarpareTartarugaTastoTatticoTavernaTavolataTazzaTecaTecnicoTelefonoTemerarioTempoTemutoTendoneTeneroTensioneTentacoloTeoremaTermeTerrazzoTerzettoTesiTesseratoTestatoTetroTettoiaTifareTigellaTimbroTintoTipicoTipografoTiraggioTiroTitanioTitoloTitubanteTizioTizzoneToccareTollerareToltoTombolaTomoTonfoTonsillaTopazioTopologiaToppaTorbaTornareTorroneTortoraToscanoTossireTostaturaTotanoTraboccoTracheaTrafilaTragediaTralcioTramontoTransitoTrapanoTrarreTraslocoTrattatoTraveTrecciaTremolioTrespoloTributoTrichecoTrifoglioTrilloTrinceaTrioTristezzaTrituratoTrivellaTrombaTronoTroppoTrottolaTrovareTruccatoTubaturaTuffatoTulipanoTumultoTunisiaTurbareTurchinoTutaTutelaUbicatoUccelloUccisoreUdireUditivoUffaUfficioUgualeUlisseUltimatoUmanoUmileUmorismoUncinettoUngereUnghereseUnicornoUnificatoUnisonoUnitarioUnteUovoUpupaUraganoUrgenzaUrloUsanzaUsatoUscitoUsignoloUsuraioUtensileUtilizzoUtopiaVacanteVaccinatoVagabondoVagliatoValangaValgoValicoVallettaValorosoValutareValvolaVampataVangareVanitosoVanoVantaggioVanveraVaporeVaranoVarcatoVarianteVascaVedettaVedovaVedutoVegetaleVeicoloVelcroVelinaVellutoVeloceVenatoVendemmiaVentoVeraceVerbaleVergognaVerificaVeroVerrucaVerticaleVescicaVessilloVestaleVeteranoVetrinaVetustoViandanteVibranteVicendaVichingoVicinanzaVidimareVigiliaVignetoVigoreVileVillanoViminiVincitoreViolaViperaVirgolaVirologoVirulentoViscosoVisioneVispoVissutoVisuraVitaVitelloVittimaVivandaVividoViziareVoceVogaVolatileVolereVolpeVoragineVulcanoZampognaZannaZappatoZatteraZavorraZefiroZelanteZeloZenzeroZerbinoZibettoZincoZirconeZittoZollaZoticoZuccheroZufoloZuluZuppa\";\n\nlet wordlist: Array<string> = null;\n\nfunction loadWords(): void {\n    if (wordlist != null) { return; }\n    wordlist = words.replace(/([A-Z])/g, ' $1').toLowerCase().substring(1).split(' ');\n}\n\nclass LangIt extends Wordlist {\n    constructor() {\n        super('it');\n    }\n\n    getWord(index: number): string {\n        loadWords();\n        return wordlist[index];\n    }\n\n    getWordIndex(word: string): number {\n        loadWords();\n        return wordlist.indexOf(word);\n    }\n}\n\nconst langIt = new LangIt();\nregister(langIt);\n\nexport { langIt }\n","\nimport { register, Wordlist } from './wordlist';\n\nimport { defineReadOnly } from '../utils/properties';\nimport { toUtf8String } from '../utils/utf8';\n\nconst data = \"}aE#4A=Yv&co#4N#6G=cJ&SM#66|/Z#4t&kn~46#4K~4q%b9=IR#7l,mB#7W_X2*dl}Uo~7s}Uf&Iw#9c&cw~6O&H6&wx&IG%v5=IQ~8a&Pv#47$PR&50%Ko&QM&3l#5f,D9#4L|/H&tQ;v0~6n]nN<di,AM=W5%QO&ka&ua,hM^tm=zV=JA=wR&+X]7P&NB#4J#5L|/b[dA}tJ<Do&6m&u2[U1&Kb.HM&mC=w0&MW<rY,Hq#6M}QG,13&wP}Jp]Ow%ue&Kg<HP<D9~4k~9T&I2_c6$9T#9/[C5~7O~4a=cs&O7=KK=An&l9$6U$8A&uD&QI|/Y&bg}Ux&F2#6b}E2&JN&kW&kp=U/&bb=Xl<Cj}k+~5J#6L&5z&9i}b4&Fo,ho(X0_g3~4O$Fz&QE<HN=Ww]6/%GF-Vw=tj&/D&PN#9g=YO}cL&Of&PI~5I&Ip=vU=IW#9G;0o-wU}ss&QR<BT&R9=tk$PY_dh&Pq-yh]7T,nj.Xu=EP&76=cI&Fs*Xg}z7$Gb&+I=DF,AF=cA}rL#7j=Dz&3y<Aa$52=PQ}b0(iY$Fa}oL&xV#6U=ec=WZ,xh%RY<dp#9N&Fl&44=WH*A7=sh&TB&8P=07;u+&PK}uh}J5#72)V/=xC,AB$k0&f6;1E|+5=1B,3v]6n&wR%b+&xx]7f=Ol}fl;+D^wG]7E;nB;uh^Ir&l5=JL,nS=cf=g5;u6|/Q$Gc=MH%Hg#5d%M6^86=U+$Gz,l/,ir^5y&Ba&/F-IY&FI&be%IZ#77&PW_Nu$kE(Yf&NX]7Z,Jy&FJ(Xo&Nz#/d=y7&MX<Ag}Z+;nE]Dt(iG#4D=13&Pj~4c%v8&Zo%OL&/X#4W<HR&ie~6J_1O(Y2=y5=Ad*cv_eB#6k&PX:BU#7A;uk&Ft&Fx_dD=U2;vB=U5=4F}+O&GN.HH:9s=b0%NV(jO&IH=JT}Z9=VZ<Af,Kx^4m&uJ%c6,6r;9m#+L}cf%Kh&F3~4H=vP}bu,Hz|++,1w]nv}k6;uu$jw*Kl*WX&uM[x7&Fr[m7$NO&QN]hu=JN}nR^8g#/h(ps|KC;vd}xz=V0}p6&FD$G1#7K<bG_4p~8g&cf;u4=tl}+k%5/}fz;uw<cA=u1}gU}VM=LJ=eX&+L&Pr#4U}p2:nC,2K]7H:jF&9x}uX#9O=MB<fz~8X~5m&4D&kN&u5%E/(h7(ZF&VG<de(qM|/e-Wt=3x(a+,/R]f/&ND$Ro&nU}0g=KA%kH&NK$Ke<dS}cB&IX~5g$TN]6m=Uv,Is&Py=Ef%Kz#+/%bi&+A<F4$OG&4C&FL#9V<Zk=2I_eE&6c]nw&kq$HG}y+&A8$P3}OH=XP]70%IS(AJ_gH%GZ&tY&AZ=vb~6y&/r=VI=Wv<Zi=fl=xf&eL}c8}OL=MJ=g8$F7=YT}9u=0+^xC}JH&nL^N0~4T]K2,Cy%OC#6s;vG(AC^xe^cG&MF}Br#9P;wD-7h$O/&xA}Fn^PC]6i]7G&8V$Qs;vl(TB~73~4l<mW&6V=2y&uY&+3)aP}XF;LP&kx$wU=t7;uy<FN&lz)7E=Oo*Y+;wI}9q}le;J6&Ri&4t&Qr#8B=cb&vG=J5|Ql(h5<Yy~4+}QD,Lx=wn%K/&RK=dO&Pw,Q9=co%4u;9u}g0@6a^4I%b0=zo|/c&tX=dQ=OS#+b=yz_AB&wB&Pm=W9$HP_gR=62=AO=ti=hI,oA&jr&dH=tm&b6$P2(x8=zi;nG~7F;05]0n[Ix&3m}rg=Xp=cd&uz]7t;97=cN;vV<jf&FF&F1=6Q&Ik*Kk&P4,2z=fQ]7D&3u,H0=d/}Uw<ZN<7R}Kv;0f$H7,MD]7n$F0#88~9Z%da=by;+T#/u=VF&fO&kr^kf<AB]sU,I5$Ng&Pz;0i&QD&vM=Yl:BM;nJ_xJ]U7&Kf&30,3f|Z9*dC)je_jA&Q4&Kp$NH(Yz#6S&Id%Ib=KX,AD=KV%dP}tW&Pk^+E_Ni=cq,3R}VZ(Si=b+}rv;0j}rZ]uA,/w(Sx&Jv$w9&4d&wE,NJ$Gy=J/]Ls#7k<ZQ<Y/&uj]Ov$PM;v3,2F&+u:up=On&3e,Jv;90=J+&Qm]6q}bK#+d~8Y(h2]hA;99&AS=I/}qB&dQ}yJ-VM}Vl&ui,iB&G3|Dc]7d=eQ%dX%JC_1L~4d^NP;vJ&/1)ZI#7N]9X[bQ&PL=0L(UZ,Lm&kc&IR}n7(iR<AQ<dg=33=vN}ft}au]7I,Ba=x9=dR~6R&Tq=Xi,3d$Nr&Bc}DI&ku&vf]Dn,/F&iD,Ll&Nw=0y&I7=Ls=/A&tU=Qe}Ua&uk&+F=g4=gh=Vj#+1&Qn}Uy*44#5F,Pc&Rz*Xn=oh=5W;0n_Nf(iE<Y7=vr=Zu]oz#5Z%mI=kN=Bv_Jp(T2;vt_Ml<FS&uI=L/&6P]64$M7}86<bo%QX(SI%IY&VK=Al&Ux;vv;ut*E/%uh<ZE|O3,M2(yc]yu=Wk&tp:Ex}hr,Cl&WE)+Z=8U}I2_4Q,hA_si=iw=OM=tM=yZ%Ia=U7;wT}b+;uo=Za}yS!5x}HD}fb#5O_dA;Nv%uB(yB;01(Sf}Fk;v7}Pt#8v<mZ#7L,/r&Pl~4w&f5=Ph$Fw_LF&8m,bL=yJ&BH}p/*Jn}tU~5Q;wB(h6]Df]8p^+B;E4&Wc=d+;Ea&bw$8C&FN,DM=Yf}mP~5w=fT#6V=mC=Fi=AV}jB&AN}lW}aH#/D)dZ;hl;vE}/7,CJ;31&w8,hj%u9_Js=jJ&4M~8k=TN&eC}nL&uc-wi&lX}dj=Mv=e2#6u=cr$uq$6G]8W}Jb:nm=Yg<b3(UA;vX&6n&xF=KT,jC,De&R8&oY=Zv&oB]7/=Z2&Oa}bf,hh(4h^tZ&72&Nx;D2&xL~5h~40)ZG)h+=OJ&RA]Bv$yB=Oq=df,AQ%Jn}OJ;11,3z&Tl&tj;v+^Hv,Dh(id=s+]7N&N3)9Q~8f,S4=uW=w4&uX,LX&3d]CJ&yp&8x<b2_do&lP=y/<cy_dG=Oi=7R(VH(lt_1T,Iq_AA;12^6T%k6#8K[B1{oO<AU[Bt;1b$9S&Ps<8T=St{bY,jB(Zp&63&Uv$9V,PM]6v&Af}zW[bW_oq}sm}nB&Kq&gC&ff_eq_2m&5F&TI}rf}Gf;Zr_z9;ER&jk}iz_sn<BN~+n&vo=Vi%97|ZR=Wc,WE&6t]6z%85(ly#84=KY)6m_5/=aX,N3}Tm&he&6K]tR_B2-I3;u/&hU&lH<AP=iB&IA=XL;/5&Nh=wv<BH#79=vS=zl<AA=0X_RG}Bw&9p$NW,AX&kP_Lp&/Z(Tc]Mu}hs#6I}5B&cI<bq&H9#6m=K9}vH(Y1(Y0#4B&w6,/9&gG<bE,/O=zb}I4_l8<B/;wL%Qo<HO[Mq=XX}0v&BP&F4(mG}0i}nm,EC=9u{I3,xG&/9=JY*DK&hR)BX=EI=cx=b/{6k}yX%A+&wa}Xb=la;wi^lL;0t}jo&Qb=xg=XB}iO<qo{bR=NV&8f=a0&Jy;0v=uK)HK;vN#6h&jB(h/%ud&NI%wY.X7=Pt}Cu-uL&Gs_hl%mH,tm]78=Lb^Q0#7Y=1u<Bt&+Q=Co_RH,w3;1e}ux<aU;ui}U3&Q5%bt]63&UQ|0l&uL}O7&3o,AV&dm|Nj(Xt*5+(Uu&Hh(p7(UF=VR=Bp^Jl&Hd[ix)9/=Iq]C8<67]66}mB%6f}bb}JI]8T$HA}db=YM&pa=2J}tS&Y0=PS&y4=cX$6E,hX,XP&nR;04,FQ&l0&Vm_Dv#5Y~8Z=Bi%MA]6x=JO:+p,Az&9q,Hj~6/}SD=K1:EJ}nA;Qo#/E]9R,Ie&6X%W3]61&v4=xX_MC=0q;06(Xq=fs}IG}Dv=0l}o7$iZ;9v&LH&DP-7a&OY,SZ,Kz,Cv&dh=fx|Nh,F/~7q=XF&w+;9n&Gw;0h}Z7<7O&JK(S7&LS<AD<ac=wo<Dt&zw%4B=4v#8P;9o~6p*vV=Tm,Or&I6=1q}nY=P0=gq&Bl&Uu,Ch%yb}UY=zh}dh}rl(T4_xk(YA#8R*xH,IN}Jn]7V}C4&Ty}j3]7p=cL=3h&wW%Qv<Z3=f0&RI&+S(ic_zq}oN&/Y=z1;Td=LW=0e=OI(Vc,+b^ju(UL;0r:Za%8v=Rp=zw&58&73&wK}qX]6y&8E)a2}WR=wP^ur&nQ<cH}Re=Aq&wk}Q0&+q=PP,Gc|/d^k5,Fw]8Y}Pg]p3=ju=ed}r5_yf&Cs]7z$/G<Cm&Jp&54_1G_gP_Ll}JZ;0u]k8_7k(Sg]65{9i=LN&Sx&WK,iW&fD&Lk{9a}Em-9c#8N&io=sy]8d&nT&IK(lx#7/$lW(Td<s8~49,3o<7Y=MW(T+_Jr&Wd,iL}Ct=xh&5V;v4&8n%Kx=iF&l2_0B{B+,If(J0,Lv;u8=Kx-vB=HC&vS=Z6&fU&vE^xK;3D=4h=MR#45:Jw;0d}iw=LU}I5=I0]gB*im,K9}GU,1k_4U&Tt=Vs(iX&lU(TF#7y,ZO}oA&m5#5P}PN}Uz=hM<B1&FB<aG,e6~7T<tP(UQ_ZT=wu&F8)aQ]iN,1r_Lo&/g:CD}84{J1_Ki&Na&3n$jz&FE=dc;uv;va}in}ll=fv(h1&3h}fp=Cy}BM(+E~8m}lo%v7=hC(T6$cj=BQ=Bw(DR,2j=Ks,NS|F+;00=fU=70}Mb(YU;+G&m7&hr=Sk%Co]t+(X5_Jw}0r}gC(AS-IP&QK<Z2#8Q$WC]WX}T2&pG_Ka,HC=R4&/N;Z+;ch(C7,D4$3p_Mk&B2$8D=n9%Ky#5z(CT&QJ#7B]DC]gW}nf~5M;Iw#80}Tc_1F#4Z-aC}Hl=ph=fz,/3=aW}JM}nn;DG;vm}wn,4P}T3;wx&RG$u+}zK=0b;+J_Ek{re<aZ=AS}yY#5D]7q,Cp}xN=VP*2C}GZ}aG~+m_Cs=OY#6r]6g<GS}LC(UB=3A=Bo}Jy<c4}Is;1P<AG}Op<Z1}ld}nS=1Z,yM&95&98=CJ(4t:2L$Hk=Zo}Vc;+I}np&N1}9y=iv}CO*7p=jL)px]tb^zh&GS&Vl%v/;vR=14=zJ&49|/f]hF}WG;03=8P}o/&Gg&rp;DB,Kv}Ji&Pb;aA^ll(4j%yt}+K$Ht#4y&hY]7Y<F1,eN}bG(Uh%6Z]t5%G7;+F_RE;it}tL=LS&Da=Xx(S+(4f=8G=yI}cJ}WP=37=jS}pX}hd)fp<A8=Jt~+o$HJ=M6}iX=g9}CS=dv=Cj(mP%Kd,xq|+9&LD(4/=Xm&QP=Lc}LX&fL;+K=Op(lu=Qs.qC:+e&L+=Jj#8w;SL]7S(b+#4I=c1&nG_Lf&uH;+R)ZV<bV%B/,TE&0H&Jq&Ah%OF&Ss(p2,Wv&I3=Wl}Vq;1L&lJ#9b_1H=8r=b8=JH(SZ=hD=J2#7U,/U#/X~6P,FU<eL=jx,mG=hG=CE&PU=Se(qX&LY=X6=y4&tk&QQ&tf=4g&xI}W+&mZ=Dc#7w}Lg;DA;wQ_Kb(cJ=hR%yX&Yb,hw{bX_4X;EP;1W_2M}Uc=b5(YF,CM&Tp^OJ{DD]6s=vF=Yo~8q}XH}Fu%P5(SJ=Qt;MO]s8<F3&B3&8T(Ul-BS*dw&dR<87}/8]62$PZ]Lx<Au}9Q]7c=ja=KR,Go,Us&v6(qk}pG&G2=ev^GM%w4&H4]7F&dv]J6}Ew:9w=sj-ZL}Ym$+h(Ut(Um~4n=Xs(U7%eE=Qc_JR<CA#6t<Fv|/I,IS,EG<F2(Xy$/n<Fa(h9}+9_2o&N4#7X<Zq|+f_Dp=dt&na,Ca=NJ)jY=8C=YG=s6&Q+<DO}D3=xB&R1(lw;Qn<bF(Cu|/B}HV=SS&n7,10&u0]Dm%A6^4Q=WR(TD=Xo<GH,Rj(l8)bP&n/=LM&CF,F5&ml=PJ;0k=LG=tq,Rh,D6@4i=1p&+9=YC%er_Mh;nI;0q=Fw]80=xq=FM$Gv;v6&nc;wK%H2&Kj;vs,AA=YP,66}bI(qR~5U=6q~4b$Ni=K5.X3$So&Iu(p+]8G=Cf=RY(TS_O3(iH&57=fE=Dg_Do#9z#7H;FK{qd_2k%JR}en&gh_z8;Rx}9p<cN_Ne,DO;LN_7o~/p=NF=5Y}gN<ce<C1,QE]Wv=3u<BC}GK]yq}DY&u/_hj=II(pz&rC,jV&+Z}ut=NQ;Cg-SR_ZS,+o=u/;Oy_RK_QF(Fx&xP}Wr&TA,Uh&g1=yr{ax[VF$Pg(YB;Ox=Vy;+W(Sp}XV%dd&33(l/]l4#4Y}OE=6c=bw(A7&9t%wd&N/&mo,JH&Qe)fm=Ao}fu=tH\";\nconst deltaData = \"FAZDC6BALcLZCA+GBARCW8wNCcDDZ8LVFBOqqDUiou+M42TFAyERXFb7EjhP+vmBFpFrUpfDV2F7eB+eCltCHJFWLFCED+pWTojEIHFXc3aFn4F68zqjEuKidS1QBVPDEhE7NA4mhMF7oThD49ot3FgtzHFCK0acW1x8DH1EmLoIlrWFBLE+y5+NA3Cx65wJHTaEZVaK1mWAmPGxgYCdxwOjTDIt/faOEhTl1vqNsKtJCOhJWuio2g07KLZEQsFBUpNtwEByBgxFslFheFbiEPvi61msDvApxCzB6rBCzox7joYA5UdDc+Cb4FSgIabpXFAj3bjkmFAxCZE+mD/SFf/0ELecYCt3nLoxC6WEZf2tKDB4oZvrEmqFkKk7BwILA7gtYBpsTq//D4jD0F0wEB9pyQ1BD5Ba0oYHDI+sbDFhvrHXdDHfgFEIJLi5r8qercNFBgFLC4bo5ERJtamWBDFy73KCEb6M8VpmEt330ygCTK58EIIFkYgF84gtGA9Uyh3m68iVrFbWFbcbqiCYHZ9J1jeRPbL8yswhMiDbhEhdNoSwFbZrLT740ABEqgCkO8J1BLd1VhKKR4sD1yUo0z+FF59Mvg71CFbyEhbHSFBKEIKyoQNgQppq9T0KAqePu0ZFGrXOHdKJqkoTFhYvpDNyuuznrN84thJbsCoO6Cu6Xlvntvy0QYuAExQEYtTUBf3CoCqwgGFZ4u1HJFzDVwEy3cjcpV4QvsPaBC3rCGyCF23o4K3pp2gberGgFEJEHo4nHICtyKH2ZqyxhN05KBBJIQlKh/Oujv/DH32VrlqFdIFC7Fz9Ct4kaqFME0UETLprnN9kfy+kFmtQBB0+5CFu0N9Ij8l/VvJDh2oq3hT6EzjTHKFN7ZjZwoTsAZ4Exsko6Fpa6WC+sduz8jyrLpegTv2h1EBeYpLpm2czQW0KoCcS0bCVXCmuWJDBjN1nQNLdF58SFJ0h7i3pC3oEOKy/FjBklL70XvBEEIWp2yZ04xObzAWDDJG7f+DbqBEA7LyiR95j7MDVdDViz2RE5vWlBMv5e4+VfhP3aXNPhvLSynb9O2x4uFBV+3jqu6d5pCG28/sETByvmu/+IJ0L3wb4rj9DNOLBF6XPIODr4L19U9RRofAG6Nxydi8Bki8BhGJbBAJKzbJxkZSlF9Q2Cu8oKqggB9hBArwLLqEBWEtFowy8XK8bEyw9snT+BeyFk1ZCSrdmgfEwFePTgCjELBEnIbjaDDPJm36rG9pztcEzT8dGk23SBhXBB1H4z+OWze0ooFzz8pDBYFvp9j9tvFByf9y4EFdVnz026CGR5qMr7fxMHN8UUdlyJAzlTBDRC28k+L4FB8078ljyD91tUj1ocnTs8vdEf7znbzm+GIjEZnoZE5rnLL700Xc7yHfz05nWxy03vBB9YGHYOWxgMQGBCR24CVYNE1hpfKxN0zKnfJDmmMgMmBWqNbjfSyFCBWSCGCgR8yFXiHyEj+VtD1FB3FpC1zI0kFbzifiKTLm9yq5zFmur+q8FHqjoOBWsBPiDbnCC2ErunV6cJ6TygXFYHYp7MKN9RUlSIS8/xBAGYLzeqUnBF4QbsTuUkUqGs6CaiDWKWjQK9EJkjpkTmNCPYXL\";\n\nconst words: { [key: string]: Array<string> } = {\n    cn: [],\n    tw: []\n}\n\nvar codes = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\nvar style = \"~!@#$%^&*_-=[]{}|;:,.()<>?\"\n\nlet deltaOffset = 0;\nfor (var i = 0; i < 2048; i++) {\n    let s = style.indexOf(data[i * 3]);\n    let bytes = [\n        228 + (s >> 2),\n        128 + codes.indexOf(data[i * 3 + 1]),\n        128 + codes.indexOf(data[i * 3 + 2]),\n    ];\n    words.cn.push(toUtf8String(bytes));\n\n    let common = s % 4;\n    for (let i = common; i < 3; i++) {\n        bytes[i] = codes.indexOf(deltaData[deltaOffset++]) + ((i == 0) ? 228: 128);\n    }\n    words.tw.push(toUtf8String(bytes));\n}\n\nclass LangZh extends Wordlist {\n    private _country: string\n    constructor(country: string) {\n        super('zh_' + country);\n        defineReadOnly(this, '_country', country);\n    }\n\n    getWord(index: number): string {\n        return words[this._country][index];\n    }\n\n    getWordIndex(word: string): number {\n        return words[this._country].indexOf(word);\n    }\n\n    split(mnemonic: string): Array<string> {\n        mnemonic = mnemonic.replace(/(?:\\u3000| )+/g, '');\n        return mnemonic.split('');\n    }\n}\n\nconst langZhCn = new LangZh('cn');\nregister(langZhCn);\n\nconst langZhTw = new LangZh('tw');\nregister(langZhTw);\n\n//var count = 0;\n//var fs = require('fs');\n//fs.readFileSync('wordlists/lang-zh.txt').toString().split('\\x0a').forEach(function(d, i) {\n//    let word = langZhCn.getWord(i);\n//    if (d !== word) {\n//        console.log(d, word, i, toUtf8Bytes(d));\n//        count++;\n//    }\n//});\n//console.log(count);\n\n//var count = 0;\n//var fs = require('fs');\n//fs.readFileSync('wordlists/lang-zh_tw.txt').toString().split('\\x0a').forEach(function(d, i) {\n//    let word = langZhTw.getWord(i);\n//    if (d !== word) {\n//        console.log(d, word, i, toUtf8Bytes(d));\n//        count++;\n//    }\n//});\n//console.log(count);\n\nexport { langZhCn, langZhTw };\n","\nimport { Wordlist } from './wordlist';\n\nimport { langJa as ja } from './lang-ja';\nimport { langKo as ko } from './lang-ko';\nimport { langIt as it } from './lang-it';\nimport { langEn as en } from './lang-en';\nimport { langZhCn as zh_cn, langZhTw as zh_tw } from './lang-zh';\n\nconst zh: Wordlist = zh_cn;\n\nexport {\n    en, it, ja, ko, zh, zh_cn, zh_tw\n}\n","/* no shims for node */\n"]}