diff --git a/dist/Tinlake.es.js b/dist/Tinlake.es.js index 0b401ba..120f569 100644 --- a/dist/Tinlake.es.js +++ b/dist/Tinlake.es.js @@ -5,56 +5,56 @@ import url from 'url'; import buffer from 'buffer'; import crypto$1 from 'crypto'; -/*! ***************************************************************************** -Copyright (c) Microsoft Corporation. All rights reserved. -Licensed under the Apache License, Version 2.0 (the "License"); you may not use -this file except in compliance with the License. You may obtain a copy of the -License at http://www.apache.org/licenses/LICENSE-2.0 - -THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED -WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, -MERCHANTABLITY OR NON-INFRINGEMENT. - -See the Apache Version 2.0 License for specific language governing permissions -and limitations under the License. -***************************************************************************** */ - -function __awaiter(thisArg, _arguments, P, generator) { - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -} - -function __generator(thisArg, body) { - var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; - return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; - function verb(n) { return function (v) { return step([n, v]); }; } - function step(op) { - if (f) throw new TypeError("Generator is already executing."); - while (_) try { - if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [op[0] & 2, t.value]; - switch (op[0]) { - case 0: case 1: t = op; break; - case 4: _.label++; return { value: op[1], done: false }; - case 5: _.label++; y = op[1]; op = [0]; continue; - case 7: op = _.ops.pop(); _.trys.pop(); continue; - default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } - if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } - if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } - if (t[2]) _.ops.pop(); - _.trys.pop(); continue; - } - op = body.call(thisArg, _); - } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } - if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; - } +/*! ***************************************************************************** +Copyright (c) Microsoft Corporation. All rights reserved. +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at http://www.apache.org/licenses/LICENSE-2.0 + +THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED +WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, +MERCHANTABLITY OR NON-INFRINGEMENT. + +See the Apache Version 2.0 License for specific language governing permissions +and limitations under the License. +***************************************************************************** */ + +function __awaiter(thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +} + +function __generator(thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } } var methods = { @@ -5469,474 +5469,474 @@ module.exports = { "default": assign, __esModule: true }; unwrapExports(assign$1); var sha3 = createCommonjsModule(function (module) { -/** - * [js-sha3]{@link https://github.com/emn178/js-sha3} - * - * @version 0.5.5 - * @author Chen, Yi-Cyuan [emn178@gmail.com] - * @copyright Chen, Yi-Cyuan 2015-2016 - * @license MIT - */ -(function (root) { - - var NODE_JS = typeof process == 'object' && process.versions && process.versions.node; - if (NODE_JS) { - root = commonjsGlobal; - } - var COMMON_JS = !root.JS_SHA3_TEST && 'object' == 'object' && module.exports; - var HEX_CHARS = '0123456789abcdef'.split(''); - var SHAKE_PADDING = [31, 7936, 2031616, 520093696]; - var KECCAK_PADDING = [1, 256, 65536, 16777216]; - var PADDING = [6, 1536, 393216, 100663296]; - var SHIFT = [0, 8, 16, 24]; - var RC = [1, 0, 32898, 0, 32906, 2147483648, 2147516416, 2147483648, 32907, 0, 2147483649, - 0, 2147516545, 2147483648, 32777, 2147483648, 138, 0, 136, 0, 2147516425, 0, - 2147483658, 0, 2147516555, 0, 139, 2147483648, 32905, 2147483648, 32771, - 2147483648, 32770, 2147483648, 128, 2147483648, 32778, 0, 2147483658, 2147483648, - 2147516545, 2147483648, 32896, 2147483648, 2147483649, 0, 2147516424, 2147483648]; - var BITS = [224, 256, 384, 512]; - var SHAKE_BITS = [128, 256]; - var OUTPUT_TYPES = ['hex', 'buffer', 'arrayBuffer', 'array']; - - var createOutputMethod = function (bits, padding, outputType) { - return function (message) { - return new Keccak(bits, padding, bits).update(message)[outputType](); - } - }; - - var createShakeOutputMethod = function (bits, padding, outputType) { - return function (message, outputBits) { - return new Keccak(bits, padding, outputBits).update(message)[outputType](); - } - }; - - var createMethod = function (bits, padding) { - var method = createOutputMethod(bits, padding, 'hex'); - method.create = function () { - return new Keccak(bits, padding, bits); - }; - method.update = function (message) { - return method.create().update(message); - }; - for (var i = 0;i < OUTPUT_TYPES.length;++i) { - var type = OUTPUT_TYPES[i]; - method[type] = createOutputMethod(bits, padding, type); - } - return method; - }; - - var createShakeMethod = function (bits, padding) { - var method = createShakeOutputMethod(bits, padding, 'hex'); - method.create = function (outputBits) { - return new Keccak(bits, padding, outputBits); - }; - method.update = function (message, outputBits) { - return method.create(outputBits).update(message); - }; - for (var i = 0;i < OUTPUT_TYPES.length;++i) { - var type = OUTPUT_TYPES[i]; - method[type] = createShakeOutputMethod(bits, padding, type); - } - return method; - }; - - var algorithms = [ - {name: 'keccak', padding: KECCAK_PADDING, bits: BITS, createMethod: createMethod}, - {name: 'sha3', padding: PADDING, bits: BITS, createMethod: createMethod}, - {name: 'shake', padding: SHAKE_PADDING, bits: SHAKE_BITS, createMethod: createShakeMethod} - ]; - - var methods = {}; - - for (var i = 0;i < algorithms.length;++i) { - var algorithm = algorithms[i]; - var bits = algorithm.bits; - for (var j = 0;j < bits.length;++j) { - methods[algorithm.name +'_' + bits[j]] = algorithm.createMethod(bits[j], algorithm.padding); - } - } - - function Keccak(bits, padding, outputBits) { - this.blocks = []; - this.s = []; - this.padding = padding; - this.outputBits = outputBits; - this.reset = true; - this.block = 0; - this.start = 0; - this.blockCount = (1600 - (bits << 1)) >> 5; - this.byteCount = this.blockCount << 2; - this.outputBlocks = outputBits >> 5; - this.extraBytes = (outputBits & 31) >> 3; - - for (var i = 0;i < 50;++i) { - this.s[i] = 0; - } - } - Keccak.prototype.update = function (message) { - var notString = typeof message != 'string'; - if (notString && message.constructor == root.ArrayBuffer) { - message = new Uint8Array(message); - } - var length = message.length, blocks = this.blocks, byteCount = this.byteCount, - blockCount = this.blockCount, index = 0, s = this.s, i, code; - - while (index < length) { - if (this.reset) { - this.reset = false; - blocks[0] = this.block; - for (i = 1;i < blockCount + 1;++i) { - blocks[i] = 0; - } - } - if (notString) { - for (i = this.start;index < length && i < byteCount;++index) { - blocks[i >> 2] |= message[index] << SHIFT[i++ & 3]; - } - } else { - for (i = this.start;index < length && i < byteCount;++index) { - code = message.charCodeAt(index); - if (code < 0x80) { - blocks[i >> 2] |= code << SHIFT[i++ & 3]; - } else if (code < 0x800) { - blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; - } else if (code < 0xd800 || code >= 0xe000) { - blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; - } else { - code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff)); - blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; - } - } - } - this.lastByteIndex = i; - if (i >= byteCount) { - this.start = i - byteCount; - this.block = blocks[blockCount]; - for (i = 0;i < blockCount;++i) { - s[i] ^= blocks[i]; - } - f(s); - this.reset = true; - } else { - this.start = i; - } - } - return this; - }; - - Keccak.prototype.finalize = function () { - var blocks = this.blocks, i = this.lastByteIndex, blockCount = this.blockCount, s = this.s; - blocks[i >> 2] |= this.padding[i & 3]; - if (this.lastByteIndex == this.byteCount) { - blocks[0] = blocks[blockCount]; - for (i = 1;i < blockCount + 1;++i) { - blocks[i] = 0; - } - } - blocks[blockCount - 1] |= 0x80000000; - for (i = 0;i < blockCount;++i) { - s[i] ^= blocks[i]; - } - f(s); - }; - - Keccak.prototype.toString = Keccak.prototype.hex = function () { - this.finalize(); - - var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, - extraBytes = this.extraBytes, i = 0, j = 0; - var hex = '', block; - while (j < outputBlocks) { - for (i = 0;i < blockCount && j < outputBlocks;++i, ++j) { - block = s[i]; - hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F] + - HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F] + - HEX_CHARS[(block >> 20) & 0x0F] + HEX_CHARS[(block >> 16) & 0x0F] + - HEX_CHARS[(block >> 28) & 0x0F] + HEX_CHARS[(block >> 24) & 0x0F]; - } - if (j % blockCount == 0) { - f(s); - i = 0; - } - } - if (extraBytes) { - block = s[i]; - if (extraBytes > 0) { - hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F]; - } - if (extraBytes > 1) { - hex += HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F]; - } - if (extraBytes > 2) { - hex += HEX_CHARS[(block >> 20) & 0x0F] + HEX_CHARS[(block >> 16) & 0x0F]; - } - } - return hex; - }; - - Keccak.prototype.arrayBuffer = function () { - this.finalize(); - - var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, - extraBytes = this.extraBytes, i = 0, j = 0; - var bytes = this.outputBits >> 3; - var buffer; - if (extraBytes) { - buffer = new ArrayBuffer((outputBlocks + 1) << 2); - } else { - buffer = new ArrayBuffer(bytes); - } - var array = new Uint32Array(buffer); - while (j < outputBlocks) { - for (i = 0;i < blockCount && j < outputBlocks;++i, ++j) { - array[j] = s[i]; - } - if (j % blockCount == 0) { - f(s); - } - } - if (extraBytes) { - array[i] = s[i]; - buffer = buffer.slice(0, bytes); - } - return buffer; - }; - - Keccak.prototype.buffer = Keccak.prototype.arrayBuffer; - - Keccak.prototype.digest = Keccak.prototype.array = function () { - this.finalize(); - - var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, - extraBytes = this.extraBytes, i = 0, j = 0; - var array = [], offset, block; - while (j < outputBlocks) { - for (i = 0;i < blockCount && j < outputBlocks;++i, ++j) { - offset = j << 2; - block = s[i]; - array[offset] = block & 0xFF; - array[offset + 1] = (block >> 8) & 0xFF; - array[offset + 2] = (block >> 16) & 0xFF; - array[offset + 3] = (block >> 24) & 0xFF; - } - if (j % blockCount == 0) { - f(s); - } - } - if (extraBytes) { - offset = j << 2; - block = s[i]; - if (extraBytes > 0) { - array[offset] = block & 0xFF; - } - if (extraBytes > 1) { - array[offset + 1] = (block >> 8) & 0xFF; - } - if (extraBytes > 2) { - array[offset + 2] = (block >> 16) & 0xFF; - } - } - return array; - }; - - var f = function (s) { - var h, l, n, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, - b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16, b17, - b18, b19, b20, b21, b22, b23, b24, b25, b26, b27, b28, b29, b30, b31, b32, b33, - b34, b35, b36, b37, b38, b39, b40, b41, b42, b43, b44, b45, b46, b47, b48, b49; - for (n = 0;n < 48;n += 2) { - c0 = s[0] ^ s[10] ^ s[20] ^ s[30] ^ s[40]; - c1 = s[1] ^ s[11] ^ s[21] ^ s[31] ^ s[41]; - c2 = s[2] ^ s[12] ^ s[22] ^ s[32] ^ s[42]; - c3 = s[3] ^ s[13] ^ s[23] ^ s[33] ^ s[43]; - c4 = s[4] ^ s[14] ^ s[24] ^ s[34] ^ s[44]; - c5 = s[5] ^ s[15] ^ s[25] ^ s[35] ^ s[45]; - c6 = s[6] ^ s[16] ^ s[26] ^ s[36] ^ s[46]; - c7 = s[7] ^ s[17] ^ s[27] ^ s[37] ^ s[47]; - c8 = s[8] ^ s[18] ^ s[28] ^ s[38] ^ s[48]; - c9 = s[9] ^ s[19] ^ s[29] ^ s[39] ^ s[49]; - - h = c8 ^ ((c2 << 1) | (c3 >>> 31)); - l = c9 ^ ((c3 << 1) | (c2 >>> 31)); - s[0] ^= h; - s[1] ^= l; - s[10] ^= h; - s[11] ^= l; - s[20] ^= h; - s[21] ^= l; - s[30] ^= h; - s[31] ^= l; - s[40] ^= h; - s[41] ^= l; - h = c0 ^ ((c4 << 1) | (c5 >>> 31)); - l = c1 ^ ((c5 << 1) | (c4 >>> 31)); - s[2] ^= h; - s[3] ^= l; - s[12] ^= h; - s[13] ^= l; - s[22] ^= h; - s[23] ^= l; - s[32] ^= h; - s[33] ^= l; - s[42] ^= h; - s[43] ^= l; - h = c2 ^ ((c6 << 1) | (c7 >>> 31)); - l = c3 ^ ((c7 << 1) | (c6 >>> 31)); - s[4] ^= h; - s[5] ^= l; - s[14] ^= h; - s[15] ^= l; - s[24] ^= h; - s[25] ^= l; - s[34] ^= h; - s[35] ^= l; - s[44] ^= h; - s[45] ^= l; - h = c4 ^ ((c8 << 1) | (c9 >>> 31)); - l = c5 ^ ((c9 << 1) | (c8 >>> 31)); - s[6] ^= h; - s[7] ^= l; - s[16] ^= h; - s[17] ^= l; - s[26] ^= h; - s[27] ^= l; - s[36] ^= h; - s[37] ^= l; - s[46] ^= h; - s[47] ^= l; - h = c6 ^ ((c0 << 1) | (c1 >>> 31)); - l = c7 ^ ((c1 << 1) | (c0 >>> 31)); - s[8] ^= h; - s[9] ^= l; - s[18] ^= h; - s[19] ^= l; - s[28] ^= h; - s[29] ^= l; - s[38] ^= h; - s[39] ^= l; - s[48] ^= h; - s[49] ^= l; - - b0 = s[0]; - b1 = s[1]; - b32 = (s[11] << 4) | (s[10] >>> 28); - b33 = (s[10] << 4) | (s[11] >>> 28); - b14 = (s[20] << 3) | (s[21] >>> 29); - b15 = (s[21] << 3) | (s[20] >>> 29); - b46 = (s[31] << 9) | (s[30] >>> 23); - b47 = (s[30] << 9) | (s[31] >>> 23); - b28 = (s[40] << 18) | (s[41] >>> 14); - b29 = (s[41] << 18) | (s[40] >>> 14); - b20 = (s[2] << 1) | (s[3] >>> 31); - b21 = (s[3] << 1) | (s[2] >>> 31); - b2 = (s[13] << 12) | (s[12] >>> 20); - b3 = (s[12] << 12) | (s[13] >>> 20); - b34 = (s[22] << 10) | (s[23] >>> 22); - b35 = (s[23] << 10) | (s[22] >>> 22); - b16 = (s[33] << 13) | (s[32] >>> 19); - b17 = (s[32] << 13) | (s[33] >>> 19); - b48 = (s[42] << 2) | (s[43] >>> 30); - b49 = (s[43] << 2) | (s[42] >>> 30); - b40 = (s[5] << 30) | (s[4] >>> 2); - b41 = (s[4] << 30) | (s[5] >>> 2); - b22 = (s[14] << 6) | (s[15] >>> 26); - b23 = (s[15] << 6) | (s[14] >>> 26); - b4 = (s[25] << 11) | (s[24] >>> 21); - b5 = (s[24] << 11) | (s[25] >>> 21); - b36 = (s[34] << 15) | (s[35] >>> 17); - b37 = (s[35] << 15) | (s[34] >>> 17); - b18 = (s[45] << 29) | (s[44] >>> 3); - b19 = (s[44] << 29) | (s[45] >>> 3); - b10 = (s[6] << 28) | (s[7] >>> 4); - b11 = (s[7] << 28) | (s[6] >>> 4); - b42 = (s[17] << 23) | (s[16] >>> 9); - b43 = (s[16] << 23) | (s[17] >>> 9); - b24 = (s[26] << 25) | (s[27] >>> 7); - b25 = (s[27] << 25) | (s[26] >>> 7); - b6 = (s[36] << 21) | (s[37] >>> 11); - b7 = (s[37] << 21) | (s[36] >>> 11); - b38 = (s[47] << 24) | (s[46] >>> 8); - b39 = (s[46] << 24) | (s[47] >>> 8); - b30 = (s[8] << 27) | (s[9] >>> 5); - b31 = (s[9] << 27) | (s[8] >>> 5); - b12 = (s[18] << 20) | (s[19] >>> 12); - b13 = (s[19] << 20) | (s[18] >>> 12); - b44 = (s[29] << 7) | (s[28] >>> 25); - b45 = (s[28] << 7) | (s[29] >>> 25); - b26 = (s[38] << 8) | (s[39] >>> 24); - b27 = (s[39] << 8) | (s[38] >>> 24); - b8 = (s[48] << 14) | (s[49] >>> 18); - b9 = (s[49] << 14) | (s[48] >>> 18); - - s[0] = b0 ^ (~b2 & b4); - s[1] = b1 ^ (~b3 & b5); - s[10] = b10 ^ (~b12 & b14); - s[11] = b11 ^ (~b13 & b15); - s[20] = b20 ^ (~b22 & b24); - s[21] = b21 ^ (~b23 & b25); - s[30] = b30 ^ (~b32 & b34); - s[31] = b31 ^ (~b33 & b35); - s[40] = b40 ^ (~b42 & b44); - s[41] = b41 ^ (~b43 & b45); - s[2] = b2 ^ (~b4 & b6); - s[3] = b3 ^ (~b5 & b7); - s[12] = b12 ^ (~b14 & b16); - s[13] = b13 ^ (~b15 & b17); - s[22] = b22 ^ (~b24 & b26); - s[23] = b23 ^ (~b25 & b27); - s[32] = b32 ^ (~b34 & b36); - s[33] = b33 ^ (~b35 & b37); - s[42] = b42 ^ (~b44 & b46); - s[43] = b43 ^ (~b45 & b47); - s[4] = b4 ^ (~b6 & b8); - s[5] = b5 ^ (~b7 & b9); - s[14] = b14 ^ (~b16 & b18); - s[15] = b15 ^ (~b17 & b19); - s[24] = b24 ^ (~b26 & b28); - s[25] = b25 ^ (~b27 & b29); - s[34] = b34 ^ (~b36 & b38); - s[35] = b35 ^ (~b37 & b39); - s[44] = b44 ^ (~b46 & b48); - s[45] = b45 ^ (~b47 & b49); - s[6] = b6 ^ (~b8 & b0); - s[7] = b7 ^ (~b9 & b1); - s[16] = b16 ^ (~b18 & b10); - s[17] = b17 ^ (~b19 & b11); - s[26] = b26 ^ (~b28 & b20); - s[27] = b27 ^ (~b29 & b21); - s[36] = b36 ^ (~b38 & b30); - s[37] = b37 ^ (~b39 & b31); - s[46] = b46 ^ (~b48 & b40); - s[47] = b47 ^ (~b49 & b41); - s[8] = b8 ^ (~b0 & b2); - s[9] = b9 ^ (~b1 & b3); - s[18] = b18 ^ (~b10 & b12); - s[19] = b19 ^ (~b11 & b13); - s[28] = b28 ^ (~b20 & b22); - s[29] = b29 ^ (~b21 & b23); - s[38] = b38 ^ (~b30 & b32); - s[39] = b39 ^ (~b31 & b33); - s[48] = b48 ^ (~b40 & b42); - s[49] = b49 ^ (~b41 & b43); - - s[0] ^= RC[n]; - s[1] ^= RC[n + 1]; - } - }; - - if (COMMON_JS) { - module.exports = methods; - } else if (root) { - for (var key in methods) { - root[key] = methods[key]; - } - } +/** + * [js-sha3]{@link https://github.com/emn178/js-sha3} + * + * @version 0.5.5 + * @author Chen, Yi-Cyuan [emn178@gmail.com] + * @copyright Chen, Yi-Cyuan 2015-2016 + * @license MIT + */ +(function (root) { + + var NODE_JS = typeof process == 'object' && process.versions && process.versions.node; + if (NODE_JS) { + root = commonjsGlobal; + } + var COMMON_JS = !root.JS_SHA3_TEST && 'object' == 'object' && module.exports; + var HEX_CHARS = '0123456789abcdef'.split(''); + var SHAKE_PADDING = [31, 7936, 2031616, 520093696]; + var KECCAK_PADDING = [1, 256, 65536, 16777216]; + var PADDING = [6, 1536, 393216, 100663296]; + var SHIFT = [0, 8, 16, 24]; + var RC = [1, 0, 32898, 0, 32906, 2147483648, 2147516416, 2147483648, 32907, 0, 2147483649, + 0, 2147516545, 2147483648, 32777, 2147483648, 138, 0, 136, 0, 2147516425, 0, + 2147483658, 0, 2147516555, 0, 139, 2147483648, 32905, 2147483648, 32771, + 2147483648, 32770, 2147483648, 128, 2147483648, 32778, 0, 2147483658, 2147483648, + 2147516545, 2147483648, 32896, 2147483648, 2147483649, 0, 2147516424, 2147483648]; + var BITS = [224, 256, 384, 512]; + var SHAKE_BITS = [128, 256]; + var OUTPUT_TYPES = ['hex', 'buffer', 'arrayBuffer', 'array']; + + var createOutputMethod = function (bits, padding, outputType) { + return function (message) { + return new Keccak(bits, padding, bits).update(message)[outputType](); + } + }; + + var createShakeOutputMethod = function (bits, padding, outputType) { + return function (message, outputBits) { + return new Keccak(bits, padding, outputBits).update(message)[outputType](); + } + }; + + var createMethod = function (bits, padding) { + var method = createOutputMethod(bits, padding, 'hex'); + method.create = function () { + return new Keccak(bits, padding, bits); + }; + method.update = function (message) { + return method.create().update(message); + }; + for (var i = 0;i < OUTPUT_TYPES.length;++i) { + var type = OUTPUT_TYPES[i]; + method[type] = createOutputMethod(bits, padding, type); + } + return method; + }; + + var createShakeMethod = function (bits, padding) { + var method = createShakeOutputMethod(bits, padding, 'hex'); + method.create = function (outputBits) { + return new Keccak(bits, padding, outputBits); + }; + method.update = function (message, outputBits) { + return method.create(outputBits).update(message); + }; + for (var i = 0;i < OUTPUT_TYPES.length;++i) { + var type = OUTPUT_TYPES[i]; + method[type] = createShakeOutputMethod(bits, padding, type); + } + return method; + }; + + var algorithms = [ + {name: 'keccak', padding: KECCAK_PADDING, bits: BITS, createMethod: createMethod}, + {name: 'sha3', padding: PADDING, bits: BITS, createMethod: createMethod}, + {name: 'shake', padding: SHAKE_PADDING, bits: SHAKE_BITS, createMethod: createShakeMethod} + ]; + + var methods = {}; + + for (var i = 0;i < algorithms.length;++i) { + var algorithm = algorithms[i]; + var bits = algorithm.bits; + for (var j = 0;j < bits.length;++j) { + methods[algorithm.name +'_' + bits[j]] = algorithm.createMethod(bits[j], algorithm.padding); + } + } + + function Keccak(bits, padding, outputBits) { + this.blocks = []; + this.s = []; + this.padding = padding; + this.outputBits = outputBits; + this.reset = true; + this.block = 0; + this.start = 0; + this.blockCount = (1600 - (bits << 1)) >> 5; + this.byteCount = this.blockCount << 2; + this.outputBlocks = outputBits >> 5; + this.extraBytes = (outputBits & 31) >> 3; + + for (var i = 0;i < 50;++i) { + this.s[i] = 0; + } + } + Keccak.prototype.update = function (message) { + var notString = typeof message != 'string'; + if (notString && message.constructor == root.ArrayBuffer) { + message = new Uint8Array(message); + } + var length = message.length, blocks = this.blocks, byteCount = this.byteCount, + blockCount = this.blockCount, index = 0, s = this.s, i, code; + + while (index < length) { + if (this.reset) { + this.reset = false; + blocks[0] = this.block; + for (i = 1;i < blockCount + 1;++i) { + blocks[i] = 0; + } + } + if (notString) { + for (i = this.start;index < length && i < byteCount;++index) { + blocks[i >> 2] |= message[index] << SHIFT[i++ & 3]; + } + } else { + for (i = this.start;index < length && i < byteCount;++index) { + code = message.charCodeAt(index); + if (code < 0x80) { + blocks[i >> 2] |= code << SHIFT[i++ & 3]; + } else if (code < 0x800) { + blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; + } else if (code < 0xd800 || code >= 0xe000) { + blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; + } else { + code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff)); + blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; + } + } + } + this.lastByteIndex = i; + if (i >= byteCount) { + this.start = i - byteCount; + this.block = blocks[blockCount]; + for (i = 0;i < blockCount;++i) { + s[i] ^= blocks[i]; + } + f(s); + this.reset = true; + } else { + this.start = i; + } + } + return this; + }; + + Keccak.prototype.finalize = function () { + var blocks = this.blocks, i = this.lastByteIndex, blockCount = this.blockCount, s = this.s; + blocks[i >> 2] |= this.padding[i & 3]; + if (this.lastByteIndex == this.byteCount) { + blocks[0] = blocks[blockCount]; + for (i = 1;i < blockCount + 1;++i) { + blocks[i] = 0; + } + } + blocks[blockCount - 1] |= 0x80000000; + for (i = 0;i < blockCount;++i) { + s[i] ^= blocks[i]; + } + f(s); + }; + + Keccak.prototype.toString = Keccak.prototype.hex = function () { + this.finalize(); + + var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, + extraBytes = this.extraBytes, i = 0, j = 0; + var hex = '', block; + while (j < outputBlocks) { + for (i = 0;i < blockCount && j < outputBlocks;++i, ++j) { + block = s[i]; + hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F] + + HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F] + + HEX_CHARS[(block >> 20) & 0x0F] + HEX_CHARS[(block >> 16) & 0x0F] + + HEX_CHARS[(block >> 28) & 0x0F] + HEX_CHARS[(block >> 24) & 0x0F]; + } + if (j % blockCount == 0) { + f(s); + i = 0; + } + } + if (extraBytes) { + block = s[i]; + if (extraBytes > 0) { + hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F]; + } + if (extraBytes > 1) { + hex += HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F]; + } + if (extraBytes > 2) { + hex += HEX_CHARS[(block >> 20) & 0x0F] + HEX_CHARS[(block >> 16) & 0x0F]; + } + } + return hex; + }; + + Keccak.prototype.arrayBuffer = function () { + this.finalize(); + + var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, + extraBytes = this.extraBytes, i = 0, j = 0; + var bytes = this.outputBits >> 3; + var buffer; + if (extraBytes) { + buffer = new ArrayBuffer((outputBlocks + 1) << 2); + } else { + buffer = new ArrayBuffer(bytes); + } + var array = new Uint32Array(buffer); + while (j < outputBlocks) { + for (i = 0;i < blockCount && j < outputBlocks;++i, ++j) { + array[j] = s[i]; + } + if (j % blockCount == 0) { + f(s); + } + } + if (extraBytes) { + array[i] = s[i]; + buffer = buffer.slice(0, bytes); + } + return buffer; + }; + + Keccak.prototype.buffer = Keccak.prototype.arrayBuffer; + + Keccak.prototype.digest = Keccak.prototype.array = function () { + this.finalize(); + + var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, + extraBytes = this.extraBytes, i = 0, j = 0; + var array = [], offset, block; + while (j < outputBlocks) { + for (i = 0;i < blockCount && j < outputBlocks;++i, ++j) { + offset = j << 2; + block = s[i]; + array[offset] = block & 0xFF; + array[offset + 1] = (block >> 8) & 0xFF; + array[offset + 2] = (block >> 16) & 0xFF; + array[offset + 3] = (block >> 24) & 0xFF; + } + if (j % blockCount == 0) { + f(s); + } + } + if (extraBytes) { + offset = j << 2; + block = s[i]; + if (extraBytes > 0) { + array[offset] = block & 0xFF; + } + if (extraBytes > 1) { + array[offset + 1] = (block >> 8) & 0xFF; + } + if (extraBytes > 2) { + array[offset + 2] = (block >> 16) & 0xFF; + } + } + return array; + }; + + var f = function (s) { + var h, l, n, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, + b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16, b17, + b18, b19, b20, b21, b22, b23, b24, b25, b26, b27, b28, b29, b30, b31, b32, b33, + b34, b35, b36, b37, b38, b39, b40, b41, b42, b43, b44, b45, b46, b47, b48, b49; + for (n = 0;n < 48;n += 2) { + c0 = s[0] ^ s[10] ^ s[20] ^ s[30] ^ s[40]; + c1 = s[1] ^ s[11] ^ s[21] ^ s[31] ^ s[41]; + c2 = s[2] ^ s[12] ^ s[22] ^ s[32] ^ s[42]; + c3 = s[3] ^ s[13] ^ s[23] ^ s[33] ^ s[43]; + c4 = s[4] ^ s[14] ^ s[24] ^ s[34] ^ s[44]; + c5 = s[5] ^ s[15] ^ s[25] ^ s[35] ^ s[45]; + c6 = s[6] ^ s[16] ^ s[26] ^ s[36] ^ s[46]; + c7 = s[7] ^ s[17] ^ s[27] ^ s[37] ^ s[47]; + c8 = s[8] ^ s[18] ^ s[28] ^ s[38] ^ s[48]; + c9 = s[9] ^ s[19] ^ s[29] ^ s[39] ^ s[49]; + + h = c8 ^ ((c2 << 1) | (c3 >>> 31)); + l = c9 ^ ((c3 << 1) | (c2 >>> 31)); + s[0] ^= h; + s[1] ^= l; + s[10] ^= h; + s[11] ^= l; + s[20] ^= h; + s[21] ^= l; + s[30] ^= h; + s[31] ^= l; + s[40] ^= h; + s[41] ^= l; + h = c0 ^ ((c4 << 1) | (c5 >>> 31)); + l = c1 ^ ((c5 << 1) | (c4 >>> 31)); + s[2] ^= h; + s[3] ^= l; + s[12] ^= h; + s[13] ^= l; + s[22] ^= h; + s[23] ^= l; + s[32] ^= h; + s[33] ^= l; + s[42] ^= h; + s[43] ^= l; + h = c2 ^ ((c6 << 1) | (c7 >>> 31)); + l = c3 ^ ((c7 << 1) | (c6 >>> 31)); + s[4] ^= h; + s[5] ^= l; + s[14] ^= h; + s[15] ^= l; + s[24] ^= h; + s[25] ^= l; + s[34] ^= h; + s[35] ^= l; + s[44] ^= h; + s[45] ^= l; + h = c4 ^ ((c8 << 1) | (c9 >>> 31)); + l = c5 ^ ((c9 << 1) | (c8 >>> 31)); + s[6] ^= h; + s[7] ^= l; + s[16] ^= h; + s[17] ^= l; + s[26] ^= h; + s[27] ^= l; + s[36] ^= h; + s[37] ^= l; + s[46] ^= h; + s[47] ^= l; + h = c6 ^ ((c0 << 1) | (c1 >>> 31)); + l = c7 ^ ((c1 << 1) | (c0 >>> 31)); + s[8] ^= h; + s[9] ^= l; + s[18] ^= h; + s[19] ^= l; + s[28] ^= h; + s[29] ^= l; + s[38] ^= h; + s[39] ^= l; + s[48] ^= h; + s[49] ^= l; + + b0 = s[0]; + b1 = s[1]; + b32 = (s[11] << 4) | (s[10] >>> 28); + b33 = (s[10] << 4) | (s[11] >>> 28); + b14 = (s[20] << 3) | (s[21] >>> 29); + b15 = (s[21] << 3) | (s[20] >>> 29); + b46 = (s[31] << 9) | (s[30] >>> 23); + b47 = (s[30] << 9) | (s[31] >>> 23); + b28 = (s[40] << 18) | (s[41] >>> 14); + b29 = (s[41] << 18) | (s[40] >>> 14); + b20 = (s[2] << 1) | (s[3] >>> 31); + b21 = (s[3] << 1) | (s[2] >>> 31); + b2 = (s[13] << 12) | (s[12] >>> 20); + b3 = (s[12] << 12) | (s[13] >>> 20); + b34 = (s[22] << 10) | (s[23] >>> 22); + b35 = (s[23] << 10) | (s[22] >>> 22); + b16 = (s[33] << 13) | (s[32] >>> 19); + b17 = (s[32] << 13) | (s[33] >>> 19); + b48 = (s[42] << 2) | (s[43] >>> 30); + b49 = (s[43] << 2) | (s[42] >>> 30); + b40 = (s[5] << 30) | (s[4] >>> 2); + b41 = (s[4] << 30) | (s[5] >>> 2); + b22 = (s[14] << 6) | (s[15] >>> 26); + b23 = (s[15] << 6) | (s[14] >>> 26); + b4 = (s[25] << 11) | (s[24] >>> 21); + b5 = (s[24] << 11) | (s[25] >>> 21); + b36 = (s[34] << 15) | (s[35] >>> 17); + b37 = (s[35] << 15) | (s[34] >>> 17); + b18 = (s[45] << 29) | (s[44] >>> 3); + b19 = (s[44] << 29) | (s[45] >>> 3); + b10 = (s[6] << 28) | (s[7] >>> 4); + b11 = (s[7] << 28) | (s[6] >>> 4); + b42 = (s[17] << 23) | (s[16] >>> 9); + b43 = (s[16] << 23) | (s[17] >>> 9); + b24 = (s[26] << 25) | (s[27] >>> 7); + b25 = (s[27] << 25) | (s[26] >>> 7); + b6 = (s[36] << 21) | (s[37] >>> 11); + b7 = (s[37] << 21) | (s[36] >>> 11); + b38 = (s[47] << 24) | (s[46] >>> 8); + b39 = (s[46] << 24) | (s[47] >>> 8); + b30 = (s[8] << 27) | (s[9] >>> 5); + b31 = (s[9] << 27) | (s[8] >>> 5); + b12 = (s[18] << 20) | (s[19] >>> 12); + b13 = (s[19] << 20) | (s[18] >>> 12); + b44 = (s[29] << 7) | (s[28] >>> 25); + b45 = (s[28] << 7) | (s[29] >>> 25); + b26 = (s[38] << 8) | (s[39] >>> 24); + b27 = (s[39] << 8) | (s[38] >>> 24); + b8 = (s[48] << 14) | (s[49] >>> 18); + b9 = (s[49] << 14) | (s[48] >>> 18); + + s[0] = b0 ^ (~b2 & b4); + s[1] = b1 ^ (~b3 & b5); + s[10] = b10 ^ (~b12 & b14); + s[11] = b11 ^ (~b13 & b15); + s[20] = b20 ^ (~b22 & b24); + s[21] = b21 ^ (~b23 & b25); + s[30] = b30 ^ (~b32 & b34); + s[31] = b31 ^ (~b33 & b35); + s[40] = b40 ^ (~b42 & b44); + s[41] = b41 ^ (~b43 & b45); + s[2] = b2 ^ (~b4 & b6); + s[3] = b3 ^ (~b5 & b7); + s[12] = b12 ^ (~b14 & b16); + s[13] = b13 ^ (~b15 & b17); + s[22] = b22 ^ (~b24 & b26); + s[23] = b23 ^ (~b25 & b27); + s[32] = b32 ^ (~b34 & b36); + s[33] = b33 ^ (~b35 & b37); + s[42] = b42 ^ (~b44 & b46); + s[43] = b43 ^ (~b45 & b47); + s[4] = b4 ^ (~b6 & b8); + s[5] = b5 ^ (~b7 & b9); + s[14] = b14 ^ (~b16 & b18); + s[15] = b15 ^ (~b17 & b19); + s[24] = b24 ^ (~b26 & b28); + s[25] = b25 ^ (~b27 & b29); + s[34] = b34 ^ (~b36 & b38); + s[35] = b35 ^ (~b37 & b39); + s[44] = b44 ^ (~b46 & b48); + s[45] = b45 ^ (~b47 & b49); + s[6] = b6 ^ (~b8 & b0); + s[7] = b7 ^ (~b9 & b1); + s[16] = b16 ^ (~b18 & b10); + s[17] = b17 ^ (~b19 & b11); + s[26] = b26 ^ (~b28 & b20); + s[27] = b27 ^ (~b29 & b21); + s[36] = b36 ^ (~b38 & b30); + s[37] = b37 ^ (~b39 & b31); + s[46] = b46 ^ (~b48 & b40); + s[47] = b47 ^ (~b49 & b41); + s[8] = b8 ^ (~b0 & b2); + s[9] = b9 ^ (~b1 & b3); + s[18] = b18 ^ (~b10 & b12); + s[19] = b19 ^ (~b11 & b13); + s[28] = b28 ^ (~b20 & b22); + s[29] = b29 ^ (~b21 & b23); + s[38] = b38 ^ (~b30 & b32); + s[39] = b39 ^ (~b31 & b33); + s[48] = b48 ^ (~b40 & b42); + s[49] = b49 ^ (~b41 & b43); + + s[0] ^= RC[n]; + s[1] ^= RC[n + 1]; + } + }; + + if (COMMON_JS) { + module.exports = methods; + } else if (root) { + for (var key in methods) { + root[key] = methods[key]; + } + } }(commonjsGlobal)); }); @@ -18937,479 +18937,479 @@ var constants_8 = constants.WeiPerEther; var constants_9 = constants.MaxUint256; var sha3$2 = createCommonjsModule(function (module) { -/** - * [js-sha3]{@link https://github.com/emn178/js-sha3} - * - * @version 0.5.7 - * @author Chen, Yi-Cyuan [emn178@gmail.com] - * @copyright Chen, Yi-Cyuan 2015-2016 - * @license MIT - */ -/*jslint bitwise: true */ -(function () { - - var root = typeof window === 'object' ? window : {}; - var NODE_JS = !root.JS_SHA3_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node; - if (NODE_JS) { - root = commonjsGlobal; - } - var COMMON_JS = !root.JS_SHA3_NO_COMMON_JS && 'object' === 'object' && module.exports; - var HEX_CHARS = '0123456789abcdef'.split(''); - var SHAKE_PADDING = [31, 7936, 2031616, 520093696]; - var KECCAK_PADDING = [1, 256, 65536, 16777216]; - var PADDING = [6, 1536, 393216, 100663296]; - var SHIFT = [0, 8, 16, 24]; - var RC = [1, 0, 32898, 0, 32906, 2147483648, 2147516416, 2147483648, 32907, 0, 2147483649, - 0, 2147516545, 2147483648, 32777, 2147483648, 138, 0, 136, 0, 2147516425, 0, - 2147483658, 0, 2147516555, 0, 139, 2147483648, 32905, 2147483648, 32771, - 2147483648, 32770, 2147483648, 128, 2147483648, 32778, 0, 2147483658, 2147483648, - 2147516545, 2147483648, 32896, 2147483648, 2147483649, 0, 2147516424, 2147483648]; - var BITS = [224, 256, 384, 512]; - var SHAKE_BITS = [128, 256]; - var OUTPUT_TYPES = ['hex', 'buffer', 'arrayBuffer', 'array']; - - var createOutputMethod = function (bits, padding, outputType) { - return function (message) { - return new Keccak(bits, padding, bits).update(message)[outputType](); - }; - }; - - var createShakeOutputMethod = function (bits, padding, outputType) { - return function (message, outputBits) { - return new Keccak(bits, padding, outputBits).update(message)[outputType](); - }; - }; - - var createMethod = function (bits, padding) { - var method = createOutputMethod(bits, padding, 'hex'); - method.create = function () { - return new Keccak(bits, padding, bits); - }; - method.update = function (message) { - return method.create().update(message); - }; - for (var i = 0; i < OUTPUT_TYPES.length; ++i) { - var type = OUTPUT_TYPES[i]; - method[type] = createOutputMethod(bits, padding, type); - } - return method; - }; - - var createShakeMethod = function (bits, padding) { - var method = createShakeOutputMethod(bits, padding, 'hex'); - method.create = function (outputBits) { - return new Keccak(bits, padding, outputBits); - }; - method.update = function (message, outputBits) { - return method.create(outputBits).update(message); - }; - for (var i = 0; i < OUTPUT_TYPES.length; ++i) { - var type = OUTPUT_TYPES[i]; - method[type] = createShakeOutputMethod(bits, padding, type); - } - return method; - }; - - var algorithms = [ - {name: 'keccak', padding: KECCAK_PADDING, bits: BITS, createMethod: createMethod}, - {name: 'sha3', padding: PADDING, bits: BITS, createMethod: createMethod}, - {name: 'shake', padding: SHAKE_PADDING, bits: SHAKE_BITS, createMethod: createShakeMethod} - ]; - - var methods = {}, methodNames = []; - - for (var i = 0; i < algorithms.length; ++i) { - var algorithm = algorithms[i]; - var bits = algorithm.bits; - for (var j = 0; j < bits.length; ++j) { - var methodName = algorithm.name +'_' + bits[j]; - methodNames.push(methodName); - methods[methodName] = algorithm.createMethod(bits[j], algorithm.padding); - } - } - - function Keccak(bits, padding, outputBits) { - this.blocks = []; - this.s = []; - this.padding = padding; - this.outputBits = outputBits; - this.reset = true; - this.block = 0; - this.start = 0; - this.blockCount = (1600 - (bits << 1)) >> 5; - this.byteCount = this.blockCount << 2; - this.outputBlocks = outputBits >> 5; - this.extraBytes = (outputBits & 31) >> 3; - - for (var i = 0; i < 50; ++i) { - this.s[i] = 0; - } - } - - Keccak.prototype.update = function (message) { - var notString = typeof message !== 'string'; - if (notString && message.constructor === ArrayBuffer) { - message = new Uint8Array(message); - } - var length = message.length, blocks = this.blocks, byteCount = this.byteCount, - blockCount = this.blockCount, index = 0, s = this.s, i, code; - - while (index < length) { - if (this.reset) { - this.reset = false; - blocks[0] = this.block; - for (i = 1; i < blockCount + 1; ++i) { - blocks[i] = 0; - } - } - if (notString) { - for (i = this.start; index < length && i < byteCount; ++index) { - blocks[i >> 2] |= message[index] << SHIFT[i++ & 3]; - } - } else { - for (i = this.start; index < length && i < byteCount; ++index) { - code = message.charCodeAt(index); - if (code < 0x80) { - blocks[i >> 2] |= code << SHIFT[i++ & 3]; - } else if (code < 0x800) { - blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; - } else if (code < 0xd800 || code >= 0xe000) { - blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; - } else { - code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff)); - blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; - } - } - } - this.lastByteIndex = i; - if (i >= byteCount) { - this.start = i - byteCount; - this.block = blocks[blockCount]; - for (i = 0; i < blockCount; ++i) { - s[i] ^= blocks[i]; - } - f(s); - this.reset = true; - } else { - this.start = i; - } - } - return this; - }; - - Keccak.prototype.finalize = function () { - var blocks = this.blocks, i = this.lastByteIndex, blockCount = this.blockCount, s = this.s; - blocks[i >> 2] |= this.padding[i & 3]; - if (this.lastByteIndex === this.byteCount) { - blocks[0] = blocks[blockCount]; - for (i = 1; i < blockCount + 1; ++i) { - blocks[i] = 0; - } - } - blocks[blockCount - 1] |= 0x80000000; - for (i = 0; i < blockCount; ++i) { - s[i] ^= blocks[i]; - } - f(s); - }; - - Keccak.prototype.toString = Keccak.prototype.hex = function () { - this.finalize(); - - var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, - extraBytes = this.extraBytes, i = 0, j = 0; - var hex = '', block; - while (j < outputBlocks) { - for (i = 0; i < blockCount && j < outputBlocks; ++i, ++j) { - block = s[i]; - hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F] + - HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F] + - HEX_CHARS[(block >> 20) & 0x0F] + HEX_CHARS[(block >> 16) & 0x0F] + - HEX_CHARS[(block >> 28) & 0x0F] + HEX_CHARS[(block >> 24) & 0x0F]; - } - if (j % blockCount === 0) { - f(s); - i = 0; - } - } - if (extraBytes) { - block = s[i]; - if (extraBytes > 0) { - hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F]; - } - if (extraBytes > 1) { - hex += HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F]; - } - if (extraBytes > 2) { - hex += HEX_CHARS[(block >> 20) & 0x0F] + HEX_CHARS[(block >> 16) & 0x0F]; - } - } - return hex; - }; - - Keccak.prototype.arrayBuffer = function () { - this.finalize(); - - var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, - extraBytes = this.extraBytes, i = 0, j = 0; - var bytes = this.outputBits >> 3; - var buffer; - if (extraBytes) { - buffer = new ArrayBuffer((outputBlocks + 1) << 2); - } else { - buffer = new ArrayBuffer(bytes); - } - var array = new Uint32Array(buffer); - while (j < outputBlocks) { - for (i = 0; i < blockCount && j < outputBlocks; ++i, ++j) { - array[j] = s[i]; - } - if (j % blockCount === 0) { - f(s); - } - } - if (extraBytes) { - array[i] = s[i]; - buffer = buffer.slice(0, bytes); - } - return buffer; - }; - - Keccak.prototype.buffer = Keccak.prototype.arrayBuffer; - - Keccak.prototype.digest = Keccak.prototype.array = function () { - this.finalize(); - - var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, - extraBytes = this.extraBytes, i = 0, j = 0; - var array = [], offset, block; - while (j < outputBlocks) { - for (i = 0; i < blockCount && j < outputBlocks; ++i, ++j) { - offset = j << 2; - block = s[i]; - array[offset] = block & 0xFF; - array[offset + 1] = (block >> 8) & 0xFF; - array[offset + 2] = (block >> 16) & 0xFF; - array[offset + 3] = (block >> 24) & 0xFF; - } - if (j % blockCount === 0) { - f(s); - } - } - if (extraBytes) { - offset = j << 2; - block = s[i]; - if (extraBytes > 0) { - array[offset] = block & 0xFF; - } - if (extraBytes > 1) { - array[offset + 1] = (block >> 8) & 0xFF; - } - if (extraBytes > 2) { - array[offset + 2] = (block >> 16) & 0xFF; - } - } - return array; - }; - - var f = function (s) { - var h, l, n, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, - b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16, b17, - b18, b19, b20, b21, b22, b23, b24, b25, b26, b27, b28, b29, b30, b31, b32, b33, - b34, b35, b36, b37, b38, b39, b40, b41, b42, b43, b44, b45, b46, b47, b48, b49; - for (n = 0; n < 48; n += 2) { - c0 = s[0] ^ s[10] ^ s[20] ^ s[30] ^ s[40]; - c1 = s[1] ^ s[11] ^ s[21] ^ s[31] ^ s[41]; - c2 = s[2] ^ s[12] ^ s[22] ^ s[32] ^ s[42]; - c3 = s[3] ^ s[13] ^ s[23] ^ s[33] ^ s[43]; - c4 = s[4] ^ s[14] ^ s[24] ^ s[34] ^ s[44]; - c5 = s[5] ^ s[15] ^ s[25] ^ s[35] ^ s[45]; - c6 = s[6] ^ s[16] ^ s[26] ^ s[36] ^ s[46]; - c7 = s[7] ^ s[17] ^ s[27] ^ s[37] ^ s[47]; - c8 = s[8] ^ s[18] ^ s[28] ^ s[38] ^ s[48]; - c9 = s[9] ^ s[19] ^ s[29] ^ s[39] ^ s[49]; - - h = c8 ^ ((c2 << 1) | (c3 >>> 31)); - l = c9 ^ ((c3 << 1) | (c2 >>> 31)); - s[0] ^= h; - s[1] ^= l; - s[10] ^= h; - s[11] ^= l; - s[20] ^= h; - s[21] ^= l; - s[30] ^= h; - s[31] ^= l; - s[40] ^= h; - s[41] ^= l; - h = c0 ^ ((c4 << 1) | (c5 >>> 31)); - l = c1 ^ ((c5 << 1) | (c4 >>> 31)); - s[2] ^= h; - s[3] ^= l; - s[12] ^= h; - s[13] ^= l; - s[22] ^= h; - s[23] ^= l; - s[32] ^= h; - s[33] ^= l; - s[42] ^= h; - s[43] ^= l; - h = c2 ^ ((c6 << 1) | (c7 >>> 31)); - l = c3 ^ ((c7 << 1) | (c6 >>> 31)); - s[4] ^= h; - s[5] ^= l; - s[14] ^= h; - s[15] ^= l; - s[24] ^= h; - s[25] ^= l; - s[34] ^= h; - s[35] ^= l; - s[44] ^= h; - s[45] ^= l; - h = c4 ^ ((c8 << 1) | (c9 >>> 31)); - l = c5 ^ ((c9 << 1) | (c8 >>> 31)); - s[6] ^= h; - s[7] ^= l; - s[16] ^= h; - s[17] ^= l; - s[26] ^= h; - s[27] ^= l; - s[36] ^= h; - s[37] ^= l; - s[46] ^= h; - s[47] ^= l; - h = c6 ^ ((c0 << 1) | (c1 >>> 31)); - l = c7 ^ ((c1 << 1) | (c0 >>> 31)); - s[8] ^= h; - s[9] ^= l; - s[18] ^= h; - s[19] ^= l; - s[28] ^= h; - s[29] ^= l; - s[38] ^= h; - s[39] ^= l; - s[48] ^= h; - s[49] ^= l; - - b0 = s[0]; - b1 = s[1]; - b32 = (s[11] << 4) | (s[10] >>> 28); - b33 = (s[10] << 4) | (s[11] >>> 28); - b14 = (s[20] << 3) | (s[21] >>> 29); - b15 = (s[21] << 3) | (s[20] >>> 29); - b46 = (s[31] << 9) | (s[30] >>> 23); - b47 = (s[30] << 9) | (s[31] >>> 23); - b28 = (s[40] << 18) | (s[41] >>> 14); - b29 = (s[41] << 18) | (s[40] >>> 14); - b20 = (s[2] << 1) | (s[3] >>> 31); - b21 = (s[3] << 1) | (s[2] >>> 31); - b2 = (s[13] << 12) | (s[12] >>> 20); - b3 = (s[12] << 12) | (s[13] >>> 20); - b34 = (s[22] << 10) | (s[23] >>> 22); - b35 = (s[23] << 10) | (s[22] >>> 22); - b16 = (s[33] << 13) | (s[32] >>> 19); - b17 = (s[32] << 13) | (s[33] >>> 19); - b48 = (s[42] << 2) | (s[43] >>> 30); - b49 = (s[43] << 2) | (s[42] >>> 30); - b40 = (s[5] << 30) | (s[4] >>> 2); - b41 = (s[4] << 30) | (s[5] >>> 2); - b22 = (s[14] << 6) | (s[15] >>> 26); - b23 = (s[15] << 6) | (s[14] >>> 26); - b4 = (s[25] << 11) | (s[24] >>> 21); - b5 = (s[24] << 11) | (s[25] >>> 21); - b36 = (s[34] << 15) | (s[35] >>> 17); - b37 = (s[35] << 15) | (s[34] >>> 17); - b18 = (s[45] << 29) | (s[44] >>> 3); - b19 = (s[44] << 29) | (s[45] >>> 3); - b10 = (s[6] << 28) | (s[7] >>> 4); - b11 = (s[7] << 28) | (s[6] >>> 4); - b42 = (s[17] << 23) | (s[16] >>> 9); - b43 = (s[16] << 23) | (s[17] >>> 9); - b24 = (s[26] << 25) | (s[27] >>> 7); - b25 = (s[27] << 25) | (s[26] >>> 7); - b6 = (s[36] << 21) | (s[37] >>> 11); - b7 = (s[37] << 21) | (s[36] >>> 11); - b38 = (s[47] << 24) | (s[46] >>> 8); - b39 = (s[46] << 24) | (s[47] >>> 8); - b30 = (s[8] << 27) | (s[9] >>> 5); - b31 = (s[9] << 27) | (s[8] >>> 5); - b12 = (s[18] << 20) | (s[19] >>> 12); - b13 = (s[19] << 20) | (s[18] >>> 12); - b44 = (s[29] << 7) | (s[28] >>> 25); - b45 = (s[28] << 7) | (s[29] >>> 25); - b26 = (s[38] << 8) | (s[39] >>> 24); - b27 = (s[39] << 8) | (s[38] >>> 24); - b8 = (s[48] << 14) | (s[49] >>> 18); - b9 = (s[49] << 14) | (s[48] >>> 18); - - s[0] = b0 ^ (~b2 & b4); - s[1] = b1 ^ (~b3 & b5); - s[10] = b10 ^ (~b12 & b14); - s[11] = b11 ^ (~b13 & b15); - s[20] = b20 ^ (~b22 & b24); - s[21] = b21 ^ (~b23 & b25); - s[30] = b30 ^ (~b32 & b34); - s[31] = b31 ^ (~b33 & b35); - s[40] = b40 ^ (~b42 & b44); - s[41] = b41 ^ (~b43 & b45); - s[2] = b2 ^ (~b4 & b6); - s[3] = b3 ^ (~b5 & b7); - s[12] = b12 ^ (~b14 & b16); - s[13] = b13 ^ (~b15 & b17); - s[22] = b22 ^ (~b24 & b26); - s[23] = b23 ^ (~b25 & b27); - s[32] = b32 ^ (~b34 & b36); - s[33] = b33 ^ (~b35 & b37); - s[42] = b42 ^ (~b44 & b46); - s[43] = b43 ^ (~b45 & b47); - s[4] = b4 ^ (~b6 & b8); - s[5] = b5 ^ (~b7 & b9); - s[14] = b14 ^ (~b16 & b18); - s[15] = b15 ^ (~b17 & b19); - s[24] = b24 ^ (~b26 & b28); - s[25] = b25 ^ (~b27 & b29); - s[34] = b34 ^ (~b36 & b38); - s[35] = b35 ^ (~b37 & b39); - s[44] = b44 ^ (~b46 & b48); - s[45] = b45 ^ (~b47 & b49); - s[6] = b6 ^ (~b8 & b0); - s[7] = b7 ^ (~b9 & b1); - s[16] = b16 ^ (~b18 & b10); - s[17] = b17 ^ (~b19 & b11); - s[26] = b26 ^ (~b28 & b20); - s[27] = b27 ^ (~b29 & b21); - s[36] = b36 ^ (~b38 & b30); - s[37] = b37 ^ (~b39 & b31); - s[46] = b46 ^ (~b48 & b40); - s[47] = b47 ^ (~b49 & b41); - s[8] = b8 ^ (~b0 & b2); - s[9] = b9 ^ (~b1 & b3); - s[18] = b18 ^ (~b10 & b12); - s[19] = b19 ^ (~b11 & b13); - s[28] = b28 ^ (~b20 & b22); - s[29] = b29 ^ (~b21 & b23); - s[38] = b38 ^ (~b30 & b32); - s[39] = b39 ^ (~b31 & b33); - s[48] = b48 ^ (~b40 & b42); - s[49] = b49 ^ (~b41 & b43); - - s[0] ^= RC[n]; - s[1] ^= RC[n + 1]; - } - }; - - if (COMMON_JS) { - module.exports = methods; - } else { - for (var i = 0; i < methodNames.length; ++i) { - root[methodNames[i]] = methods[methodNames[i]]; - } - } +/** + * [js-sha3]{@link https://github.com/emn178/js-sha3} + * + * @version 0.5.7 + * @author Chen, Yi-Cyuan [emn178@gmail.com] + * @copyright Chen, Yi-Cyuan 2015-2016 + * @license MIT + */ +/*jslint bitwise: true */ +(function () { + + var root = typeof window === 'object' ? window : {}; + var NODE_JS = !root.JS_SHA3_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node; + if (NODE_JS) { + root = commonjsGlobal; + } + var COMMON_JS = !root.JS_SHA3_NO_COMMON_JS && 'object' === 'object' && module.exports; + var HEX_CHARS = '0123456789abcdef'.split(''); + var SHAKE_PADDING = [31, 7936, 2031616, 520093696]; + var KECCAK_PADDING = [1, 256, 65536, 16777216]; + var PADDING = [6, 1536, 393216, 100663296]; + var SHIFT = [0, 8, 16, 24]; + var RC = [1, 0, 32898, 0, 32906, 2147483648, 2147516416, 2147483648, 32907, 0, 2147483649, + 0, 2147516545, 2147483648, 32777, 2147483648, 138, 0, 136, 0, 2147516425, 0, + 2147483658, 0, 2147516555, 0, 139, 2147483648, 32905, 2147483648, 32771, + 2147483648, 32770, 2147483648, 128, 2147483648, 32778, 0, 2147483658, 2147483648, + 2147516545, 2147483648, 32896, 2147483648, 2147483649, 0, 2147516424, 2147483648]; + var BITS = [224, 256, 384, 512]; + var SHAKE_BITS = [128, 256]; + var OUTPUT_TYPES = ['hex', 'buffer', 'arrayBuffer', 'array']; + + var createOutputMethod = function (bits, padding, outputType) { + return function (message) { + return new Keccak(bits, padding, bits).update(message)[outputType](); + }; + }; + + var createShakeOutputMethod = function (bits, padding, outputType) { + return function (message, outputBits) { + return new Keccak(bits, padding, outputBits).update(message)[outputType](); + }; + }; + + var createMethod = function (bits, padding) { + var method = createOutputMethod(bits, padding, 'hex'); + method.create = function () { + return new Keccak(bits, padding, bits); + }; + method.update = function (message) { + return method.create().update(message); + }; + for (var i = 0; i < OUTPUT_TYPES.length; ++i) { + var type = OUTPUT_TYPES[i]; + method[type] = createOutputMethod(bits, padding, type); + } + return method; + }; + + var createShakeMethod = function (bits, padding) { + var method = createShakeOutputMethod(bits, padding, 'hex'); + method.create = function (outputBits) { + return new Keccak(bits, padding, outputBits); + }; + method.update = function (message, outputBits) { + return method.create(outputBits).update(message); + }; + for (var i = 0; i < OUTPUT_TYPES.length; ++i) { + var type = OUTPUT_TYPES[i]; + method[type] = createShakeOutputMethod(bits, padding, type); + } + return method; + }; + + var algorithms = [ + {name: 'keccak', padding: KECCAK_PADDING, bits: BITS, createMethod: createMethod}, + {name: 'sha3', padding: PADDING, bits: BITS, createMethod: createMethod}, + {name: 'shake', padding: SHAKE_PADDING, bits: SHAKE_BITS, createMethod: createShakeMethod} + ]; + + var methods = {}, methodNames = []; + + for (var i = 0; i < algorithms.length; ++i) { + var algorithm = algorithms[i]; + var bits = algorithm.bits; + for (var j = 0; j < bits.length; ++j) { + var methodName = algorithm.name +'_' + bits[j]; + methodNames.push(methodName); + methods[methodName] = algorithm.createMethod(bits[j], algorithm.padding); + } + } + + function Keccak(bits, padding, outputBits) { + this.blocks = []; + this.s = []; + this.padding = padding; + this.outputBits = outputBits; + this.reset = true; + this.block = 0; + this.start = 0; + this.blockCount = (1600 - (bits << 1)) >> 5; + this.byteCount = this.blockCount << 2; + this.outputBlocks = outputBits >> 5; + this.extraBytes = (outputBits & 31) >> 3; + + for (var i = 0; i < 50; ++i) { + this.s[i] = 0; + } + } + + Keccak.prototype.update = function (message) { + var notString = typeof message !== 'string'; + if (notString && message.constructor === ArrayBuffer) { + message = new Uint8Array(message); + } + var length = message.length, blocks = this.blocks, byteCount = this.byteCount, + blockCount = this.blockCount, index = 0, s = this.s, i, code; + + while (index < length) { + if (this.reset) { + this.reset = false; + blocks[0] = this.block; + for (i = 1; i < blockCount + 1; ++i) { + blocks[i] = 0; + } + } + if (notString) { + for (i = this.start; index < length && i < byteCount; ++index) { + blocks[i >> 2] |= message[index] << SHIFT[i++ & 3]; + } + } else { + for (i = this.start; index < length && i < byteCount; ++index) { + code = message.charCodeAt(index); + if (code < 0x80) { + blocks[i >> 2] |= code << SHIFT[i++ & 3]; + } else if (code < 0x800) { + blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; + } else if (code < 0xd800 || code >= 0xe000) { + blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; + } else { + code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff)); + blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; + } + } + } + this.lastByteIndex = i; + if (i >= byteCount) { + this.start = i - byteCount; + this.block = blocks[blockCount]; + for (i = 0; i < blockCount; ++i) { + s[i] ^= blocks[i]; + } + f(s); + this.reset = true; + } else { + this.start = i; + } + } + return this; + }; + + Keccak.prototype.finalize = function () { + var blocks = this.blocks, i = this.lastByteIndex, blockCount = this.blockCount, s = this.s; + blocks[i >> 2] |= this.padding[i & 3]; + if (this.lastByteIndex === this.byteCount) { + blocks[0] = blocks[blockCount]; + for (i = 1; i < blockCount + 1; ++i) { + blocks[i] = 0; + } + } + blocks[blockCount - 1] |= 0x80000000; + for (i = 0; i < blockCount; ++i) { + s[i] ^= blocks[i]; + } + f(s); + }; + + Keccak.prototype.toString = Keccak.prototype.hex = function () { + this.finalize(); + + var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, + extraBytes = this.extraBytes, i = 0, j = 0; + var hex = '', block; + while (j < outputBlocks) { + for (i = 0; i < blockCount && j < outputBlocks; ++i, ++j) { + block = s[i]; + hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F] + + HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F] + + HEX_CHARS[(block >> 20) & 0x0F] + HEX_CHARS[(block >> 16) & 0x0F] + + HEX_CHARS[(block >> 28) & 0x0F] + HEX_CHARS[(block >> 24) & 0x0F]; + } + if (j % blockCount === 0) { + f(s); + i = 0; + } + } + if (extraBytes) { + block = s[i]; + if (extraBytes > 0) { + hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F]; + } + if (extraBytes > 1) { + hex += HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F]; + } + if (extraBytes > 2) { + hex += HEX_CHARS[(block >> 20) & 0x0F] + HEX_CHARS[(block >> 16) & 0x0F]; + } + } + return hex; + }; + + Keccak.prototype.arrayBuffer = function () { + this.finalize(); + + var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, + extraBytes = this.extraBytes, i = 0, j = 0; + var bytes = this.outputBits >> 3; + var buffer; + if (extraBytes) { + buffer = new ArrayBuffer((outputBlocks + 1) << 2); + } else { + buffer = new ArrayBuffer(bytes); + } + var array = new Uint32Array(buffer); + while (j < outputBlocks) { + for (i = 0; i < blockCount && j < outputBlocks; ++i, ++j) { + array[j] = s[i]; + } + if (j % blockCount === 0) { + f(s); + } + } + if (extraBytes) { + array[i] = s[i]; + buffer = buffer.slice(0, bytes); + } + return buffer; + }; + + Keccak.prototype.buffer = Keccak.prototype.arrayBuffer; + + Keccak.prototype.digest = Keccak.prototype.array = function () { + this.finalize(); + + var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, + extraBytes = this.extraBytes, i = 0, j = 0; + var array = [], offset, block; + while (j < outputBlocks) { + for (i = 0; i < blockCount && j < outputBlocks; ++i, ++j) { + offset = j << 2; + block = s[i]; + array[offset] = block & 0xFF; + array[offset + 1] = (block >> 8) & 0xFF; + array[offset + 2] = (block >> 16) & 0xFF; + array[offset + 3] = (block >> 24) & 0xFF; + } + if (j % blockCount === 0) { + f(s); + } + } + if (extraBytes) { + offset = j << 2; + block = s[i]; + if (extraBytes > 0) { + array[offset] = block & 0xFF; + } + if (extraBytes > 1) { + array[offset + 1] = (block >> 8) & 0xFF; + } + if (extraBytes > 2) { + array[offset + 2] = (block >> 16) & 0xFF; + } + } + return array; + }; + + var f = function (s) { + var h, l, n, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, + b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16, b17, + b18, b19, b20, b21, b22, b23, b24, b25, b26, b27, b28, b29, b30, b31, b32, b33, + b34, b35, b36, b37, b38, b39, b40, b41, b42, b43, b44, b45, b46, b47, b48, b49; + for (n = 0; n < 48; n += 2) { + c0 = s[0] ^ s[10] ^ s[20] ^ s[30] ^ s[40]; + c1 = s[1] ^ s[11] ^ s[21] ^ s[31] ^ s[41]; + c2 = s[2] ^ s[12] ^ s[22] ^ s[32] ^ s[42]; + c3 = s[3] ^ s[13] ^ s[23] ^ s[33] ^ s[43]; + c4 = s[4] ^ s[14] ^ s[24] ^ s[34] ^ s[44]; + c5 = s[5] ^ s[15] ^ s[25] ^ s[35] ^ s[45]; + c6 = s[6] ^ s[16] ^ s[26] ^ s[36] ^ s[46]; + c7 = s[7] ^ s[17] ^ s[27] ^ s[37] ^ s[47]; + c8 = s[8] ^ s[18] ^ s[28] ^ s[38] ^ s[48]; + c9 = s[9] ^ s[19] ^ s[29] ^ s[39] ^ s[49]; + + h = c8 ^ ((c2 << 1) | (c3 >>> 31)); + l = c9 ^ ((c3 << 1) | (c2 >>> 31)); + s[0] ^= h; + s[1] ^= l; + s[10] ^= h; + s[11] ^= l; + s[20] ^= h; + s[21] ^= l; + s[30] ^= h; + s[31] ^= l; + s[40] ^= h; + s[41] ^= l; + h = c0 ^ ((c4 << 1) | (c5 >>> 31)); + l = c1 ^ ((c5 << 1) | (c4 >>> 31)); + s[2] ^= h; + s[3] ^= l; + s[12] ^= h; + s[13] ^= l; + s[22] ^= h; + s[23] ^= l; + s[32] ^= h; + s[33] ^= l; + s[42] ^= h; + s[43] ^= l; + h = c2 ^ ((c6 << 1) | (c7 >>> 31)); + l = c3 ^ ((c7 << 1) | (c6 >>> 31)); + s[4] ^= h; + s[5] ^= l; + s[14] ^= h; + s[15] ^= l; + s[24] ^= h; + s[25] ^= l; + s[34] ^= h; + s[35] ^= l; + s[44] ^= h; + s[45] ^= l; + h = c4 ^ ((c8 << 1) | (c9 >>> 31)); + l = c5 ^ ((c9 << 1) | (c8 >>> 31)); + s[6] ^= h; + s[7] ^= l; + s[16] ^= h; + s[17] ^= l; + s[26] ^= h; + s[27] ^= l; + s[36] ^= h; + s[37] ^= l; + s[46] ^= h; + s[47] ^= l; + h = c6 ^ ((c0 << 1) | (c1 >>> 31)); + l = c7 ^ ((c1 << 1) | (c0 >>> 31)); + s[8] ^= h; + s[9] ^= l; + s[18] ^= h; + s[19] ^= l; + s[28] ^= h; + s[29] ^= l; + s[38] ^= h; + s[39] ^= l; + s[48] ^= h; + s[49] ^= l; + + b0 = s[0]; + b1 = s[1]; + b32 = (s[11] << 4) | (s[10] >>> 28); + b33 = (s[10] << 4) | (s[11] >>> 28); + b14 = (s[20] << 3) | (s[21] >>> 29); + b15 = (s[21] << 3) | (s[20] >>> 29); + b46 = (s[31] << 9) | (s[30] >>> 23); + b47 = (s[30] << 9) | (s[31] >>> 23); + b28 = (s[40] << 18) | (s[41] >>> 14); + b29 = (s[41] << 18) | (s[40] >>> 14); + b20 = (s[2] << 1) | (s[3] >>> 31); + b21 = (s[3] << 1) | (s[2] >>> 31); + b2 = (s[13] << 12) | (s[12] >>> 20); + b3 = (s[12] << 12) | (s[13] >>> 20); + b34 = (s[22] << 10) | (s[23] >>> 22); + b35 = (s[23] << 10) | (s[22] >>> 22); + b16 = (s[33] << 13) | (s[32] >>> 19); + b17 = (s[32] << 13) | (s[33] >>> 19); + b48 = (s[42] << 2) | (s[43] >>> 30); + b49 = (s[43] << 2) | (s[42] >>> 30); + b40 = (s[5] << 30) | (s[4] >>> 2); + b41 = (s[4] << 30) | (s[5] >>> 2); + b22 = (s[14] << 6) | (s[15] >>> 26); + b23 = (s[15] << 6) | (s[14] >>> 26); + b4 = (s[25] << 11) | (s[24] >>> 21); + b5 = (s[24] << 11) | (s[25] >>> 21); + b36 = (s[34] << 15) | (s[35] >>> 17); + b37 = (s[35] << 15) | (s[34] >>> 17); + b18 = (s[45] << 29) | (s[44] >>> 3); + b19 = (s[44] << 29) | (s[45] >>> 3); + b10 = (s[6] << 28) | (s[7] >>> 4); + b11 = (s[7] << 28) | (s[6] >>> 4); + b42 = (s[17] << 23) | (s[16] >>> 9); + b43 = (s[16] << 23) | (s[17] >>> 9); + b24 = (s[26] << 25) | (s[27] >>> 7); + b25 = (s[27] << 25) | (s[26] >>> 7); + b6 = (s[36] << 21) | (s[37] >>> 11); + b7 = (s[37] << 21) | (s[36] >>> 11); + b38 = (s[47] << 24) | (s[46] >>> 8); + b39 = (s[46] << 24) | (s[47] >>> 8); + b30 = (s[8] << 27) | (s[9] >>> 5); + b31 = (s[9] << 27) | (s[8] >>> 5); + b12 = (s[18] << 20) | (s[19] >>> 12); + b13 = (s[19] << 20) | (s[18] >>> 12); + b44 = (s[29] << 7) | (s[28] >>> 25); + b45 = (s[28] << 7) | (s[29] >>> 25); + b26 = (s[38] << 8) | (s[39] >>> 24); + b27 = (s[39] << 8) | (s[38] >>> 24); + b8 = (s[48] << 14) | (s[49] >>> 18); + b9 = (s[49] << 14) | (s[48] >>> 18); + + s[0] = b0 ^ (~b2 & b4); + s[1] = b1 ^ (~b3 & b5); + s[10] = b10 ^ (~b12 & b14); + s[11] = b11 ^ (~b13 & b15); + s[20] = b20 ^ (~b22 & b24); + s[21] = b21 ^ (~b23 & b25); + s[30] = b30 ^ (~b32 & b34); + s[31] = b31 ^ (~b33 & b35); + s[40] = b40 ^ (~b42 & b44); + s[41] = b41 ^ (~b43 & b45); + s[2] = b2 ^ (~b4 & b6); + s[3] = b3 ^ (~b5 & b7); + s[12] = b12 ^ (~b14 & b16); + s[13] = b13 ^ (~b15 & b17); + s[22] = b22 ^ (~b24 & b26); + s[23] = b23 ^ (~b25 & b27); + s[32] = b32 ^ (~b34 & b36); + s[33] = b33 ^ (~b35 & b37); + s[42] = b42 ^ (~b44 & b46); + s[43] = b43 ^ (~b45 & b47); + s[4] = b4 ^ (~b6 & b8); + s[5] = b5 ^ (~b7 & b9); + s[14] = b14 ^ (~b16 & b18); + s[15] = b15 ^ (~b17 & b19); + s[24] = b24 ^ (~b26 & b28); + s[25] = b25 ^ (~b27 & b29); + s[34] = b34 ^ (~b36 & b38); + s[35] = b35 ^ (~b37 & b39); + s[44] = b44 ^ (~b46 & b48); + s[45] = b45 ^ (~b47 & b49); + s[6] = b6 ^ (~b8 & b0); + s[7] = b7 ^ (~b9 & b1); + s[16] = b16 ^ (~b18 & b10); + s[17] = b17 ^ (~b19 & b11); + s[26] = b26 ^ (~b28 & b20); + s[27] = b27 ^ (~b29 & b21); + s[36] = b36 ^ (~b38 & b30); + s[37] = b37 ^ (~b39 & b31); + s[46] = b46 ^ (~b48 & b40); + s[47] = b47 ^ (~b49 & b41); + s[8] = b8 ^ (~b0 & b2); + s[9] = b9 ^ (~b1 & b3); + s[18] = b18 ^ (~b10 & b12); + s[19] = b19 ^ (~b11 & b13); + s[28] = b28 ^ (~b20 & b22); + s[29] = b29 ^ (~b21 & b23); + s[38] = b38 ^ (~b30 & b32); + s[39] = b39 ^ (~b31 & b33); + s[48] = b48 ^ (~b40 & b42); + s[49] = b49 ^ (~b41 & b43); + + s[0] ^= RC[n]; + s[1] ^= RC[n + 1]; + } + }; + + if (COMMON_JS) { + module.exports = methods; + } else { + for (var i = 0; i < methodNames.length; ++i) { + root[methodNames[i]] = methods[methodNames[i]]; + } + } })(); }); @@ -32502,2615 +32502,2621 @@ var contractAbiPileForInit = [ } ]; -var baseToDisplay = function (base, decimals) { - var baseStr = typeof base === 'string' ? base : base.toString(); - var a = baseStr.slice(0, -decimals) || '0'; - var b = baseStr.slice(-decimals).padStart(decimals, '0'); - return a + "." + b; +var baseToDisplay = function (base, decimals) { + var baseStr = typeof base === 'string' ? base : base.toString(); + var a = baseStr.slice(0, -decimals) || '0'; + var b = baseStr.slice(-decimals).padStart(decimals, '0'); + return a + "." + b; }; var bnToHex = function (bn) { return "0x" + bn.toString(16); }; -var displayToBase = function (display, decimals) { - var a = display.split('.')[0]; - var b = (display.split('.')[1] || '').padEnd(decimals, '0').substr(0, decimals); - return "" + a + b; -}; - -/* - * decimal.js-light v2.5.0 - * An arbitrary-precision Decimal type for JavaScript. - * https://github.com/MikeMcl/decimal.js-light - * Copyright (c) 2018 Michael Mclaughlin - * MIT Expat Licence - */ - - -// ------------------------------------ EDITABLE DEFAULTS ------------------------------------- // - - -// The limit on the value of `precision`, and on the value of the first argument to -// `toDecimalPlaces`, `toExponential`, `toFixed`, `toPrecision` and `toSignificantDigits`. -var MAX_DIGITS = 1e9, // 0 to 1e9 - - - // The initial configuration properties of the Decimal constructor. - defaults = { - - // These values must be integers within the stated ranges (inclusive). - // Most of these values can be changed during run-time using `Decimal.config`. - - // The maximum number of significant digits of the result of a calculation or base conversion. - // E.g. `Decimal.config({ precision: 20 });` - precision: 20, // 1 to MAX_DIGITS - - // The rounding mode used by default by `toInteger`, `toDecimalPlaces`, `toExponential`, - // `toFixed`, `toPrecision` and `toSignificantDigits`. - // - // ROUND_UP 0 Away from zero. - // ROUND_DOWN 1 Towards zero. - // ROUND_CEIL 2 Towards +Infinity. - // ROUND_FLOOR 3 Towards -Infinity. - // ROUND_HALF_UP 4 Towards nearest neighbour. If equidistant, up. - // ROUND_HALF_DOWN 5 Towards nearest neighbour. If equidistant, down. - // ROUND_HALF_EVEN 6 Towards nearest neighbour. If equidistant, towards even neighbour. - // ROUND_HALF_CEIL 7 Towards nearest neighbour. If equidistant, towards +Infinity. - // ROUND_HALF_FLOOR 8 Towards nearest neighbour. If equidistant, towards -Infinity. - // - // E.g. - // `Decimal.rounding = 4;` - // `Decimal.rounding = Decimal.ROUND_HALF_UP;` - rounding: 4, // 0 to 8 - - // The exponent value at and beneath which `toString` returns exponential notation. - // JavaScript numbers: -7 - toExpNeg: -7, // 0 to -MAX_E - - // The exponent value at and above which `toString` returns exponential notation. - // JavaScript numbers: 21 - toExpPos: 21, // 0 to MAX_E - - // The natural logarithm of 10. - // 115 digits - LN10: '2.302585092994045684017991454684364207601101488628772976033327900967572609677352480235997205089598298341967784042286' - }, - - -// ------------------------------------ END OF EDITABLE DEFAULTS -------------------------------- // - - - Decimal, - external = true, - - decimalError = '[DecimalError] ', - invalidArgument = decimalError + 'Invalid argument: ', - exponentOutOfRange = decimalError + 'Exponent out of range: ', - - mathfloor = Math.floor, - mathpow = Math.pow, - - isDecimal = /^(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i, - - ONE, - BASE = 1e7, - LOG_BASE = 7, - MAX_SAFE_INTEGER$2 = 9007199254740991, - MAX_E = mathfloor(MAX_SAFE_INTEGER$2 / LOG_BASE), // 1286742750677284 - - // Decimal.prototype object - P = {}; - - -// Decimal prototype methods - - -/* - * absoluteValue abs - * comparedTo cmp - * decimalPlaces dp - * dividedBy div - * dividedToIntegerBy idiv - * equals eq - * exponent - * greaterThan gt - * greaterThanOrEqualTo gte - * isInteger isint - * isNegative isneg - * isPositive ispos - * isZero - * lessThan lt - * lessThanOrEqualTo lte - * logarithm log - * minus sub - * modulo mod - * naturalExponential exp - * naturalLogarithm ln - * negated neg - * plus add - * precision sd - * squareRoot sqrt - * times mul - * toDecimalPlaces todp - * toExponential - * toFixed - * toInteger toint - * toNumber - * toPower pow - * toPrecision - * toSignificantDigits tosd - * toString - * valueOf val - */ - - -/* - * Return a new Decimal whose value is the absolute value of this Decimal. - * - */ -P.absoluteValue = P.abs = function () { - var x = new this.constructor(this); - if (x.s) x.s = 1; - return x; -}; - - -/* - * Return - * 1 if the value of this Decimal is greater than the value of `y`, - * -1 if the value of this Decimal is less than the value of `y`, - * 0 if they have the same value - * - */ -P.comparedTo = P.cmp = function (y) { - var i, j, xdL, ydL, - x = this; - - y = new x.constructor(y); - - // Signs differ? - if (x.s !== y.s) return x.s || -y.s; - - // Compare exponents. - if (x.e !== y.e) return x.e > y.e ^ x.s < 0 ? 1 : -1; - - xdL = x.d.length; - ydL = y.d.length; - - // Compare digit by digit. - for (i = 0, j = xdL < ydL ? xdL : ydL; i < j; ++i) { - if (x.d[i] !== y.d[i]) return x.d[i] > y.d[i] ^ x.s < 0 ? 1 : -1; - } - - // Compare lengths. - return xdL === ydL ? 0 : xdL > ydL ^ x.s < 0 ? 1 : -1; -}; - - -/* - * Return the number of decimal places of the value of this Decimal. - * - */ -P.decimalPlaces = P.dp = function () { - var x = this, - w = x.d.length - 1, - dp = (w - x.e) * LOG_BASE; - - // Subtract the number of trailing zeros of the last word. - w = x.d[w]; - if (w) for (; w % 10 == 0; w /= 10) dp--; - - return dp < 0 ? 0 : dp; +var displayToBase = function (display, decimals) { + var a = display.split('.')[0]; + var b = (display.split('.')[1] || '').padEnd(decimals, '0').substr(0, decimals); + return "" + a + b; }; +/* + * decimal.js-light v2.5.0 + * An arbitrary-precision Decimal type for JavaScript. + * https://github.com/MikeMcl/decimal.js-light + * Copyright (c) 2018 Michael Mclaughlin + * MIT Expat Licence + */ + + +// ------------------------------------ EDITABLE DEFAULTS ------------------------------------- // + + +// The limit on the value of `precision`, and on the value of the first argument to +// `toDecimalPlaces`, `toExponential`, `toFixed`, `toPrecision` and `toSignificantDigits`. +var MAX_DIGITS = 1e9, // 0 to 1e9 + + + // The initial configuration properties of the Decimal constructor. + defaults = { + + // These values must be integers within the stated ranges (inclusive). + // Most of these values can be changed during run-time using `Decimal.config`. + + // The maximum number of significant digits of the result of a calculation or base conversion. + // E.g. `Decimal.config({ precision: 20 });` + precision: 20, // 1 to MAX_DIGITS + + // The rounding mode used by default by `toInteger`, `toDecimalPlaces`, `toExponential`, + // `toFixed`, `toPrecision` and `toSignificantDigits`. + // + // ROUND_UP 0 Away from zero. + // ROUND_DOWN 1 Towards zero. + // ROUND_CEIL 2 Towards +Infinity. + // ROUND_FLOOR 3 Towards -Infinity. + // ROUND_HALF_UP 4 Towards nearest neighbour. If equidistant, up. + // ROUND_HALF_DOWN 5 Towards nearest neighbour. If equidistant, down. + // ROUND_HALF_EVEN 6 Towards nearest neighbour. If equidistant, towards even neighbour. + // ROUND_HALF_CEIL 7 Towards nearest neighbour. If equidistant, towards +Infinity. + // ROUND_HALF_FLOOR 8 Towards nearest neighbour. If equidistant, towards -Infinity. + // + // E.g. + // `Decimal.rounding = 4;` + // `Decimal.rounding = Decimal.ROUND_HALF_UP;` + rounding: 4, // 0 to 8 + + // The exponent value at and beneath which `toString` returns exponential notation. + // JavaScript numbers: -7 + toExpNeg: -7, // 0 to -MAX_E + + // The exponent value at and above which `toString` returns exponential notation. + // JavaScript numbers: 21 + toExpPos: 21, // 0 to MAX_E + + // The natural logarithm of 10. + // 115 digits + LN10: '2.302585092994045684017991454684364207601101488628772976033327900967572609677352480235997205089598298341967784042286' + }, + + +// ------------------------------------ END OF EDITABLE DEFAULTS -------------------------------- // + + + Decimal, + external = true, + + decimalError = '[DecimalError] ', + invalidArgument = decimalError + 'Invalid argument: ', + exponentOutOfRange = decimalError + 'Exponent out of range: ', + + mathfloor = Math.floor, + mathpow = Math.pow, + + isDecimal = /^(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i, + + ONE, + BASE = 1e7, + LOG_BASE = 7, + MAX_SAFE_INTEGER$2 = 9007199254740991, + MAX_E = mathfloor(MAX_SAFE_INTEGER$2 / LOG_BASE), // 1286742750677284 + + // Decimal.prototype object + P = {}; + + +// Decimal prototype methods + + +/* + * absoluteValue abs + * comparedTo cmp + * decimalPlaces dp + * dividedBy div + * dividedToIntegerBy idiv + * equals eq + * exponent + * greaterThan gt + * greaterThanOrEqualTo gte + * isInteger isint + * isNegative isneg + * isPositive ispos + * isZero + * lessThan lt + * lessThanOrEqualTo lte + * logarithm log + * minus sub + * modulo mod + * naturalExponential exp + * naturalLogarithm ln + * negated neg + * plus add + * precision sd + * squareRoot sqrt + * times mul + * toDecimalPlaces todp + * toExponential + * toFixed + * toInteger toint + * toNumber + * toPower pow + * toPrecision + * toSignificantDigits tosd + * toString + * valueOf val + */ + + +/* + * Return a new Decimal whose value is the absolute value of this Decimal. + * + */ +P.absoluteValue = P.abs = function () { + var x = new this.constructor(this); + if (x.s) x.s = 1; + return x; +}; + + +/* + * Return + * 1 if the value of this Decimal is greater than the value of `y`, + * -1 if the value of this Decimal is less than the value of `y`, + * 0 if they have the same value + * + */ +P.comparedTo = P.cmp = function (y) { + var i, j, xdL, ydL, + x = this; + + y = new x.constructor(y); + + // Signs differ? + if (x.s !== y.s) return x.s || -y.s; + + // Compare exponents. + if (x.e !== y.e) return x.e > y.e ^ x.s < 0 ? 1 : -1; + + xdL = x.d.length; + ydL = y.d.length; + + // Compare digit by digit. + for (i = 0, j = xdL < ydL ? xdL : ydL; i < j; ++i) { + if (x.d[i] !== y.d[i]) return x.d[i] > y.d[i] ^ x.s < 0 ? 1 : -1; + } + + // Compare lengths. + return xdL === ydL ? 0 : xdL > ydL ^ x.s < 0 ? 1 : -1; +}; + + +/* + * Return the number of decimal places of the value of this Decimal. + * + */ +P.decimalPlaces = P.dp = function () { + var x = this, + w = x.d.length - 1, + dp = (w - x.e) * LOG_BASE; + + // Subtract the number of trailing zeros of the last word. + w = x.d[w]; + if (w) for (; w % 10 == 0; w /= 10) dp--; + + return dp < 0 ? 0 : dp; +}; + + +/* + * Return a new Decimal whose value is the value of this Decimal divided by `y`, truncated to + * `precision` significant digits. + * + */ +P.dividedBy = P.div = function (y) { + return divide(this, new this.constructor(y)); +}; + + +/* + * Return a new Decimal whose value is the integer part of dividing the value of this Decimal + * by the value of `y`, truncated to `precision` significant digits. + * + */ +P.dividedToIntegerBy = P.idiv = function (y) { + var x = this, + Ctor = x.constructor; + return round(divide(x, new Ctor(y), 0, 1), Ctor.precision); +}; + + +/* + * Return true if the value of this Decimal is equal to the value of `y`, otherwise return false. + * + */ +P.equals = P.eq = function (y) { + return !this.cmp(y); +}; + + +/* + * Return the (base 10) exponent value of this Decimal (this.e is the base 10000000 exponent). + * + */ +P.exponent = function () { + return getBase10Exponent(this); +}; + + +/* + * Return true if the value of this Decimal is greater than the value of `y`, otherwise return + * false. + * + */ +P.greaterThan = P.gt = function (y) { + return this.cmp(y) > 0; +}; + + +/* + * Return true if the value of this Decimal is greater than or equal to the value of `y`, + * otherwise return false. + * + */ +P.greaterThanOrEqualTo = P.gte = function (y) { + return this.cmp(y) >= 0; +}; + + +/* + * Return true if the value of this Decimal is an integer, otherwise return false. + * + */ +P.isInteger = P.isint = function () { + return this.e > this.d.length - 2; +}; + + +/* + * Return true if the value of this Decimal is negative, otherwise return false. + * + */ +P.isNegative = P.isneg = function () { + return this.s < 0; +}; + + +/* + * Return true if the value of this Decimal is positive, otherwise return false. + * + */ +P.isPositive = P.ispos = function () { + return this.s > 0; +}; + + +/* + * Return true if the value of this Decimal is 0, otherwise return false. + * + */ +P.isZero = function () { + return this.s === 0; +}; + + +/* + * Return true if the value of this Decimal is less than `y`, otherwise return false. + * + */ +P.lessThan = P.lt = function (y) { + return this.cmp(y) < 0; +}; + + +/* + * Return true if the value of this Decimal is less than or equal to `y`, otherwise return false. + * + */ +P.lessThanOrEqualTo = P.lte = function (y) { + return this.cmp(y) < 1; +}; + + +/* + * Return the logarithm of the value of this Decimal to the specified base, truncated to + * `precision` significant digits. + * + * If no base is specified, return log[10](x). + * + * log[base](x) = ln(x) / ln(base) + * + * The maximum error of the result is 1 ulp (unit in the last place). + * + * [base] {number|string|Decimal} The base of the logarithm. + * + */ +P.logarithm = P.log = function (base) { + var r, + x = this, + Ctor = x.constructor, + pr = Ctor.precision, + wpr = pr + 5; + + // Default base is 10. + if (base === void 0) { + base = new Ctor(10); + } else { + base = new Ctor(base); + + // log[-b](x) = NaN + // log[0](x) = NaN + // log[1](x) = NaN + if (base.s < 1 || base.eq(ONE)) throw Error(decimalError + 'NaN'); + } + + // log[b](-x) = NaN + // log[b](0) = -Infinity + if (x.s < 1) throw Error(decimalError + (x.s ? 'NaN' : '-Infinity')); + + // log[b](1) = 0 + if (x.eq(ONE)) return new Ctor(0); + + external = false; + r = divide(ln(x, wpr), ln(base, wpr), wpr); + external = true; + + return round(r, pr); +}; + + +/* + * Return a new Decimal whose value is the value of this Decimal minus `y`, truncated to + * `precision` significant digits. + * + */ +P.minus = P.sub = function (y) { + var x = this; + y = new x.constructor(y); + return x.s == y.s ? subtract(x, y) : add(x, (y.s = -y.s, y)); +}; + + +/* + * Return a new Decimal whose value is the value of this Decimal modulo `y`, truncated to + * `precision` significant digits. + * + */ +P.modulo = P.mod = function (y) { + var q, + x = this, + Ctor = x.constructor, + pr = Ctor.precision; + + y = new Ctor(y); + + // x % 0 = NaN + if (!y.s) throw Error(decimalError + 'NaN'); + + // Return x if x is 0. + if (!x.s) return round(new Ctor(x), pr); + + // Prevent rounding of intermediate calculations. + external = false; + q = divide(x, y, 0, 1).times(y); + external = true; + + return x.minus(q); +}; + + +/* + * Return a new Decimal whose value is the natural exponential of the value of this Decimal, + * i.e. the base e raised to the power the value of this Decimal, truncated to `precision` + * significant digits. + * + */ +P.naturalExponential = P.exp = function () { + return exp(this); +}; + + +/* + * Return a new Decimal whose value is the natural logarithm of the value of this Decimal, + * truncated to `precision` significant digits. + * + */ +P.naturalLogarithm = P.ln = function () { + return ln(this); +}; + + +/* + * Return a new Decimal whose value is the value of this Decimal negated, i.e. as if multiplied by + * -1. + * + */ +P.negated = P.neg = function () { + var x = new this.constructor(this); + x.s = -x.s || 0; + return x; +}; + + +/* + * Return a new Decimal whose value is the value of this Decimal plus `y`, truncated to + * `precision` significant digits. + * + */ +P.plus = P.add = function (y) { + var x = this; + y = new x.constructor(y); + return x.s == y.s ? add(x, y) : subtract(x, (y.s = -y.s, y)); +}; + + +/* + * Return the number of significant digits of the value of this Decimal. + * + * [z] {boolean|number} Whether to count integer-part trailing zeros: true, false, 1 or 0. + * + */ +P.precision = P.sd = function (z) { + var e, sd, w, + x = this; + + if (z !== void 0 && z !== !!z && z !== 1 && z !== 0) throw Error(invalidArgument + z); + + e = getBase10Exponent(x) + 1; + w = x.d.length - 1; + sd = w * LOG_BASE + 1; + w = x.d[w]; + + // If non-zero... + if (w) { + + // Subtract the number of trailing zeros of the last word. + for (; w % 10 == 0; w /= 10) sd--; + + // Add the number of digits of the first word. + for (w = x.d[0]; w >= 10; w /= 10) sd++; + } + + return z && e > sd ? e : sd; +}; + + +/* + * Return a new Decimal whose value is the square root of this Decimal, truncated to `precision` + * significant digits. + * + */ +P.squareRoot = P.sqrt = function () { + var e, n, pr, r, s, t, wpr, + x = this, + Ctor = x.constructor; + + // Negative or zero? + if (x.s < 1) { + if (!x.s) return new Ctor(0); + + // sqrt(-x) = NaN + throw Error(decimalError + 'NaN'); + } + + e = getBase10Exponent(x); + external = false; + + // Initial estimate. + s = Math.sqrt(+x); + + // Math.sqrt underflow/overflow? + // Pass x to Math.sqrt as integer, then adjust the exponent of the result. + if (s == 0 || s == 1 / 0) { + n = digitsToString(x.d); + if ((n.length + e) % 2 == 0) n += '0'; + s = Math.sqrt(n); + e = mathfloor((e + 1) / 2) - (e < 0 || e % 2); + + if (s == 1 / 0) { + n = '1e' + e; + } else { + n = s.toExponential(); + n = n.slice(0, n.indexOf('e') + 1) + e; + } + + r = new Ctor(n); + } else { + r = new Ctor(s.toString()); + } + + pr = Ctor.precision; + s = wpr = pr + 3; + + // Newton-Raphson iteration. + for (;;) { + t = r; + r = t.plus(divide(x, t, wpr + 2)).times(0.5); + + if (digitsToString(t.d).slice(0, wpr) === (n = digitsToString(r.d)).slice(0, wpr)) { + n = n.slice(wpr - 3, wpr + 1); + + // The 4th rounding digit may be in error by -1 so if the 4 rounding digits are 9999 or + // 4999, i.e. approaching a rounding boundary, continue the iteration. + if (s == wpr && n == '4999') { + + // On the first iteration only, check to see if rounding up gives the exact result as the + // nines may infinitely repeat. + round(t, pr + 1, 0); + + if (t.times(t).eq(x)) { + r = t; + break; + } + } else if (n != '9999') { + break; + } + + wpr += 4; + } + } + + external = true; + + return round(r, pr); +}; + + +/* + * Return a new Decimal whose value is the value of this Decimal times `y`, truncated to + * `precision` significant digits. + * + */ +P.times = P.mul = function (y) { + var carry, e, i, k, r, rL, t, xdL, ydL, + x = this, + Ctor = x.constructor, + xd = x.d, + yd = (y = new Ctor(y)).d; + + // Return 0 if either is 0. + if (!x.s || !y.s) return new Ctor(0); + + y.s *= x.s; + e = x.e + y.e; + xdL = xd.length; + ydL = yd.length; + + // Ensure xd points to the longer array. + if (xdL < ydL) { + r = xd; + xd = yd; + yd = r; + rL = xdL; + xdL = ydL; + ydL = rL; + } + + // Initialise the result array with zeros. + r = []; + rL = xdL + ydL; + for (i = rL; i--;) r.push(0); + + // Multiply! + for (i = ydL; --i >= 0;) { + carry = 0; + for (k = xdL + i; k > i;) { + t = r[k] + yd[i] * xd[k - i - 1] + carry; + r[k--] = t % BASE | 0; + carry = t / BASE | 0; + } + + r[k] = (r[k] + carry) % BASE | 0; + } + + // Remove trailing zeros. + for (; !r[--rL];) r.pop(); + + if (carry) ++e; + else r.shift(); + + y.d = r; + y.e = e; + + return external ? round(y, Ctor.precision) : y; +}; + + +/* + * Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `dp` + * decimal places using rounding mode `rm` or `rounding` if `rm` is omitted. + * + * If `dp` is omitted, return a new Decimal whose value is the value of this Decimal. + * + * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + */ +P.toDecimalPlaces = P.todp = function (dp, rm) { + var x = this, + Ctor = x.constructor; + + x = new Ctor(x); + if (dp === void 0) return x; + + checkInt32(dp, 0, MAX_DIGITS); + + if (rm === void 0) rm = Ctor.rounding; + else checkInt32(rm, 0, 8); + + return round(x, dp + getBase10Exponent(x) + 1, rm); +}; + + +/* + * Return a string representing the value of this Decimal in exponential notation rounded to + * `dp` fixed decimal places using rounding mode `rounding`. + * + * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + */ +P.toExponential = function (dp, rm) { + var str, + x = this, + Ctor = x.constructor; + + if (dp === void 0) { + str = toString$3(x, true); + } else { + checkInt32(dp, 0, MAX_DIGITS); + + if (rm === void 0) rm = Ctor.rounding; + else checkInt32(rm, 0, 8); + + x = round(new Ctor(x), dp + 1, rm); + str = toString$3(x, true, dp + 1); + } + + return str; +}; + + +/* + * Return a string representing the value of this Decimal in normal (fixed-point) notation to + * `dp` fixed decimal places and rounded using rounding mode `rm` or `rounding` if `rm` is + * omitted. + * + * As with JavaScript numbers, (-0).toFixed(0) is '0', but e.g. (-0.00001).toFixed(0) is '-0'. + * + * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + * (-0).toFixed(0) is '0', but (-0.1).toFixed(0) is '-0'. + * (-0).toFixed(1) is '0.0', but (-0.01).toFixed(1) is '-0.0'. + * (-0).toFixed(3) is '0.000'. + * (-0.5).toFixed(0) is '-0'. + * + */ +P.toFixed = function (dp, rm) { + var str, y, + x = this, + Ctor = x.constructor; + + if (dp === void 0) return toString$3(x); + + checkInt32(dp, 0, MAX_DIGITS); + + if (rm === void 0) rm = Ctor.rounding; + else checkInt32(rm, 0, 8); + + y = round(new Ctor(x), dp + getBase10Exponent(x) + 1, rm); + str = toString$3(y.abs(), false, dp + getBase10Exponent(y) + 1); + + // To determine whether to add the minus sign look at the value before it was rounded, + // i.e. look at `x` rather than `y`. + return x.isneg() && !x.isZero() ? '-' + str : str; +}; + + +/* + * Return a new Decimal whose value is the value of this Decimal rounded to a whole number using + * rounding mode `rounding`. + * + */ +P.toInteger = P.toint = function () { + var x = this, + Ctor = x.constructor; + return round(new Ctor(x), getBase10Exponent(x) + 1, Ctor.rounding); +}; + + +/* + * Return the value of this Decimal converted to a number primitive. + * + */ +P.toNumber = function () { + return +this; +}; + + +/* + * Return a new Decimal whose value is the value of this Decimal raised to the power `y`, + * truncated to `precision` significant digits. + * + * For non-integer or very large exponents pow(x, y) is calculated using + * + * x^y = exp(y*ln(x)) + * + * The maximum error is 1 ulp (unit in last place). + * + * y {number|string|Decimal} The power to which to raise this Decimal. + * + */ +P.toPower = P.pow = function (y) { + var e, k, pr, r, sign, yIsInt, + x = this, + Ctor = x.constructor, + guard = 12, + yn = +(y = new Ctor(y)); + + // pow(x, 0) = 1 + if (!y.s) return new Ctor(ONE); + + x = new Ctor(x); + + // pow(0, y > 0) = 0 + // pow(0, y < 0) = Infinity + if (!x.s) { + if (y.s < 1) throw Error(decimalError + 'Infinity'); + return x; + } + + // pow(1, y) = 1 + if (x.eq(ONE)) return x; + + pr = Ctor.precision; + + // pow(x, 1) = x + if (y.eq(ONE)) return round(x, pr); + + e = y.e; + k = y.d.length - 1; + yIsInt = e >= k; + sign = x.s; + + if (!yIsInt) { + + // pow(x < 0, y non-integer) = NaN + if (sign < 0) throw Error(decimalError + 'NaN'); + + // If y is a small integer use the 'exponentiation by squaring' algorithm. + } else if ((k = yn < 0 ? -yn : yn) <= MAX_SAFE_INTEGER$2) { + r = new Ctor(ONE); + + // Max k of 9007199254740991 takes 53 loop iterations. + // Maximum digits array length; leaves [28, 34] guard digits. + e = Math.ceil(pr / LOG_BASE + 4); + + external = false; + + for (;;) { + if (k % 2) { + r = r.times(x); + truncate(r.d, e); + } + + k = mathfloor(k / 2); + if (k === 0) break; + + x = x.times(x); + truncate(x.d, e); + } + + external = true; + + return y.s < 0 ? new Ctor(ONE).div(r) : round(r, pr); + } + + // Result is negative if x is negative and the last digit of integer y is odd. + sign = sign < 0 && y.d[Math.max(e, k)] & 1 ? -1 : 1; + + x.s = 1; + external = false; + r = y.times(ln(x, pr + guard)); + external = true; + r = exp(r); + r.s = sign; + + return r; +}; + + +/* + * Return a string representing the value of this Decimal rounded to `sd` significant digits + * using rounding mode `rounding`. + * + * Return exponential notation if `sd` is less than the number of digits necessary to represent + * the integer part of the value in normal notation. + * + * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + */ +P.toPrecision = function (sd, rm) { + var e, str, + x = this, + Ctor = x.constructor; + + if (sd === void 0) { + e = getBase10Exponent(x); + str = toString$3(x, e <= Ctor.toExpNeg || e >= Ctor.toExpPos); + } else { + checkInt32(sd, 1, MAX_DIGITS); + + if (rm === void 0) rm = Ctor.rounding; + else checkInt32(rm, 0, 8); + + x = round(new Ctor(x), sd, rm); + e = getBase10Exponent(x); + str = toString$3(x, sd <= e || e <= Ctor.toExpNeg, sd); + } + + return str; +}; + + +/* + * Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `sd` + * significant digits using rounding mode `rm`, or to `precision` and `rounding` respectively if + * omitted. + * + * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + */ +P.toSignificantDigits = P.tosd = function (sd, rm) { + var x = this, + Ctor = x.constructor; + + if (sd === void 0) { + sd = Ctor.precision; + rm = Ctor.rounding; + } else { + checkInt32(sd, 1, MAX_DIGITS); + + if (rm === void 0) rm = Ctor.rounding; + else checkInt32(rm, 0, 8); + } + + return round(new Ctor(x), sd, rm); +}; + + +/* + * Return a string representing the value of this Decimal. + * + * Return exponential notation if this Decimal has a positive exponent equal to or greater than + * `toExpPos`, or a negative exponent equal to or less than `toExpNeg`. + * + */ +P.toString = P.valueOf = P.val = P.toJSON = P[Symbol.for('nodejs.util.inspect.custom')] = function () { + var x = this, + e = getBase10Exponent(x), + Ctor = x.constructor; + + return toString$3(x, e <= Ctor.toExpNeg || e >= Ctor.toExpPos); +}; + + +// Helper functions for Decimal.prototype (P) and/or Decimal methods, and their callers. + + +/* + * add P.minus, P.plus + * checkInt32 P.todp, P.toExponential, P.toFixed, P.toPrecision, P.tosd + * digitsToString P.log, P.sqrt, P.pow, toString, exp, ln + * divide P.div, P.idiv, P.log, P.mod, P.sqrt, exp, ln + * exp P.exp, P.pow + * getBase10Exponent P.exponent, P.sd, P.toint, P.sqrt, P.todp, P.toFixed, P.toPrecision, + * P.toString, divide, round, toString, exp, ln + * getLn10 P.log, ln + * getZeroString digitsToString, toString + * ln P.log, P.ln, P.pow, exp + * parseDecimal Decimal + * round P.abs, P.idiv, P.log, P.minus, P.mod, P.neg, P.plus, P.toint, P.sqrt, + * P.times, P.todp, P.toExponential, P.toFixed, P.pow, P.toPrecision, P.tosd, + * divide, getLn10, exp, ln + * subtract P.minus, P.plus + * toString P.toExponential, P.toFixed, P.toPrecision, P.toString, P.valueOf + * truncate P.pow + * + * Throws: P.log, P.mod, P.sd, P.sqrt, P.pow, checkInt32, divide, round, + * getLn10, exp, ln, parseDecimal, Decimal, config + */ + + +function add(x, y) { + var carry, d, e, i, k, len, xd, yd, + Ctor = x.constructor, + pr = Ctor.precision; + + // If either is zero... + if (!x.s || !y.s) { + + // Return x if y is zero. + // Return y if y is non-zero. + if (!y.s) y = new Ctor(x); + return external ? round(y, pr) : y; + } + + xd = x.d; + yd = y.d; + + // x and y are finite, non-zero numbers with the same sign. + + k = x.e; + e = y.e; + xd = xd.slice(); + i = k - e; + + // If base 1e7 exponents differ... + if (i) { + if (i < 0) { + d = xd; + i = -i; + len = yd.length; + } else { + d = yd; + e = k; + len = xd.length; + } + + // Limit number of zeros prepended to max(ceil(pr / LOG_BASE), len) + 1. + k = Math.ceil(pr / LOG_BASE); + len = k > len ? k + 1 : len + 1; + + if (i > len) { + i = len; + d.length = 1; + } + + // Prepend zeros to equalise exponents. Note: Faster to use reverse then do unshifts. + d.reverse(); + for (; i--;) d.push(0); + d.reverse(); + } + + len = xd.length; + i = yd.length; + + // If yd is longer than xd, swap xd and yd so xd points to the longer array. + if (len - i < 0) { + i = len; + d = yd; + yd = xd; + xd = d; + } + + // Only start adding at yd.length - 1 as the further digits of xd can be left as they are. + for (carry = 0; i;) { + carry = (xd[--i] = xd[i] + yd[i] + carry) / BASE | 0; + xd[i] %= BASE; + } + + if (carry) { + xd.unshift(carry); + ++e; + } + + // Remove trailing zeros. + // No need to check for zero, as +x + +y != 0 && -x + -y != 0 + for (len = xd.length; xd[--len] == 0;) xd.pop(); + + y.d = xd; + y.e = e; + + return external ? round(y, pr) : y; +} + + +function checkInt32(i, min, max) { + if (i !== ~~i || i < min || i > max) { + throw Error(invalidArgument + i); + } +} + + +function digitsToString(d) { + var i, k, ws, + indexOfLastWord = d.length - 1, + str = '', + w = d[0]; + + if (indexOfLastWord > 0) { + str += w; + for (i = 1; i < indexOfLastWord; i++) { + ws = d[i] + ''; + k = LOG_BASE - ws.length; + if (k) str += getZeroString(k); + str += ws; + } + + w = d[i]; + ws = w + ''; + k = LOG_BASE - ws.length; + if (k) str += getZeroString(k); + } else if (w === 0) { + return '0'; + } + + // Remove trailing zeros of last w. + for (; w % 10 === 0;) w /= 10; + + return str + w; +} + + +var divide = (function () { + + // Assumes non-zero x and k, and hence non-zero result. + function multiplyInteger(x, k) { + var temp, + carry = 0, + i = x.length; + + for (x = x.slice(); i--;) { + temp = x[i] * k + carry; + x[i] = temp % BASE | 0; + carry = temp / BASE | 0; + } + + if (carry) x.unshift(carry); + + return x; + } + + function compare(a, b, aL, bL) { + var i, r; + + if (aL != bL) { + r = aL > bL ? 1 : -1; + } else { + for (i = r = 0; i < aL; i++) { + if (a[i] != b[i]) { + r = a[i] > b[i] ? 1 : -1; + break; + } + } + } + + return r; + } + + function subtract(a, b, aL) { + var i = 0; + + // Subtract b from a. + for (; aL--;) { + a[aL] -= i; + i = a[aL] < b[aL] ? 1 : 0; + a[aL] = i * BASE + a[aL] - b[aL]; + } + + // Remove leading zeros. + for (; !a[0] && a.length > 1;) a.shift(); + } + + return function (x, y, pr, dp) { + var cmp, e, i, k, prod, prodL, q, qd, rem, remL, rem0, sd, t, xi, xL, yd0, yL, yz, + Ctor = x.constructor, + sign = x.s == y.s ? 1 : -1, + xd = x.d, + yd = y.d; + + // Either 0? + if (!x.s) return new Ctor(x); + if (!y.s) throw Error(decimalError + 'Division by zero'); + + e = x.e - y.e; + yL = yd.length; + xL = xd.length; + q = new Ctor(sign); + qd = q.d = []; + + // Result exponent may be one less than e. + for (i = 0; yd[i] == (xd[i] || 0); ) ++i; + if (yd[i] > (xd[i] || 0)) --e; + + if (pr == null) { + sd = pr = Ctor.precision; + } else if (dp) { + sd = pr + (getBase10Exponent(x) - getBase10Exponent(y)) + 1; + } else { + sd = pr; + } + + if (sd < 0) return new Ctor(0); + + // Convert precision in number of base 10 digits to base 1e7 digits. + sd = sd / LOG_BASE + 2 | 0; + i = 0; + + // divisor < 1e7 + if (yL == 1) { + k = 0; + yd = yd[0]; + sd++; + + // k is the carry. + for (; (i < xL || k) && sd--; i++) { + t = k * BASE + (xd[i] || 0); + qd[i] = t / yd | 0; + k = t % yd | 0; + } + + // divisor >= 1e7 + } else { + + // Normalise xd and yd so highest order digit of yd is >= BASE/2 + k = BASE / (yd[0] + 1) | 0; + + if (k > 1) { + yd = multiplyInteger(yd, k); + xd = multiplyInteger(xd, k); + yL = yd.length; + xL = xd.length; + } + + xi = yL; + rem = xd.slice(0, yL); + remL = rem.length; + + // Add zeros to make remainder as long as divisor. + for (; remL < yL;) rem[remL++] = 0; + + yz = yd.slice(); + yz.unshift(0); + yd0 = yd[0]; + + if (yd[1] >= BASE / 2) ++yd0; + + do { + k = 0; + + // Compare divisor and remainder. + cmp = compare(yd, rem, yL, remL); + + // If divisor < remainder. + if (cmp < 0) { + + // Calculate trial digit, k. + rem0 = rem[0]; + if (yL != remL) rem0 = rem0 * BASE + (rem[1] || 0); + + // k will be how many times the divisor goes into the current remainder. + k = rem0 / yd0 | 0; + + // Algorithm: + // 1. product = divisor * trial digit (k) + // 2. if product > remainder: product -= divisor, k-- + // 3. remainder -= product + // 4. if product was < remainder at 2: + // 5. compare new remainder and divisor + // 6. If remainder > divisor: remainder -= divisor, k++ + + if (k > 1) { + if (k >= BASE) k = BASE - 1; + + // product = divisor * trial digit. + prod = multiplyInteger(yd, k); + prodL = prod.length; + remL = rem.length; + + // Compare product and remainder. + cmp = compare(prod, rem, prodL, remL); + + // product > remainder. + if (cmp == 1) { + k--; + + // Subtract divisor from product. + subtract(prod, yL < prodL ? yz : yd, prodL); + } + } else { + + // cmp is -1. + // If k is 0, there is no need to compare yd and rem again below, so change cmp to 1 + // to avoid it. If k is 1 there is a need to compare yd and rem again below. + if (k == 0) cmp = k = 1; + prod = yd.slice(); + } + + prodL = prod.length; + if (prodL < remL) prod.unshift(0); + + // Subtract product from remainder. + subtract(rem, prod, remL); + + // If product was < previous remainder. + if (cmp == -1) { + remL = rem.length; + + // Compare divisor and new remainder. + cmp = compare(yd, rem, yL, remL); + + // If divisor < new remainder, subtract divisor from remainder. + if (cmp < 1) { + k++; + + // Subtract divisor from remainder. + subtract(rem, yL < remL ? yz : yd, remL); + } + } + + remL = rem.length; + } else if (cmp === 0) { + k++; + rem = [0]; + } // if cmp === 1, k will be 0 + + // Add the next digit, k, to the result array. + qd[i++] = k; + + // Update the remainder. + if (cmp && rem[0]) { + rem[remL++] = xd[xi] || 0; + } else { + rem = [xd[xi]]; + remL = 1; + } + + } while ((xi++ < xL || rem[0] !== void 0) && sd--); + } + + // Leading zero? + if (!qd[0]) qd.shift(); + + q.e = e; + + return round(q, dp ? pr + getBase10Exponent(q) + 1 : pr); + }; +})(); + + +/* + * Return a new Decimal whose value is the natural exponential of `x` truncated to `sd` + * significant digits. + * + * Taylor/Maclaurin series. + * + * exp(x) = x^0/0! + x^1/1! + x^2/2! + x^3/3! + ... + * + * Argument reduction: + * Repeat x = x / 32, k += 5, until |x| < 0.1 + * exp(x) = exp(x / 2^k)^(2^k) + * + * Previously, the argument was initially reduced by + * exp(x) = exp(r) * 10^k where r = x - k * ln10, k = floor(x / ln10) + * to first put r in the range [0, ln10], before dividing by 32 until |x| < 0.1, but this was + * found to be slower than just dividing repeatedly by 32 as above. + * + * (Math object integer min/max: Math.exp(709) = 8.2e+307, Math.exp(-745) = 5e-324) + * + * exp(x) is non-terminating for any finite, non-zero x. + * + */ +function exp(x, sd) { + var denominator, guard, pow, sum, t, wpr, + i = 0, + k = 0, + Ctor = x.constructor, + pr = Ctor.precision; + + if (getBase10Exponent(x) > 16) throw Error(exponentOutOfRange + getBase10Exponent(x)); + + // exp(0) = 1 + if (!x.s) return new Ctor(ONE); + + if (sd == null) { + external = false; + wpr = pr; + } else { + wpr = sd; + } + + t = new Ctor(0.03125); + + while (x.abs().gte(0.1)) { + x = x.times(t); // x = x / 2^5 + k += 5; + } + + // Estimate the precision increase necessary to ensure the first 4 rounding digits are correct. + guard = Math.log(mathpow(2, k)) / Math.LN10 * 2 + 5 | 0; + wpr += guard; + denominator = pow = sum = new Ctor(ONE); + Ctor.precision = wpr; + + for (;;) { + pow = round(pow.times(x), wpr); + denominator = denominator.times(++i); + t = sum.plus(divide(pow, denominator, wpr)); + + if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) { + while (k--) sum = round(sum.times(sum), wpr); + Ctor.precision = pr; + return sd == null ? (external = true, round(sum, pr)) : sum; + } + + sum = t; + } +} + + +// Calculate the base 10 exponent from the base 1e7 exponent. +function getBase10Exponent(x) { + var e = x.e * LOG_BASE, + w = x.d[0]; + + // Add the number of digits of the first word of the digits array. + for (; w >= 10; w /= 10) e++; + return e; +} + + +function getLn10(Ctor, sd, pr) { + + if (sd > Ctor.LN10.sd()) { + + + // Reset global state in case the exception is caught. + external = true; + if (pr) Ctor.precision = pr; + throw Error(decimalError + 'LN10 precision limit exceeded'); + } + + return round(new Ctor(Ctor.LN10), sd); +} + + +function getZeroString(k) { + var zs = ''; + for (; k--;) zs += '0'; + return zs; +} + + +/* + * Return a new Decimal whose value is the natural logarithm of `x` truncated to `sd` significant + * digits. + * + * ln(n) is non-terminating (n != 1) + * + */ +function ln(y, sd) { + var c, c0, denominator, e, numerator, sum, t, wpr, x2, + n = 1, + guard = 10, + x = y, + xd = x.d, + Ctor = x.constructor, + pr = Ctor.precision; + + // ln(-x) = NaN + // ln(0) = -Infinity + if (x.s < 1) throw Error(decimalError + (x.s ? 'NaN' : '-Infinity')); + + // ln(1) = 0 + if (x.eq(ONE)) return new Ctor(0); + + if (sd == null) { + external = false; + wpr = pr; + } else { + wpr = sd; + } + + if (x.eq(10)) { + if (sd == null) external = true; + return getLn10(Ctor, wpr); + } + + wpr += guard; + Ctor.precision = wpr; + c = digitsToString(xd); + c0 = c.charAt(0); + e = getBase10Exponent(x); + + if (Math.abs(e) < 1.5e15) { + + // Argument reduction. + // The series converges faster the closer the argument is to 1, so using + // ln(a^b) = b * ln(a), ln(a) = ln(a^b) / b + // multiply the argument by itself until the leading digits of the significand are 7, 8, 9, + // 10, 11, 12 or 13, recording the number of multiplications so the sum of the series can + // later be divided by this number, then separate out the power of 10 using + // ln(a*10^b) = ln(a) + b*ln(10). + + // max n is 21 (gives 0.9, 1.0 or 1.1) (9e15 / 21 = 4.2e14). + //while (c0 < 9 && c0 != 1 || c0 == 1 && c.charAt(1) > 1) { + // max n is 6 (gives 0.7 - 1.3) + while (c0 < 7 && c0 != 1 || c0 == 1 && c.charAt(1) > 3) { + x = x.times(y); + c = digitsToString(x.d); + c0 = c.charAt(0); + n++; + } + + e = getBase10Exponent(x); + + if (c0 > 1) { + x = new Ctor('0.' + c); + e++; + } else { + x = new Ctor(c0 + '.' + c.slice(1)); + } + } else { + + // The argument reduction method above may result in overflow if the argument y is a massive + // number with exponent >= 1500000000000000 (9e15 / 6 = 1.5e15), so instead recall this + // function using ln(x*10^e) = ln(x) + e*ln(10). + t = getLn10(Ctor, wpr + 2, pr).times(e + ''); + x = ln(new Ctor(c0 + '.' + c.slice(1)), wpr - guard).plus(t); + + Ctor.precision = pr; + return sd == null ? (external = true, round(x, pr)) : x; + } + + // x is reduced to a value near 1. + + // Taylor series. + // ln(y) = ln((1 + x)/(1 - x)) = 2(x + x^3/3 + x^5/5 + x^7/7 + ...) + // where x = (y - 1)/(y + 1) (|x| < 1) + sum = numerator = x = divide(x.minus(ONE), x.plus(ONE), wpr); + x2 = round(x.times(x), wpr); + denominator = 3; + + for (;;) { + numerator = round(numerator.times(x2), wpr); + t = sum.plus(divide(numerator, new Ctor(denominator), wpr)); + + if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) { + sum = sum.times(2); + + // Reverse the argument reduction. + if (e !== 0) sum = sum.plus(getLn10(Ctor, wpr + 2, pr).times(e + '')); + sum = divide(sum, new Ctor(n), wpr); + + Ctor.precision = pr; + return sd == null ? (external = true, round(sum, pr)) : sum; + } + + sum = t; + denominator += 2; + } +} + + +/* + * Parse the value of a new Decimal `x` from string `str`. + */ +function parseDecimal(x, str) { + var e, i, len; + + // Decimal point? + if ((e = str.indexOf('.')) > -1) str = str.replace('.', ''); + + // Exponential form? + if ((i = str.search(/e/i)) > 0) { + + // Determine exponent. + if (e < 0) e = i; + e += +str.slice(i + 1); + str = str.substring(0, i); + } else if (e < 0) { + + // Integer. + e = str.length; + } + + // Determine leading zeros. + for (i = 0; str.charCodeAt(i) === 48;) ++i; + + // Determine trailing zeros. + for (len = str.length; str.charCodeAt(len - 1) === 48;) --len; + str = str.slice(i, len); + + if (str) { + len -= i; + e = e - i - 1; + x.e = mathfloor(e / LOG_BASE); + x.d = []; + + // Transform base + + // e is the base 10 exponent. + // i is where to slice str to get the first word of the digits array. + i = (e + 1) % LOG_BASE; + if (e < 0) i += LOG_BASE; + + if (i < len) { + if (i) x.d.push(+str.slice(0, i)); + for (len -= LOG_BASE; i < len;) x.d.push(+str.slice(i, i += LOG_BASE)); + str = str.slice(i); + i = LOG_BASE - str.length; + } else { + i -= len; + } + + for (; i--;) str += '0'; + x.d.push(+str); + + if (external && (x.e > MAX_E || x.e < -MAX_E)) throw Error(exponentOutOfRange + e); + } else { + + // Zero. + x.s = 0; + x.e = 0; + x.d = [0]; + } + + return x; +} + + +/* + * Round `x` to `sd` significant digits, using rounding mode `rm` if present (truncate otherwise). + */ + function round(x, sd, rm) { + var i, j, k, n, rd, doRound, w, xdi, + xd = x.d; + + // rd: the rounding digit, i.e. the digit after the digit that may be rounded up. + // w: the word of xd which contains the rounding digit, a base 1e7 number. + // xdi: the index of w within xd. + // n: the number of digits of w. + // i: what would be the index of rd within w if all the numbers were 7 digits long (i.e. if + // they had leading zeros) + // j: if > 0, the actual index of rd within w (if < 0, rd is a leading zero). + + // Get the length of the first word of the digits array xd. + for (n = 1, k = xd[0]; k >= 10; k /= 10) n++; + i = sd - n; + + // Is the rounding digit in the first word of xd? + if (i < 0) { + i += LOG_BASE; + j = sd; + w = xd[xdi = 0]; + } else { + xdi = Math.ceil((i + 1) / LOG_BASE); + k = xd.length; + if (xdi >= k) return x; + w = k = xd[xdi]; + + // Get the number of digits of w. + for (n = 1; k >= 10; k /= 10) n++; + + // Get the index of rd within w. + i %= LOG_BASE; + + // Get the index of rd within w, adjusted for leading zeros. + // The number of leading zeros of w is given by LOG_BASE - n. + j = i - LOG_BASE + n; + } + + if (rm !== void 0) { + k = mathpow(10, n - j - 1); + + // Get the rounding digit at index j of w. + rd = w / k % 10 | 0; + + // Are there any non-zero digits after the rounding digit? + doRound = sd < 0 || xd[xdi + 1] !== void 0 || w % k; + + // The expression `w % mathpow(10, n - j - 1)` returns all the digits of w to the right of the + // digit at (left-to-right) index j, e.g. if w is 908714 and j is 2, the expression will give + // 714. + + doRound = rm < 4 + ? (rd || doRound) && (rm == 0 || rm == (x.s < 0 ? 3 : 2)) + : rd > 5 || rd == 5 && (rm == 4 || doRound || rm == 6 && + + // Check whether the digit to the left of the rounding digit is odd. + ((i > 0 ? j > 0 ? w / mathpow(10, n - j) : 0 : xd[xdi - 1]) % 10) & 1 || + rm == (x.s < 0 ? 8 : 7)); + } + + if (sd < 1 || !xd[0]) { + if (doRound) { + k = getBase10Exponent(x); + xd.length = 1; + + // Convert sd to decimal places. + sd = sd - k - 1; + + // 1, 0.1, 0.01, 0.001, 0.0001 etc. + xd[0] = mathpow(10, (LOG_BASE - sd % LOG_BASE) % LOG_BASE); + x.e = mathfloor(-sd / LOG_BASE) || 0; + } else { + xd.length = 1; + + // Zero. + xd[0] = x.e = x.s = 0; + } + + return x; + } + + // Remove excess digits. + if (i == 0) { + xd.length = xdi; + k = 1; + xdi--; + } else { + xd.length = xdi + 1; + k = mathpow(10, LOG_BASE - i); + + // E.g. 56700 becomes 56000 if 7 is the rounding digit. + // j > 0 means i > number of leading zeros of w. + xd[xdi] = j > 0 ? (w / mathpow(10, n - j) % mathpow(10, j) | 0) * k : 0; + } + + if (doRound) { + for (;;) { + + // Is the digit to be rounded up in the first word of xd? + if (xdi == 0) { + if ((xd[0] += k) == BASE) { + xd[0] = 1; + ++x.e; + } + + break; + } else { + xd[xdi] += k; + if (xd[xdi] != BASE) break; + xd[xdi--] = 0; + k = 1; + } + } + } + + // Remove trailing zeros. + for (i = xd.length; xd[--i] === 0;) xd.pop(); + + if (external && (x.e > MAX_E || x.e < -MAX_E)) { + throw Error(exponentOutOfRange + getBase10Exponent(x)); + } + + return x; +} + + +function subtract(x, y) { + var d, e, i, j, k, len, xd, xe, xLTy, yd, + Ctor = x.constructor, + pr = Ctor.precision; + + // Return y negated if x is zero. + // Return x if y is zero and x is non-zero. + if (!x.s || !y.s) { + if (y.s) y.s = -y.s; + else y = new Ctor(x); + return external ? round(y, pr) : y; + } + + xd = x.d; + yd = y.d; + + // x and y are non-zero numbers with the same sign. + + e = y.e; + xe = x.e; + xd = xd.slice(); + k = xe - e; + + // If exponents differ... + if (k) { + xLTy = k < 0; + + if (xLTy) { + d = xd; + k = -k; + len = yd.length; + } else { + d = yd; + e = xe; + len = xd.length; + } + + // Numbers with massively different exponents would result in a very high number of zeros + // needing to be prepended, but this can be avoided while still ensuring correct rounding by + // limiting the number of zeros to `Math.ceil(pr / LOG_BASE) + 2`. + i = Math.max(Math.ceil(pr / LOG_BASE), len) + 2; + + if (k > i) { + k = i; + d.length = 1; + } + + // Prepend zeros to equalise exponents. + d.reverse(); + for (i = k; i--;) d.push(0); + d.reverse(); + + // Base 1e7 exponents equal. + } else { + + // Check digits to determine which is the bigger number. + + i = xd.length; + len = yd.length; + xLTy = i < len; + if (xLTy) len = i; + + for (i = 0; i < len; i++) { + if (xd[i] != yd[i]) { + xLTy = xd[i] < yd[i]; + break; + } + } + + k = 0; + } + + if (xLTy) { + d = xd; + xd = yd; + yd = d; + y.s = -y.s; + } + + len = xd.length; + + // Append zeros to xd if shorter. + // Don't add zeros to yd if shorter as subtraction only needs to start at yd length. + for (i = yd.length - len; i > 0; --i) xd[len++] = 0; + + // Subtract yd from xd. + for (i = yd.length; i > k;) { + if (xd[--i] < yd[i]) { + for (j = i; j && xd[--j] === 0;) xd[j] = BASE - 1; + --xd[j]; + xd[i] += BASE; + } + + xd[i] -= yd[i]; + } + + // Remove trailing zeros. + for (; xd[--len] === 0;) xd.pop(); + + // Remove leading zeros and adjust exponent accordingly. + for (; xd[0] === 0; xd.shift()) --e; + + // Zero? + if (!xd[0]) return new Ctor(0); + + y.d = xd; + y.e = e; + + //return external && xd.length >= pr / LOG_BASE ? round(y, pr) : y; + return external ? round(y, pr) : y; +} + + +function toString$3(x, isExp, sd) { + var k, + e = getBase10Exponent(x), + str = digitsToString(x.d), + len = str.length; + + if (isExp) { + if (sd && (k = sd - len) > 0) { + str = str.charAt(0) + '.' + str.slice(1) + getZeroString(k); + } else if (len > 1) { + str = str.charAt(0) + '.' + str.slice(1); + } + + str = str + (e < 0 ? 'e' : 'e+') + e; + } else if (e < 0) { + str = '0.' + getZeroString(-e - 1) + str; + if (sd && (k = sd - len) > 0) str += getZeroString(k); + } else if (e >= len) { + str += getZeroString(e + 1 - len); + if (sd && (k = sd - e - 1) > 0) str = str + '.' + getZeroString(k); + } else { + if ((k = e + 1) < len) str = str.slice(0, k) + '.' + str.slice(k); + if (sd && (k = sd - len) > 0) { + if (e + 1 === len) str += '.'; + str += getZeroString(k); + } + } + + return x.s < 0 ? '-' + str : str; +} + + +// Does not strip trailing zeros. +function truncate(arr, len) { + if (arr.length > len) { + arr.length = len; + return true; + } +} + + +// Decimal methods + + +/* + * clone + * config/set + */ + + +/* + * Create and return a Decimal constructor with the same configuration properties as this Decimal + * constructor. + * + */ +function clone(obj) { + var i, p, ps; + + /* + * The Decimal constructor and exported function. + * Return a new Decimal instance. + * + * value {number|string|Decimal} A numeric value. + * + */ + function Decimal(value) { + var x = this; + + // Decimal called without new. + if (!(x instanceof Decimal)) return new Decimal(value); + + // Retain a reference to this Decimal constructor, and shadow Decimal.prototype.constructor + // which points to Object. + x.constructor = Decimal; + + // Duplicate. + if (value instanceof Decimal) { + x.s = value.s; + x.e = value.e; + x.d = (value = value.d) ? value.slice() : value; + return; + } + + if (typeof value === 'number') { + + // Reject Infinity/NaN. + if (value * 0 !== 0) { + throw Error(invalidArgument + value); + } + + if (value > 0) { + x.s = 1; + } else if (value < 0) { + value = -value; + x.s = -1; + } else { + x.s = 0; + x.e = 0; + x.d = [0]; + return; + } + + // Fast path for small integers. + if (value === ~~value && value < 1e7) { + x.e = 0; + x.d = [value]; + return; + } + + return parseDecimal(x, value.toString()); + } else if (typeof value !== 'string') { + throw Error(invalidArgument + value); + } + + // Minus sign? + if (value.charCodeAt(0) === 45) { + value = value.slice(1); + x.s = -1; + } else { + x.s = 1; + } + + if (isDecimal.test(value)) parseDecimal(x, value); + else throw Error(invalidArgument + value); + } + + Decimal.prototype = P; + + Decimal.ROUND_UP = 0; + Decimal.ROUND_DOWN = 1; + Decimal.ROUND_CEIL = 2; + Decimal.ROUND_FLOOR = 3; + Decimal.ROUND_HALF_UP = 4; + Decimal.ROUND_HALF_DOWN = 5; + Decimal.ROUND_HALF_EVEN = 6; + Decimal.ROUND_HALF_CEIL = 7; + Decimal.ROUND_HALF_FLOOR = 8; + + Decimal.clone = clone; + Decimal.config = Decimal.set = config; + + if (obj === void 0) obj = {}; + if (obj) { + ps = ['precision', 'rounding', 'toExpNeg', 'toExpPos', 'LN10']; + for (i = 0; i < ps.length;) if (!obj.hasOwnProperty(p = ps[i++])) obj[p] = this[p]; + } + + Decimal.config(obj); + + return Decimal; +} + + +/* + * Configure global settings for a Decimal constructor. + * + * `obj` is an object with one or more of the following properties, + * + * precision {number} + * rounding {number} + * toExpNeg {number} + * toExpPos {number} + * + * E.g. Decimal.config({ precision: 20, rounding: 4 }) + * + */ +function config(obj) { + if (!obj || typeof obj !== 'object') { + throw Error(decimalError + 'Object expected'); + } + var i, p, v, + ps = [ + 'precision', 1, MAX_DIGITS, + 'rounding', 0, 8, + 'toExpNeg', -1 / 0, 0, + 'toExpPos', 0, 1 / 0 + ]; + + for (i = 0; i < ps.length; i += 3) { + if ((v = obj[p = ps[i]]) !== void 0) { + if (mathfloor(v) === v && v >= ps[i + 1] && v <= ps[i + 2]) this[p] = v; + else throw Error(invalidArgument + p + ': ' + v); + } + } + + if ((v = obj[p = 'LN10']) !== void 0) { + if (v == Math.LN10) this[p] = new this(v); + else throw Error(invalidArgument + p + ': ' + v); + } + + return this; +} + + +// Create and configure initial Decimal constructor. +var Decimal = clone(defaults); + +// Internal constant. +ONE = new Decimal(1); -/* - * Return a new Decimal whose value is the value of this Decimal divided by `y`, truncated to - * `precision` significant digits. - * - */ -P.dividedBy = P.div = function (y) { - return divide(this, new this.constructor(y)); +Decimal.set({ + precision: 30, + toExpNeg: -7, + toExpPos: 29, +}); +var n = new Decimal(60 * 60 * 24 * 365); +var lookup = {}; +/** + * Get interest rate in percentage points for a specified fee. + * This function uses a lookup table for performance reasons. + * This function uses decimal.js-light, since we need non-integer powers for our calculations here. + * We can remove that dependency in the future if we decide to either add a hardcoded + * lookup table for fees and interest rates or if we decide to implement the relevant + * functions here by hand. + * @param fee Fee + */ +var feeToInterestRate = function (fee) { + // tslint:disable-next-line:no-parameter-reassignment + if (typeof fee !== 'string' && typeof fee !== 'number') { + fee = fee.toString(); + } + if (lookup[fee]) { + return lookup[fee]; + } + var i = new Decimal(fee).div('1e27').pow(n); + var interestRate = i.minus(1).mul(100).toSignificantDigits(2); + var interestRateString = interestRate.toString(); + lookup[fee] = interestRateString; + return interestRateString; }; - -/* - * Return a new Decimal whose value is the integer part of dividing the value of this Decimal - * by the value of `y`, truncated to `precision` significant digits. - * - */ -P.dividedToIntegerBy = P.idiv = function (y) { - var x = this, - Ctor = x.constructor; - return round(divide(x, new Ctor(y), 0, 1), Ctor.precision); +function getLoanStatus(principal, debt) { + if (!principal.isZero()) { + return 'Whitelisted'; + } + if (principal.isZero() && !debt.isZero()) { + return 'Ongoing'; + } + if (principal.isZero() && debt.isZero()) { + return 'Repaid'; + } + throw Error('Unknown loan status'); +} + +Decimal.set({ + precision: 28, + toExpNeg: -7, + toExpPos: 29, +}); +var n$1 = new Decimal(60 * 60 * 24 * 365); +var lookup$1 = {}; +/** + * Get fee for a specified interest rate. This function uses a lookup table for performance reasons. + * This function uses decimal.js-light, since we need non-integer powers for our calculations here. + * We can remove that dependency in the future if we decide to either add a hardcoded + * lookup table for fees and interest rates or if we decide to implement the relevant + * functions here by hand. + * @param interestRate Interest rate in percentage points, i. e. "5" for 5 % (= 0.05) + */ +var interestRateToFee = function (interestRate) { + if (lookup$1[interestRate]) { + return lookup$1[interestRate]; + } + var i = new Decimal(interestRate).div(100).plus(1); + var fee = i.pow(new Decimal(1).div(n$1)).mul('1e27').toDecimalPlaces(0); + var feeString = fee.toString(); + lookup$1[interestRate] = feeString; + return feeString; }; - -/* - * Return true if the value of this Decimal is equal to the value of `y`, otherwise return false. - * - */ -P.equals = P.eq = function (y) { - return !this.cmp(y); -}; - - -/* - * Return the (base 10) exponent value of this Decimal (this.e is the base 10000000 exponent). - * - */ -P.exponent = function () { - return getBase10Exponent(this); -}; - - -/* - * Return true if the value of this Decimal is greater than the value of `y`, otherwise return - * false. - * - */ -P.greaterThan = P.gt = function (y) { - return this.cmp(y) > 0; -}; - - -/* - * Return true if the value of this Decimal is greater than or equal to the value of `y`, - * otherwise return false. - * - */ -P.greaterThanOrEqualTo = P.gte = function (y) { - return this.cmp(y) >= 0; -}; - - -/* - * Return true if the value of this Decimal is an integer, otherwise return false. - * - */ -P.isInteger = P.isint = function () { - return this.e > this.d.length - 2; -}; - - -/* - * Return true if the value of this Decimal is negative, otherwise return false. - * - */ -P.isNegative = P.isneg = function () { - return this.s < 0; -}; - - -/* - * Return true if the value of this Decimal is positive, otherwise return false. - * - */ -P.isPositive = P.ispos = function () { - return this.s > 0; -}; - - -/* - * Return true if the value of this Decimal is 0, otherwise return false. - * - */ -P.isZero = function () { - return this.s === 0; -}; - - -/* - * Return true if the value of this Decimal is less than `y`, otherwise return false. - * - */ -P.lessThan = P.lt = function (y) { - return this.cmp(y) < 0; -}; - - -/* - * Return true if the value of this Decimal is less than or equal to `y`, otherwise return false. - * - */ -P.lessThanOrEqualTo = P.lte = function (y) { - return this.cmp(y) < 1; -}; - - -/* - * Return the logarithm of the value of this Decimal to the specified base, truncated to - * `precision` significant digits. - * - * If no base is specified, return log[10](x). - * - * log[base](x) = ln(x) / ln(base) - * - * The maximum error of the result is 1 ulp (unit in the last place). - * - * [base] {number|string|Decimal} The base of the logarithm. - * - */ -P.logarithm = P.log = function (base) { - var r, - x = this, - Ctor = x.constructor, - pr = Ctor.precision, - wpr = pr + 5; - - // Default base is 10. - if (base === void 0) { - base = new Ctor(10); - } else { - base = new Ctor(base); - - // log[-b](x) = NaN - // log[0](x) = NaN - // log[1](x) = NaN - if (base.s < 1 || base.eq(ONE)) throw Error(decimalError + 'NaN'); - } - - // log[b](-x) = NaN - // log[b](0) = -Infinity - if (x.s < 1) throw Error(decimalError + (x.s ? 'NaN' : '-Infinity')); - - // log[b](1) = 0 - if (x.eq(ONE)) return new Ctor(0); - - external = false; - r = divide(ln(x, wpr), ln(base, wpr), wpr); - external = true; - - return round(r, pr); -}; - - -/* - * Return a new Decimal whose value is the value of this Decimal minus `y`, truncated to - * `precision` significant digits. - * - */ -P.minus = P.sub = function (y) { - var x = this; - y = new x.constructor(y); - return x.s == y.s ? subtract(x, y) : add(x, (y.s = -y.s, y)); -}; - - -/* - * Return a new Decimal whose value is the value of this Decimal modulo `y`, truncated to - * `precision` significant digits. - * - */ -P.modulo = P.mod = function (y) { - var q, - x = this, - Ctor = x.constructor, - pr = Ctor.precision; - - y = new Ctor(y); - - // x % 0 = NaN - if (!y.s) throw Error(decimalError + 'NaN'); - - // Return x if x is 0. - if (!x.s) return round(new Ctor(x), pr); - - // Prevent rounding of intermediate calculations. - external = false; - q = divide(x, y, 0, 1).times(y); - external = true; - - return x.minus(q); -}; - - -/* - * Return a new Decimal whose value is the natural exponential of the value of this Decimal, - * i.e. the base e raised to the power the value of this Decimal, truncated to `precision` - * significant digits. - * - */ -P.naturalExponential = P.exp = function () { - return exp(this); -}; - - -/* - * Return a new Decimal whose value is the natural logarithm of the value of this Decimal, - * truncated to `precision` significant digits. - * - */ -P.naturalLogarithm = P.ln = function () { - return ln(this); -}; - - -/* - * Return a new Decimal whose value is the value of this Decimal negated, i.e. as if multiplied by - * -1. - * - */ -P.negated = P.neg = function () { - var x = new this.constructor(this); - x.s = -x.s || 0; - return x; -}; - - -/* - * Return a new Decimal whose value is the value of this Decimal plus `y`, truncated to - * `precision` significant digits. - * - */ -P.plus = P.add = function (y) { - var x = this; - y = new x.constructor(y); - return x.s == y.s ? add(x, y) : subtract(x, (y.s = -y.s, y)); -}; - - -/* - * Return the number of significant digits of the value of this Decimal. - * - * [z] {boolean|number} Whether to count integer-part trailing zeros: true, false, 1 or 0. - * - */ -P.precision = P.sd = function (z) { - var e, sd, w, - x = this; - - if (z !== void 0 && z !== !!z && z !== 1 && z !== 0) throw Error(invalidArgument + z); - - e = getBase10Exponent(x) + 1; - w = x.d.length - 1; - sd = w * LOG_BASE + 1; - w = x.d[w]; - - // If non-zero... - if (w) { - - // Subtract the number of trailing zeros of the last word. - for (; w % 10 == 0; w /= 10) sd--; - - // Add the number of digits of the first word. - for (w = x.d[0]; w >= 10; w /= 10) sd++; - } - - return z && e > sd ? e : sd; -}; - - -/* - * Return a new Decimal whose value is the square root of this Decimal, truncated to `precision` - * significant digits. - * - */ -P.squareRoot = P.sqrt = function () { - var e, n, pr, r, s, t, wpr, - x = this, - Ctor = x.constructor; - - // Negative or zero? - if (x.s < 1) { - if (!x.s) return new Ctor(0); - - // sqrt(-x) = NaN - throw Error(decimalError + 'NaN'); - } - - e = getBase10Exponent(x); - external = false; - - // Initial estimate. - s = Math.sqrt(+x); - - // Math.sqrt underflow/overflow? - // Pass x to Math.sqrt as integer, then adjust the exponent of the result. - if (s == 0 || s == 1 / 0) { - n = digitsToString(x.d); - if ((n.length + e) % 2 == 0) n += '0'; - s = Math.sqrt(n); - e = mathfloor((e + 1) / 2) - (e < 0 || e % 2); - - if (s == 1 / 0) { - n = '1e' + e; - } else { - n = s.toExponential(); - n = n.slice(0, n.indexOf('e') + 1) + e; - } - - r = new Ctor(n); - } else { - r = new Ctor(s.toString()); - } - - pr = Ctor.precision; - s = wpr = pr + 3; - - // Newton-Raphson iteration. - for (;;) { - t = r; - r = t.plus(divide(x, t, wpr + 2)).times(0.5); - - if (digitsToString(t.d).slice(0, wpr) === (n = digitsToString(r.d)).slice(0, wpr)) { - n = n.slice(wpr - 3, wpr + 1); - - // The 4th rounding digit may be in error by -1 so if the 4 rounding digits are 9999 or - // 4999, i.e. approaching a rounding boundary, continue the iteration. - if (s == wpr && n == '4999') { - - // On the first iteration only, check to see if rounding up gives the exact result as the - // nines may infinitely repeat. - round(t, pr + 1, 0); - - if (t.times(t).eq(x)) { - r = t; - break; - } - } else if (n != '9999') { - break; - } - - wpr += 4; - } - } - - external = true; - - return round(r, pr); -}; - - -/* - * Return a new Decimal whose value is the value of this Decimal times `y`, truncated to - * `precision` significant digits. - * - */ -P.times = P.mul = function (y) { - var carry, e, i, k, r, rL, t, xdL, ydL, - x = this, - Ctor = x.constructor, - xd = x.d, - yd = (y = new Ctor(y)).d; - - // Return 0 if either is 0. - if (!x.s || !y.s) return new Ctor(0); - - y.s *= x.s; - e = x.e + y.e; - xdL = xd.length; - ydL = yd.length; - - // Ensure xd points to the longer array. - if (xdL < ydL) { - r = xd; - xd = yd; - yd = r; - rL = xdL; - xdL = ydL; - ydL = rL; - } - - // Initialise the result array with zeros. - r = []; - rL = xdL + ydL; - for (i = rL; i--;) r.push(0); - - // Multiply! - for (i = ydL; --i >= 0;) { - carry = 0; - for (k = xdL + i; k > i;) { - t = r[k] + yd[i] * xd[k - i - 1] + carry; - r[k--] = t % BASE | 0; - carry = t / BASE | 0; - } - - r[k] = (r[k] + carry) % BASE | 0; - } - - // Remove trailing zeros. - for (; !r[--rL];) r.pop(); - - if (carry) ++e; - else r.shift(); - - y.d = r; - y.e = e; - - return external ? round(y, Ctor.precision) : y; -}; - - -/* - * Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `dp` - * decimal places using rounding mode `rm` or `rounding` if `rm` is omitted. - * - * If `dp` is omitted, return a new Decimal whose value is the value of this Decimal. - * - * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - */ -P.toDecimalPlaces = P.todp = function (dp, rm) { - var x = this, - Ctor = x.constructor; - - x = new Ctor(x); - if (dp === void 0) return x; - - checkInt32(dp, 0, MAX_DIGITS); - - if (rm === void 0) rm = Ctor.rounding; - else checkInt32(rm, 0, 8); - - return round(x, dp + getBase10Exponent(x) + 1, rm); -}; - - -/* - * Return a string representing the value of this Decimal in exponential notation rounded to - * `dp` fixed decimal places using rounding mode `rounding`. - * - * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - */ -P.toExponential = function (dp, rm) { - var str, - x = this, - Ctor = x.constructor; - - if (dp === void 0) { - str = toString$3(x, true); - } else { - checkInt32(dp, 0, MAX_DIGITS); - - if (rm === void 0) rm = Ctor.rounding; - else checkInt32(rm, 0, 8); - - x = round(new Ctor(x), dp + 1, rm); - str = toString$3(x, true, dp + 1); - } - - return str; -}; - - -/* - * Return a string representing the value of this Decimal in normal (fixed-point) notation to - * `dp` fixed decimal places and rounded using rounding mode `rm` or `rounding` if `rm` is - * omitted. - * - * As with JavaScript numbers, (-0).toFixed(0) is '0', but e.g. (-0.00001).toFixed(0) is '-0'. - * - * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - * (-0).toFixed(0) is '0', but (-0.1).toFixed(0) is '-0'. - * (-0).toFixed(1) is '0.0', but (-0.01).toFixed(1) is '-0.0'. - * (-0).toFixed(3) is '0.000'. - * (-0.5).toFixed(0) is '-0'. - * - */ -P.toFixed = function (dp, rm) { - var str, y, - x = this, - Ctor = x.constructor; - - if (dp === void 0) return toString$3(x); - - checkInt32(dp, 0, MAX_DIGITS); - - if (rm === void 0) rm = Ctor.rounding; - else checkInt32(rm, 0, 8); - - y = round(new Ctor(x), dp + getBase10Exponent(x) + 1, rm); - str = toString$3(y.abs(), false, dp + getBase10Exponent(y) + 1); - - // To determine whether to add the minus sign look at the value before it was rounded, - // i.e. look at `x` rather than `y`. - return x.isneg() && !x.isZero() ? '-' + str : str; -}; - - -/* - * Return a new Decimal whose value is the value of this Decimal rounded to a whole number using - * rounding mode `rounding`. - * - */ -P.toInteger = P.toint = function () { - var x = this, - Ctor = x.constructor; - return round(new Ctor(x), getBase10Exponent(x) + 1, Ctor.rounding); -}; - - -/* - * Return the value of this Decimal converted to a number primitive. - * - */ -P.toNumber = function () { - return +this; -}; - - -/* - * Return a new Decimal whose value is the value of this Decimal raised to the power `y`, - * truncated to `precision` significant digits. - * - * For non-integer or very large exponents pow(x, y) is calculated using - * - * x^y = exp(y*ln(x)) - * - * The maximum error is 1 ulp (unit in last place). - * - * y {number|string|Decimal} The power to which to raise this Decimal. - * - */ -P.toPower = P.pow = function (y) { - var e, k, pr, r, sign, yIsInt, - x = this, - Ctor = x.constructor, - guard = 12, - yn = +(y = new Ctor(y)); - - // pow(x, 0) = 1 - if (!y.s) return new Ctor(ONE); - - x = new Ctor(x); - - // pow(0, y > 0) = 0 - // pow(0, y < 0) = Infinity - if (!x.s) { - if (y.s < 1) throw Error(decimalError + 'Infinity'); - return x; - } - - // pow(1, y) = 1 - if (x.eq(ONE)) return x; - - pr = Ctor.precision; - - // pow(x, 1) = x - if (y.eq(ONE)) return round(x, pr); - - e = y.e; - k = y.d.length - 1; - yIsInt = e >= k; - sign = x.s; - - if (!yIsInt) { - - // pow(x < 0, y non-integer) = NaN - if (sign < 0) throw Error(decimalError + 'NaN'); - - // If y is a small integer use the 'exponentiation by squaring' algorithm. - } else if ((k = yn < 0 ? -yn : yn) <= MAX_SAFE_INTEGER$2) { - r = new Ctor(ONE); - - // Max k of 9007199254740991 takes 53 loop iterations. - // Maximum digits array length; leaves [28, 34] guard digits. - e = Math.ceil(pr / LOG_BASE + 4); - - external = false; - - for (;;) { - if (k % 2) { - r = r.times(x); - truncate(r.d, e); - } - - k = mathfloor(k / 2); - if (k === 0) break; - - x = x.times(x); - truncate(x.d, e); - } - - external = true; - - return y.s < 0 ? new Ctor(ONE).div(r) : round(r, pr); - } - - // Result is negative if x is negative and the last digit of integer y is odd. - sign = sign < 0 && y.d[Math.max(e, k)] & 1 ? -1 : 1; - - x.s = 1; - external = false; - r = y.times(ln(x, pr + guard)); - external = true; - r = exp(r); - r.s = sign; - - return r; -}; - - -/* - * Return a string representing the value of this Decimal rounded to `sd` significant digits - * using rounding mode `rounding`. - * - * Return exponential notation if `sd` is less than the number of digits necessary to represent - * the integer part of the value in normal notation. - * - * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - */ -P.toPrecision = function (sd, rm) { - var e, str, - x = this, - Ctor = x.constructor; - - if (sd === void 0) { - e = getBase10Exponent(x); - str = toString$3(x, e <= Ctor.toExpNeg || e >= Ctor.toExpPos); - } else { - checkInt32(sd, 1, MAX_DIGITS); - - if (rm === void 0) rm = Ctor.rounding; - else checkInt32(rm, 0, 8); - - x = round(new Ctor(x), sd, rm); - e = getBase10Exponent(x); - str = toString$3(x, sd <= e || e <= Ctor.toExpNeg, sd); - } - - return str; -}; - - -/* - * Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `sd` - * significant digits using rounding mode `rm`, or to `precision` and `rounding` respectively if - * omitted. - * - * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - */ -P.toSignificantDigits = P.tosd = function (sd, rm) { - var x = this, - Ctor = x.constructor; - - if (sd === void 0) { - sd = Ctor.precision; - rm = Ctor.rounding; - } else { - checkInt32(sd, 1, MAX_DIGITS); - - if (rm === void 0) rm = Ctor.rounding; - else checkInt32(rm, 0, 8); - } - - return round(new Ctor(x), sd, rm); -}; - - -/* - * Return a string representing the value of this Decimal. - * - * Return exponential notation if this Decimal has a positive exponent equal to or greater than - * `toExpPos`, or a negative exponent equal to or less than `toExpNeg`. - * - */ -P.toString = P.valueOf = P.val = P.toJSON = P[Symbol.for('nodejs.util.inspect.custom')] = function () { - var x = this, - e = getBase10Exponent(x), - Ctor = x.constructor; - - return toString$3(x, e <= Ctor.toExpNeg || e >= Ctor.toExpPos); -}; - - -// Helper functions for Decimal.prototype (P) and/or Decimal methods, and their callers. - - -/* - * add P.minus, P.plus - * checkInt32 P.todp, P.toExponential, P.toFixed, P.toPrecision, P.tosd - * digitsToString P.log, P.sqrt, P.pow, toString, exp, ln - * divide P.div, P.idiv, P.log, P.mod, P.sqrt, exp, ln - * exp P.exp, P.pow - * getBase10Exponent P.exponent, P.sd, P.toint, P.sqrt, P.todp, P.toFixed, P.toPrecision, - * P.toString, divide, round, toString, exp, ln - * getLn10 P.log, ln - * getZeroString digitsToString, toString - * ln P.log, P.ln, P.pow, exp - * parseDecimal Decimal - * round P.abs, P.idiv, P.log, P.minus, P.mod, P.neg, P.plus, P.toint, P.sqrt, - * P.times, P.todp, P.toExponential, P.toFixed, P.pow, P.toPrecision, P.tosd, - * divide, getLn10, exp, ln - * subtract P.minus, P.plus - * toString P.toExponential, P.toFixed, P.toPrecision, P.toString, P.valueOf - * truncate P.pow - * - * Throws: P.log, P.mod, P.sd, P.sqrt, P.pow, checkInt32, divide, round, - * getLn10, exp, ln, parseDecimal, Decimal, config - */ - - -function add(x, y) { - var carry, d, e, i, k, len, xd, yd, - Ctor = x.constructor, - pr = Ctor.precision; - - // If either is zero... - if (!x.s || !y.s) { - - // Return x if y is zero. - // Return y if y is non-zero. - if (!y.s) y = new Ctor(x); - return external ? round(y, pr) : y; - } - - xd = x.d; - yd = y.d; - - // x and y are finite, non-zero numbers with the same sign. - - k = x.e; - e = y.e; - xd = xd.slice(); - i = k - e; - - // If base 1e7 exponents differ... - if (i) { - if (i < 0) { - d = xd; - i = -i; - len = yd.length; - } else { - d = yd; - e = k; - len = xd.length; - } - - // Limit number of zeros prepended to max(ceil(pr / LOG_BASE), len) + 1. - k = Math.ceil(pr / LOG_BASE); - len = k > len ? k + 1 : len + 1; - - if (i > len) { - i = len; - d.length = 1; - } - - // Prepend zeros to equalise exponents. Note: Faster to use reverse then do unshifts. - d.reverse(); - for (; i--;) d.push(0); - d.reverse(); - } - - len = xd.length; - i = yd.length; - - // If yd is longer than xd, swap xd and yd so xd points to the longer array. - if (len - i < 0) { - i = len; - d = yd; - yd = xd; - xd = d; - } - - // Only start adding at yd.length - 1 as the further digits of xd can be left as they are. - for (carry = 0; i;) { - carry = (xd[--i] = xd[i] + yd[i] + carry) / BASE | 0; - xd[i] %= BASE; - } - - if (carry) { - xd.unshift(carry); - ++e; - } - - // Remove trailing zeros. - // No need to check for zero, as +x + +y != 0 && -x + -y != 0 - for (len = xd.length; xd[--len] == 0;) xd.pop(); - - y.d = xd; - y.e = e; - - return external ? round(y, pr) : y; -} - - -function checkInt32(i, min, max) { - if (i !== ~~i || i < min || i > max) { - throw Error(invalidArgument + i); - } -} - - -function digitsToString(d) { - var i, k, ws, - indexOfLastWord = d.length - 1, - str = '', - w = d[0]; - - if (indexOfLastWord > 0) { - str += w; - for (i = 1; i < indexOfLastWord; i++) { - ws = d[i] + ''; - k = LOG_BASE - ws.length; - if (k) str += getZeroString(k); - str += ws; - } - - w = d[i]; - ws = w + ''; - k = LOG_BASE - ws.length; - if (k) str += getZeroString(k); - } else if (w === 0) { - return '0'; - } - - // Remove trailing zeros of last w. - for (; w % 10 === 0;) w /= 10; - - return str + w; -} - - -var divide = (function () { - - // Assumes non-zero x and k, and hence non-zero result. - function multiplyInteger(x, k) { - var temp, - carry = 0, - i = x.length; - - for (x = x.slice(); i--;) { - temp = x[i] * k + carry; - x[i] = temp % BASE | 0; - carry = temp / BASE | 0; - } - - if (carry) x.unshift(carry); - - return x; - } - - function compare(a, b, aL, bL) { - var i, r; - - if (aL != bL) { - r = aL > bL ? 1 : -1; - } else { - for (i = r = 0; i < aL; i++) { - if (a[i] != b[i]) { - r = a[i] > b[i] ? 1 : -1; - break; - } - } - } - - return r; - } - - function subtract(a, b, aL) { - var i = 0; - - // Subtract b from a. - for (; aL--;) { - a[aL] -= i; - i = a[aL] < b[aL] ? 1 : 0; - a[aL] = i * BASE + a[aL] - b[aL]; - } - - // Remove leading zeros. - for (; !a[0] && a.length > 1;) a.shift(); - } - - return function (x, y, pr, dp) { - var cmp, e, i, k, prod, prodL, q, qd, rem, remL, rem0, sd, t, xi, xL, yd0, yL, yz, - Ctor = x.constructor, - sign = x.s == y.s ? 1 : -1, - xd = x.d, - yd = y.d; - - // Either 0? - if (!x.s) return new Ctor(x); - if (!y.s) throw Error(decimalError + 'Division by zero'); - - e = x.e - y.e; - yL = yd.length; - xL = xd.length; - q = new Ctor(sign); - qd = q.d = []; - - // Result exponent may be one less than e. - for (i = 0; yd[i] == (xd[i] || 0); ) ++i; - if (yd[i] > (xd[i] || 0)) --e; - - if (pr == null) { - sd = pr = Ctor.precision; - } else if (dp) { - sd = pr + (getBase10Exponent(x) - getBase10Exponent(y)) + 1; - } else { - sd = pr; - } - - if (sd < 0) return new Ctor(0); - - // Convert precision in number of base 10 digits to base 1e7 digits. - sd = sd / LOG_BASE + 2 | 0; - i = 0; - - // divisor < 1e7 - if (yL == 1) { - k = 0; - yd = yd[0]; - sd++; - - // k is the carry. - for (; (i < xL || k) && sd--; i++) { - t = k * BASE + (xd[i] || 0); - qd[i] = t / yd | 0; - k = t % yd | 0; - } - - // divisor >= 1e7 - } else { - - // Normalise xd and yd so highest order digit of yd is >= BASE/2 - k = BASE / (yd[0] + 1) | 0; - - if (k > 1) { - yd = multiplyInteger(yd, k); - xd = multiplyInteger(xd, k); - yL = yd.length; - xL = xd.length; - } - - xi = yL; - rem = xd.slice(0, yL); - remL = rem.length; - - // Add zeros to make remainder as long as divisor. - for (; remL < yL;) rem[remL++] = 0; - - yz = yd.slice(); - yz.unshift(0); - yd0 = yd[0]; - - if (yd[1] >= BASE / 2) ++yd0; - - do { - k = 0; - - // Compare divisor and remainder. - cmp = compare(yd, rem, yL, remL); - - // If divisor < remainder. - if (cmp < 0) { - - // Calculate trial digit, k. - rem0 = rem[0]; - if (yL != remL) rem0 = rem0 * BASE + (rem[1] || 0); - - // k will be how many times the divisor goes into the current remainder. - k = rem0 / yd0 | 0; - - // Algorithm: - // 1. product = divisor * trial digit (k) - // 2. if product > remainder: product -= divisor, k-- - // 3. remainder -= product - // 4. if product was < remainder at 2: - // 5. compare new remainder and divisor - // 6. If remainder > divisor: remainder -= divisor, k++ - - if (k > 1) { - if (k >= BASE) k = BASE - 1; - - // product = divisor * trial digit. - prod = multiplyInteger(yd, k); - prodL = prod.length; - remL = rem.length; - - // Compare product and remainder. - cmp = compare(prod, rem, prodL, remL); - - // product > remainder. - if (cmp == 1) { - k--; - - // Subtract divisor from product. - subtract(prod, yL < prodL ? yz : yd, prodL); - } - } else { - - // cmp is -1. - // If k is 0, there is no need to compare yd and rem again below, so change cmp to 1 - // to avoid it. If k is 1 there is a need to compare yd and rem again below. - if (k == 0) cmp = k = 1; - prod = yd.slice(); - } - - prodL = prod.length; - if (prodL < remL) prod.unshift(0); - - // Subtract product from remainder. - subtract(rem, prod, remL); - - // If product was < previous remainder. - if (cmp == -1) { - remL = rem.length; - - // Compare divisor and new remainder. - cmp = compare(yd, rem, yL, remL); - - // If divisor < new remainder, subtract divisor from remainder. - if (cmp < 1) { - k++; - - // Subtract divisor from remainder. - subtract(rem, yL < remL ? yz : yd, remL); - } - } - - remL = rem.length; - } else if (cmp === 0) { - k++; - rem = [0]; - } // if cmp === 1, k will be 0 - - // Add the next digit, k, to the result array. - qd[i++] = k; - - // Update the remainder. - if (cmp && rem[0]) { - rem[remL++] = xd[xi] || 0; - } else { - rem = [xd[xi]]; - remL = 1; - } - - } while ((xi++ < xL || rem[0] !== void 0) && sd--); - } - - // Leading zero? - if (!qd[0]) qd.shift(); - - q.e = e; - - return round(q, dp ? pr + getBase10Exponent(q) + 1 : pr); - }; -})(); - - -/* - * Return a new Decimal whose value is the natural exponential of `x` truncated to `sd` - * significant digits. - * - * Taylor/Maclaurin series. - * - * exp(x) = x^0/0! + x^1/1! + x^2/2! + x^3/3! + ... - * - * Argument reduction: - * Repeat x = x / 32, k += 5, until |x| < 0.1 - * exp(x) = exp(x / 2^k)^(2^k) - * - * Previously, the argument was initially reduced by - * exp(x) = exp(r) * 10^k where r = x - k * ln10, k = floor(x / ln10) - * to first put r in the range [0, ln10], before dividing by 32 until |x| < 0.1, but this was - * found to be slower than just dividing repeatedly by 32 as above. - * - * (Math object integer min/max: Math.exp(709) = 8.2e+307, Math.exp(-745) = 5e-324) - * - * exp(x) is non-terminating for any finite, non-zero x. - * - */ -function exp(x, sd) { - var denominator, guard, pow, sum, t, wpr, - i = 0, - k = 0, - Ctor = x.constructor, - pr = Ctor.precision; - - if (getBase10Exponent(x) > 16) throw Error(exponentOutOfRange + getBase10Exponent(x)); - - // exp(0) = 1 - if (!x.s) return new Ctor(ONE); - - if (sd == null) { - external = false; - wpr = pr; - } else { - wpr = sd; - } - - t = new Ctor(0.03125); - - while (x.abs().gte(0.1)) { - x = x.times(t); // x = x / 2^5 - k += 5; - } - - // Estimate the precision increase necessary to ensure the first 4 rounding digits are correct. - guard = Math.log(mathpow(2, k)) / Math.LN10 * 2 + 5 | 0; - wpr += guard; - denominator = pow = sum = new Ctor(ONE); - Ctor.precision = wpr; - - for (;;) { - pow = round(pow.times(x), wpr); - denominator = denominator.times(++i); - t = sum.plus(divide(pow, denominator, wpr)); - - if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) { - while (k--) sum = round(sum.times(sum), wpr); - Ctor.precision = pr; - return sd == null ? (external = true, round(sum, pr)) : sum; - } - - sum = t; - } -} - - -// Calculate the base 10 exponent from the base 1e7 exponent. -function getBase10Exponent(x) { - var e = x.e * LOG_BASE, - w = x.d[0]; - - // Add the number of digits of the first word of the digits array. - for (; w >= 10; w /= 10) e++; - return e; -} - - -function getLn10(Ctor, sd, pr) { - - if (sd > Ctor.LN10.sd()) { - - - // Reset global state in case the exception is caught. - external = true; - if (pr) Ctor.precision = pr; - throw Error(decimalError + 'LN10 precision limit exceeded'); - } - - return round(new Ctor(Ctor.LN10), sd); -} - - -function getZeroString(k) { - var zs = ''; - for (; k--;) zs += '0'; - return zs; -} - - -/* - * Return a new Decimal whose value is the natural logarithm of `x` truncated to `sd` significant - * digits. - * - * ln(n) is non-terminating (n != 1) - * - */ -function ln(y, sd) { - var c, c0, denominator, e, numerator, sum, t, wpr, x2, - n = 1, - guard = 10, - x = y, - xd = x.d, - Ctor = x.constructor, - pr = Ctor.precision; - - // ln(-x) = NaN - // ln(0) = -Infinity - if (x.s < 1) throw Error(decimalError + (x.s ? 'NaN' : '-Infinity')); - - // ln(1) = 0 - if (x.eq(ONE)) return new Ctor(0); - - if (sd == null) { - external = false; - wpr = pr; - } else { - wpr = sd; - } - - if (x.eq(10)) { - if (sd == null) external = true; - return getLn10(Ctor, wpr); - } - - wpr += guard; - Ctor.precision = wpr; - c = digitsToString(xd); - c0 = c.charAt(0); - e = getBase10Exponent(x); - - if (Math.abs(e) < 1.5e15) { - - // Argument reduction. - // The series converges faster the closer the argument is to 1, so using - // ln(a^b) = b * ln(a), ln(a) = ln(a^b) / b - // multiply the argument by itself until the leading digits of the significand are 7, 8, 9, - // 10, 11, 12 or 13, recording the number of multiplications so the sum of the series can - // later be divided by this number, then separate out the power of 10 using - // ln(a*10^b) = ln(a) + b*ln(10). - - // max n is 21 (gives 0.9, 1.0 or 1.1) (9e15 / 21 = 4.2e14). - //while (c0 < 9 && c0 != 1 || c0 == 1 && c.charAt(1) > 1) { - // max n is 6 (gives 0.7 - 1.3) - while (c0 < 7 && c0 != 1 || c0 == 1 && c.charAt(1) > 3) { - x = x.times(y); - c = digitsToString(x.d); - c0 = c.charAt(0); - n++; - } - - e = getBase10Exponent(x); - - if (c0 > 1) { - x = new Ctor('0.' + c); - e++; - } else { - x = new Ctor(c0 + '.' + c.slice(1)); - } - } else { - - // The argument reduction method above may result in overflow if the argument y is a massive - // number with exponent >= 1500000000000000 (9e15 / 6 = 1.5e15), so instead recall this - // function using ln(x*10^e) = ln(x) + e*ln(10). - t = getLn10(Ctor, wpr + 2, pr).times(e + ''); - x = ln(new Ctor(c0 + '.' + c.slice(1)), wpr - guard).plus(t); - - Ctor.precision = pr; - return sd == null ? (external = true, round(x, pr)) : x; - } - - // x is reduced to a value near 1. - - // Taylor series. - // ln(y) = ln((1 + x)/(1 - x)) = 2(x + x^3/3 + x^5/5 + x^7/7 + ...) - // where x = (y - 1)/(y + 1) (|x| < 1) - sum = numerator = x = divide(x.minus(ONE), x.plus(ONE), wpr); - x2 = round(x.times(x), wpr); - denominator = 3; - - for (;;) { - numerator = round(numerator.times(x2), wpr); - t = sum.plus(divide(numerator, new Ctor(denominator), wpr)); - - if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) { - sum = sum.times(2); - - // Reverse the argument reduction. - if (e !== 0) sum = sum.plus(getLn10(Ctor, wpr + 2, pr).times(e + '')); - sum = divide(sum, new Ctor(n), wpr); - - Ctor.precision = pr; - return sd == null ? (external = true, round(sum, pr)) : sum; - } - - sum = t; - denominator += 2; - } -} - - -/* - * Parse the value of a new Decimal `x` from string `str`. - */ -function parseDecimal(x, str) { - var e, i, len; - - // Decimal point? - if ((e = str.indexOf('.')) > -1) str = str.replace('.', ''); - - // Exponential form? - if ((i = str.search(/e/i)) > 0) { - - // Determine exponent. - if (e < 0) e = i; - e += +str.slice(i + 1); - str = str.substring(0, i); - } else if (e < 0) { - - // Integer. - e = str.length; - } - - // Determine leading zeros. - for (i = 0; str.charCodeAt(i) === 48;) ++i; - - // Determine trailing zeros. - for (len = str.length; str.charCodeAt(len - 1) === 48;) --len; - str = str.slice(i, len); - - if (str) { - len -= i; - e = e - i - 1; - x.e = mathfloor(e / LOG_BASE); - x.d = []; - - // Transform base - - // e is the base 10 exponent. - // i is where to slice str to get the first word of the digits array. - i = (e + 1) % LOG_BASE; - if (e < 0) i += LOG_BASE; - - if (i < len) { - if (i) x.d.push(+str.slice(0, i)); - for (len -= LOG_BASE; i < len;) x.d.push(+str.slice(i, i += LOG_BASE)); - str = str.slice(i); - i = LOG_BASE - str.length; - } else { - i -= len; - } - - for (; i--;) str += '0'; - x.d.push(+str); - - if (external && (x.e > MAX_E || x.e < -MAX_E)) throw Error(exponentOutOfRange + e); - } else { - - // Zero. - x.s = 0; - x.e = 0; - x.d = [0]; - } - - return x; -} - - -/* - * Round `x` to `sd` significant digits, using rounding mode `rm` if present (truncate otherwise). - */ - function round(x, sd, rm) { - var i, j, k, n, rd, doRound, w, xdi, - xd = x.d; - - // rd: the rounding digit, i.e. the digit after the digit that may be rounded up. - // w: the word of xd which contains the rounding digit, a base 1e7 number. - // xdi: the index of w within xd. - // n: the number of digits of w. - // i: what would be the index of rd within w if all the numbers were 7 digits long (i.e. if - // they had leading zeros) - // j: if > 0, the actual index of rd within w (if < 0, rd is a leading zero). - - // Get the length of the first word of the digits array xd. - for (n = 1, k = xd[0]; k >= 10; k /= 10) n++; - i = sd - n; - - // Is the rounding digit in the first word of xd? - if (i < 0) { - i += LOG_BASE; - j = sd; - w = xd[xdi = 0]; - } else { - xdi = Math.ceil((i + 1) / LOG_BASE); - k = xd.length; - if (xdi >= k) return x; - w = k = xd[xdi]; - - // Get the number of digits of w. - for (n = 1; k >= 10; k /= 10) n++; - - // Get the index of rd within w. - i %= LOG_BASE; - - // Get the index of rd within w, adjusted for leading zeros. - // The number of leading zeros of w is given by LOG_BASE - n. - j = i - LOG_BASE + n; - } - - if (rm !== void 0) { - k = mathpow(10, n - j - 1); - - // Get the rounding digit at index j of w. - rd = w / k % 10 | 0; - - // Are there any non-zero digits after the rounding digit? - doRound = sd < 0 || xd[xdi + 1] !== void 0 || w % k; - - // The expression `w % mathpow(10, n - j - 1)` returns all the digits of w to the right of the - // digit at (left-to-right) index j, e.g. if w is 908714 and j is 2, the expression will give - // 714. - - doRound = rm < 4 - ? (rd || doRound) && (rm == 0 || rm == (x.s < 0 ? 3 : 2)) - : rd > 5 || rd == 5 && (rm == 4 || doRound || rm == 6 && - - // Check whether the digit to the left of the rounding digit is odd. - ((i > 0 ? j > 0 ? w / mathpow(10, n - j) : 0 : xd[xdi - 1]) % 10) & 1 || - rm == (x.s < 0 ? 8 : 7)); - } - - if (sd < 1 || !xd[0]) { - if (doRound) { - k = getBase10Exponent(x); - xd.length = 1; - - // Convert sd to decimal places. - sd = sd - k - 1; - - // 1, 0.1, 0.01, 0.001, 0.0001 etc. - xd[0] = mathpow(10, (LOG_BASE - sd % LOG_BASE) % LOG_BASE); - x.e = mathfloor(-sd / LOG_BASE) || 0; - } else { - xd.length = 1; - - // Zero. - xd[0] = x.e = x.s = 0; - } - - return x; - } - - // Remove excess digits. - if (i == 0) { - xd.length = xdi; - k = 1; - xdi--; - } else { - xd.length = xdi + 1; - k = mathpow(10, LOG_BASE - i); - - // E.g. 56700 becomes 56000 if 7 is the rounding digit. - // j > 0 means i > number of leading zeros of w. - xd[xdi] = j > 0 ? (w / mathpow(10, n - j) % mathpow(10, j) | 0) * k : 0; - } - - if (doRound) { - for (;;) { - - // Is the digit to be rounded up in the first word of xd? - if (xdi == 0) { - if ((xd[0] += k) == BASE) { - xd[0] = 1; - ++x.e; - } - - break; - } else { - xd[xdi] += k; - if (xd[xdi] != BASE) break; - xd[xdi--] = 0; - k = 1; - } - } - } - - // Remove trailing zeros. - for (i = xd.length; xd[--i] === 0;) xd.pop(); - - if (external && (x.e > MAX_E || x.e < -MAX_E)) { - throw Error(exponentOutOfRange + getBase10Exponent(x)); - } - - return x; -} - - -function subtract(x, y) { - var d, e, i, j, k, len, xd, xe, xLTy, yd, - Ctor = x.constructor, - pr = Ctor.precision; - - // Return y negated if x is zero. - // Return x if y is zero and x is non-zero. - if (!x.s || !y.s) { - if (y.s) y.s = -y.s; - else y = new Ctor(x); - return external ? round(y, pr) : y; - } - - xd = x.d; - yd = y.d; - - // x and y are non-zero numbers with the same sign. - - e = y.e; - xe = x.e; - xd = xd.slice(); - k = xe - e; - - // If exponents differ... - if (k) { - xLTy = k < 0; - - if (xLTy) { - d = xd; - k = -k; - len = yd.length; - } else { - d = yd; - e = xe; - len = xd.length; - } - - // Numbers with massively different exponents would result in a very high number of zeros - // needing to be prepended, but this can be avoided while still ensuring correct rounding by - // limiting the number of zeros to `Math.ceil(pr / LOG_BASE) + 2`. - i = Math.max(Math.ceil(pr / LOG_BASE), len) + 2; - - if (k > i) { - k = i; - d.length = 1; - } - - // Prepend zeros to equalise exponents. - d.reverse(); - for (i = k; i--;) d.push(0); - d.reverse(); - - // Base 1e7 exponents equal. - } else { - - // Check digits to determine which is the bigger number. - - i = xd.length; - len = yd.length; - xLTy = i < len; - if (xLTy) len = i; - - for (i = 0; i < len; i++) { - if (xd[i] != yd[i]) { - xLTy = xd[i] < yd[i]; - break; - } - } - - k = 0; - } - - if (xLTy) { - d = xd; - xd = yd; - yd = d; - y.s = -y.s; - } - - len = xd.length; - - // Append zeros to xd if shorter. - // Don't add zeros to yd if shorter as subtraction only needs to start at yd length. - for (i = yd.length - len; i > 0; --i) xd[len++] = 0; - - // Subtract yd from xd. - for (i = yd.length; i > k;) { - if (xd[--i] < yd[i]) { - for (j = i; j && xd[--j] === 0;) xd[j] = BASE - 1; - --xd[j]; - xd[i] += BASE; - } - - xd[i] -= yd[i]; - } - - // Remove trailing zeros. - for (; xd[--len] === 0;) xd.pop(); - - // Remove leading zeros and adjust exponent accordingly. - for (; xd[0] === 0; xd.shift()) --e; - - // Zero? - if (!xd[0]) return new Ctor(0); - - y.d = xd; - y.e = e; - - //return external && xd.length >= pr / LOG_BASE ? round(y, pr) : y; - return external ? round(y, pr) : y; -} - - -function toString$3(x, isExp, sd) { - var k, - e = getBase10Exponent(x), - str = digitsToString(x.d), - len = str.length; - - if (isExp) { - if (sd && (k = sd - len) > 0) { - str = str.charAt(0) + '.' + str.slice(1) + getZeroString(k); - } else if (len > 1) { - str = str.charAt(0) + '.' + str.slice(1); - } - - str = str + (e < 0 ? 'e' : 'e+') + e; - } else if (e < 0) { - str = '0.' + getZeroString(-e - 1) + str; - if (sd && (k = sd - len) > 0) str += getZeroString(k); - } else if (e >= len) { - str += getZeroString(e + 1 - len); - if (sd && (k = sd - e - 1) > 0) str = str + '.' + getZeroString(k); - } else { - if ((k = e + 1) < len) str = str.slice(0, k) + '.' + str.slice(k); - if (sd && (k = sd - len) > 0) { - if (e + 1 === len) str += '.'; - str += getZeroString(k); - } - } - - return x.s < 0 ? '-' + str : str; -} - - -// Does not strip trailing zeros. -function truncate(arr, len) { - if (arr.length > len) { - arr.length = len; - return true; - } -} - - -// Decimal methods - - -/* - * clone - * config/set - */ - - -/* - * Create and return a Decimal constructor with the same configuration properties as this Decimal - * constructor. - * - */ -function clone(obj) { - var i, p, ps; - - /* - * The Decimal constructor and exported function. - * Return a new Decimal instance. - * - * value {number|string|Decimal} A numeric value. - * - */ - function Decimal(value) { - var x = this; - - // Decimal called without new. - if (!(x instanceof Decimal)) return new Decimal(value); - - // Retain a reference to this Decimal constructor, and shadow Decimal.prototype.constructor - // which points to Object. - x.constructor = Decimal; - - // Duplicate. - if (value instanceof Decimal) { - x.s = value.s; - x.e = value.e; - x.d = (value = value.d) ? value.slice() : value; - return; - } - - if (typeof value === 'number') { - - // Reject Infinity/NaN. - if (value * 0 !== 0) { - throw Error(invalidArgument + value); - } - - if (value > 0) { - x.s = 1; - } else if (value < 0) { - value = -value; - x.s = -1; - } else { - x.s = 0; - x.e = 0; - x.d = [0]; - return; - } - - // Fast path for small integers. - if (value === ~~value && value < 1e7) { - x.e = 0; - x.d = [value]; - return; - } - - return parseDecimal(x, value.toString()); - } else if (typeof value !== 'string') { - throw Error(invalidArgument + value); - } - - // Minus sign? - if (value.charCodeAt(0) === 45) { - value = value.slice(1); - x.s = -1; - } else { - x.s = 1; - } - - if (isDecimal.test(value)) parseDecimal(x, value); - else throw Error(invalidArgument + value); - } - - Decimal.prototype = P; - - Decimal.ROUND_UP = 0; - Decimal.ROUND_DOWN = 1; - Decimal.ROUND_CEIL = 2; - Decimal.ROUND_FLOOR = 3; - Decimal.ROUND_HALF_UP = 4; - Decimal.ROUND_HALF_DOWN = 5; - Decimal.ROUND_HALF_EVEN = 6; - Decimal.ROUND_HALF_CEIL = 7; - Decimal.ROUND_HALF_FLOOR = 8; - - Decimal.clone = clone; - Decimal.config = Decimal.set = config; - - if (obj === void 0) obj = {}; - if (obj) { - ps = ['precision', 'rounding', 'toExpNeg', 'toExpPos', 'LN10']; - for (i = 0; i < ps.length;) if (!obj.hasOwnProperty(p = ps[i++])) obj[p] = this[p]; - } - - Decimal.config(obj); - - return Decimal; -} - - -/* - * Configure global settings for a Decimal constructor. - * - * `obj` is an object with one or more of the following properties, - * - * precision {number} - * rounding {number} - * toExpNeg {number} - * toExpPos {number} - * - * E.g. Decimal.config({ precision: 20, rounding: 4 }) - * - */ -function config(obj) { - if (!obj || typeof obj !== 'object') { - throw Error(decimalError + 'Object expected'); - } - var i, p, v, - ps = [ - 'precision', 1, MAX_DIGITS, - 'rounding', 0, 8, - 'toExpNeg', -1 / 0, 0, - 'toExpPos', 0, 1 / 0 - ]; - - for (i = 0; i < ps.length; i += 3) { - if ((v = obj[p = ps[i]]) !== void 0) { - if (mathfloor(v) === v && v >= ps[i + 1] && v <= ps[i + 2]) this[p] = v; - else throw Error(invalidArgument + p + ': ' + v); - } - } - - if ((v = obj[p = 'LN10']) !== void 0) { - if (v == Math.LN10) this[p] = new this(v); - else throw Error(invalidArgument + p + ': ' + v); - } - - return this; -} - - -// Create and configure initial Decimal constructor. -var Decimal = clone(defaults); - -// Internal constant. -ONE = new Decimal(1); - -Decimal.set({ - precision: 30, - toExpNeg: -7, - toExpPos: 29, -}); -var n = new Decimal(60 * 60 * 24 * 365); -var lookup = {}; -/** - * Get interest rate in percentage points for a specified fee. - * This function uses a lookup table for performance reasons. - * This function uses decimal.js-light, since we need non-integer powers for our calculations here. - * We can remove that dependency in the future if we decide to either add a hardcoded - * lookup table for fees and interest rates or if we decide to implement the relevant - * functions here by hand. - * @param fee Fee - */ -var feeToInterestRate = function (fee) { - // tslint:disable-next-line:no-parameter-reassignment - if (typeof fee !== 'string' && typeof fee !== 'number') { - fee = fee.toString(); - } - if (lookup[fee]) { - return lookup[fee]; - } - var i = new Decimal(fee).div('1e27').pow(n); - var interestRate = i.minus(1).mul(100).toSignificantDigits(2); - var interestRateString = interestRate.toString(); - lookup[fee] = interestRateString; - return interestRateString; -}; - -function getLoanStatus(principal, debt) { - if (!principal.isZero()) { - return 'Whitelisted'; - } - if (principal.isZero() && !debt.isZero()) { - return 'Ongoing'; - } - if (principal.isZero() && debt.isZero()) { - return 'Repaid'; - } - throw Error('Unknown loan status'); -} - -Decimal.set({ - precision: 28, - toExpNeg: -7, - toExpPos: 29, -}); -var n$1 = new Decimal(60 * 60 * 24 * 365); -var lookup$1 = {}; -/** - * Get fee for a specified interest rate. This function uses a lookup table for performance reasons. - * This function uses decimal.js-light, since we need non-integer powers for our calculations here. - * We can remove that dependency in the future if we decide to either add a hardcoded - * lookup table for fees and interest rates or if we decide to implement the relevant - * functions here by hand. - * @param interestRate Interest rate in percentage points, i. e. "5" for 5 % (= 0.05) - */ -var interestRateToFee = function (interestRate) { - if (lookup$1[interestRate]) { - return lookup$1[interestRate]; - } - var i = new Decimal(interestRate).div(100).plus(1); - var fee = i.pow(new Decimal(1).div(n$1)).mul('1e27').toDecimalPlaces(0); - var feeString = fee.toString(); - lookup$1[interestRate] = feeString; - return feeString; -}; - -var _this = undefined; -var abiCoder$1 = new AbiCoder$1(); -var pollingInterval = 1000; -var LOAN_ID_IDX = 2; -var Tinlake = /** @class */ (function () { - function Tinlake(provider, contractAddresses, nftDataOutputs, transactionTimeout, _a) { - var _this = this; - var _b = _a === void 0 ? {} : _a, contractAbis = _b.contractAbis, ethOptions = _b.ethOptions, ethConfig = _b.ethConfig; - this.setProvider = function (provider, ethOptions) { - _this.provider = provider; - _this.ethOptions = ethOptions || {}; - _this.eth = new lib$a(_this.provider, _this.ethOptions); - _this.contracts = { - nft: _this.eth.contract(_this.contractAbis.nft) - .at(_this.contractAddresses['NFT_COLLATERAL']), - title: _this.eth.contract(_this.contractAbis.title) - .at(_this.contractAddresses['TITLE']), - currency: _this.eth.contract(_this.contractAbis.currency) - .at(_this.contractAddresses['CURRENCY']), - admit: _this.eth.contract(_this.contractAbis.admit) - .at(_this.contractAddresses['ADMIT']), - reception: _this.eth.contract(_this.contractAbis.reception) - .at(_this.contractAddresses['RECEPTION']), - desk: _this.eth.contract(_this.contractAbis.desk) - .at(_this.contractAddresses['DESK']), - shelf: _this.eth.contract(_this.contractAbis.shelf) - .at(_this.contractAddresses['SHELF']), - appraiser: _this.eth.contract(_this.contractAbis.appraiser) - .at(_this.contractAddresses['APPRAISER']), - lender: _this.eth.contract(_this.contractAbis.lender) - .at(_this.contractAddresses['LENDER']), - collateral: _this.eth.contract(_this.contractAbis.collateral) - .at(_this.contractAddresses['COLLATERAL']), - pile: _this.eth.contract(_this.contractAbis.pile) - .at(_this.contractAddresses['PILE']), - pileForAdd: _this.eth.contract(_this.contractAbis.pileForAdd) - .at(_this.contractAddresses['PILE']), - pileForInit: _this.eth.contract(_this.contractAbis.pileForInit) - .at(_this.contractAddresses['PILE']), - admin: _this.eth.contract(_this.contractAbis.admin) - .at(_this.contractAddresses['ADMIN']), - nftData: _this.eth.contract(_this.contractAbis.nftData) - .at(_this.contractAddresses['NFT_COLLATERAL']), - }; - }; - this.setEthConfig = function (ethConfig) { - _this.ethConfig = ethConfig; - }; - this.isAdmin = function (address) { return __awaiter(_this, void 0, void 0, function () { - var res; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.admin.wards, [address])]; - case 1: - res = _a.sent(); - return [2 /*return*/, !res[0].isZero()]; - } - }); - }); }; - this.loanCount = function () { return __awaiter(_this, void 0, void 0, function () { - var res; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.title.count, [])]; - case 1: - res = _a.sent(); - return [2 /*return*/, res[0]]; - } - }); - }); }; - this.getLoan = function (loanId) { return __awaiter(_this, void 0, void 0, function () { - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.shelf.shelf, [loanId])]; - case 1: return [2 /*return*/, _a.sent()]; - } - }); - }); }; - this.getBalanceDebt = function (loanId) { return __awaiter(_this, void 0, void 0, function () { - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.pile.loans, [loanId])]; - case 1: return [2 /*return*/, _a.sent()]; - } - }); - }); }; - this.approveNFT = function (tokenId, to) { return __awaiter(_this, void 0, void 0, function () { - var txHash; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.nft.approve, [to, tokenId, this.ethConfig])]; - case 1: - txHash = _a.sent(); - console.log("[NFT Approve] txHash: " + txHash); - return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['nft'].abi, this.transactionTimeout)]; - } - }); - }); }; - this.approveCollateral = function (usr, wad) { return __awaiter(_this, void 0, void 0, function () { - var txHash; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.collateral.approve, [usr, wad, this.ethConfig])]; - case 1: - txHash = _a.sent(); - console.log("[Collateral Approve] txHash: " + txHash); - return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['collateral'].abi, this.transactionTimeout)]; - } - }); - }); }; - this.ownerOfNFT = function (tokenId) { return __awaiter(_this, void 0, void 0, function () { - var res; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.nft.ownerOf, [tokenId])]; - case 1: - res = _a.sent(); - return [2 /*return*/, res['0']]; - } - }); - }); }; - this.ownerOfLoan = function (loanId) { return __awaiter(_this, void 0, void 0, function () { - var res; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.title.ownerOf, [loanId])]; - case 1: - res = _a.sent(); - return [2 /*return*/, res['0']]; - } - }); - }); }; - this.balanceOfCurrency = function (usr) { return __awaiter(_this, void 0, void 0, function () { - return __generator(this, function (_a) { - return [2 /*return*/, executeAndRetry(this.contracts.currency.balanceOf, [usr])]; - }); - }); }; - this.mintCurrency = function (usr, wad) { return __awaiter(_this, void 0, void 0, function () { - var txHash; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.currency.mint, [usr, wad, this.ethConfig])]; - case 1: - txHash = _a.sent(); - console.log("[Currency.mint] txHash: " + txHash); - return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['currency'].abi, this.transactionTimeout)]; - } - }); - }); }; - /** - * @param owner Owner of the new NFT - */ - this.mintNFT = function (owner, tokenId) { - var tkn = abiCoder$1.encodeParameter('uint', tokenId); - return _this.contracts.nft.mint(owner, tkn, _this.ethConfig).then(function (txHash) { - console.log("[NFT.mint] txHash: " + txHash); - return waitAndReturnEvents(_this.eth, txHash, _this.contracts['nft'].abi, _this.transactionTimeout); - }); - }); }; - /** - * @param owner Owner of the created loan - */ - this.adminAdmit = function (registry, nft, principal, owner) { return __awaiter(_this, void 0, void 0, function () { - var txHash; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.admit.admit, [registry, nft, principal, owner, this.ethConfig])]; - case 1: - txHash = _a.sent(); - console.log("[Admit.admit] txHash: " + txHash); - return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['nft'].abi, this.transactionTimeout)]; - } - }); - }); }; - this.adminAppraise = function (loanID, appraisal) { return __awaiter(_this, void 0, void 0, function () { - var txHash; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.appraiser.file, [loanID, appraisal, this.ethConfig])]; - case 1: - txHash = _a.sent(); - console.log("[Appraisal.file] txHash: " + txHash); - return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['nft'].abi, this.transactionTimeout)]; - } - }); - }); }; - this.getAppraisal = function (loanID) { return __awaiter(_this, void 0, void 0, function () { - var res; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.appraiser.value, [loanID])]; - case 1: - res = _a.sent(); - return [2 /*return*/, res['0']]; - } - }); - }); }; - /** - * @param to Address that should receive the currency (e. g. DAI) - */ - this.borrow = function (loanId, to) { return __awaiter(_this, void 0, void 0, function () { - var txHash; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.reception.borrow, [loanId, to, this.ethConfig])]; - case 1: - txHash = _a.sent(); - console.log("[Reception.borrow] txHash: " + txHash); - return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['reception'].abi, this.transactionTimeout)]; - } - }); - }); }; - /** - * @param wad Amount which should be repaid - * @param usr Address that receives the NFT - */ - this.repay = function (loanId, wad, usr) { return __awaiter(_this, void 0, void 0, function () { - var txHash; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.reception.repay, [loanId, wad, usr, this.ethConfig])]; - case 1: - txHash = _a.sent(); - console.log("[Reception.repay] txHash: " + txHash); - return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['reception'].abi, this.transactionTimeout)]; - } - }); - }); }; - /** - * @param wad Amount which should be repaid - * @param usr Address that receives the NFT - */ - this.close = function (loanId, usr) { return __awaiter(_this, void 0, void 0, function () { - var txHash; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.reception.close, [loanId, usr, this.ethConfig])]; - case 1: - txHash = _a.sent(); - console.log("[Reception.close] txHash: " + txHash); - return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['reception'].abi, this.transactionTimeout)]; - } - }); - }); }; - this.approveCurrency = function (usr, wad) { return __awaiter(_this, void 0, void 0, function () { - var txHash; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.currency.approve, [usr, wad, this.ethConfig])]; - case 1: - txHash = _a.sent(); - console.log("[Currency.approve] txHash: " + txHash); - return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['currency'].abi, this.transactionTimeout)]; - } - }); - }); }; - this.lenderRely = function (usr) { return __awaiter(_this, void 0, void 0, function () { - var txHash; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.lender.rely, [usr, this.ethConfig])]; - case 1: - txHash = _a.sent(); - console.log("[Lender.rely] txHash: " + txHash); - return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['lender'].abi, this.transactionTimeout)]; - } - }); - }); }; - this.initFee = function (fee) { return __awaiter(_this, void 0, void 0, function () { - var txHash; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.pileForInit.file, [fee, fee, this.ethConfig])]; - case 1: - txHash = _a.sent(); - console.log("[Pile.file] txHash: " + txHash); - return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts.pileForInit.abi, this.transactionTimeout)]; - } - }); - }); }; - this.existsFee = function (fee) { return __awaiter(_this, void 0, void 0, function () { - var res; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.pile.fees, [fee])]; - case 1: - res = _a.sent(); - return [2 /*return*/, !res.speed.isZero()]; - } - }); - }); }; - this.addFee = function (loanId, fee, balance) { return __awaiter(_this, void 0, void 0, function () { - var txHash; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.pileForAdd.file, [loanId, fee, balance, this.ethConfig])]; - case 1: - txHash = _a.sent(); - console.log("[Pile.file] txHash: " + txHash); - return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts.pileForAdd.abi, this.transactionTimeout)]; - } - }); - }); }; - this.getCurrentDebt = function (loanId) { return __awaiter(_this, void 0, void 0, function () { - var res; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.pile.burden, [loanId])]; - case 1: - res = _a.sent(); - return [2 /*return*/, res['0']]; - } - }); - }); }; - /** - * whitelist is a shortcut contract that calls adminAdmit (admit.admit), - * adminAppraise (appraiser.file) and addFee (pile.file) to prevent additional - * transactions. It is required though that the fee is already initialized - * using initFee - * @param owner Owner of the created loan - */ - this.whitelist = function (registry, nft, principal, appraisal, fee, owner) { return __awaiter(_this, void 0, void 0, function () { - var txHash; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.admin.whitelist, [registry, nft, principal, appraisal, fee, owner, this.ethConfig])]; - case 1: - txHash = _a.sent(); - console.log("[Admin.whitelist] txHash: " + txHash); - return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['nft'].abi, this.transactionTimeout)]; - } - }); - }); }; - this.unwhitelist = function (loanId, registry, nft) { return __awaiter(_this, void 0, void 0, function () { - var txHash; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.shelf.file, [loanId, registry, nft, '0', this.ethConfig])]; - case 1: - txHash = _a.sent(); - console.log("[Shelf.file] txHash: " + txHash); - return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['shelf'].abi, this.transactionTimeout)]; - } - }); - }); }; - this.getTotalDebt = function () { return __awaiter(_this, void 0, void 0, function () { - var res; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.pile.Debt, [])]; - case 1: - res = _a.sent(); - return [2 /*return*/, res['0']]; - } - }); - }); }; - this.getTotalBalance = function () { return __awaiter(_this, void 0, void 0, function () { - var res; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.pile.Balance, [])]; - case 1: - res = _a.sent(); - return [2 /*return*/, res['0']]; - } - }); - }); }; - this.getTotalValueOfNFTs = function () { return __awaiter(_this, void 0, void 0, function () { - var res; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.collateral.totalSupply, [])]; - case 1: - res = _a.sent(); - return [2 /*return*/, res['0']]; - } - }); - }); }; - this.getNFTData = function (tokenId) { return __awaiter(_this, void 0, void 0, function () { - var res; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.nftData.data, [tokenId])]; - case 1: - res = _a.sent(); - return [2 /*return*/, res]; - } - }); - }); }; - this.contractAbis = contractAbis || { - nft: contractAbiNft, - title: contractAbiTitle, - currency: contractAbiCurrency, - admit: contractAbiAdmit, - reception: contractAbiReception, - desk: contractAbiDesk, - shelf: contractAbiShelf, - appraiser: contractAbiAppraiser, - lender: contractAbiLender, - collateral: contractAbiCollateral, - pile: contractAbiPile, - pileForAdd: contractAbiPileForAdd, - pileForInit: contractAbiPileForInit, - admin: contractAbiAdmin, - nftData: [{ - constant: true, - inputs: [ - { - name: '', - type: 'uint256', - }, - ], - name: 'data', - outputs: nftDataOutputs, - payable: false, - stateMutability: 'view', - type: 'function', - }], - }; - this.contractAddresses = contractAddresses; - this.transactionTimeout = transactionTimeout; - this.setProvider(provider, ethOptions); - this.setEthConfig(ethConfig || {}); - } - return Tinlake; -}()); -function executeAndRetry(f, args) { - if (args === void 0) { args = []; } - return __awaiter(this, void 0, void 0, function () { - var result, e_1; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - _a.trys.push([0, 2, , 3]); - return [4 /*yield*/, f.apply(void 0, args)]; - case 1: - result = _a.sent(); - return [2 /*return*/, result]; - case 2: - e_1 = _a.sent(); - // using error message, since error code -32603 is not unique enough - // todo introduce retry limit - if (e_1 && e_1.message && (e_1.message.indexOf("Cannot read property 'number' of null") !== -1 || - e_1.message.indexOf('error with payload') !== -1)) { - console.log("internal RPC error detected, retry triggered...", e_1); - throw (new Error("Internal RPC Error. Please try again.")); - // await sleep(1000); - // return executeAndRetry(f, args); - } - else { - throw (e_1); - } - return [3 /*break*/, 3]; - case 3: return [2 /*return*/]; - } - }); - }); -} -var waitAndReturnEvents = function (eth, txHash, abi, transactionTimeout) { return __awaiter(_this, void 0, void 0, function () { - var tx; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, waitForTransaction(eth, txHash, transactionTimeout)]; - case 1: - tx = _a.sent(); - return [2 /*return*/, new Promise(function (resolve, reject) { - eth.getTransactionReceipt(tx.hash, function (err, receipt) { - if (err != null) { - reject('failed to get receipt'); - } - var events = getEvents(receipt, abi); - resolve({ events: events, txHash: tx.hash, status: receipt.status }); - }); - })]; - } - }); -}); }; -// todo replace with a better polling -var waitForTransaction = function (eth, txHash, transactionTimeout) { - return new Promise(function (resolve, reject) { - var secMax = transactionTimeout; - var sec = 0; - var wait = function (txHash) { - setTimeout(function () { - eth.getTransactionByHash(txHash, function (err, tx) { - if (err) { - reject(err); - return; - } - if (tx && tx.blockHash != null) { - resolve(tx); - return; - } - console.log("waiting for tx :" + txHash); - sec = sec + 1; - if (sec < secMax) { - wait(txHash); - } - else { - reject(new Error("waiting for transaction tx " + txHash + " timed out after " + secMax + " seconds")); - } - }); - }, pollingInterval); - }; - wait(txHash); - }); -}; -var findEvent = function (abi, funcSignature) { - return abi.filter(function (item) { - if (item.type !== 'event') - return false; - var signature = item.name + "(" + item.inputs.map(function (input) { return input.type; }).join(',') + ")"; - var hash = src_11(signature); - if (hash === funcSignature) - return true; - }); -}; -var getEvents = function (receipt, abi) { - if (receipt.logs.length === 0) { - return null; - } - var events = []; - receipt.logs.forEach(function (log) { - var funcSignature = log.topics[0]; - var matches = findEvent(abi, funcSignature); - if (matches.length === 1) { - var event = matches[0]; - var inputs = event.inputs.filter(function (input) { return input.indexed; }) - .map(function (input) { return input.type; }); - // remove 0x prefix from topics - var topics = log.topics.map(function (t) { - return t.replace('0x', ''); - }); - // concat topics without first topic (func signature) - var bytes = "0x" + topics.slice(1).join(''); - var data = abiCoder$1.decodeParameters(inputs, bytes); - events.push({ event: event, data: data }); - } - }); - return events; +var _this = undefined; +var abiCoder$1 = new AbiCoder$1(); +var pollingInterval = 1000; +var LOAN_ID_IDX = 2; +var Tinlake = /** @class */ (function () { + function Tinlake(provider, contractAddresses, nftDataOutputs, transactionTimeout, _a) { + var _this = this; + var _b = _a === void 0 ? {} : _a, contractAbis = _b.contractAbis, ethOptions = _b.ethOptions, ethConfig = _b.ethConfig; + this.setProvider = function (provider, ethOptions) { + _this.provider = provider; + _this.ethOptions = ethOptions || {}; + _this.eth = new lib$a(_this.provider, _this.ethOptions); + _this.contracts = { + nft: _this.eth.contract(_this.contractAbis.nft) + .at(_this.contractAddresses['NFT_COLLATERAL']), + title: _this.eth.contract(_this.contractAbis.title) + .at(_this.contractAddresses['TITLE']), + currency: _this.eth.contract(_this.contractAbis.currency) + .at(_this.contractAddresses['CURRENCY']), + admit: _this.eth.contract(_this.contractAbis.admit) + .at(_this.contractAddresses['ADMIT']), + reception: _this.eth.contract(_this.contractAbis.reception) + .at(_this.contractAddresses['RECEPTION']), + desk: _this.eth.contract(_this.contractAbis.desk) + .at(_this.contractAddresses['DESK']), + shelf: _this.eth.contract(_this.contractAbis.shelf) + .at(_this.contractAddresses['SHELF']), + appraiser: _this.eth.contract(_this.contractAbis.appraiser) + .at(_this.contractAddresses['APPRAISER']), + lender: _this.eth.contract(_this.contractAbis.lender) + .at(_this.contractAddresses['LENDER']), + collateral: _this.eth.contract(_this.contractAbis.collateral) + .at(_this.contractAddresses['COLLATERAL']), + pile: _this.eth.contract(_this.contractAbis.pile) + .at(_this.contractAddresses['PILE']), + pileForAdd: _this.eth.contract(_this.contractAbis.pileForAdd) + .at(_this.contractAddresses['PILE']), + pileForInit: _this.eth.contract(_this.contractAbis.pileForInit) + .at(_this.contractAddresses['PILE']), + admin: _this.eth.contract(_this.contractAbis.admin) + .at(_this.contractAddresses['ADMIN']), + nftData: _this.eth.contract(_this.contractAbis.nftData) + .at(_this.contractAddresses['NFT_COLLATERAL']), + }; + }; + this.setEthConfig = function (ethConfig) { + _this.ethConfig = ethConfig; + }; + this.isAdmin = function (address) { return __awaiter(_this, void 0, void 0, function () { + var res; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.admin.wards, [address])]; + case 1: + res = _a.sent(); + return [2 /*return*/, !res[0].isZero()]; + } + }); + }); }; + this.loanCount = function () { return __awaiter(_this, void 0, void 0, function () { + var res; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.title.count, [])]; + case 1: + res = _a.sent(); + return [2 /*return*/, res[0]]; + } + }); + }); }; + this.getLoan = function (loanId) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.shelf.shelf, [loanId])]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); }; + this.getBalanceDebt = function (loanId) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.pile.loans, [loanId])]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); }; + this.approveNFT = function (tokenId, to) { return __awaiter(_this, void 0, void 0, function () { + var txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.nft.approve, [to, tokenId, this.ethConfig])]; + case 1: + txHash = _a.sent(); + console.log("[NFT Approve] txHash: " + txHash); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['nft'].abi, this.transactionTimeout)]; + } + }); + }); }; + this.approveCollateral = function (usr, wad) { return __awaiter(_this, void 0, void 0, function () { + var txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.collateral.approve, [usr, wad, this.ethConfig])]; + case 1: + txHash = _a.sent(); + console.log("[Collateral Approve] txHash: " + txHash); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['collateral'].abi, this.transactionTimeout)]; + } + }); + }); }; + this.ownerOfNFT = function (tokenId) { return __awaiter(_this, void 0, void 0, function () { + var res; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.nft.ownerOf, [tokenId])]; + case 1: + res = _a.sent(); + return [2 /*return*/, res['0']]; + } + }); + }); }; + this.ownerOfLoan = function (loanId) { return __awaiter(_this, void 0, void 0, function () { + var res; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.title.ownerOf, [loanId])]; + case 1: + res = _a.sent(); + return [2 /*return*/, res['0']]; + } + }); + }); }; + this.balanceOfCurrency = function (usr) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, executeAndRetry(this.contracts.currency.balanceOf, [usr])]; + }); + }); }; + this.mintCurrency = function (usr, wad) { return __awaiter(_this, void 0, void 0, function () { + var txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.currency.mint, [usr, wad, this.ethConfig])]; + case 1: + txHash = _a.sent(); + console.log("[Currency.mint] txHash: " + txHash); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['currency'].abi, this.transactionTimeout)]; + } + }); + }); }; + /** + * @param owner Owner of the new NFT + */ + this.mintNFT = function (owner, tokenId) { return __awaiter(_this, void 0, void 0, function () { + var tkn, txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + tkn = abiCoder$1.encodeParameter('uint', tokenId); + return [4 /*yield*/, this.contracts.nft.mint(owner, tkn, this.ethConfig)]; + case 1: + txHash = _a.sent(); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['nft'].abi, this.transactionTimeout)]; + } + }); + }); }; + /** + * @param owner Owner of the created loan + */ + this.adminAdmit = function (registry, nft, principal, owner) { return __awaiter(_this, void 0, void 0, function () { + var txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.admit.admit, [registry, nft, principal, owner, this.ethConfig])]; + case 1: + txHash = _a.sent(); + console.log("[Admit.admit] txHash: " + txHash); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['nft'].abi, this.transactionTimeout)]; + } + }); + }); }; + this.adminAppraise = function (loanID, appraisal) { return __awaiter(_this, void 0, void 0, function () { + var txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.appraiser.file, [loanID, appraisal, this.ethConfig])]; + case 1: + txHash = _a.sent(); + console.log("[Appraisal.file] txHash: " + txHash); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['nft'].abi, this.transactionTimeout)]; + } + }); + }); }; + this.getAppraisal = function (loanID) { return __awaiter(_this, void 0, void 0, function () { + var res; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.appraiser.value, [loanID])]; + case 1: + res = _a.sent(); + return [2 /*return*/, res['0']]; + } + }); + }); }; + /** + * @param to Address that should receive the currency (e. g. DAI) + */ + this.borrow = function (loanId, to) { return __awaiter(_this, void 0, void 0, function () { + var txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.reception.borrow, [loanId, to, this.ethConfig])]; + case 1: + txHash = _a.sent(); + console.log("[Reception.borrow] txHash: " + txHash); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['reception'].abi, this.transactionTimeout)]; + } + }); + }); }; + /** + * @param wad Amount which should be repaid + * @param usr Address that receives the NFT + */ + this.repay = function (loanId, wad, usr) { return __awaiter(_this, void 0, void 0, function () { + var txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.reception.repay, [loanId, wad, usr, this.ethConfig])]; + case 1: + txHash = _a.sent(); + console.log("[Reception.repay] txHash: " + txHash); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['reception'].abi, this.transactionTimeout)]; + } + }); + }); }; + /** + * @param wad Amount which should be repaid + * @param usr Address that receives the NFT + */ + this.close = function (loanId, usr) { return __awaiter(_this, void 0, void 0, function () { + var txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.reception.close, [loanId, usr, this.ethConfig])]; + case 1: + txHash = _a.sent(); + console.log("[Reception.close] txHash: " + txHash); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['reception'].abi, this.transactionTimeout)]; + } + }); + }); }; + this.approveCurrency = function (usr, wad) { return __awaiter(_this, void 0, void 0, function () { + var txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.currency.approve, [usr, wad, this.ethConfig])]; + case 1: + txHash = _a.sent(); + console.log("[Currency.approve] txHash: " + txHash); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['currency'].abi, this.transactionTimeout)]; + } + }); + }); }; + this.lenderRely = function (usr) { return __awaiter(_this, void 0, void 0, function () { + var txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.lender.rely, [usr, this.ethConfig])]; + case 1: + txHash = _a.sent(); + console.log("[Lender.rely] txHash: " + txHash); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['lender'].abi, this.transactionTimeout)]; + } + }); + }); }; + this.initFee = function (fee) { return __awaiter(_this, void 0, void 0, function () { + var txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.pileForInit.file, [fee, fee, this.ethConfig])]; + case 1: + txHash = _a.sent(); + console.log("[Pile.file] txHash: " + txHash); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts.pileForInit.abi, this.transactionTimeout)]; + } + }); + }); }; + this.existsFee = function (fee) { return __awaiter(_this, void 0, void 0, function () { + var res; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.pile.fees, [fee])]; + case 1: + res = _a.sent(); + return [2 /*return*/, !res.speed.isZero()]; + } + }); + }); }; + this.addFee = function (loanId, fee, balance) { return __awaiter(_this, void 0, void 0, function () { + var txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.pileForAdd.file, [loanId, fee, balance, this.ethConfig])]; + case 1: + txHash = _a.sent(); + console.log("[Pile.file] txHash: " + txHash); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts.pileForAdd.abi, this.transactionTimeout)]; + } + }); + }); }; + this.getCurrentDebt = function (loanId) { return __awaiter(_this, void 0, void 0, function () { + var res; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.pile.burden, [loanId])]; + case 1: + res = _a.sent(); + return [2 /*return*/, res['0']]; + } + }); + }); }; + /** + * whitelist is a shortcut contract that calls adminAdmit (admit.admit), + * adminAppraise (appraiser.file) and addFee (pile.file) to prevent additional + * transactions. It is required though that the fee is already initialized + * using initFee + * @param owner Owner of the created loan + */ + this.whitelist = function (registry, nft, principal, appraisal, fee, owner) { return __awaiter(_this, void 0, void 0, function () { + var txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.admin.whitelist, [registry, nft, principal, appraisal, fee, owner, this.ethConfig])]; + case 1: + txHash = _a.sent(); + console.log("[Admin.whitelist] txHash: " + txHash); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['nft'].abi, this.transactionTimeout)]; + } + }); + }); }; + this.unwhitelist = function (loanId, registry, nft) { return __awaiter(_this, void 0, void 0, function () { + var txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.shelf.file, [loanId, registry, nft, '0', this.ethConfig])]; + case 1: + txHash = _a.sent(); + console.log("[Shelf.file] txHash: " + txHash); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['shelf'].abi, this.transactionTimeout)]; + } + }); + }); }; + this.getTotalDebt = function () { return __awaiter(_this, void 0, void 0, function () { + var res; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.pile.Debt, [])]; + case 1: + res = _a.sent(); + return [2 /*return*/, res['0']]; + } + }); + }); }; + this.getTotalBalance = function () { return __awaiter(_this, void 0, void 0, function () { + var res; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.pile.Balance, [])]; + case 1: + res = _a.sent(); + return [2 /*return*/, res['0']]; + } + }); + }); }; + this.getTotalValueOfNFTs = function () { return __awaiter(_this, void 0, void 0, function () { + var res; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.collateral.totalSupply, [])]; + case 1: + res = _a.sent(); + return [2 /*return*/, res['0']]; + } + }); + }); }; + this.getNFTData = function (tokenId) { return __awaiter(_this, void 0, void 0, function () { + var res; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.nftData.data, [tokenId])]; + case 1: + res = _a.sent(); + return [2 /*return*/, res]; + } + }); + }); }; + this.contractAbis = contractAbis || { + nft: contractAbiNft, + title: contractAbiTitle, + currency: contractAbiCurrency, + admit: contractAbiAdmit, + reception: contractAbiReception, + desk: contractAbiDesk, + shelf: contractAbiShelf, + appraiser: contractAbiAppraiser, + lender: contractAbiLender, + collateral: contractAbiCollateral, + pile: contractAbiPile, + pileForAdd: contractAbiPileForAdd, + pileForInit: contractAbiPileForInit, + admin: contractAbiAdmin, + nftData: [{ + constant: true, + inputs: [ + { + name: '', + type: 'uint256', + }, + ], + name: 'data', + outputs: nftDataOutputs, + payable: false, + stateMutability: 'view', + type: 'function', + }], + }; + this.contractAddresses = contractAddresses; + this.transactionTimeout = transactionTimeout; + this.setProvider(provider, ethOptions); + this.setEthConfig(ethConfig || {}); + } + return Tinlake; +}()); +function executeAndRetry(f, args) { + if (args === void 0) { args = []; } + return __awaiter(this, void 0, void 0, function () { + var result, e_1; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + _a.trys.push([0, 2, , 3]); + return [4 /*yield*/, f.apply(void 0, args)]; + case 1: + result = _a.sent(); + return [2 /*return*/, result]; + case 2: + e_1 = _a.sent(); + // using error message, since error code -32603 is not unique enough + // todo introduce retry limit + if (e_1 && e_1.message && (e_1.message.indexOf("Cannot read property 'number' of null") !== -1 || + e_1.message.indexOf('error with payload') !== -1)) { + console.log("internal RPC error detected, retry triggered...", e_1); + throw (new Error("Internal RPC Error. Please try again.")); + // await sleep(1000); + // return executeAndRetry(f, args); + } + else { + throw (e_1); + } + return [3 /*break*/, 3]; + case 3: return [2 /*return*/]; + } + }); + }); +} +var waitAndReturnEvents = function (eth, txHash, abi, transactionTimeout) { return __awaiter(_this, void 0, void 0, function () { + var tx; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, waitForTransaction(eth, txHash, transactionTimeout)]; + case 1: + tx = _a.sent(); + return [2 /*return*/, new Promise(function (resolve, reject) { + eth.getTransactionReceipt(tx.hash, function (err, receipt) { + if (err != null) { + reject('failed to get receipt'); + } + var events = getEvents(receipt, abi); + resolve({ events: events, txHash: tx.hash, status: receipt.status }); + }); + })]; + } + }); +}); }; +// todo replace with a better polling +var waitForTransaction = function (eth, txHash, transactionTimeout) { + return new Promise(function (resolve, reject) { + var secMax = transactionTimeout; + var sec = 0; + var wait = function (txHash) { + setTimeout(function () { + eth.getTransactionByHash(txHash, function (err, tx) { + if (err) { + reject(err); + return; + } + if (tx && tx.blockHash != null) { + resolve(tx); + return; + } + console.log("waiting for tx :" + txHash); + sec = sec + 1; + if (sec < secMax) { + wait(txHash); + } + else { + reject(new Error("waiting for transaction tx " + txHash + " timed out after " + secMax + " seconds")); + } + }); + }, pollingInterval); + }; + wait(txHash); + }); +}; +var findEvent = function (abi, funcSignature) { + return abi.filter(function (item) { + if (item.type !== 'event') + return false; + var signature = item.name + "(" + item.inputs.map(function (input) { return input.type; }).join(',') + ")"; + var hash = src_11(signature); + if (hash === funcSignature) + return true; + }); +}; +var getEvents = function (receipt, abi) { + if (receipt.logs.length === 0) { + return null; + } + var events = []; + receipt.logs.forEach(function (log) { + var funcSignature = log.topics[0]; + var matches = findEvent(abi, funcSignature); + if (matches.length === 1) { + var event = matches[0]; + var inputs = event.inputs.filter(function (input) { return input.indexed; }) + .map(function (input) { return input.type; }); + // remove 0x prefix from topics + var topics = log.topics.map(function (t) { + return t.replace('0x', ''); + }); + // concat topics without first topic (func signature) + var bytes = "0x" + topics.slice(1).join(''); + var data = abiCoder$1.decodeParameters(inputs, bytes); + events.push({ event: event, data: data }); + } + }); + return events; }; export default Tinlake; diff --git a/dist/Tinlake.js b/dist/Tinlake.js index 6d418de..a0670ed 100644 --- a/dist/Tinlake.js +++ b/dist/Tinlake.js @@ -11,56 +11,56 @@ var url = _interopDefault(require('url')); var buffer = _interopDefault(require('buffer')); var crypto$1 = _interopDefault(require('crypto')); -/*! ***************************************************************************** -Copyright (c) Microsoft Corporation. All rights reserved. -Licensed under the Apache License, Version 2.0 (the "License"); you may not use -this file except in compliance with the License. You may obtain a copy of the -License at http://www.apache.org/licenses/LICENSE-2.0 - -THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED -WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, -MERCHANTABLITY OR NON-INFRINGEMENT. - -See the Apache Version 2.0 License for specific language governing permissions -and limitations under the License. -***************************************************************************** */ - -function __awaiter(thisArg, _arguments, P, generator) { - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -} - -function __generator(thisArg, body) { - var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; - return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; - function verb(n) { return function (v) { return step([n, v]); }; } - function step(op) { - if (f) throw new TypeError("Generator is already executing."); - while (_) try { - if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [op[0] & 2, t.value]; - switch (op[0]) { - case 0: case 1: t = op; break; - case 4: _.label++; return { value: op[1], done: false }; - case 5: _.label++; y = op[1]; op = [0]; continue; - case 7: op = _.ops.pop(); _.trys.pop(); continue; - default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } - if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } - if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } - if (t[2]) _.ops.pop(); - _.trys.pop(); continue; - } - op = body.call(thisArg, _); - } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } - if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; - } +/*! ***************************************************************************** +Copyright (c) Microsoft Corporation. All rights reserved. +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at http://www.apache.org/licenses/LICENSE-2.0 + +THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED +WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, +MERCHANTABLITY OR NON-INFRINGEMENT. + +See the Apache Version 2.0 License for specific language governing permissions +and limitations under the License. +***************************************************************************** */ + +function __awaiter(thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +} + +function __generator(thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } } var methods = { @@ -5475,474 +5475,474 @@ module.exports = { "default": assign, __esModule: true }; unwrapExports(assign$1); var sha3 = createCommonjsModule(function (module) { -/** - * [js-sha3]{@link https://github.com/emn178/js-sha3} - * - * @version 0.5.5 - * @author Chen, Yi-Cyuan [emn178@gmail.com] - * @copyright Chen, Yi-Cyuan 2015-2016 - * @license MIT - */ -(function (root) { - - var NODE_JS = typeof process == 'object' && process.versions && process.versions.node; - if (NODE_JS) { - root = commonjsGlobal; - } - var COMMON_JS = !root.JS_SHA3_TEST && 'object' == 'object' && module.exports; - var HEX_CHARS = '0123456789abcdef'.split(''); - var SHAKE_PADDING = [31, 7936, 2031616, 520093696]; - var KECCAK_PADDING = [1, 256, 65536, 16777216]; - var PADDING = [6, 1536, 393216, 100663296]; - var SHIFT = [0, 8, 16, 24]; - var RC = [1, 0, 32898, 0, 32906, 2147483648, 2147516416, 2147483648, 32907, 0, 2147483649, - 0, 2147516545, 2147483648, 32777, 2147483648, 138, 0, 136, 0, 2147516425, 0, - 2147483658, 0, 2147516555, 0, 139, 2147483648, 32905, 2147483648, 32771, - 2147483648, 32770, 2147483648, 128, 2147483648, 32778, 0, 2147483658, 2147483648, - 2147516545, 2147483648, 32896, 2147483648, 2147483649, 0, 2147516424, 2147483648]; - var BITS = [224, 256, 384, 512]; - var SHAKE_BITS = [128, 256]; - var OUTPUT_TYPES = ['hex', 'buffer', 'arrayBuffer', 'array']; - - var createOutputMethod = function (bits, padding, outputType) { - return function (message) { - return new Keccak(bits, padding, bits).update(message)[outputType](); - } - }; - - var createShakeOutputMethod = function (bits, padding, outputType) { - return function (message, outputBits) { - return new Keccak(bits, padding, outputBits).update(message)[outputType](); - } - }; - - var createMethod = function (bits, padding) { - var method = createOutputMethod(bits, padding, 'hex'); - method.create = function () { - return new Keccak(bits, padding, bits); - }; - method.update = function (message) { - return method.create().update(message); - }; - for (var i = 0;i < OUTPUT_TYPES.length;++i) { - var type = OUTPUT_TYPES[i]; - method[type] = createOutputMethod(bits, padding, type); - } - return method; - }; - - var createShakeMethod = function (bits, padding) { - var method = createShakeOutputMethod(bits, padding, 'hex'); - method.create = function (outputBits) { - return new Keccak(bits, padding, outputBits); - }; - method.update = function (message, outputBits) { - return method.create(outputBits).update(message); - }; - for (var i = 0;i < OUTPUT_TYPES.length;++i) { - var type = OUTPUT_TYPES[i]; - method[type] = createShakeOutputMethod(bits, padding, type); - } - return method; - }; - - var algorithms = [ - {name: 'keccak', padding: KECCAK_PADDING, bits: BITS, createMethod: createMethod}, - {name: 'sha3', padding: PADDING, bits: BITS, createMethod: createMethod}, - {name: 'shake', padding: SHAKE_PADDING, bits: SHAKE_BITS, createMethod: createShakeMethod} - ]; - - var methods = {}; - - for (var i = 0;i < algorithms.length;++i) { - var algorithm = algorithms[i]; - var bits = algorithm.bits; - for (var j = 0;j < bits.length;++j) { - methods[algorithm.name +'_' + bits[j]] = algorithm.createMethod(bits[j], algorithm.padding); - } - } - - function Keccak(bits, padding, outputBits) { - this.blocks = []; - this.s = []; - this.padding = padding; - this.outputBits = outputBits; - this.reset = true; - this.block = 0; - this.start = 0; - this.blockCount = (1600 - (bits << 1)) >> 5; - this.byteCount = this.blockCount << 2; - this.outputBlocks = outputBits >> 5; - this.extraBytes = (outputBits & 31) >> 3; - - for (var i = 0;i < 50;++i) { - this.s[i] = 0; - } - } - Keccak.prototype.update = function (message) { - var notString = typeof message != 'string'; - if (notString && message.constructor == root.ArrayBuffer) { - message = new Uint8Array(message); - } - var length = message.length, blocks = this.blocks, byteCount = this.byteCount, - blockCount = this.blockCount, index = 0, s = this.s, i, code; - - while (index < length) { - if (this.reset) { - this.reset = false; - blocks[0] = this.block; - for (i = 1;i < blockCount + 1;++i) { - blocks[i] = 0; - } - } - if (notString) { - for (i = this.start;index < length && i < byteCount;++index) { - blocks[i >> 2] |= message[index] << SHIFT[i++ & 3]; - } - } else { - for (i = this.start;index < length && i < byteCount;++index) { - code = message.charCodeAt(index); - if (code < 0x80) { - blocks[i >> 2] |= code << SHIFT[i++ & 3]; - } else if (code < 0x800) { - blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; - } else if (code < 0xd800 || code >= 0xe000) { - blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; - } else { - code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff)); - blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; - } - } - } - this.lastByteIndex = i; - if (i >= byteCount) { - this.start = i - byteCount; - this.block = blocks[blockCount]; - for (i = 0;i < blockCount;++i) { - s[i] ^= blocks[i]; - } - f(s); - this.reset = true; - } else { - this.start = i; - } - } - return this; - }; - - Keccak.prototype.finalize = function () { - var blocks = this.blocks, i = this.lastByteIndex, blockCount = this.blockCount, s = this.s; - blocks[i >> 2] |= this.padding[i & 3]; - if (this.lastByteIndex == this.byteCount) { - blocks[0] = blocks[blockCount]; - for (i = 1;i < blockCount + 1;++i) { - blocks[i] = 0; - } - } - blocks[blockCount - 1] |= 0x80000000; - for (i = 0;i < blockCount;++i) { - s[i] ^= blocks[i]; - } - f(s); - }; - - Keccak.prototype.toString = Keccak.prototype.hex = function () { - this.finalize(); - - var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, - extraBytes = this.extraBytes, i = 0, j = 0; - var hex = '', block; - while (j < outputBlocks) { - for (i = 0;i < blockCount && j < outputBlocks;++i, ++j) { - block = s[i]; - hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F] + - HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F] + - HEX_CHARS[(block >> 20) & 0x0F] + HEX_CHARS[(block >> 16) & 0x0F] + - HEX_CHARS[(block >> 28) & 0x0F] + HEX_CHARS[(block >> 24) & 0x0F]; - } - if (j % blockCount == 0) { - f(s); - i = 0; - } - } - if (extraBytes) { - block = s[i]; - if (extraBytes > 0) { - hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F]; - } - if (extraBytes > 1) { - hex += HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F]; - } - if (extraBytes > 2) { - hex += HEX_CHARS[(block >> 20) & 0x0F] + HEX_CHARS[(block >> 16) & 0x0F]; - } - } - return hex; - }; - - Keccak.prototype.arrayBuffer = function () { - this.finalize(); - - var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, - extraBytes = this.extraBytes, i = 0, j = 0; - var bytes = this.outputBits >> 3; - var buffer; - if (extraBytes) { - buffer = new ArrayBuffer((outputBlocks + 1) << 2); - } else { - buffer = new ArrayBuffer(bytes); - } - var array = new Uint32Array(buffer); - while (j < outputBlocks) { - for (i = 0;i < blockCount && j < outputBlocks;++i, ++j) { - array[j] = s[i]; - } - if (j % blockCount == 0) { - f(s); - } - } - if (extraBytes) { - array[i] = s[i]; - buffer = buffer.slice(0, bytes); - } - return buffer; - }; - - Keccak.prototype.buffer = Keccak.prototype.arrayBuffer; - - Keccak.prototype.digest = Keccak.prototype.array = function () { - this.finalize(); - - var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, - extraBytes = this.extraBytes, i = 0, j = 0; - var array = [], offset, block; - while (j < outputBlocks) { - for (i = 0;i < blockCount && j < outputBlocks;++i, ++j) { - offset = j << 2; - block = s[i]; - array[offset] = block & 0xFF; - array[offset + 1] = (block >> 8) & 0xFF; - array[offset + 2] = (block >> 16) & 0xFF; - array[offset + 3] = (block >> 24) & 0xFF; - } - if (j % blockCount == 0) { - f(s); - } - } - if (extraBytes) { - offset = j << 2; - block = s[i]; - if (extraBytes > 0) { - array[offset] = block & 0xFF; - } - if (extraBytes > 1) { - array[offset + 1] = (block >> 8) & 0xFF; - } - if (extraBytes > 2) { - array[offset + 2] = (block >> 16) & 0xFF; - } - } - return array; - }; - - var f = function (s) { - var h, l, n, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, - b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16, b17, - b18, b19, b20, b21, b22, b23, b24, b25, b26, b27, b28, b29, b30, b31, b32, b33, - b34, b35, b36, b37, b38, b39, b40, b41, b42, b43, b44, b45, b46, b47, b48, b49; - for (n = 0;n < 48;n += 2) { - c0 = s[0] ^ s[10] ^ s[20] ^ s[30] ^ s[40]; - c1 = s[1] ^ s[11] ^ s[21] ^ s[31] ^ s[41]; - c2 = s[2] ^ s[12] ^ s[22] ^ s[32] ^ s[42]; - c3 = s[3] ^ s[13] ^ s[23] ^ s[33] ^ s[43]; - c4 = s[4] ^ s[14] ^ s[24] ^ s[34] ^ s[44]; - c5 = s[5] ^ s[15] ^ s[25] ^ s[35] ^ s[45]; - c6 = s[6] ^ s[16] ^ s[26] ^ s[36] ^ s[46]; - c7 = s[7] ^ s[17] ^ s[27] ^ s[37] ^ s[47]; - c8 = s[8] ^ s[18] ^ s[28] ^ s[38] ^ s[48]; - c9 = s[9] ^ s[19] ^ s[29] ^ s[39] ^ s[49]; - - h = c8 ^ ((c2 << 1) | (c3 >>> 31)); - l = c9 ^ ((c3 << 1) | (c2 >>> 31)); - s[0] ^= h; - s[1] ^= l; - s[10] ^= h; - s[11] ^= l; - s[20] ^= h; - s[21] ^= l; - s[30] ^= h; - s[31] ^= l; - s[40] ^= h; - s[41] ^= l; - h = c0 ^ ((c4 << 1) | (c5 >>> 31)); - l = c1 ^ ((c5 << 1) | (c4 >>> 31)); - s[2] ^= h; - s[3] ^= l; - s[12] ^= h; - s[13] ^= l; - s[22] ^= h; - s[23] ^= l; - s[32] ^= h; - s[33] ^= l; - s[42] ^= h; - s[43] ^= l; - h = c2 ^ ((c6 << 1) | (c7 >>> 31)); - l = c3 ^ ((c7 << 1) | (c6 >>> 31)); - s[4] ^= h; - s[5] ^= l; - s[14] ^= h; - s[15] ^= l; - s[24] ^= h; - s[25] ^= l; - s[34] ^= h; - s[35] ^= l; - s[44] ^= h; - s[45] ^= l; - h = c4 ^ ((c8 << 1) | (c9 >>> 31)); - l = c5 ^ ((c9 << 1) | (c8 >>> 31)); - s[6] ^= h; - s[7] ^= l; - s[16] ^= h; - s[17] ^= l; - s[26] ^= h; - s[27] ^= l; - s[36] ^= h; - s[37] ^= l; - s[46] ^= h; - s[47] ^= l; - h = c6 ^ ((c0 << 1) | (c1 >>> 31)); - l = c7 ^ ((c1 << 1) | (c0 >>> 31)); - s[8] ^= h; - s[9] ^= l; - s[18] ^= h; - s[19] ^= l; - s[28] ^= h; - s[29] ^= l; - s[38] ^= h; - s[39] ^= l; - s[48] ^= h; - s[49] ^= l; - - b0 = s[0]; - b1 = s[1]; - b32 = (s[11] << 4) | (s[10] >>> 28); - b33 = (s[10] << 4) | (s[11] >>> 28); - b14 = (s[20] << 3) | (s[21] >>> 29); - b15 = (s[21] << 3) | (s[20] >>> 29); - b46 = (s[31] << 9) | (s[30] >>> 23); - b47 = (s[30] << 9) | (s[31] >>> 23); - b28 = (s[40] << 18) | (s[41] >>> 14); - b29 = (s[41] << 18) | (s[40] >>> 14); - b20 = (s[2] << 1) | (s[3] >>> 31); - b21 = (s[3] << 1) | (s[2] >>> 31); - b2 = (s[13] << 12) | (s[12] >>> 20); - b3 = (s[12] << 12) | (s[13] >>> 20); - b34 = (s[22] << 10) | (s[23] >>> 22); - b35 = (s[23] << 10) | (s[22] >>> 22); - b16 = (s[33] << 13) | (s[32] >>> 19); - b17 = (s[32] << 13) | (s[33] >>> 19); - b48 = (s[42] << 2) | (s[43] >>> 30); - b49 = (s[43] << 2) | (s[42] >>> 30); - b40 = (s[5] << 30) | (s[4] >>> 2); - b41 = (s[4] << 30) | (s[5] >>> 2); - b22 = (s[14] << 6) | (s[15] >>> 26); - b23 = (s[15] << 6) | (s[14] >>> 26); - b4 = (s[25] << 11) | (s[24] >>> 21); - b5 = (s[24] << 11) | (s[25] >>> 21); - b36 = (s[34] << 15) | (s[35] >>> 17); - b37 = (s[35] << 15) | (s[34] >>> 17); - b18 = (s[45] << 29) | (s[44] >>> 3); - b19 = (s[44] << 29) | (s[45] >>> 3); - b10 = (s[6] << 28) | (s[7] >>> 4); - b11 = (s[7] << 28) | (s[6] >>> 4); - b42 = (s[17] << 23) | (s[16] >>> 9); - b43 = (s[16] << 23) | (s[17] >>> 9); - b24 = (s[26] << 25) | (s[27] >>> 7); - b25 = (s[27] << 25) | (s[26] >>> 7); - b6 = (s[36] << 21) | (s[37] >>> 11); - b7 = (s[37] << 21) | (s[36] >>> 11); - b38 = (s[47] << 24) | (s[46] >>> 8); - b39 = (s[46] << 24) | (s[47] >>> 8); - b30 = (s[8] << 27) | (s[9] >>> 5); - b31 = (s[9] << 27) | (s[8] >>> 5); - b12 = (s[18] << 20) | (s[19] >>> 12); - b13 = (s[19] << 20) | (s[18] >>> 12); - b44 = (s[29] << 7) | (s[28] >>> 25); - b45 = (s[28] << 7) | (s[29] >>> 25); - b26 = (s[38] << 8) | (s[39] >>> 24); - b27 = (s[39] << 8) | (s[38] >>> 24); - b8 = (s[48] << 14) | (s[49] >>> 18); - b9 = (s[49] << 14) | (s[48] >>> 18); - - s[0] = b0 ^ (~b2 & b4); - s[1] = b1 ^ (~b3 & b5); - s[10] = b10 ^ (~b12 & b14); - s[11] = b11 ^ (~b13 & b15); - s[20] = b20 ^ (~b22 & b24); - s[21] = b21 ^ (~b23 & b25); - s[30] = b30 ^ (~b32 & b34); - s[31] = b31 ^ (~b33 & b35); - s[40] = b40 ^ (~b42 & b44); - s[41] = b41 ^ (~b43 & b45); - s[2] = b2 ^ (~b4 & b6); - s[3] = b3 ^ (~b5 & b7); - s[12] = b12 ^ (~b14 & b16); - s[13] = b13 ^ (~b15 & b17); - s[22] = b22 ^ (~b24 & b26); - s[23] = b23 ^ (~b25 & b27); - s[32] = b32 ^ (~b34 & b36); - s[33] = b33 ^ (~b35 & b37); - s[42] = b42 ^ (~b44 & b46); - s[43] = b43 ^ (~b45 & b47); - s[4] = b4 ^ (~b6 & b8); - s[5] = b5 ^ (~b7 & b9); - s[14] = b14 ^ (~b16 & b18); - s[15] = b15 ^ (~b17 & b19); - s[24] = b24 ^ (~b26 & b28); - s[25] = b25 ^ (~b27 & b29); - s[34] = b34 ^ (~b36 & b38); - s[35] = b35 ^ (~b37 & b39); - s[44] = b44 ^ (~b46 & b48); - s[45] = b45 ^ (~b47 & b49); - s[6] = b6 ^ (~b8 & b0); - s[7] = b7 ^ (~b9 & b1); - s[16] = b16 ^ (~b18 & b10); - s[17] = b17 ^ (~b19 & b11); - s[26] = b26 ^ (~b28 & b20); - s[27] = b27 ^ (~b29 & b21); - s[36] = b36 ^ (~b38 & b30); - s[37] = b37 ^ (~b39 & b31); - s[46] = b46 ^ (~b48 & b40); - s[47] = b47 ^ (~b49 & b41); - s[8] = b8 ^ (~b0 & b2); - s[9] = b9 ^ (~b1 & b3); - s[18] = b18 ^ (~b10 & b12); - s[19] = b19 ^ (~b11 & b13); - s[28] = b28 ^ (~b20 & b22); - s[29] = b29 ^ (~b21 & b23); - s[38] = b38 ^ (~b30 & b32); - s[39] = b39 ^ (~b31 & b33); - s[48] = b48 ^ (~b40 & b42); - s[49] = b49 ^ (~b41 & b43); - - s[0] ^= RC[n]; - s[1] ^= RC[n + 1]; - } - }; - - if (COMMON_JS) { - module.exports = methods; - } else if (root) { - for (var key in methods) { - root[key] = methods[key]; - } - } +/** + * [js-sha3]{@link https://github.com/emn178/js-sha3} + * + * @version 0.5.5 + * @author Chen, Yi-Cyuan [emn178@gmail.com] + * @copyright Chen, Yi-Cyuan 2015-2016 + * @license MIT + */ +(function (root) { + + var NODE_JS = typeof process == 'object' && process.versions && process.versions.node; + if (NODE_JS) { + root = commonjsGlobal; + } + var COMMON_JS = !root.JS_SHA3_TEST && 'object' == 'object' && module.exports; + var HEX_CHARS = '0123456789abcdef'.split(''); + var SHAKE_PADDING = [31, 7936, 2031616, 520093696]; + var KECCAK_PADDING = [1, 256, 65536, 16777216]; + var PADDING = [6, 1536, 393216, 100663296]; + var SHIFT = [0, 8, 16, 24]; + var RC = [1, 0, 32898, 0, 32906, 2147483648, 2147516416, 2147483648, 32907, 0, 2147483649, + 0, 2147516545, 2147483648, 32777, 2147483648, 138, 0, 136, 0, 2147516425, 0, + 2147483658, 0, 2147516555, 0, 139, 2147483648, 32905, 2147483648, 32771, + 2147483648, 32770, 2147483648, 128, 2147483648, 32778, 0, 2147483658, 2147483648, + 2147516545, 2147483648, 32896, 2147483648, 2147483649, 0, 2147516424, 2147483648]; + var BITS = [224, 256, 384, 512]; + var SHAKE_BITS = [128, 256]; + var OUTPUT_TYPES = ['hex', 'buffer', 'arrayBuffer', 'array']; + + var createOutputMethod = function (bits, padding, outputType) { + return function (message) { + return new Keccak(bits, padding, bits).update(message)[outputType](); + } + }; + + var createShakeOutputMethod = function (bits, padding, outputType) { + return function (message, outputBits) { + return new Keccak(bits, padding, outputBits).update(message)[outputType](); + } + }; + + var createMethod = function (bits, padding) { + var method = createOutputMethod(bits, padding, 'hex'); + method.create = function () { + return new Keccak(bits, padding, bits); + }; + method.update = function (message) { + return method.create().update(message); + }; + for (var i = 0;i < OUTPUT_TYPES.length;++i) { + var type = OUTPUT_TYPES[i]; + method[type] = createOutputMethod(bits, padding, type); + } + return method; + }; + + var createShakeMethod = function (bits, padding) { + var method = createShakeOutputMethod(bits, padding, 'hex'); + method.create = function (outputBits) { + return new Keccak(bits, padding, outputBits); + }; + method.update = function (message, outputBits) { + return method.create(outputBits).update(message); + }; + for (var i = 0;i < OUTPUT_TYPES.length;++i) { + var type = OUTPUT_TYPES[i]; + method[type] = createShakeOutputMethod(bits, padding, type); + } + return method; + }; + + var algorithms = [ + {name: 'keccak', padding: KECCAK_PADDING, bits: BITS, createMethod: createMethod}, + {name: 'sha3', padding: PADDING, bits: BITS, createMethod: createMethod}, + {name: 'shake', padding: SHAKE_PADDING, bits: SHAKE_BITS, createMethod: createShakeMethod} + ]; + + var methods = {}; + + for (var i = 0;i < algorithms.length;++i) { + var algorithm = algorithms[i]; + var bits = algorithm.bits; + for (var j = 0;j < bits.length;++j) { + methods[algorithm.name +'_' + bits[j]] = algorithm.createMethod(bits[j], algorithm.padding); + } + } + + function Keccak(bits, padding, outputBits) { + this.blocks = []; + this.s = []; + this.padding = padding; + this.outputBits = outputBits; + this.reset = true; + this.block = 0; + this.start = 0; + this.blockCount = (1600 - (bits << 1)) >> 5; + this.byteCount = this.blockCount << 2; + this.outputBlocks = outputBits >> 5; + this.extraBytes = (outputBits & 31) >> 3; + + for (var i = 0;i < 50;++i) { + this.s[i] = 0; + } + } + Keccak.prototype.update = function (message) { + var notString = typeof message != 'string'; + if (notString && message.constructor == root.ArrayBuffer) { + message = new Uint8Array(message); + } + var length = message.length, blocks = this.blocks, byteCount = this.byteCount, + blockCount = this.blockCount, index = 0, s = this.s, i, code; + + while (index < length) { + if (this.reset) { + this.reset = false; + blocks[0] = this.block; + for (i = 1;i < blockCount + 1;++i) { + blocks[i] = 0; + } + } + if (notString) { + for (i = this.start;index < length && i < byteCount;++index) { + blocks[i >> 2] |= message[index] << SHIFT[i++ & 3]; + } + } else { + for (i = this.start;index < length && i < byteCount;++index) { + code = message.charCodeAt(index); + if (code < 0x80) { + blocks[i >> 2] |= code << SHIFT[i++ & 3]; + } else if (code < 0x800) { + blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; + } else if (code < 0xd800 || code >= 0xe000) { + blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; + } else { + code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff)); + blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; + } + } + } + this.lastByteIndex = i; + if (i >= byteCount) { + this.start = i - byteCount; + this.block = blocks[blockCount]; + for (i = 0;i < blockCount;++i) { + s[i] ^= blocks[i]; + } + f(s); + this.reset = true; + } else { + this.start = i; + } + } + return this; + }; + + Keccak.prototype.finalize = function () { + var blocks = this.blocks, i = this.lastByteIndex, blockCount = this.blockCount, s = this.s; + blocks[i >> 2] |= this.padding[i & 3]; + if (this.lastByteIndex == this.byteCount) { + blocks[0] = blocks[blockCount]; + for (i = 1;i < blockCount + 1;++i) { + blocks[i] = 0; + } + } + blocks[blockCount - 1] |= 0x80000000; + for (i = 0;i < blockCount;++i) { + s[i] ^= blocks[i]; + } + f(s); + }; + + Keccak.prototype.toString = Keccak.prototype.hex = function () { + this.finalize(); + + var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, + extraBytes = this.extraBytes, i = 0, j = 0; + var hex = '', block; + while (j < outputBlocks) { + for (i = 0;i < blockCount && j < outputBlocks;++i, ++j) { + block = s[i]; + hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F] + + HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F] + + HEX_CHARS[(block >> 20) & 0x0F] + HEX_CHARS[(block >> 16) & 0x0F] + + HEX_CHARS[(block >> 28) & 0x0F] + HEX_CHARS[(block >> 24) & 0x0F]; + } + if (j % blockCount == 0) { + f(s); + i = 0; + } + } + if (extraBytes) { + block = s[i]; + if (extraBytes > 0) { + hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F]; + } + if (extraBytes > 1) { + hex += HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F]; + } + if (extraBytes > 2) { + hex += HEX_CHARS[(block >> 20) & 0x0F] + HEX_CHARS[(block >> 16) & 0x0F]; + } + } + return hex; + }; + + Keccak.prototype.arrayBuffer = function () { + this.finalize(); + + var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, + extraBytes = this.extraBytes, i = 0, j = 0; + var bytes = this.outputBits >> 3; + var buffer; + if (extraBytes) { + buffer = new ArrayBuffer((outputBlocks + 1) << 2); + } else { + buffer = new ArrayBuffer(bytes); + } + var array = new Uint32Array(buffer); + while (j < outputBlocks) { + for (i = 0;i < blockCount && j < outputBlocks;++i, ++j) { + array[j] = s[i]; + } + if (j % blockCount == 0) { + f(s); + } + } + if (extraBytes) { + array[i] = s[i]; + buffer = buffer.slice(0, bytes); + } + return buffer; + }; + + Keccak.prototype.buffer = Keccak.prototype.arrayBuffer; + + Keccak.prototype.digest = Keccak.prototype.array = function () { + this.finalize(); + + var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, + extraBytes = this.extraBytes, i = 0, j = 0; + var array = [], offset, block; + while (j < outputBlocks) { + for (i = 0;i < blockCount && j < outputBlocks;++i, ++j) { + offset = j << 2; + block = s[i]; + array[offset] = block & 0xFF; + array[offset + 1] = (block >> 8) & 0xFF; + array[offset + 2] = (block >> 16) & 0xFF; + array[offset + 3] = (block >> 24) & 0xFF; + } + if (j % blockCount == 0) { + f(s); + } + } + if (extraBytes) { + offset = j << 2; + block = s[i]; + if (extraBytes > 0) { + array[offset] = block & 0xFF; + } + if (extraBytes > 1) { + array[offset + 1] = (block >> 8) & 0xFF; + } + if (extraBytes > 2) { + array[offset + 2] = (block >> 16) & 0xFF; + } + } + return array; + }; + + var f = function (s) { + var h, l, n, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, + b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16, b17, + b18, b19, b20, b21, b22, b23, b24, b25, b26, b27, b28, b29, b30, b31, b32, b33, + b34, b35, b36, b37, b38, b39, b40, b41, b42, b43, b44, b45, b46, b47, b48, b49; + for (n = 0;n < 48;n += 2) { + c0 = s[0] ^ s[10] ^ s[20] ^ s[30] ^ s[40]; + c1 = s[1] ^ s[11] ^ s[21] ^ s[31] ^ s[41]; + c2 = s[2] ^ s[12] ^ s[22] ^ s[32] ^ s[42]; + c3 = s[3] ^ s[13] ^ s[23] ^ s[33] ^ s[43]; + c4 = s[4] ^ s[14] ^ s[24] ^ s[34] ^ s[44]; + c5 = s[5] ^ s[15] ^ s[25] ^ s[35] ^ s[45]; + c6 = s[6] ^ s[16] ^ s[26] ^ s[36] ^ s[46]; + c7 = s[7] ^ s[17] ^ s[27] ^ s[37] ^ s[47]; + c8 = s[8] ^ s[18] ^ s[28] ^ s[38] ^ s[48]; + c9 = s[9] ^ s[19] ^ s[29] ^ s[39] ^ s[49]; + + h = c8 ^ ((c2 << 1) | (c3 >>> 31)); + l = c9 ^ ((c3 << 1) | (c2 >>> 31)); + s[0] ^= h; + s[1] ^= l; + s[10] ^= h; + s[11] ^= l; + s[20] ^= h; + s[21] ^= l; + s[30] ^= h; + s[31] ^= l; + s[40] ^= h; + s[41] ^= l; + h = c0 ^ ((c4 << 1) | (c5 >>> 31)); + l = c1 ^ ((c5 << 1) | (c4 >>> 31)); + s[2] ^= h; + s[3] ^= l; + s[12] ^= h; + s[13] ^= l; + s[22] ^= h; + s[23] ^= l; + s[32] ^= h; + s[33] ^= l; + s[42] ^= h; + s[43] ^= l; + h = c2 ^ ((c6 << 1) | (c7 >>> 31)); + l = c3 ^ ((c7 << 1) | (c6 >>> 31)); + s[4] ^= h; + s[5] ^= l; + s[14] ^= h; + s[15] ^= l; + s[24] ^= h; + s[25] ^= l; + s[34] ^= h; + s[35] ^= l; + s[44] ^= h; + s[45] ^= l; + h = c4 ^ ((c8 << 1) | (c9 >>> 31)); + l = c5 ^ ((c9 << 1) | (c8 >>> 31)); + s[6] ^= h; + s[7] ^= l; + s[16] ^= h; + s[17] ^= l; + s[26] ^= h; + s[27] ^= l; + s[36] ^= h; + s[37] ^= l; + s[46] ^= h; + s[47] ^= l; + h = c6 ^ ((c0 << 1) | (c1 >>> 31)); + l = c7 ^ ((c1 << 1) | (c0 >>> 31)); + s[8] ^= h; + s[9] ^= l; + s[18] ^= h; + s[19] ^= l; + s[28] ^= h; + s[29] ^= l; + s[38] ^= h; + s[39] ^= l; + s[48] ^= h; + s[49] ^= l; + + b0 = s[0]; + b1 = s[1]; + b32 = (s[11] << 4) | (s[10] >>> 28); + b33 = (s[10] << 4) | (s[11] >>> 28); + b14 = (s[20] << 3) | (s[21] >>> 29); + b15 = (s[21] << 3) | (s[20] >>> 29); + b46 = (s[31] << 9) | (s[30] >>> 23); + b47 = (s[30] << 9) | (s[31] >>> 23); + b28 = (s[40] << 18) | (s[41] >>> 14); + b29 = (s[41] << 18) | (s[40] >>> 14); + b20 = (s[2] << 1) | (s[3] >>> 31); + b21 = (s[3] << 1) | (s[2] >>> 31); + b2 = (s[13] << 12) | (s[12] >>> 20); + b3 = (s[12] << 12) | (s[13] >>> 20); + b34 = (s[22] << 10) | (s[23] >>> 22); + b35 = (s[23] << 10) | (s[22] >>> 22); + b16 = (s[33] << 13) | (s[32] >>> 19); + b17 = (s[32] << 13) | (s[33] >>> 19); + b48 = (s[42] << 2) | (s[43] >>> 30); + b49 = (s[43] << 2) | (s[42] >>> 30); + b40 = (s[5] << 30) | (s[4] >>> 2); + b41 = (s[4] << 30) | (s[5] >>> 2); + b22 = (s[14] << 6) | (s[15] >>> 26); + b23 = (s[15] << 6) | (s[14] >>> 26); + b4 = (s[25] << 11) | (s[24] >>> 21); + b5 = (s[24] << 11) | (s[25] >>> 21); + b36 = (s[34] << 15) | (s[35] >>> 17); + b37 = (s[35] << 15) | (s[34] >>> 17); + b18 = (s[45] << 29) | (s[44] >>> 3); + b19 = (s[44] << 29) | (s[45] >>> 3); + b10 = (s[6] << 28) | (s[7] >>> 4); + b11 = (s[7] << 28) | (s[6] >>> 4); + b42 = (s[17] << 23) | (s[16] >>> 9); + b43 = (s[16] << 23) | (s[17] >>> 9); + b24 = (s[26] << 25) | (s[27] >>> 7); + b25 = (s[27] << 25) | (s[26] >>> 7); + b6 = (s[36] << 21) | (s[37] >>> 11); + b7 = (s[37] << 21) | (s[36] >>> 11); + b38 = (s[47] << 24) | (s[46] >>> 8); + b39 = (s[46] << 24) | (s[47] >>> 8); + b30 = (s[8] << 27) | (s[9] >>> 5); + b31 = (s[9] << 27) | (s[8] >>> 5); + b12 = (s[18] << 20) | (s[19] >>> 12); + b13 = (s[19] << 20) | (s[18] >>> 12); + b44 = (s[29] << 7) | (s[28] >>> 25); + b45 = (s[28] << 7) | (s[29] >>> 25); + b26 = (s[38] << 8) | (s[39] >>> 24); + b27 = (s[39] << 8) | (s[38] >>> 24); + b8 = (s[48] << 14) | (s[49] >>> 18); + b9 = (s[49] << 14) | (s[48] >>> 18); + + s[0] = b0 ^ (~b2 & b4); + s[1] = b1 ^ (~b3 & b5); + s[10] = b10 ^ (~b12 & b14); + s[11] = b11 ^ (~b13 & b15); + s[20] = b20 ^ (~b22 & b24); + s[21] = b21 ^ (~b23 & b25); + s[30] = b30 ^ (~b32 & b34); + s[31] = b31 ^ (~b33 & b35); + s[40] = b40 ^ (~b42 & b44); + s[41] = b41 ^ (~b43 & b45); + s[2] = b2 ^ (~b4 & b6); + s[3] = b3 ^ (~b5 & b7); + s[12] = b12 ^ (~b14 & b16); + s[13] = b13 ^ (~b15 & b17); + s[22] = b22 ^ (~b24 & b26); + s[23] = b23 ^ (~b25 & b27); + s[32] = b32 ^ (~b34 & b36); + s[33] = b33 ^ (~b35 & b37); + s[42] = b42 ^ (~b44 & b46); + s[43] = b43 ^ (~b45 & b47); + s[4] = b4 ^ (~b6 & b8); + s[5] = b5 ^ (~b7 & b9); + s[14] = b14 ^ (~b16 & b18); + s[15] = b15 ^ (~b17 & b19); + s[24] = b24 ^ (~b26 & b28); + s[25] = b25 ^ (~b27 & b29); + s[34] = b34 ^ (~b36 & b38); + s[35] = b35 ^ (~b37 & b39); + s[44] = b44 ^ (~b46 & b48); + s[45] = b45 ^ (~b47 & b49); + s[6] = b6 ^ (~b8 & b0); + s[7] = b7 ^ (~b9 & b1); + s[16] = b16 ^ (~b18 & b10); + s[17] = b17 ^ (~b19 & b11); + s[26] = b26 ^ (~b28 & b20); + s[27] = b27 ^ (~b29 & b21); + s[36] = b36 ^ (~b38 & b30); + s[37] = b37 ^ (~b39 & b31); + s[46] = b46 ^ (~b48 & b40); + s[47] = b47 ^ (~b49 & b41); + s[8] = b8 ^ (~b0 & b2); + s[9] = b9 ^ (~b1 & b3); + s[18] = b18 ^ (~b10 & b12); + s[19] = b19 ^ (~b11 & b13); + s[28] = b28 ^ (~b20 & b22); + s[29] = b29 ^ (~b21 & b23); + s[38] = b38 ^ (~b30 & b32); + s[39] = b39 ^ (~b31 & b33); + s[48] = b48 ^ (~b40 & b42); + s[49] = b49 ^ (~b41 & b43); + + s[0] ^= RC[n]; + s[1] ^= RC[n + 1]; + } + }; + + if (COMMON_JS) { + module.exports = methods; + } else if (root) { + for (var key in methods) { + root[key] = methods[key]; + } + } }(commonjsGlobal)); }); @@ -18943,479 +18943,479 @@ var constants_8 = constants.WeiPerEther; var constants_9 = constants.MaxUint256; var sha3$2 = createCommonjsModule(function (module) { -/** - * [js-sha3]{@link https://github.com/emn178/js-sha3} - * - * @version 0.5.7 - * @author Chen, Yi-Cyuan [emn178@gmail.com] - * @copyright Chen, Yi-Cyuan 2015-2016 - * @license MIT - */ -/*jslint bitwise: true */ -(function () { - - var root = typeof window === 'object' ? window : {}; - var NODE_JS = !root.JS_SHA3_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node; - if (NODE_JS) { - root = commonjsGlobal; - } - var COMMON_JS = !root.JS_SHA3_NO_COMMON_JS && 'object' === 'object' && module.exports; - var HEX_CHARS = '0123456789abcdef'.split(''); - var SHAKE_PADDING = [31, 7936, 2031616, 520093696]; - var KECCAK_PADDING = [1, 256, 65536, 16777216]; - var PADDING = [6, 1536, 393216, 100663296]; - var SHIFT = [0, 8, 16, 24]; - var RC = [1, 0, 32898, 0, 32906, 2147483648, 2147516416, 2147483648, 32907, 0, 2147483649, - 0, 2147516545, 2147483648, 32777, 2147483648, 138, 0, 136, 0, 2147516425, 0, - 2147483658, 0, 2147516555, 0, 139, 2147483648, 32905, 2147483648, 32771, - 2147483648, 32770, 2147483648, 128, 2147483648, 32778, 0, 2147483658, 2147483648, - 2147516545, 2147483648, 32896, 2147483648, 2147483649, 0, 2147516424, 2147483648]; - var BITS = [224, 256, 384, 512]; - var SHAKE_BITS = [128, 256]; - var OUTPUT_TYPES = ['hex', 'buffer', 'arrayBuffer', 'array']; - - var createOutputMethod = function (bits, padding, outputType) { - return function (message) { - return new Keccak(bits, padding, bits).update(message)[outputType](); - }; - }; - - var createShakeOutputMethod = function (bits, padding, outputType) { - return function (message, outputBits) { - return new Keccak(bits, padding, outputBits).update(message)[outputType](); - }; - }; - - var createMethod = function (bits, padding) { - var method = createOutputMethod(bits, padding, 'hex'); - method.create = function () { - return new Keccak(bits, padding, bits); - }; - method.update = function (message) { - return method.create().update(message); - }; - for (var i = 0; i < OUTPUT_TYPES.length; ++i) { - var type = OUTPUT_TYPES[i]; - method[type] = createOutputMethod(bits, padding, type); - } - return method; - }; - - var createShakeMethod = function (bits, padding) { - var method = createShakeOutputMethod(bits, padding, 'hex'); - method.create = function (outputBits) { - return new Keccak(bits, padding, outputBits); - }; - method.update = function (message, outputBits) { - return method.create(outputBits).update(message); - }; - for (var i = 0; i < OUTPUT_TYPES.length; ++i) { - var type = OUTPUT_TYPES[i]; - method[type] = createShakeOutputMethod(bits, padding, type); - } - return method; - }; - - var algorithms = [ - {name: 'keccak', padding: KECCAK_PADDING, bits: BITS, createMethod: createMethod}, - {name: 'sha3', padding: PADDING, bits: BITS, createMethod: createMethod}, - {name: 'shake', padding: SHAKE_PADDING, bits: SHAKE_BITS, createMethod: createShakeMethod} - ]; - - var methods = {}, methodNames = []; - - for (var i = 0; i < algorithms.length; ++i) { - var algorithm = algorithms[i]; - var bits = algorithm.bits; - for (var j = 0; j < bits.length; ++j) { - var methodName = algorithm.name +'_' + bits[j]; - methodNames.push(methodName); - methods[methodName] = algorithm.createMethod(bits[j], algorithm.padding); - } - } - - function Keccak(bits, padding, outputBits) { - this.blocks = []; - this.s = []; - this.padding = padding; - this.outputBits = outputBits; - this.reset = true; - this.block = 0; - this.start = 0; - this.blockCount = (1600 - (bits << 1)) >> 5; - this.byteCount = this.blockCount << 2; - this.outputBlocks = outputBits >> 5; - this.extraBytes = (outputBits & 31) >> 3; - - for (var i = 0; i < 50; ++i) { - this.s[i] = 0; - } - } - - Keccak.prototype.update = function (message) { - var notString = typeof message !== 'string'; - if (notString && message.constructor === ArrayBuffer) { - message = new Uint8Array(message); - } - var length = message.length, blocks = this.blocks, byteCount = this.byteCount, - blockCount = this.blockCount, index = 0, s = this.s, i, code; - - while (index < length) { - if (this.reset) { - this.reset = false; - blocks[0] = this.block; - for (i = 1; i < blockCount + 1; ++i) { - blocks[i] = 0; - } - } - if (notString) { - for (i = this.start; index < length && i < byteCount; ++index) { - blocks[i >> 2] |= message[index] << SHIFT[i++ & 3]; - } - } else { - for (i = this.start; index < length && i < byteCount; ++index) { - code = message.charCodeAt(index); - if (code < 0x80) { - blocks[i >> 2] |= code << SHIFT[i++ & 3]; - } else if (code < 0x800) { - blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; - } else if (code < 0xd800 || code >= 0xe000) { - blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; - } else { - code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff)); - blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; - } - } - } - this.lastByteIndex = i; - if (i >= byteCount) { - this.start = i - byteCount; - this.block = blocks[blockCount]; - for (i = 0; i < blockCount; ++i) { - s[i] ^= blocks[i]; - } - f(s); - this.reset = true; - } else { - this.start = i; - } - } - return this; - }; - - Keccak.prototype.finalize = function () { - var blocks = this.blocks, i = this.lastByteIndex, blockCount = this.blockCount, s = this.s; - blocks[i >> 2] |= this.padding[i & 3]; - if (this.lastByteIndex === this.byteCount) { - blocks[0] = blocks[blockCount]; - for (i = 1; i < blockCount + 1; ++i) { - blocks[i] = 0; - } - } - blocks[blockCount - 1] |= 0x80000000; - for (i = 0; i < blockCount; ++i) { - s[i] ^= blocks[i]; - } - f(s); - }; - - Keccak.prototype.toString = Keccak.prototype.hex = function () { - this.finalize(); - - var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, - extraBytes = this.extraBytes, i = 0, j = 0; - var hex = '', block; - while (j < outputBlocks) { - for (i = 0; i < blockCount && j < outputBlocks; ++i, ++j) { - block = s[i]; - hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F] + - HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F] + - HEX_CHARS[(block >> 20) & 0x0F] + HEX_CHARS[(block >> 16) & 0x0F] + - HEX_CHARS[(block >> 28) & 0x0F] + HEX_CHARS[(block >> 24) & 0x0F]; - } - if (j % blockCount === 0) { - f(s); - i = 0; - } - } - if (extraBytes) { - block = s[i]; - if (extraBytes > 0) { - hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F]; - } - if (extraBytes > 1) { - hex += HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F]; - } - if (extraBytes > 2) { - hex += HEX_CHARS[(block >> 20) & 0x0F] + HEX_CHARS[(block >> 16) & 0x0F]; - } - } - return hex; - }; - - Keccak.prototype.arrayBuffer = function () { - this.finalize(); - - var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, - extraBytes = this.extraBytes, i = 0, j = 0; - var bytes = this.outputBits >> 3; - var buffer; - if (extraBytes) { - buffer = new ArrayBuffer((outputBlocks + 1) << 2); - } else { - buffer = new ArrayBuffer(bytes); - } - var array = new Uint32Array(buffer); - while (j < outputBlocks) { - for (i = 0; i < blockCount && j < outputBlocks; ++i, ++j) { - array[j] = s[i]; - } - if (j % blockCount === 0) { - f(s); - } - } - if (extraBytes) { - array[i] = s[i]; - buffer = buffer.slice(0, bytes); - } - return buffer; - }; - - Keccak.prototype.buffer = Keccak.prototype.arrayBuffer; - - Keccak.prototype.digest = Keccak.prototype.array = function () { - this.finalize(); - - var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, - extraBytes = this.extraBytes, i = 0, j = 0; - var array = [], offset, block; - while (j < outputBlocks) { - for (i = 0; i < blockCount && j < outputBlocks; ++i, ++j) { - offset = j << 2; - block = s[i]; - array[offset] = block & 0xFF; - array[offset + 1] = (block >> 8) & 0xFF; - array[offset + 2] = (block >> 16) & 0xFF; - array[offset + 3] = (block >> 24) & 0xFF; - } - if (j % blockCount === 0) { - f(s); - } - } - if (extraBytes) { - offset = j << 2; - block = s[i]; - if (extraBytes > 0) { - array[offset] = block & 0xFF; - } - if (extraBytes > 1) { - array[offset + 1] = (block >> 8) & 0xFF; - } - if (extraBytes > 2) { - array[offset + 2] = (block >> 16) & 0xFF; - } - } - return array; - }; - - var f = function (s) { - var h, l, n, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, - b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16, b17, - b18, b19, b20, b21, b22, b23, b24, b25, b26, b27, b28, b29, b30, b31, b32, b33, - b34, b35, b36, b37, b38, b39, b40, b41, b42, b43, b44, b45, b46, b47, b48, b49; - for (n = 0; n < 48; n += 2) { - c0 = s[0] ^ s[10] ^ s[20] ^ s[30] ^ s[40]; - c1 = s[1] ^ s[11] ^ s[21] ^ s[31] ^ s[41]; - c2 = s[2] ^ s[12] ^ s[22] ^ s[32] ^ s[42]; - c3 = s[3] ^ s[13] ^ s[23] ^ s[33] ^ s[43]; - c4 = s[4] ^ s[14] ^ s[24] ^ s[34] ^ s[44]; - c5 = s[5] ^ s[15] ^ s[25] ^ s[35] ^ s[45]; - c6 = s[6] ^ s[16] ^ s[26] ^ s[36] ^ s[46]; - c7 = s[7] ^ s[17] ^ s[27] ^ s[37] ^ s[47]; - c8 = s[8] ^ s[18] ^ s[28] ^ s[38] ^ s[48]; - c9 = s[9] ^ s[19] ^ s[29] ^ s[39] ^ s[49]; - - h = c8 ^ ((c2 << 1) | (c3 >>> 31)); - l = c9 ^ ((c3 << 1) | (c2 >>> 31)); - s[0] ^= h; - s[1] ^= l; - s[10] ^= h; - s[11] ^= l; - s[20] ^= h; - s[21] ^= l; - s[30] ^= h; - s[31] ^= l; - s[40] ^= h; - s[41] ^= l; - h = c0 ^ ((c4 << 1) | (c5 >>> 31)); - l = c1 ^ ((c5 << 1) | (c4 >>> 31)); - s[2] ^= h; - s[3] ^= l; - s[12] ^= h; - s[13] ^= l; - s[22] ^= h; - s[23] ^= l; - s[32] ^= h; - s[33] ^= l; - s[42] ^= h; - s[43] ^= l; - h = c2 ^ ((c6 << 1) | (c7 >>> 31)); - l = c3 ^ ((c7 << 1) | (c6 >>> 31)); - s[4] ^= h; - s[5] ^= l; - s[14] ^= h; - s[15] ^= l; - s[24] ^= h; - s[25] ^= l; - s[34] ^= h; - s[35] ^= l; - s[44] ^= h; - s[45] ^= l; - h = c4 ^ ((c8 << 1) | (c9 >>> 31)); - l = c5 ^ ((c9 << 1) | (c8 >>> 31)); - s[6] ^= h; - s[7] ^= l; - s[16] ^= h; - s[17] ^= l; - s[26] ^= h; - s[27] ^= l; - s[36] ^= h; - s[37] ^= l; - s[46] ^= h; - s[47] ^= l; - h = c6 ^ ((c0 << 1) | (c1 >>> 31)); - l = c7 ^ ((c1 << 1) | (c0 >>> 31)); - s[8] ^= h; - s[9] ^= l; - s[18] ^= h; - s[19] ^= l; - s[28] ^= h; - s[29] ^= l; - s[38] ^= h; - s[39] ^= l; - s[48] ^= h; - s[49] ^= l; - - b0 = s[0]; - b1 = s[1]; - b32 = (s[11] << 4) | (s[10] >>> 28); - b33 = (s[10] << 4) | (s[11] >>> 28); - b14 = (s[20] << 3) | (s[21] >>> 29); - b15 = (s[21] << 3) | (s[20] >>> 29); - b46 = (s[31] << 9) | (s[30] >>> 23); - b47 = (s[30] << 9) | (s[31] >>> 23); - b28 = (s[40] << 18) | (s[41] >>> 14); - b29 = (s[41] << 18) | (s[40] >>> 14); - b20 = (s[2] << 1) | (s[3] >>> 31); - b21 = (s[3] << 1) | (s[2] >>> 31); - b2 = (s[13] << 12) | (s[12] >>> 20); - b3 = (s[12] << 12) | (s[13] >>> 20); - b34 = (s[22] << 10) | (s[23] >>> 22); - b35 = (s[23] << 10) | (s[22] >>> 22); - b16 = (s[33] << 13) | (s[32] >>> 19); - b17 = (s[32] << 13) | (s[33] >>> 19); - b48 = (s[42] << 2) | (s[43] >>> 30); - b49 = (s[43] << 2) | (s[42] >>> 30); - b40 = (s[5] << 30) | (s[4] >>> 2); - b41 = (s[4] << 30) | (s[5] >>> 2); - b22 = (s[14] << 6) | (s[15] >>> 26); - b23 = (s[15] << 6) | (s[14] >>> 26); - b4 = (s[25] << 11) | (s[24] >>> 21); - b5 = (s[24] << 11) | (s[25] >>> 21); - b36 = (s[34] << 15) | (s[35] >>> 17); - b37 = (s[35] << 15) | (s[34] >>> 17); - b18 = (s[45] << 29) | (s[44] >>> 3); - b19 = (s[44] << 29) | (s[45] >>> 3); - b10 = (s[6] << 28) | (s[7] >>> 4); - b11 = (s[7] << 28) | (s[6] >>> 4); - b42 = (s[17] << 23) | (s[16] >>> 9); - b43 = (s[16] << 23) | (s[17] >>> 9); - b24 = (s[26] << 25) | (s[27] >>> 7); - b25 = (s[27] << 25) | (s[26] >>> 7); - b6 = (s[36] << 21) | (s[37] >>> 11); - b7 = (s[37] << 21) | (s[36] >>> 11); - b38 = (s[47] << 24) | (s[46] >>> 8); - b39 = (s[46] << 24) | (s[47] >>> 8); - b30 = (s[8] << 27) | (s[9] >>> 5); - b31 = (s[9] << 27) | (s[8] >>> 5); - b12 = (s[18] << 20) | (s[19] >>> 12); - b13 = (s[19] << 20) | (s[18] >>> 12); - b44 = (s[29] << 7) | (s[28] >>> 25); - b45 = (s[28] << 7) | (s[29] >>> 25); - b26 = (s[38] << 8) | (s[39] >>> 24); - b27 = (s[39] << 8) | (s[38] >>> 24); - b8 = (s[48] << 14) | (s[49] >>> 18); - b9 = (s[49] << 14) | (s[48] >>> 18); - - s[0] = b0 ^ (~b2 & b4); - s[1] = b1 ^ (~b3 & b5); - s[10] = b10 ^ (~b12 & b14); - s[11] = b11 ^ (~b13 & b15); - s[20] = b20 ^ (~b22 & b24); - s[21] = b21 ^ (~b23 & b25); - s[30] = b30 ^ (~b32 & b34); - s[31] = b31 ^ (~b33 & b35); - s[40] = b40 ^ (~b42 & b44); - s[41] = b41 ^ (~b43 & b45); - s[2] = b2 ^ (~b4 & b6); - s[3] = b3 ^ (~b5 & b7); - s[12] = b12 ^ (~b14 & b16); - s[13] = b13 ^ (~b15 & b17); - s[22] = b22 ^ (~b24 & b26); - s[23] = b23 ^ (~b25 & b27); - s[32] = b32 ^ (~b34 & b36); - s[33] = b33 ^ (~b35 & b37); - s[42] = b42 ^ (~b44 & b46); - s[43] = b43 ^ (~b45 & b47); - s[4] = b4 ^ (~b6 & b8); - s[5] = b5 ^ (~b7 & b9); - s[14] = b14 ^ (~b16 & b18); - s[15] = b15 ^ (~b17 & b19); - s[24] = b24 ^ (~b26 & b28); - s[25] = b25 ^ (~b27 & b29); - s[34] = b34 ^ (~b36 & b38); - s[35] = b35 ^ (~b37 & b39); - s[44] = b44 ^ (~b46 & b48); - s[45] = b45 ^ (~b47 & b49); - s[6] = b6 ^ (~b8 & b0); - s[7] = b7 ^ (~b9 & b1); - s[16] = b16 ^ (~b18 & b10); - s[17] = b17 ^ (~b19 & b11); - s[26] = b26 ^ (~b28 & b20); - s[27] = b27 ^ (~b29 & b21); - s[36] = b36 ^ (~b38 & b30); - s[37] = b37 ^ (~b39 & b31); - s[46] = b46 ^ (~b48 & b40); - s[47] = b47 ^ (~b49 & b41); - s[8] = b8 ^ (~b0 & b2); - s[9] = b9 ^ (~b1 & b3); - s[18] = b18 ^ (~b10 & b12); - s[19] = b19 ^ (~b11 & b13); - s[28] = b28 ^ (~b20 & b22); - s[29] = b29 ^ (~b21 & b23); - s[38] = b38 ^ (~b30 & b32); - s[39] = b39 ^ (~b31 & b33); - s[48] = b48 ^ (~b40 & b42); - s[49] = b49 ^ (~b41 & b43); - - s[0] ^= RC[n]; - s[1] ^= RC[n + 1]; - } - }; - - if (COMMON_JS) { - module.exports = methods; - } else { - for (var i = 0; i < methodNames.length; ++i) { - root[methodNames[i]] = methods[methodNames[i]]; - } - } +/** + * [js-sha3]{@link https://github.com/emn178/js-sha3} + * + * @version 0.5.7 + * @author Chen, Yi-Cyuan [emn178@gmail.com] + * @copyright Chen, Yi-Cyuan 2015-2016 + * @license MIT + */ +/*jslint bitwise: true */ +(function () { + + var root = typeof window === 'object' ? window : {}; + var NODE_JS = !root.JS_SHA3_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node; + if (NODE_JS) { + root = commonjsGlobal; + } + var COMMON_JS = !root.JS_SHA3_NO_COMMON_JS && 'object' === 'object' && module.exports; + var HEX_CHARS = '0123456789abcdef'.split(''); + var SHAKE_PADDING = [31, 7936, 2031616, 520093696]; + var KECCAK_PADDING = [1, 256, 65536, 16777216]; + var PADDING = [6, 1536, 393216, 100663296]; + var SHIFT = [0, 8, 16, 24]; + var RC = [1, 0, 32898, 0, 32906, 2147483648, 2147516416, 2147483648, 32907, 0, 2147483649, + 0, 2147516545, 2147483648, 32777, 2147483648, 138, 0, 136, 0, 2147516425, 0, + 2147483658, 0, 2147516555, 0, 139, 2147483648, 32905, 2147483648, 32771, + 2147483648, 32770, 2147483648, 128, 2147483648, 32778, 0, 2147483658, 2147483648, + 2147516545, 2147483648, 32896, 2147483648, 2147483649, 0, 2147516424, 2147483648]; + var BITS = [224, 256, 384, 512]; + var SHAKE_BITS = [128, 256]; + var OUTPUT_TYPES = ['hex', 'buffer', 'arrayBuffer', 'array']; + + var createOutputMethod = function (bits, padding, outputType) { + return function (message) { + return new Keccak(bits, padding, bits).update(message)[outputType](); + }; + }; + + var createShakeOutputMethod = function (bits, padding, outputType) { + return function (message, outputBits) { + return new Keccak(bits, padding, outputBits).update(message)[outputType](); + }; + }; + + var createMethod = function (bits, padding) { + var method = createOutputMethod(bits, padding, 'hex'); + method.create = function () { + return new Keccak(bits, padding, bits); + }; + method.update = function (message) { + return method.create().update(message); + }; + for (var i = 0; i < OUTPUT_TYPES.length; ++i) { + var type = OUTPUT_TYPES[i]; + method[type] = createOutputMethod(bits, padding, type); + } + return method; + }; + + var createShakeMethod = function (bits, padding) { + var method = createShakeOutputMethod(bits, padding, 'hex'); + method.create = function (outputBits) { + return new Keccak(bits, padding, outputBits); + }; + method.update = function (message, outputBits) { + return method.create(outputBits).update(message); + }; + for (var i = 0; i < OUTPUT_TYPES.length; ++i) { + var type = OUTPUT_TYPES[i]; + method[type] = createShakeOutputMethod(bits, padding, type); + } + return method; + }; + + var algorithms = [ + {name: 'keccak', padding: KECCAK_PADDING, bits: BITS, createMethod: createMethod}, + {name: 'sha3', padding: PADDING, bits: BITS, createMethod: createMethod}, + {name: 'shake', padding: SHAKE_PADDING, bits: SHAKE_BITS, createMethod: createShakeMethod} + ]; + + var methods = {}, methodNames = []; + + for (var i = 0; i < algorithms.length; ++i) { + var algorithm = algorithms[i]; + var bits = algorithm.bits; + for (var j = 0; j < bits.length; ++j) { + var methodName = algorithm.name +'_' + bits[j]; + methodNames.push(methodName); + methods[methodName] = algorithm.createMethod(bits[j], algorithm.padding); + } + } + + function Keccak(bits, padding, outputBits) { + this.blocks = []; + this.s = []; + this.padding = padding; + this.outputBits = outputBits; + this.reset = true; + this.block = 0; + this.start = 0; + this.blockCount = (1600 - (bits << 1)) >> 5; + this.byteCount = this.blockCount << 2; + this.outputBlocks = outputBits >> 5; + this.extraBytes = (outputBits & 31) >> 3; + + for (var i = 0; i < 50; ++i) { + this.s[i] = 0; + } + } + + Keccak.prototype.update = function (message) { + var notString = typeof message !== 'string'; + if (notString && message.constructor === ArrayBuffer) { + message = new Uint8Array(message); + } + var length = message.length, blocks = this.blocks, byteCount = this.byteCount, + blockCount = this.blockCount, index = 0, s = this.s, i, code; + + while (index < length) { + if (this.reset) { + this.reset = false; + blocks[0] = this.block; + for (i = 1; i < blockCount + 1; ++i) { + blocks[i] = 0; + } + } + if (notString) { + for (i = this.start; index < length && i < byteCount; ++index) { + blocks[i >> 2] |= message[index] << SHIFT[i++ & 3]; + } + } else { + for (i = this.start; index < length && i < byteCount; ++index) { + code = message.charCodeAt(index); + if (code < 0x80) { + blocks[i >> 2] |= code << SHIFT[i++ & 3]; + } else if (code < 0x800) { + blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; + } else if (code < 0xd800 || code >= 0xe000) { + blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; + } else { + code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff)); + blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; + } + } + } + this.lastByteIndex = i; + if (i >= byteCount) { + this.start = i - byteCount; + this.block = blocks[blockCount]; + for (i = 0; i < blockCount; ++i) { + s[i] ^= blocks[i]; + } + f(s); + this.reset = true; + } else { + this.start = i; + } + } + return this; + }; + + Keccak.prototype.finalize = function () { + var blocks = this.blocks, i = this.lastByteIndex, blockCount = this.blockCount, s = this.s; + blocks[i >> 2] |= this.padding[i & 3]; + if (this.lastByteIndex === this.byteCount) { + blocks[0] = blocks[blockCount]; + for (i = 1; i < blockCount + 1; ++i) { + blocks[i] = 0; + } + } + blocks[blockCount - 1] |= 0x80000000; + for (i = 0; i < blockCount; ++i) { + s[i] ^= blocks[i]; + } + f(s); + }; + + Keccak.prototype.toString = Keccak.prototype.hex = function () { + this.finalize(); + + var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, + extraBytes = this.extraBytes, i = 0, j = 0; + var hex = '', block; + while (j < outputBlocks) { + for (i = 0; i < blockCount && j < outputBlocks; ++i, ++j) { + block = s[i]; + hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F] + + HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F] + + HEX_CHARS[(block >> 20) & 0x0F] + HEX_CHARS[(block >> 16) & 0x0F] + + HEX_CHARS[(block >> 28) & 0x0F] + HEX_CHARS[(block >> 24) & 0x0F]; + } + if (j % blockCount === 0) { + f(s); + i = 0; + } + } + if (extraBytes) { + block = s[i]; + if (extraBytes > 0) { + hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F]; + } + if (extraBytes > 1) { + hex += HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F]; + } + if (extraBytes > 2) { + hex += HEX_CHARS[(block >> 20) & 0x0F] + HEX_CHARS[(block >> 16) & 0x0F]; + } + } + return hex; + }; + + Keccak.prototype.arrayBuffer = function () { + this.finalize(); + + var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, + extraBytes = this.extraBytes, i = 0, j = 0; + var bytes = this.outputBits >> 3; + var buffer; + if (extraBytes) { + buffer = new ArrayBuffer((outputBlocks + 1) << 2); + } else { + buffer = new ArrayBuffer(bytes); + } + var array = new Uint32Array(buffer); + while (j < outputBlocks) { + for (i = 0; i < blockCount && j < outputBlocks; ++i, ++j) { + array[j] = s[i]; + } + if (j % blockCount === 0) { + f(s); + } + } + if (extraBytes) { + array[i] = s[i]; + buffer = buffer.slice(0, bytes); + } + return buffer; + }; + + Keccak.prototype.buffer = Keccak.prototype.arrayBuffer; + + Keccak.prototype.digest = Keccak.prototype.array = function () { + this.finalize(); + + var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, + extraBytes = this.extraBytes, i = 0, j = 0; + var array = [], offset, block; + while (j < outputBlocks) { + for (i = 0; i < blockCount && j < outputBlocks; ++i, ++j) { + offset = j << 2; + block = s[i]; + array[offset] = block & 0xFF; + array[offset + 1] = (block >> 8) & 0xFF; + array[offset + 2] = (block >> 16) & 0xFF; + array[offset + 3] = (block >> 24) & 0xFF; + } + if (j % blockCount === 0) { + f(s); + } + } + if (extraBytes) { + offset = j << 2; + block = s[i]; + if (extraBytes > 0) { + array[offset] = block & 0xFF; + } + if (extraBytes > 1) { + array[offset + 1] = (block >> 8) & 0xFF; + } + if (extraBytes > 2) { + array[offset + 2] = (block >> 16) & 0xFF; + } + } + return array; + }; + + var f = function (s) { + var h, l, n, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, + b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16, b17, + b18, b19, b20, b21, b22, b23, b24, b25, b26, b27, b28, b29, b30, b31, b32, b33, + b34, b35, b36, b37, b38, b39, b40, b41, b42, b43, b44, b45, b46, b47, b48, b49; + for (n = 0; n < 48; n += 2) { + c0 = s[0] ^ s[10] ^ s[20] ^ s[30] ^ s[40]; + c1 = s[1] ^ s[11] ^ s[21] ^ s[31] ^ s[41]; + c2 = s[2] ^ s[12] ^ s[22] ^ s[32] ^ s[42]; + c3 = s[3] ^ s[13] ^ s[23] ^ s[33] ^ s[43]; + c4 = s[4] ^ s[14] ^ s[24] ^ s[34] ^ s[44]; + c5 = s[5] ^ s[15] ^ s[25] ^ s[35] ^ s[45]; + c6 = s[6] ^ s[16] ^ s[26] ^ s[36] ^ s[46]; + c7 = s[7] ^ s[17] ^ s[27] ^ s[37] ^ s[47]; + c8 = s[8] ^ s[18] ^ s[28] ^ s[38] ^ s[48]; + c9 = s[9] ^ s[19] ^ s[29] ^ s[39] ^ s[49]; + + h = c8 ^ ((c2 << 1) | (c3 >>> 31)); + l = c9 ^ ((c3 << 1) | (c2 >>> 31)); + s[0] ^= h; + s[1] ^= l; + s[10] ^= h; + s[11] ^= l; + s[20] ^= h; + s[21] ^= l; + s[30] ^= h; + s[31] ^= l; + s[40] ^= h; + s[41] ^= l; + h = c0 ^ ((c4 << 1) | (c5 >>> 31)); + l = c1 ^ ((c5 << 1) | (c4 >>> 31)); + s[2] ^= h; + s[3] ^= l; + s[12] ^= h; + s[13] ^= l; + s[22] ^= h; + s[23] ^= l; + s[32] ^= h; + s[33] ^= l; + s[42] ^= h; + s[43] ^= l; + h = c2 ^ ((c6 << 1) | (c7 >>> 31)); + l = c3 ^ ((c7 << 1) | (c6 >>> 31)); + s[4] ^= h; + s[5] ^= l; + s[14] ^= h; + s[15] ^= l; + s[24] ^= h; + s[25] ^= l; + s[34] ^= h; + s[35] ^= l; + s[44] ^= h; + s[45] ^= l; + h = c4 ^ ((c8 << 1) | (c9 >>> 31)); + l = c5 ^ ((c9 << 1) | (c8 >>> 31)); + s[6] ^= h; + s[7] ^= l; + s[16] ^= h; + s[17] ^= l; + s[26] ^= h; + s[27] ^= l; + s[36] ^= h; + s[37] ^= l; + s[46] ^= h; + s[47] ^= l; + h = c6 ^ ((c0 << 1) | (c1 >>> 31)); + l = c7 ^ ((c1 << 1) | (c0 >>> 31)); + s[8] ^= h; + s[9] ^= l; + s[18] ^= h; + s[19] ^= l; + s[28] ^= h; + s[29] ^= l; + s[38] ^= h; + s[39] ^= l; + s[48] ^= h; + s[49] ^= l; + + b0 = s[0]; + b1 = s[1]; + b32 = (s[11] << 4) | (s[10] >>> 28); + b33 = (s[10] << 4) | (s[11] >>> 28); + b14 = (s[20] << 3) | (s[21] >>> 29); + b15 = (s[21] << 3) | (s[20] >>> 29); + b46 = (s[31] << 9) | (s[30] >>> 23); + b47 = (s[30] << 9) | (s[31] >>> 23); + b28 = (s[40] << 18) | (s[41] >>> 14); + b29 = (s[41] << 18) | (s[40] >>> 14); + b20 = (s[2] << 1) | (s[3] >>> 31); + b21 = (s[3] << 1) | (s[2] >>> 31); + b2 = (s[13] << 12) | (s[12] >>> 20); + b3 = (s[12] << 12) | (s[13] >>> 20); + b34 = (s[22] << 10) | (s[23] >>> 22); + b35 = (s[23] << 10) | (s[22] >>> 22); + b16 = (s[33] << 13) | (s[32] >>> 19); + b17 = (s[32] << 13) | (s[33] >>> 19); + b48 = (s[42] << 2) | (s[43] >>> 30); + b49 = (s[43] << 2) | (s[42] >>> 30); + b40 = (s[5] << 30) | (s[4] >>> 2); + b41 = (s[4] << 30) | (s[5] >>> 2); + b22 = (s[14] << 6) | (s[15] >>> 26); + b23 = (s[15] << 6) | (s[14] >>> 26); + b4 = (s[25] << 11) | (s[24] >>> 21); + b5 = (s[24] << 11) | (s[25] >>> 21); + b36 = (s[34] << 15) | (s[35] >>> 17); + b37 = (s[35] << 15) | (s[34] >>> 17); + b18 = (s[45] << 29) | (s[44] >>> 3); + b19 = (s[44] << 29) | (s[45] >>> 3); + b10 = (s[6] << 28) | (s[7] >>> 4); + b11 = (s[7] << 28) | (s[6] >>> 4); + b42 = (s[17] << 23) | (s[16] >>> 9); + b43 = (s[16] << 23) | (s[17] >>> 9); + b24 = (s[26] << 25) | (s[27] >>> 7); + b25 = (s[27] << 25) | (s[26] >>> 7); + b6 = (s[36] << 21) | (s[37] >>> 11); + b7 = (s[37] << 21) | (s[36] >>> 11); + b38 = (s[47] << 24) | (s[46] >>> 8); + b39 = (s[46] << 24) | (s[47] >>> 8); + b30 = (s[8] << 27) | (s[9] >>> 5); + b31 = (s[9] << 27) | (s[8] >>> 5); + b12 = (s[18] << 20) | (s[19] >>> 12); + b13 = (s[19] << 20) | (s[18] >>> 12); + b44 = (s[29] << 7) | (s[28] >>> 25); + b45 = (s[28] << 7) | (s[29] >>> 25); + b26 = (s[38] << 8) | (s[39] >>> 24); + b27 = (s[39] << 8) | (s[38] >>> 24); + b8 = (s[48] << 14) | (s[49] >>> 18); + b9 = (s[49] << 14) | (s[48] >>> 18); + + s[0] = b0 ^ (~b2 & b4); + s[1] = b1 ^ (~b3 & b5); + s[10] = b10 ^ (~b12 & b14); + s[11] = b11 ^ (~b13 & b15); + s[20] = b20 ^ (~b22 & b24); + s[21] = b21 ^ (~b23 & b25); + s[30] = b30 ^ (~b32 & b34); + s[31] = b31 ^ (~b33 & b35); + s[40] = b40 ^ (~b42 & b44); + s[41] = b41 ^ (~b43 & b45); + s[2] = b2 ^ (~b4 & b6); + s[3] = b3 ^ (~b5 & b7); + s[12] = b12 ^ (~b14 & b16); + s[13] = b13 ^ (~b15 & b17); + s[22] = b22 ^ (~b24 & b26); + s[23] = b23 ^ (~b25 & b27); + s[32] = b32 ^ (~b34 & b36); + s[33] = b33 ^ (~b35 & b37); + s[42] = b42 ^ (~b44 & b46); + s[43] = b43 ^ (~b45 & b47); + s[4] = b4 ^ (~b6 & b8); + s[5] = b5 ^ (~b7 & b9); + s[14] = b14 ^ (~b16 & b18); + s[15] = b15 ^ (~b17 & b19); + s[24] = b24 ^ (~b26 & b28); + s[25] = b25 ^ (~b27 & b29); + s[34] = b34 ^ (~b36 & b38); + s[35] = b35 ^ (~b37 & b39); + s[44] = b44 ^ (~b46 & b48); + s[45] = b45 ^ (~b47 & b49); + s[6] = b6 ^ (~b8 & b0); + s[7] = b7 ^ (~b9 & b1); + s[16] = b16 ^ (~b18 & b10); + s[17] = b17 ^ (~b19 & b11); + s[26] = b26 ^ (~b28 & b20); + s[27] = b27 ^ (~b29 & b21); + s[36] = b36 ^ (~b38 & b30); + s[37] = b37 ^ (~b39 & b31); + s[46] = b46 ^ (~b48 & b40); + s[47] = b47 ^ (~b49 & b41); + s[8] = b8 ^ (~b0 & b2); + s[9] = b9 ^ (~b1 & b3); + s[18] = b18 ^ (~b10 & b12); + s[19] = b19 ^ (~b11 & b13); + s[28] = b28 ^ (~b20 & b22); + s[29] = b29 ^ (~b21 & b23); + s[38] = b38 ^ (~b30 & b32); + s[39] = b39 ^ (~b31 & b33); + s[48] = b48 ^ (~b40 & b42); + s[49] = b49 ^ (~b41 & b43); + + s[0] ^= RC[n]; + s[1] ^= RC[n + 1]; + } + }; + + if (COMMON_JS) { + module.exports = methods; + } else { + for (var i = 0; i < methodNames.length; ++i) { + root[methodNames[i]] = methods[methodNames[i]]; + } + } })(); }); @@ -32508,2615 +32508,2621 @@ var contractAbiPileForInit = [ } ]; -var baseToDisplay = function (base, decimals) { - var baseStr = typeof base === 'string' ? base : base.toString(); - var a = baseStr.slice(0, -decimals) || '0'; - var b = baseStr.slice(-decimals).padStart(decimals, '0'); - return a + "." + b; +var baseToDisplay = function (base, decimals) { + var baseStr = typeof base === 'string' ? base : base.toString(); + var a = baseStr.slice(0, -decimals) || '0'; + var b = baseStr.slice(-decimals).padStart(decimals, '0'); + return a + "." + b; }; var bnToHex = function (bn) { return "0x" + bn.toString(16); }; -var displayToBase = function (display, decimals) { - var a = display.split('.')[0]; - var b = (display.split('.')[1] || '').padEnd(decimals, '0').substr(0, decimals); - return "" + a + b; -}; - -/* - * decimal.js-light v2.5.0 - * An arbitrary-precision Decimal type for JavaScript. - * https://github.com/MikeMcl/decimal.js-light - * Copyright (c) 2018 Michael Mclaughlin - * MIT Expat Licence - */ - - -// ------------------------------------ EDITABLE DEFAULTS ------------------------------------- // - - -// The limit on the value of `precision`, and on the value of the first argument to -// `toDecimalPlaces`, `toExponential`, `toFixed`, `toPrecision` and `toSignificantDigits`. -var MAX_DIGITS = 1e9, // 0 to 1e9 - - - // The initial configuration properties of the Decimal constructor. - defaults = { - - // These values must be integers within the stated ranges (inclusive). - // Most of these values can be changed during run-time using `Decimal.config`. - - // The maximum number of significant digits of the result of a calculation or base conversion. - // E.g. `Decimal.config({ precision: 20 });` - precision: 20, // 1 to MAX_DIGITS - - // The rounding mode used by default by `toInteger`, `toDecimalPlaces`, `toExponential`, - // `toFixed`, `toPrecision` and `toSignificantDigits`. - // - // ROUND_UP 0 Away from zero. - // ROUND_DOWN 1 Towards zero. - // ROUND_CEIL 2 Towards +Infinity. - // ROUND_FLOOR 3 Towards -Infinity. - // ROUND_HALF_UP 4 Towards nearest neighbour. If equidistant, up. - // ROUND_HALF_DOWN 5 Towards nearest neighbour. If equidistant, down. - // ROUND_HALF_EVEN 6 Towards nearest neighbour. If equidistant, towards even neighbour. - // ROUND_HALF_CEIL 7 Towards nearest neighbour. If equidistant, towards +Infinity. - // ROUND_HALF_FLOOR 8 Towards nearest neighbour. If equidistant, towards -Infinity. - // - // E.g. - // `Decimal.rounding = 4;` - // `Decimal.rounding = Decimal.ROUND_HALF_UP;` - rounding: 4, // 0 to 8 - - // The exponent value at and beneath which `toString` returns exponential notation. - // JavaScript numbers: -7 - toExpNeg: -7, // 0 to -MAX_E - - // The exponent value at and above which `toString` returns exponential notation. - // JavaScript numbers: 21 - toExpPos: 21, // 0 to MAX_E - - // The natural logarithm of 10. - // 115 digits - LN10: '2.302585092994045684017991454684364207601101488628772976033327900967572609677352480235997205089598298341967784042286' - }, - - -// ------------------------------------ END OF EDITABLE DEFAULTS -------------------------------- // - - - Decimal, - external = true, - - decimalError = '[DecimalError] ', - invalidArgument = decimalError + 'Invalid argument: ', - exponentOutOfRange = decimalError + 'Exponent out of range: ', - - mathfloor = Math.floor, - mathpow = Math.pow, - - isDecimal = /^(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i, - - ONE, - BASE = 1e7, - LOG_BASE = 7, - MAX_SAFE_INTEGER$2 = 9007199254740991, - MAX_E = mathfloor(MAX_SAFE_INTEGER$2 / LOG_BASE), // 1286742750677284 - - // Decimal.prototype object - P = {}; - - -// Decimal prototype methods - - -/* - * absoluteValue abs - * comparedTo cmp - * decimalPlaces dp - * dividedBy div - * dividedToIntegerBy idiv - * equals eq - * exponent - * greaterThan gt - * greaterThanOrEqualTo gte - * isInteger isint - * isNegative isneg - * isPositive ispos - * isZero - * lessThan lt - * lessThanOrEqualTo lte - * logarithm log - * minus sub - * modulo mod - * naturalExponential exp - * naturalLogarithm ln - * negated neg - * plus add - * precision sd - * squareRoot sqrt - * times mul - * toDecimalPlaces todp - * toExponential - * toFixed - * toInteger toint - * toNumber - * toPower pow - * toPrecision - * toSignificantDigits tosd - * toString - * valueOf val - */ - - -/* - * Return a new Decimal whose value is the absolute value of this Decimal. - * - */ -P.absoluteValue = P.abs = function () { - var x = new this.constructor(this); - if (x.s) x.s = 1; - return x; -}; - - -/* - * Return - * 1 if the value of this Decimal is greater than the value of `y`, - * -1 if the value of this Decimal is less than the value of `y`, - * 0 if they have the same value - * - */ -P.comparedTo = P.cmp = function (y) { - var i, j, xdL, ydL, - x = this; - - y = new x.constructor(y); - - // Signs differ? - if (x.s !== y.s) return x.s || -y.s; - - // Compare exponents. - if (x.e !== y.e) return x.e > y.e ^ x.s < 0 ? 1 : -1; - - xdL = x.d.length; - ydL = y.d.length; - - // Compare digit by digit. - for (i = 0, j = xdL < ydL ? xdL : ydL; i < j; ++i) { - if (x.d[i] !== y.d[i]) return x.d[i] > y.d[i] ^ x.s < 0 ? 1 : -1; - } - - // Compare lengths. - return xdL === ydL ? 0 : xdL > ydL ^ x.s < 0 ? 1 : -1; -}; - - -/* - * Return the number of decimal places of the value of this Decimal. - * - */ -P.decimalPlaces = P.dp = function () { - var x = this, - w = x.d.length - 1, - dp = (w - x.e) * LOG_BASE; - - // Subtract the number of trailing zeros of the last word. - w = x.d[w]; - if (w) for (; w % 10 == 0; w /= 10) dp--; - - return dp < 0 ? 0 : dp; +var displayToBase = function (display, decimals) { + var a = display.split('.')[0]; + var b = (display.split('.')[1] || '').padEnd(decimals, '0').substr(0, decimals); + return "" + a + b; }; +/* + * decimal.js-light v2.5.0 + * An arbitrary-precision Decimal type for JavaScript. + * https://github.com/MikeMcl/decimal.js-light + * Copyright (c) 2018 Michael Mclaughlin + * MIT Expat Licence + */ + + +// ------------------------------------ EDITABLE DEFAULTS ------------------------------------- // + + +// The limit on the value of `precision`, and on the value of the first argument to +// `toDecimalPlaces`, `toExponential`, `toFixed`, `toPrecision` and `toSignificantDigits`. +var MAX_DIGITS = 1e9, // 0 to 1e9 + + + // The initial configuration properties of the Decimal constructor. + defaults = { + + // These values must be integers within the stated ranges (inclusive). + // Most of these values can be changed during run-time using `Decimal.config`. + + // The maximum number of significant digits of the result of a calculation or base conversion. + // E.g. `Decimal.config({ precision: 20 });` + precision: 20, // 1 to MAX_DIGITS + + // The rounding mode used by default by `toInteger`, `toDecimalPlaces`, `toExponential`, + // `toFixed`, `toPrecision` and `toSignificantDigits`. + // + // ROUND_UP 0 Away from zero. + // ROUND_DOWN 1 Towards zero. + // ROUND_CEIL 2 Towards +Infinity. + // ROUND_FLOOR 3 Towards -Infinity. + // ROUND_HALF_UP 4 Towards nearest neighbour. If equidistant, up. + // ROUND_HALF_DOWN 5 Towards nearest neighbour. If equidistant, down. + // ROUND_HALF_EVEN 6 Towards nearest neighbour. If equidistant, towards even neighbour. + // ROUND_HALF_CEIL 7 Towards nearest neighbour. If equidistant, towards +Infinity. + // ROUND_HALF_FLOOR 8 Towards nearest neighbour. If equidistant, towards -Infinity. + // + // E.g. + // `Decimal.rounding = 4;` + // `Decimal.rounding = Decimal.ROUND_HALF_UP;` + rounding: 4, // 0 to 8 + + // The exponent value at and beneath which `toString` returns exponential notation. + // JavaScript numbers: -7 + toExpNeg: -7, // 0 to -MAX_E + + // The exponent value at and above which `toString` returns exponential notation. + // JavaScript numbers: 21 + toExpPos: 21, // 0 to MAX_E + + // The natural logarithm of 10. + // 115 digits + LN10: '2.302585092994045684017991454684364207601101488628772976033327900967572609677352480235997205089598298341967784042286' + }, + + +// ------------------------------------ END OF EDITABLE DEFAULTS -------------------------------- // + + + Decimal, + external = true, + + decimalError = '[DecimalError] ', + invalidArgument = decimalError + 'Invalid argument: ', + exponentOutOfRange = decimalError + 'Exponent out of range: ', + + mathfloor = Math.floor, + mathpow = Math.pow, + + isDecimal = /^(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i, + + ONE, + BASE = 1e7, + LOG_BASE = 7, + MAX_SAFE_INTEGER$2 = 9007199254740991, + MAX_E = mathfloor(MAX_SAFE_INTEGER$2 / LOG_BASE), // 1286742750677284 + + // Decimal.prototype object + P = {}; + + +// Decimal prototype methods + + +/* + * absoluteValue abs + * comparedTo cmp + * decimalPlaces dp + * dividedBy div + * dividedToIntegerBy idiv + * equals eq + * exponent + * greaterThan gt + * greaterThanOrEqualTo gte + * isInteger isint + * isNegative isneg + * isPositive ispos + * isZero + * lessThan lt + * lessThanOrEqualTo lte + * logarithm log + * minus sub + * modulo mod + * naturalExponential exp + * naturalLogarithm ln + * negated neg + * plus add + * precision sd + * squareRoot sqrt + * times mul + * toDecimalPlaces todp + * toExponential + * toFixed + * toInteger toint + * toNumber + * toPower pow + * toPrecision + * toSignificantDigits tosd + * toString + * valueOf val + */ + + +/* + * Return a new Decimal whose value is the absolute value of this Decimal. + * + */ +P.absoluteValue = P.abs = function () { + var x = new this.constructor(this); + if (x.s) x.s = 1; + return x; +}; + + +/* + * Return + * 1 if the value of this Decimal is greater than the value of `y`, + * -1 if the value of this Decimal is less than the value of `y`, + * 0 if they have the same value + * + */ +P.comparedTo = P.cmp = function (y) { + var i, j, xdL, ydL, + x = this; + + y = new x.constructor(y); + + // Signs differ? + if (x.s !== y.s) return x.s || -y.s; + + // Compare exponents. + if (x.e !== y.e) return x.e > y.e ^ x.s < 0 ? 1 : -1; + + xdL = x.d.length; + ydL = y.d.length; + + // Compare digit by digit. + for (i = 0, j = xdL < ydL ? xdL : ydL; i < j; ++i) { + if (x.d[i] !== y.d[i]) return x.d[i] > y.d[i] ^ x.s < 0 ? 1 : -1; + } + + // Compare lengths. + return xdL === ydL ? 0 : xdL > ydL ^ x.s < 0 ? 1 : -1; +}; + + +/* + * Return the number of decimal places of the value of this Decimal. + * + */ +P.decimalPlaces = P.dp = function () { + var x = this, + w = x.d.length - 1, + dp = (w - x.e) * LOG_BASE; + + // Subtract the number of trailing zeros of the last word. + w = x.d[w]; + if (w) for (; w % 10 == 0; w /= 10) dp--; + + return dp < 0 ? 0 : dp; +}; + + +/* + * Return a new Decimal whose value is the value of this Decimal divided by `y`, truncated to + * `precision` significant digits. + * + */ +P.dividedBy = P.div = function (y) { + return divide(this, new this.constructor(y)); +}; + + +/* + * Return a new Decimal whose value is the integer part of dividing the value of this Decimal + * by the value of `y`, truncated to `precision` significant digits. + * + */ +P.dividedToIntegerBy = P.idiv = function (y) { + var x = this, + Ctor = x.constructor; + return round(divide(x, new Ctor(y), 0, 1), Ctor.precision); +}; + + +/* + * Return true if the value of this Decimal is equal to the value of `y`, otherwise return false. + * + */ +P.equals = P.eq = function (y) { + return !this.cmp(y); +}; + + +/* + * Return the (base 10) exponent value of this Decimal (this.e is the base 10000000 exponent). + * + */ +P.exponent = function () { + return getBase10Exponent(this); +}; + + +/* + * Return true if the value of this Decimal is greater than the value of `y`, otherwise return + * false. + * + */ +P.greaterThan = P.gt = function (y) { + return this.cmp(y) > 0; +}; + + +/* + * Return true if the value of this Decimal is greater than or equal to the value of `y`, + * otherwise return false. + * + */ +P.greaterThanOrEqualTo = P.gte = function (y) { + return this.cmp(y) >= 0; +}; + + +/* + * Return true if the value of this Decimal is an integer, otherwise return false. + * + */ +P.isInteger = P.isint = function () { + return this.e > this.d.length - 2; +}; + + +/* + * Return true if the value of this Decimal is negative, otherwise return false. + * + */ +P.isNegative = P.isneg = function () { + return this.s < 0; +}; + + +/* + * Return true if the value of this Decimal is positive, otherwise return false. + * + */ +P.isPositive = P.ispos = function () { + return this.s > 0; +}; + + +/* + * Return true if the value of this Decimal is 0, otherwise return false. + * + */ +P.isZero = function () { + return this.s === 0; +}; + + +/* + * Return true if the value of this Decimal is less than `y`, otherwise return false. + * + */ +P.lessThan = P.lt = function (y) { + return this.cmp(y) < 0; +}; + + +/* + * Return true if the value of this Decimal is less than or equal to `y`, otherwise return false. + * + */ +P.lessThanOrEqualTo = P.lte = function (y) { + return this.cmp(y) < 1; +}; + + +/* + * Return the logarithm of the value of this Decimal to the specified base, truncated to + * `precision` significant digits. + * + * If no base is specified, return log[10](x). + * + * log[base](x) = ln(x) / ln(base) + * + * The maximum error of the result is 1 ulp (unit in the last place). + * + * [base] {number|string|Decimal} The base of the logarithm. + * + */ +P.logarithm = P.log = function (base) { + var r, + x = this, + Ctor = x.constructor, + pr = Ctor.precision, + wpr = pr + 5; + + // Default base is 10. + if (base === void 0) { + base = new Ctor(10); + } else { + base = new Ctor(base); + + // log[-b](x) = NaN + // log[0](x) = NaN + // log[1](x) = NaN + if (base.s < 1 || base.eq(ONE)) throw Error(decimalError + 'NaN'); + } + + // log[b](-x) = NaN + // log[b](0) = -Infinity + if (x.s < 1) throw Error(decimalError + (x.s ? 'NaN' : '-Infinity')); + + // log[b](1) = 0 + if (x.eq(ONE)) return new Ctor(0); + + external = false; + r = divide(ln(x, wpr), ln(base, wpr), wpr); + external = true; + + return round(r, pr); +}; + + +/* + * Return a new Decimal whose value is the value of this Decimal minus `y`, truncated to + * `precision` significant digits. + * + */ +P.minus = P.sub = function (y) { + var x = this; + y = new x.constructor(y); + return x.s == y.s ? subtract(x, y) : add(x, (y.s = -y.s, y)); +}; + + +/* + * Return a new Decimal whose value is the value of this Decimal modulo `y`, truncated to + * `precision` significant digits. + * + */ +P.modulo = P.mod = function (y) { + var q, + x = this, + Ctor = x.constructor, + pr = Ctor.precision; + + y = new Ctor(y); + + // x % 0 = NaN + if (!y.s) throw Error(decimalError + 'NaN'); + + // Return x if x is 0. + if (!x.s) return round(new Ctor(x), pr); + + // Prevent rounding of intermediate calculations. + external = false; + q = divide(x, y, 0, 1).times(y); + external = true; + + return x.minus(q); +}; + + +/* + * Return a new Decimal whose value is the natural exponential of the value of this Decimal, + * i.e. the base e raised to the power the value of this Decimal, truncated to `precision` + * significant digits. + * + */ +P.naturalExponential = P.exp = function () { + return exp(this); +}; + + +/* + * Return a new Decimal whose value is the natural logarithm of the value of this Decimal, + * truncated to `precision` significant digits. + * + */ +P.naturalLogarithm = P.ln = function () { + return ln(this); +}; + + +/* + * Return a new Decimal whose value is the value of this Decimal negated, i.e. as if multiplied by + * -1. + * + */ +P.negated = P.neg = function () { + var x = new this.constructor(this); + x.s = -x.s || 0; + return x; +}; + + +/* + * Return a new Decimal whose value is the value of this Decimal plus `y`, truncated to + * `precision` significant digits. + * + */ +P.plus = P.add = function (y) { + var x = this; + y = new x.constructor(y); + return x.s == y.s ? add(x, y) : subtract(x, (y.s = -y.s, y)); +}; + + +/* + * Return the number of significant digits of the value of this Decimal. + * + * [z] {boolean|number} Whether to count integer-part trailing zeros: true, false, 1 or 0. + * + */ +P.precision = P.sd = function (z) { + var e, sd, w, + x = this; + + if (z !== void 0 && z !== !!z && z !== 1 && z !== 0) throw Error(invalidArgument + z); + + e = getBase10Exponent(x) + 1; + w = x.d.length - 1; + sd = w * LOG_BASE + 1; + w = x.d[w]; + + // If non-zero... + if (w) { + + // Subtract the number of trailing zeros of the last word. + for (; w % 10 == 0; w /= 10) sd--; + + // Add the number of digits of the first word. + for (w = x.d[0]; w >= 10; w /= 10) sd++; + } + + return z && e > sd ? e : sd; +}; + + +/* + * Return a new Decimal whose value is the square root of this Decimal, truncated to `precision` + * significant digits. + * + */ +P.squareRoot = P.sqrt = function () { + var e, n, pr, r, s, t, wpr, + x = this, + Ctor = x.constructor; + + // Negative or zero? + if (x.s < 1) { + if (!x.s) return new Ctor(0); + + // sqrt(-x) = NaN + throw Error(decimalError + 'NaN'); + } + + e = getBase10Exponent(x); + external = false; + + // Initial estimate. + s = Math.sqrt(+x); + + // Math.sqrt underflow/overflow? + // Pass x to Math.sqrt as integer, then adjust the exponent of the result. + if (s == 0 || s == 1 / 0) { + n = digitsToString(x.d); + if ((n.length + e) % 2 == 0) n += '0'; + s = Math.sqrt(n); + e = mathfloor((e + 1) / 2) - (e < 0 || e % 2); + + if (s == 1 / 0) { + n = '1e' + e; + } else { + n = s.toExponential(); + n = n.slice(0, n.indexOf('e') + 1) + e; + } + + r = new Ctor(n); + } else { + r = new Ctor(s.toString()); + } + + pr = Ctor.precision; + s = wpr = pr + 3; + + // Newton-Raphson iteration. + for (;;) { + t = r; + r = t.plus(divide(x, t, wpr + 2)).times(0.5); + + if (digitsToString(t.d).slice(0, wpr) === (n = digitsToString(r.d)).slice(0, wpr)) { + n = n.slice(wpr - 3, wpr + 1); + + // The 4th rounding digit may be in error by -1 so if the 4 rounding digits are 9999 or + // 4999, i.e. approaching a rounding boundary, continue the iteration. + if (s == wpr && n == '4999') { + + // On the first iteration only, check to see if rounding up gives the exact result as the + // nines may infinitely repeat. + round(t, pr + 1, 0); + + if (t.times(t).eq(x)) { + r = t; + break; + } + } else if (n != '9999') { + break; + } + + wpr += 4; + } + } + + external = true; + + return round(r, pr); +}; + + +/* + * Return a new Decimal whose value is the value of this Decimal times `y`, truncated to + * `precision` significant digits. + * + */ +P.times = P.mul = function (y) { + var carry, e, i, k, r, rL, t, xdL, ydL, + x = this, + Ctor = x.constructor, + xd = x.d, + yd = (y = new Ctor(y)).d; + + // Return 0 if either is 0. + if (!x.s || !y.s) return new Ctor(0); + + y.s *= x.s; + e = x.e + y.e; + xdL = xd.length; + ydL = yd.length; + + // Ensure xd points to the longer array. + if (xdL < ydL) { + r = xd; + xd = yd; + yd = r; + rL = xdL; + xdL = ydL; + ydL = rL; + } + + // Initialise the result array with zeros. + r = []; + rL = xdL + ydL; + for (i = rL; i--;) r.push(0); + + // Multiply! + for (i = ydL; --i >= 0;) { + carry = 0; + for (k = xdL + i; k > i;) { + t = r[k] + yd[i] * xd[k - i - 1] + carry; + r[k--] = t % BASE | 0; + carry = t / BASE | 0; + } + + r[k] = (r[k] + carry) % BASE | 0; + } + + // Remove trailing zeros. + for (; !r[--rL];) r.pop(); + + if (carry) ++e; + else r.shift(); + + y.d = r; + y.e = e; + + return external ? round(y, Ctor.precision) : y; +}; + + +/* + * Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `dp` + * decimal places using rounding mode `rm` or `rounding` if `rm` is omitted. + * + * If `dp` is omitted, return a new Decimal whose value is the value of this Decimal. + * + * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + */ +P.toDecimalPlaces = P.todp = function (dp, rm) { + var x = this, + Ctor = x.constructor; + + x = new Ctor(x); + if (dp === void 0) return x; + + checkInt32(dp, 0, MAX_DIGITS); + + if (rm === void 0) rm = Ctor.rounding; + else checkInt32(rm, 0, 8); + + return round(x, dp + getBase10Exponent(x) + 1, rm); +}; + + +/* + * Return a string representing the value of this Decimal in exponential notation rounded to + * `dp` fixed decimal places using rounding mode `rounding`. + * + * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + */ +P.toExponential = function (dp, rm) { + var str, + x = this, + Ctor = x.constructor; + + if (dp === void 0) { + str = toString$3(x, true); + } else { + checkInt32(dp, 0, MAX_DIGITS); + + if (rm === void 0) rm = Ctor.rounding; + else checkInt32(rm, 0, 8); + + x = round(new Ctor(x), dp + 1, rm); + str = toString$3(x, true, dp + 1); + } + + return str; +}; + + +/* + * Return a string representing the value of this Decimal in normal (fixed-point) notation to + * `dp` fixed decimal places and rounded using rounding mode `rm` or `rounding` if `rm` is + * omitted. + * + * As with JavaScript numbers, (-0).toFixed(0) is '0', but e.g. (-0.00001).toFixed(0) is '-0'. + * + * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + * (-0).toFixed(0) is '0', but (-0.1).toFixed(0) is '-0'. + * (-0).toFixed(1) is '0.0', but (-0.01).toFixed(1) is '-0.0'. + * (-0).toFixed(3) is '0.000'. + * (-0.5).toFixed(0) is '-0'. + * + */ +P.toFixed = function (dp, rm) { + var str, y, + x = this, + Ctor = x.constructor; + + if (dp === void 0) return toString$3(x); + + checkInt32(dp, 0, MAX_DIGITS); + + if (rm === void 0) rm = Ctor.rounding; + else checkInt32(rm, 0, 8); + + y = round(new Ctor(x), dp + getBase10Exponent(x) + 1, rm); + str = toString$3(y.abs(), false, dp + getBase10Exponent(y) + 1); + + // To determine whether to add the minus sign look at the value before it was rounded, + // i.e. look at `x` rather than `y`. + return x.isneg() && !x.isZero() ? '-' + str : str; +}; + + +/* + * Return a new Decimal whose value is the value of this Decimal rounded to a whole number using + * rounding mode `rounding`. + * + */ +P.toInteger = P.toint = function () { + var x = this, + Ctor = x.constructor; + return round(new Ctor(x), getBase10Exponent(x) + 1, Ctor.rounding); +}; + + +/* + * Return the value of this Decimal converted to a number primitive. + * + */ +P.toNumber = function () { + return +this; +}; + + +/* + * Return a new Decimal whose value is the value of this Decimal raised to the power `y`, + * truncated to `precision` significant digits. + * + * For non-integer or very large exponents pow(x, y) is calculated using + * + * x^y = exp(y*ln(x)) + * + * The maximum error is 1 ulp (unit in last place). + * + * y {number|string|Decimal} The power to which to raise this Decimal. + * + */ +P.toPower = P.pow = function (y) { + var e, k, pr, r, sign, yIsInt, + x = this, + Ctor = x.constructor, + guard = 12, + yn = +(y = new Ctor(y)); + + // pow(x, 0) = 1 + if (!y.s) return new Ctor(ONE); + + x = new Ctor(x); + + // pow(0, y > 0) = 0 + // pow(0, y < 0) = Infinity + if (!x.s) { + if (y.s < 1) throw Error(decimalError + 'Infinity'); + return x; + } + + // pow(1, y) = 1 + if (x.eq(ONE)) return x; + + pr = Ctor.precision; + + // pow(x, 1) = x + if (y.eq(ONE)) return round(x, pr); + + e = y.e; + k = y.d.length - 1; + yIsInt = e >= k; + sign = x.s; + + if (!yIsInt) { + + // pow(x < 0, y non-integer) = NaN + if (sign < 0) throw Error(decimalError + 'NaN'); + + // If y is a small integer use the 'exponentiation by squaring' algorithm. + } else if ((k = yn < 0 ? -yn : yn) <= MAX_SAFE_INTEGER$2) { + r = new Ctor(ONE); + + // Max k of 9007199254740991 takes 53 loop iterations. + // Maximum digits array length; leaves [28, 34] guard digits. + e = Math.ceil(pr / LOG_BASE + 4); + + external = false; + + for (;;) { + if (k % 2) { + r = r.times(x); + truncate(r.d, e); + } + + k = mathfloor(k / 2); + if (k === 0) break; + + x = x.times(x); + truncate(x.d, e); + } + + external = true; + + return y.s < 0 ? new Ctor(ONE).div(r) : round(r, pr); + } + + // Result is negative if x is negative and the last digit of integer y is odd. + sign = sign < 0 && y.d[Math.max(e, k)] & 1 ? -1 : 1; + + x.s = 1; + external = false; + r = y.times(ln(x, pr + guard)); + external = true; + r = exp(r); + r.s = sign; + + return r; +}; + + +/* + * Return a string representing the value of this Decimal rounded to `sd` significant digits + * using rounding mode `rounding`. + * + * Return exponential notation if `sd` is less than the number of digits necessary to represent + * the integer part of the value in normal notation. + * + * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + */ +P.toPrecision = function (sd, rm) { + var e, str, + x = this, + Ctor = x.constructor; + + if (sd === void 0) { + e = getBase10Exponent(x); + str = toString$3(x, e <= Ctor.toExpNeg || e >= Ctor.toExpPos); + } else { + checkInt32(sd, 1, MAX_DIGITS); + + if (rm === void 0) rm = Ctor.rounding; + else checkInt32(rm, 0, 8); + + x = round(new Ctor(x), sd, rm); + e = getBase10Exponent(x); + str = toString$3(x, sd <= e || e <= Ctor.toExpNeg, sd); + } + + return str; +}; + + +/* + * Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `sd` + * significant digits using rounding mode `rm`, or to `precision` and `rounding` respectively if + * omitted. + * + * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + */ +P.toSignificantDigits = P.tosd = function (sd, rm) { + var x = this, + Ctor = x.constructor; + + if (sd === void 0) { + sd = Ctor.precision; + rm = Ctor.rounding; + } else { + checkInt32(sd, 1, MAX_DIGITS); + + if (rm === void 0) rm = Ctor.rounding; + else checkInt32(rm, 0, 8); + } + + return round(new Ctor(x), sd, rm); +}; + + +/* + * Return a string representing the value of this Decimal. + * + * Return exponential notation if this Decimal has a positive exponent equal to or greater than + * `toExpPos`, or a negative exponent equal to or less than `toExpNeg`. + * + */ +P.toString = P.valueOf = P.val = P.toJSON = P[Symbol.for('nodejs.util.inspect.custom')] = function () { + var x = this, + e = getBase10Exponent(x), + Ctor = x.constructor; + + return toString$3(x, e <= Ctor.toExpNeg || e >= Ctor.toExpPos); +}; + + +// Helper functions for Decimal.prototype (P) and/or Decimal methods, and their callers. + + +/* + * add P.minus, P.plus + * checkInt32 P.todp, P.toExponential, P.toFixed, P.toPrecision, P.tosd + * digitsToString P.log, P.sqrt, P.pow, toString, exp, ln + * divide P.div, P.idiv, P.log, P.mod, P.sqrt, exp, ln + * exp P.exp, P.pow + * getBase10Exponent P.exponent, P.sd, P.toint, P.sqrt, P.todp, P.toFixed, P.toPrecision, + * P.toString, divide, round, toString, exp, ln + * getLn10 P.log, ln + * getZeroString digitsToString, toString + * ln P.log, P.ln, P.pow, exp + * parseDecimal Decimal + * round P.abs, P.idiv, P.log, P.minus, P.mod, P.neg, P.plus, P.toint, P.sqrt, + * P.times, P.todp, P.toExponential, P.toFixed, P.pow, P.toPrecision, P.tosd, + * divide, getLn10, exp, ln + * subtract P.minus, P.plus + * toString P.toExponential, P.toFixed, P.toPrecision, P.toString, P.valueOf + * truncate P.pow + * + * Throws: P.log, P.mod, P.sd, P.sqrt, P.pow, checkInt32, divide, round, + * getLn10, exp, ln, parseDecimal, Decimal, config + */ + + +function add(x, y) { + var carry, d, e, i, k, len, xd, yd, + Ctor = x.constructor, + pr = Ctor.precision; + + // If either is zero... + if (!x.s || !y.s) { + + // Return x if y is zero. + // Return y if y is non-zero. + if (!y.s) y = new Ctor(x); + return external ? round(y, pr) : y; + } + + xd = x.d; + yd = y.d; + + // x and y are finite, non-zero numbers with the same sign. + + k = x.e; + e = y.e; + xd = xd.slice(); + i = k - e; + + // If base 1e7 exponents differ... + if (i) { + if (i < 0) { + d = xd; + i = -i; + len = yd.length; + } else { + d = yd; + e = k; + len = xd.length; + } + + // Limit number of zeros prepended to max(ceil(pr / LOG_BASE), len) + 1. + k = Math.ceil(pr / LOG_BASE); + len = k > len ? k + 1 : len + 1; + + if (i > len) { + i = len; + d.length = 1; + } + + // Prepend zeros to equalise exponents. Note: Faster to use reverse then do unshifts. + d.reverse(); + for (; i--;) d.push(0); + d.reverse(); + } + + len = xd.length; + i = yd.length; + + // If yd is longer than xd, swap xd and yd so xd points to the longer array. + if (len - i < 0) { + i = len; + d = yd; + yd = xd; + xd = d; + } + + // Only start adding at yd.length - 1 as the further digits of xd can be left as they are. + for (carry = 0; i;) { + carry = (xd[--i] = xd[i] + yd[i] + carry) / BASE | 0; + xd[i] %= BASE; + } + + if (carry) { + xd.unshift(carry); + ++e; + } + + // Remove trailing zeros. + // No need to check for zero, as +x + +y != 0 && -x + -y != 0 + for (len = xd.length; xd[--len] == 0;) xd.pop(); + + y.d = xd; + y.e = e; + + return external ? round(y, pr) : y; +} + + +function checkInt32(i, min, max) { + if (i !== ~~i || i < min || i > max) { + throw Error(invalidArgument + i); + } +} + + +function digitsToString(d) { + var i, k, ws, + indexOfLastWord = d.length - 1, + str = '', + w = d[0]; + + if (indexOfLastWord > 0) { + str += w; + for (i = 1; i < indexOfLastWord; i++) { + ws = d[i] + ''; + k = LOG_BASE - ws.length; + if (k) str += getZeroString(k); + str += ws; + } + + w = d[i]; + ws = w + ''; + k = LOG_BASE - ws.length; + if (k) str += getZeroString(k); + } else if (w === 0) { + return '0'; + } + + // Remove trailing zeros of last w. + for (; w % 10 === 0;) w /= 10; + + return str + w; +} + + +var divide = (function () { + + // Assumes non-zero x and k, and hence non-zero result. + function multiplyInteger(x, k) { + var temp, + carry = 0, + i = x.length; + + for (x = x.slice(); i--;) { + temp = x[i] * k + carry; + x[i] = temp % BASE | 0; + carry = temp / BASE | 0; + } + + if (carry) x.unshift(carry); + + return x; + } + + function compare(a, b, aL, bL) { + var i, r; + + if (aL != bL) { + r = aL > bL ? 1 : -1; + } else { + for (i = r = 0; i < aL; i++) { + if (a[i] != b[i]) { + r = a[i] > b[i] ? 1 : -1; + break; + } + } + } + + return r; + } + + function subtract(a, b, aL) { + var i = 0; + + // Subtract b from a. + for (; aL--;) { + a[aL] -= i; + i = a[aL] < b[aL] ? 1 : 0; + a[aL] = i * BASE + a[aL] - b[aL]; + } + + // Remove leading zeros. + for (; !a[0] && a.length > 1;) a.shift(); + } + + return function (x, y, pr, dp) { + var cmp, e, i, k, prod, prodL, q, qd, rem, remL, rem0, sd, t, xi, xL, yd0, yL, yz, + Ctor = x.constructor, + sign = x.s == y.s ? 1 : -1, + xd = x.d, + yd = y.d; + + // Either 0? + if (!x.s) return new Ctor(x); + if (!y.s) throw Error(decimalError + 'Division by zero'); + + e = x.e - y.e; + yL = yd.length; + xL = xd.length; + q = new Ctor(sign); + qd = q.d = []; + + // Result exponent may be one less than e. + for (i = 0; yd[i] == (xd[i] || 0); ) ++i; + if (yd[i] > (xd[i] || 0)) --e; + + if (pr == null) { + sd = pr = Ctor.precision; + } else if (dp) { + sd = pr + (getBase10Exponent(x) - getBase10Exponent(y)) + 1; + } else { + sd = pr; + } + + if (sd < 0) return new Ctor(0); + + // Convert precision in number of base 10 digits to base 1e7 digits. + sd = sd / LOG_BASE + 2 | 0; + i = 0; + + // divisor < 1e7 + if (yL == 1) { + k = 0; + yd = yd[0]; + sd++; + + // k is the carry. + for (; (i < xL || k) && sd--; i++) { + t = k * BASE + (xd[i] || 0); + qd[i] = t / yd | 0; + k = t % yd | 0; + } + + // divisor >= 1e7 + } else { + + // Normalise xd and yd so highest order digit of yd is >= BASE/2 + k = BASE / (yd[0] + 1) | 0; + + if (k > 1) { + yd = multiplyInteger(yd, k); + xd = multiplyInteger(xd, k); + yL = yd.length; + xL = xd.length; + } + + xi = yL; + rem = xd.slice(0, yL); + remL = rem.length; + + // Add zeros to make remainder as long as divisor. + for (; remL < yL;) rem[remL++] = 0; + + yz = yd.slice(); + yz.unshift(0); + yd0 = yd[0]; + + if (yd[1] >= BASE / 2) ++yd0; + + do { + k = 0; + + // Compare divisor and remainder. + cmp = compare(yd, rem, yL, remL); + + // If divisor < remainder. + if (cmp < 0) { + + // Calculate trial digit, k. + rem0 = rem[0]; + if (yL != remL) rem0 = rem0 * BASE + (rem[1] || 0); + + // k will be how many times the divisor goes into the current remainder. + k = rem0 / yd0 | 0; + + // Algorithm: + // 1. product = divisor * trial digit (k) + // 2. if product > remainder: product -= divisor, k-- + // 3. remainder -= product + // 4. if product was < remainder at 2: + // 5. compare new remainder and divisor + // 6. If remainder > divisor: remainder -= divisor, k++ + + if (k > 1) { + if (k >= BASE) k = BASE - 1; + + // product = divisor * trial digit. + prod = multiplyInteger(yd, k); + prodL = prod.length; + remL = rem.length; + + // Compare product and remainder. + cmp = compare(prod, rem, prodL, remL); + + // product > remainder. + if (cmp == 1) { + k--; + + // Subtract divisor from product. + subtract(prod, yL < prodL ? yz : yd, prodL); + } + } else { + + // cmp is -1. + // If k is 0, there is no need to compare yd and rem again below, so change cmp to 1 + // to avoid it. If k is 1 there is a need to compare yd and rem again below. + if (k == 0) cmp = k = 1; + prod = yd.slice(); + } + + prodL = prod.length; + if (prodL < remL) prod.unshift(0); + + // Subtract product from remainder. + subtract(rem, prod, remL); + + // If product was < previous remainder. + if (cmp == -1) { + remL = rem.length; + + // Compare divisor and new remainder. + cmp = compare(yd, rem, yL, remL); + + // If divisor < new remainder, subtract divisor from remainder. + if (cmp < 1) { + k++; + + // Subtract divisor from remainder. + subtract(rem, yL < remL ? yz : yd, remL); + } + } + + remL = rem.length; + } else if (cmp === 0) { + k++; + rem = [0]; + } // if cmp === 1, k will be 0 + + // Add the next digit, k, to the result array. + qd[i++] = k; + + // Update the remainder. + if (cmp && rem[0]) { + rem[remL++] = xd[xi] || 0; + } else { + rem = [xd[xi]]; + remL = 1; + } + + } while ((xi++ < xL || rem[0] !== void 0) && sd--); + } + + // Leading zero? + if (!qd[0]) qd.shift(); + + q.e = e; + + return round(q, dp ? pr + getBase10Exponent(q) + 1 : pr); + }; +})(); + + +/* + * Return a new Decimal whose value is the natural exponential of `x` truncated to `sd` + * significant digits. + * + * Taylor/Maclaurin series. + * + * exp(x) = x^0/0! + x^1/1! + x^2/2! + x^3/3! + ... + * + * Argument reduction: + * Repeat x = x / 32, k += 5, until |x| < 0.1 + * exp(x) = exp(x / 2^k)^(2^k) + * + * Previously, the argument was initially reduced by + * exp(x) = exp(r) * 10^k where r = x - k * ln10, k = floor(x / ln10) + * to first put r in the range [0, ln10], before dividing by 32 until |x| < 0.1, but this was + * found to be slower than just dividing repeatedly by 32 as above. + * + * (Math object integer min/max: Math.exp(709) = 8.2e+307, Math.exp(-745) = 5e-324) + * + * exp(x) is non-terminating for any finite, non-zero x. + * + */ +function exp(x, sd) { + var denominator, guard, pow, sum, t, wpr, + i = 0, + k = 0, + Ctor = x.constructor, + pr = Ctor.precision; + + if (getBase10Exponent(x) > 16) throw Error(exponentOutOfRange + getBase10Exponent(x)); + + // exp(0) = 1 + if (!x.s) return new Ctor(ONE); + + if (sd == null) { + external = false; + wpr = pr; + } else { + wpr = sd; + } + + t = new Ctor(0.03125); + + while (x.abs().gte(0.1)) { + x = x.times(t); // x = x / 2^5 + k += 5; + } + + // Estimate the precision increase necessary to ensure the first 4 rounding digits are correct. + guard = Math.log(mathpow(2, k)) / Math.LN10 * 2 + 5 | 0; + wpr += guard; + denominator = pow = sum = new Ctor(ONE); + Ctor.precision = wpr; + + for (;;) { + pow = round(pow.times(x), wpr); + denominator = denominator.times(++i); + t = sum.plus(divide(pow, denominator, wpr)); + + if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) { + while (k--) sum = round(sum.times(sum), wpr); + Ctor.precision = pr; + return sd == null ? (external = true, round(sum, pr)) : sum; + } + + sum = t; + } +} + + +// Calculate the base 10 exponent from the base 1e7 exponent. +function getBase10Exponent(x) { + var e = x.e * LOG_BASE, + w = x.d[0]; + + // Add the number of digits of the first word of the digits array. + for (; w >= 10; w /= 10) e++; + return e; +} + + +function getLn10(Ctor, sd, pr) { + + if (sd > Ctor.LN10.sd()) { + + + // Reset global state in case the exception is caught. + external = true; + if (pr) Ctor.precision = pr; + throw Error(decimalError + 'LN10 precision limit exceeded'); + } + + return round(new Ctor(Ctor.LN10), sd); +} + + +function getZeroString(k) { + var zs = ''; + for (; k--;) zs += '0'; + return zs; +} + + +/* + * Return a new Decimal whose value is the natural logarithm of `x` truncated to `sd` significant + * digits. + * + * ln(n) is non-terminating (n != 1) + * + */ +function ln(y, sd) { + var c, c0, denominator, e, numerator, sum, t, wpr, x2, + n = 1, + guard = 10, + x = y, + xd = x.d, + Ctor = x.constructor, + pr = Ctor.precision; + + // ln(-x) = NaN + // ln(0) = -Infinity + if (x.s < 1) throw Error(decimalError + (x.s ? 'NaN' : '-Infinity')); + + // ln(1) = 0 + if (x.eq(ONE)) return new Ctor(0); + + if (sd == null) { + external = false; + wpr = pr; + } else { + wpr = sd; + } + + if (x.eq(10)) { + if (sd == null) external = true; + return getLn10(Ctor, wpr); + } + + wpr += guard; + Ctor.precision = wpr; + c = digitsToString(xd); + c0 = c.charAt(0); + e = getBase10Exponent(x); + + if (Math.abs(e) < 1.5e15) { + + // Argument reduction. + // The series converges faster the closer the argument is to 1, so using + // ln(a^b) = b * ln(a), ln(a) = ln(a^b) / b + // multiply the argument by itself until the leading digits of the significand are 7, 8, 9, + // 10, 11, 12 or 13, recording the number of multiplications so the sum of the series can + // later be divided by this number, then separate out the power of 10 using + // ln(a*10^b) = ln(a) + b*ln(10). + + // max n is 21 (gives 0.9, 1.0 or 1.1) (9e15 / 21 = 4.2e14). + //while (c0 < 9 && c0 != 1 || c0 == 1 && c.charAt(1) > 1) { + // max n is 6 (gives 0.7 - 1.3) + while (c0 < 7 && c0 != 1 || c0 == 1 && c.charAt(1) > 3) { + x = x.times(y); + c = digitsToString(x.d); + c0 = c.charAt(0); + n++; + } + + e = getBase10Exponent(x); + + if (c0 > 1) { + x = new Ctor('0.' + c); + e++; + } else { + x = new Ctor(c0 + '.' + c.slice(1)); + } + } else { + + // The argument reduction method above may result in overflow if the argument y is a massive + // number with exponent >= 1500000000000000 (9e15 / 6 = 1.5e15), so instead recall this + // function using ln(x*10^e) = ln(x) + e*ln(10). + t = getLn10(Ctor, wpr + 2, pr).times(e + ''); + x = ln(new Ctor(c0 + '.' + c.slice(1)), wpr - guard).plus(t); + + Ctor.precision = pr; + return sd == null ? (external = true, round(x, pr)) : x; + } + + // x is reduced to a value near 1. + + // Taylor series. + // ln(y) = ln((1 + x)/(1 - x)) = 2(x + x^3/3 + x^5/5 + x^7/7 + ...) + // where x = (y - 1)/(y + 1) (|x| < 1) + sum = numerator = x = divide(x.minus(ONE), x.plus(ONE), wpr); + x2 = round(x.times(x), wpr); + denominator = 3; + + for (;;) { + numerator = round(numerator.times(x2), wpr); + t = sum.plus(divide(numerator, new Ctor(denominator), wpr)); + + if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) { + sum = sum.times(2); + + // Reverse the argument reduction. + if (e !== 0) sum = sum.plus(getLn10(Ctor, wpr + 2, pr).times(e + '')); + sum = divide(sum, new Ctor(n), wpr); + + Ctor.precision = pr; + return sd == null ? (external = true, round(sum, pr)) : sum; + } + + sum = t; + denominator += 2; + } +} + + +/* + * Parse the value of a new Decimal `x` from string `str`. + */ +function parseDecimal(x, str) { + var e, i, len; + + // Decimal point? + if ((e = str.indexOf('.')) > -1) str = str.replace('.', ''); + + // Exponential form? + if ((i = str.search(/e/i)) > 0) { + + // Determine exponent. + if (e < 0) e = i; + e += +str.slice(i + 1); + str = str.substring(0, i); + } else if (e < 0) { + + // Integer. + e = str.length; + } + + // Determine leading zeros. + for (i = 0; str.charCodeAt(i) === 48;) ++i; + + // Determine trailing zeros. + for (len = str.length; str.charCodeAt(len - 1) === 48;) --len; + str = str.slice(i, len); + + if (str) { + len -= i; + e = e - i - 1; + x.e = mathfloor(e / LOG_BASE); + x.d = []; + + // Transform base + + // e is the base 10 exponent. + // i is where to slice str to get the first word of the digits array. + i = (e + 1) % LOG_BASE; + if (e < 0) i += LOG_BASE; + + if (i < len) { + if (i) x.d.push(+str.slice(0, i)); + for (len -= LOG_BASE; i < len;) x.d.push(+str.slice(i, i += LOG_BASE)); + str = str.slice(i); + i = LOG_BASE - str.length; + } else { + i -= len; + } + + for (; i--;) str += '0'; + x.d.push(+str); + + if (external && (x.e > MAX_E || x.e < -MAX_E)) throw Error(exponentOutOfRange + e); + } else { + + // Zero. + x.s = 0; + x.e = 0; + x.d = [0]; + } + + return x; +} + + +/* + * Round `x` to `sd` significant digits, using rounding mode `rm` if present (truncate otherwise). + */ + function round(x, sd, rm) { + var i, j, k, n, rd, doRound, w, xdi, + xd = x.d; + + // rd: the rounding digit, i.e. the digit after the digit that may be rounded up. + // w: the word of xd which contains the rounding digit, a base 1e7 number. + // xdi: the index of w within xd. + // n: the number of digits of w. + // i: what would be the index of rd within w if all the numbers were 7 digits long (i.e. if + // they had leading zeros) + // j: if > 0, the actual index of rd within w (if < 0, rd is a leading zero). + + // Get the length of the first word of the digits array xd. + for (n = 1, k = xd[0]; k >= 10; k /= 10) n++; + i = sd - n; + + // Is the rounding digit in the first word of xd? + if (i < 0) { + i += LOG_BASE; + j = sd; + w = xd[xdi = 0]; + } else { + xdi = Math.ceil((i + 1) / LOG_BASE); + k = xd.length; + if (xdi >= k) return x; + w = k = xd[xdi]; + + // Get the number of digits of w. + for (n = 1; k >= 10; k /= 10) n++; + + // Get the index of rd within w. + i %= LOG_BASE; + + // Get the index of rd within w, adjusted for leading zeros. + // The number of leading zeros of w is given by LOG_BASE - n. + j = i - LOG_BASE + n; + } + + if (rm !== void 0) { + k = mathpow(10, n - j - 1); + + // Get the rounding digit at index j of w. + rd = w / k % 10 | 0; + + // Are there any non-zero digits after the rounding digit? + doRound = sd < 0 || xd[xdi + 1] !== void 0 || w % k; + + // The expression `w % mathpow(10, n - j - 1)` returns all the digits of w to the right of the + // digit at (left-to-right) index j, e.g. if w is 908714 and j is 2, the expression will give + // 714. + + doRound = rm < 4 + ? (rd || doRound) && (rm == 0 || rm == (x.s < 0 ? 3 : 2)) + : rd > 5 || rd == 5 && (rm == 4 || doRound || rm == 6 && + + // Check whether the digit to the left of the rounding digit is odd. + ((i > 0 ? j > 0 ? w / mathpow(10, n - j) : 0 : xd[xdi - 1]) % 10) & 1 || + rm == (x.s < 0 ? 8 : 7)); + } + + if (sd < 1 || !xd[0]) { + if (doRound) { + k = getBase10Exponent(x); + xd.length = 1; + + // Convert sd to decimal places. + sd = sd - k - 1; + + // 1, 0.1, 0.01, 0.001, 0.0001 etc. + xd[0] = mathpow(10, (LOG_BASE - sd % LOG_BASE) % LOG_BASE); + x.e = mathfloor(-sd / LOG_BASE) || 0; + } else { + xd.length = 1; + + // Zero. + xd[0] = x.e = x.s = 0; + } + + return x; + } + + // Remove excess digits. + if (i == 0) { + xd.length = xdi; + k = 1; + xdi--; + } else { + xd.length = xdi + 1; + k = mathpow(10, LOG_BASE - i); + + // E.g. 56700 becomes 56000 if 7 is the rounding digit. + // j > 0 means i > number of leading zeros of w. + xd[xdi] = j > 0 ? (w / mathpow(10, n - j) % mathpow(10, j) | 0) * k : 0; + } + + if (doRound) { + for (;;) { + + // Is the digit to be rounded up in the first word of xd? + if (xdi == 0) { + if ((xd[0] += k) == BASE) { + xd[0] = 1; + ++x.e; + } + + break; + } else { + xd[xdi] += k; + if (xd[xdi] != BASE) break; + xd[xdi--] = 0; + k = 1; + } + } + } + + // Remove trailing zeros. + for (i = xd.length; xd[--i] === 0;) xd.pop(); + + if (external && (x.e > MAX_E || x.e < -MAX_E)) { + throw Error(exponentOutOfRange + getBase10Exponent(x)); + } + + return x; +} + + +function subtract(x, y) { + var d, e, i, j, k, len, xd, xe, xLTy, yd, + Ctor = x.constructor, + pr = Ctor.precision; + + // Return y negated if x is zero. + // Return x if y is zero and x is non-zero. + if (!x.s || !y.s) { + if (y.s) y.s = -y.s; + else y = new Ctor(x); + return external ? round(y, pr) : y; + } + + xd = x.d; + yd = y.d; + + // x and y are non-zero numbers with the same sign. + + e = y.e; + xe = x.e; + xd = xd.slice(); + k = xe - e; + + // If exponents differ... + if (k) { + xLTy = k < 0; + + if (xLTy) { + d = xd; + k = -k; + len = yd.length; + } else { + d = yd; + e = xe; + len = xd.length; + } + + // Numbers with massively different exponents would result in a very high number of zeros + // needing to be prepended, but this can be avoided while still ensuring correct rounding by + // limiting the number of zeros to `Math.ceil(pr / LOG_BASE) + 2`. + i = Math.max(Math.ceil(pr / LOG_BASE), len) + 2; + + if (k > i) { + k = i; + d.length = 1; + } + + // Prepend zeros to equalise exponents. + d.reverse(); + for (i = k; i--;) d.push(0); + d.reverse(); + + // Base 1e7 exponents equal. + } else { + + // Check digits to determine which is the bigger number. + + i = xd.length; + len = yd.length; + xLTy = i < len; + if (xLTy) len = i; + + for (i = 0; i < len; i++) { + if (xd[i] != yd[i]) { + xLTy = xd[i] < yd[i]; + break; + } + } + + k = 0; + } + + if (xLTy) { + d = xd; + xd = yd; + yd = d; + y.s = -y.s; + } + + len = xd.length; + + // Append zeros to xd if shorter. + // Don't add zeros to yd if shorter as subtraction only needs to start at yd length. + for (i = yd.length - len; i > 0; --i) xd[len++] = 0; + + // Subtract yd from xd. + for (i = yd.length; i > k;) { + if (xd[--i] < yd[i]) { + for (j = i; j && xd[--j] === 0;) xd[j] = BASE - 1; + --xd[j]; + xd[i] += BASE; + } + + xd[i] -= yd[i]; + } + + // Remove trailing zeros. + for (; xd[--len] === 0;) xd.pop(); + + // Remove leading zeros and adjust exponent accordingly. + for (; xd[0] === 0; xd.shift()) --e; + + // Zero? + if (!xd[0]) return new Ctor(0); + + y.d = xd; + y.e = e; + + //return external && xd.length >= pr / LOG_BASE ? round(y, pr) : y; + return external ? round(y, pr) : y; +} + + +function toString$3(x, isExp, sd) { + var k, + e = getBase10Exponent(x), + str = digitsToString(x.d), + len = str.length; + + if (isExp) { + if (sd && (k = sd - len) > 0) { + str = str.charAt(0) + '.' + str.slice(1) + getZeroString(k); + } else if (len > 1) { + str = str.charAt(0) + '.' + str.slice(1); + } + + str = str + (e < 0 ? 'e' : 'e+') + e; + } else if (e < 0) { + str = '0.' + getZeroString(-e - 1) + str; + if (sd && (k = sd - len) > 0) str += getZeroString(k); + } else if (e >= len) { + str += getZeroString(e + 1 - len); + if (sd && (k = sd - e - 1) > 0) str = str + '.' + getZeroString(k); + } else { + if ((k = e + 1) < len) str = str.slice(0, k) + '.' + str.slice(k); + if (sd && (k = sd - len) > 0) { + if (e + 1 === len) str += '.'; + str += getZeroString(k); + } + } + + return x.s < 0 ? '-' + str : str; +} + + +// Does not strip trailing zeros. +function truncate(arr, len) { + if (arr.length > len) { + arr.length = len; + return true; + } +} + + +// Decimal methods + + +/* + * clone + * config/set + */ + + +/* + * Create and return a Decimal constructor with the same configuration properties as this Decimal + * constructor. + * + */ +function clone(obj) { + var i, p, ps; + + /* + * The Decimal constructor and exported function. + * Return a new Decimal instance. + * + * value {number|string|Decimal} A numeric value. + * + */ + function Decimal(value) { + var x = this; + + // Decimal called without new. + if (!(x instanceof Decimal)) return new Decimal(value); + + // Retain a reference to this Decimal constructor, and shadow Decimal.prototype.constructor + // which points to Object. + x.constructor = Decimal; + + // Duplicate. + if (value instanceof Decimal) { + x.s = value.s; + x.e = value.e; + x.d = (value = value.d) ? value.slice() : value; + return; + } + + if (typeof value === 'number') { + + // Reject Infinity/NaN. + if (value * 0 !== 0) { + throw Error(invalidArgument + value); + } + + if (value > 0) { + x.s = 1; + } else if (value < 0) { + value = -value; + x.s = -1; + } else { + x.s = 0; + x.e = 0; + x.d = [0]; + return; + } + + // Fast path for small integers. + if (value === ~~value && value < 1e7) { + x.e = 0; + x.d = [value]; + return; + } + + return parseDecimal(x, value.toString()); + } else if (typeof value !== 'string') { + throw Error(invalidArgument + value); + } + + // Minus sign? + if (value.charCodeAt(0) === 45) { + value = value.slice(1); + x.s = -1; + } else { + x.s = 1; + } + + if (isDecimal.test(value)) parseDecimal(x, value); + else throw Error(invalidArgument + value); + } + + Decimal.prototype = P; + + Decimal.ROUND_UP = 0; + Decimal.ROUND_DOWN = 1; + Decimal.ROUND_CEIL = 2; + Decimal.ROUND_FLOOR = 3; + Decimal.ROUND_HALF_UP = 4; + Decimal.ROUND_HALF_DOWN = 5; + Decimal.ROUND_HALF_EVEN = 6; + Decimal.ROUND_HALF_CEIL = 7; + Decimal.ROUND_HALF_FLOOR = 8; + + Decimal.clone = clone; + Decimal.config = Decimal.set = config; + + if (obj === void 0) obj = {}; + if (obj) { + ps = ['precision', 'rounding', 'toExpNeg', 'toExpPos', 'LN10']; + for (i = 0; i < ps.length;) if (!obj.hasOwnProperty(p = ps[i++])) obj[p] = this[p]; + } + + Decimal.config(obj); + + return Decimal; +} + + +/* + * Configure global settings for a Decimal constructor. + * + * `obj` is an object with one or more of the following properties, + * + * precision {number} + * rounding {number} + * toExpNeg {number} + * toExpPos {number} + * + * E.g. Decimal.config({ precision: 20, rounding: 4 }) + * + */ +function config(obj) { + if (!obj || typeof obj !== 'object') { + throw Error(decimalError + 'Object expected'); + } + var i, p, v, + ps = [ + 'precision', 1, MAX_DIGITS, + 'rounding', 0, 8, + 'toExpNeg', -1 / 0, 0, + 'toExpPos', 0, 1 / 0 + ]; + + for (i = 0; i < ps.length; i += 3) { + if ((v = obj[p = ps[i]]) !== void 0) { + if (mathfloor(v) === v && v >= ps[i + 1] && v <= ps[i + 2]) this[p] = v; + else throw Error(invalidArgument + p + ': ' + v); + } + } + + if ((v = obj[p = 'LN10']) !== void 0) { + if (v == Math.LN10) this[p] = new this(v); + else throw Error(invalidArgument + p + ': ' + v); + } + + return this; +} + + +// Create and configure initial Decimal constructor. +var Decimal = clone(defaults); + +// Internal constant. +ONE = new Decimal(1); -/* - * Return a new Decimal whose value is the value of this Decimal divided by `y`, truncated to - * `precision` significant digits. - * - */ -P.dividedBy = P.div = function (y) { - return divide(this, new this.constructor(y)); +Decimal.set({ + precision: 30, + toExpNeg: -7, + toExpPos: 29, +}); +var n = new Decimal(60 * 60 * 24 * 365); +var lookup = {}; +/** + * Get interest rate in percentage points for a specified fee. + * This function uses a lookup table for performance reasons. + * This function uses decimal.js-light, since we need non-integer powers for our calculations here. + * We can remove that dependency in the future if we decide to either add a hardcoded + * lookup table for fees and interest rates or if we decide to implement the relevant + * functions here by hand. + * @param fee Fee + */ +var feeToInterestRate = function (fee) { + // tslint:disable-next-line:no-parameter-reassignment + if (typeof fee !== 'string' && typeof fee !== 'number') { + fee = fee.toString(); + } + if (lookup[fee]) { + return lookup[fee]; + } + var i = new Decimal(fee).div('1e27').pow(n); + var interestRate = i.minus(1).mul(100).toSignificantDigits(2); + var interestRateString = interestRate.toString(); + lookup[fee] = interestRateString; + return interestRateString; }; - -/* - * Return a new Decimal whose value is the integer part of dividing the value of this Decimal - * by the value of `y`, truncated to `precision` significant digits. - * - */ -P.dividedToIntegerBy = P.idiv = function (y) { - var x = this, - Ctor = x.constructor; - return round(divide(x, new Ctor(y), 0, 1), Ctor.precision); +function getLoanStatus(principal, debt) { + if (!principal.isZero()) { + return 'Whitelisted'; + } + if (principal.isZero() && !debt.isZero()) { + return 'Ongoing'; + } + if (principal.isZero() && debt.isZero()) { + return 'Repaid'; + } + throw Error('Unknown loan status'); +} + +Decimal.set({ + precision: 28, + toExpNeg: -7, + toExpPos: 29, +}); +var n$1 = new Decimal(60 * 60 * 24 * 365); +var lookup$1 = {}; +/** + * Get fee for a specified interest rate. This function uses a lookup table for performance reasons. + * This function uses decimal.js-light, since we need non-integer powers for our calculations here. + * We can remove that dependency in the future if we decide to either add a hardcoded + * lookup table for fees and interest rates or if we decide to implement the relevant + * functions here by hand. + * @param interestRate Interest rate in percentage points, i. e. "5" for 5 % (= 0.05) + */ +var interestRateToFee = function (interestRate) { + if (lookup$1[interestRate]) { + return lookup$1[interestRate]; + } + var i = new Decimal(interestRate).div(100).plus(1); + var fee = i.pow(new Decimal(1).div(n$1)).mul('1e27').toDecimalPlaces(0); + var feeString = fee.toString(); + lookup$1[interestRate] = feeString; + return feeString; }; - -/* - * Return true if the value of this Decimal is equal to the value of `y`, otherwise return false. - * - */ -P.equals = P.eq = function (y) { - return !this.cmp(y); -}; - - -/* - * Return the (base 10) exponent value of this Decimal (this.e is the base 10000000 exponent). - * - */ -P.exponent = function () { - return getBase10Exponent(this); -}; - - -/* - * Return true if the value of this Decimal is greater than the value of `y`, otherwise return - * false. - * - */ -P.greaterThan = P.gt = function (y) { - return this.cmp(y) > 0; -}; - - -/* - * Return true if the value of this Decimal is greater than or equal to the value of `y`, - * otherwise return false. - * - */ -P.greaterThanOrEqualTo = P.gte = function (y) { - return this.cmp(y) >= 0; -}; - - -/* - * Return true if the value of this Decimal is an integer, otherwise return false. - * - */ -P.isInteger = P.isint = function () { - return this.e > this.d.length - 2; -}; - - -/* - * Return true if the value of this Decimal is negative, otherwise return false. - * - */ -P.isNegative = P.isneg = function () { - return this.s < 0; -}; - - -/* - * Return true if the value of this Decimal is positive, otherwise return false. - * - */ -P.isPositive = P.ispos = function () { - return this.s > 0; -}; - - -/* - * Return true if the value of this Decimal is 0, otherwise return false. - * - */ -P.isZero = function () { - return this.s === 0; -}; - - -/* - * Return true if the value of this Decimal is less than `y`, otherwise return false. - * - */ -P.lessThan = P.lt = function (y) { - return this.cmp(y) < 0; -}; - - -/* - * Return true if the value of this Decimal is less than or equal to `y`, otherwise return false. - * - */ -P.lessThanOrEqualTo = P.lte = function (y) { - return this.cmp(y) < 1; -}; - - -/* - * Return the logarithm of the value of this Decimal to the specified base, truncated to - * `precision` significant digits. - * - * If no base is specified, return log[10](x). - * - * log[base](x) = ln(x) / ln(base) - * - * The maximum error of the result is 1 ulp (unit in the last place). - * - * [base] {number|string|Decimal} The base of the logarithm. - * - */ -P.logarithm = P.log = function (base) { - var r, - x = this, - Ctor = x.constructor, - pr = Ctor.precision, - wpr = pr + 5; - - // Default base is 10. - if (base === void 0) { - base = new Ctor(10); - } else { - base = new Ctor(base); - - // log[-b](x) = NaN - // log[0](x) = NaN - // log[1](x) = NaN - if (base.s < 1 || base.eq(ONE)) throw Error(decimalError + 'NaN'); - } - - // log[b](-x) = NaN - // log[b](0) = -Infinity - if (x.s < 1) throw Error(decimalError + (x.s ? 'NaN' : '-Infinity')); - - // log[b](1) = 0 - if (x.eq(ONE)) return new Ctor(0); - - external = false; - r = divide(ln(x, wpr), ln(base, wpr), wpr); - external = true; - - return round(r, pr); -}; - - -/* - * Return a new Decimal whose value is the value of this Decimal minus `y`, truncated to - * `precision` significant digits. - * - */ -P.minus = P.sub = function (y) { - var x = this; - y = new x.constructor(y); - return x.s == y.s ? subtract(x, y) : add(x, (y.s = -y.s, y)); -}; - - -/* - * Return a new Decimal whose value is the value of this Decimal modulo `y`, truncated to - * `precision` significant digits. - * - */ -P.modulo = P.mod = function (y) { - var q, - x = this, - Ctor = x.constructor, - pr = Ctor.precision; - - y = new Ctor(y); - - // x % 0 = NaN - if (!y.s) throw Error(decimalError + 'NaN'); - - // Return x if x is 0. - if (!x.s) return round(new Ctor(x), pr); - - // Prevent rounding of intermediate calculations. - external = false; - q = divide(x, y, 0, 1).times(y); - external = true; - - return x.minus(q); -}; - - -/* - * Return a new Decimal whose value is the natural exponential of the value of this Decimal, - * i.e. the base e raised to the power the value of this Decimal, truncated to `precision` - * significant digits. - * - */ -P.naturalExponential = P.exp = function () { - return exp(this); -}; - - -/* - * Return a new Decimal whose value is the natural logarithm of the value of this Decimal, - * truncated to `precision` significant digits. - * - */ -P.naturalLogarithm = P.ln = function () { - return ln(this); -}; - - -/* - * Return a new Decimal whose value is the value of this Decimal negated, i.e. as if multiplied by - * -1. - * - */ -P.negated = P.neg = function () { - var x = new this.constructor(this); - x.s = -x.s || 0; - return x; -}; - - -/* - * Return a new Decimal whose value is the value of this Decimal plus `y`, truncated to - * `precision` significant digits. - * - */ -P.plus = P.add = function (y) { - var x = this; - y = new x.constructor(y); - return x.s == y.s ? add(x, y) : subtract(x, (y.s = -y.s, y)); -}; - - -/* - * Return the number of significant digits of the value of this Decimal. - * - * [z] {boolean|number} Whether to count integer-part trailing zeros: true, false, 1 or 0. - * - */ -P.precision = P.sd = function (z) { - var e, sd, w, - x = this; - - if (z !== void 0 && z !== !!z && z !== 1 && z !== 0) throw Error(invalidArgument + z); - - e = getBase10Exponent(x) + 1; - w = x.d.length - 1; - sd = w * LOG_BASE + 1; - w = x.d[w]; - - // If non-zero... - if (w) { - - // Subtract the number of trailing zeros of the last word. - for (; w % 10 == 0; w /= 10) sd--; - - // Add the number of digits of the first word. - for (w = x.d[0]; w >= 10; w /= 10) sd++; - } - - return z && e > sd ? e : sd; -}; - - -/* - * Return a new Decimal whose value is the square root of this Decimal, truncated to `precision` - * significant digits. - * - */ -P.squareRoot = P.sqrt = function () { - var e, n, pr, r, s, t, wpr, - x = this, - Ctor = x.constructor; - - // Negative or zero? - if (x.s < 1) { - if (!x.s) return new Ctor(0); - - // sqrt(-x) = NaN - throw Error(decimalError + 'NaN'); - } - - e = getBase10Exponent(x); - external = false; - - // Initial estimate. - s = Math.sqrt(+x); - - // Math.sqrt underflow/overflow? - // Pass x to Math.sqrt as integer, then adjust the exponent of the result. - if (s == 0 || s == 1 / 0) { - n = digitsToString(x.d); - if ((n.length + e) % 2 == 0) n += '0'; - s = Math.sqrt(n); - e = mathfloor((e + 1) / 2) - (e < 0 || e % 2); - - if (s == 1 / 0) { - n = '1e' + e; - } else { - n = s.toExponential(); - n = n.slice(0, n.indexOf('e') + 1) + e; - } - - r = new Ctor(n); - } else { - r = new Ctor(s.toString()); - } - - pr = Ctor.precision; - s = wpr = pr + 3; - - // Newton-Raphson iteration. - for (;;) { - t = r; - r = t.plus(divide(x, t, wpr + 2)).times(0.5); - - if (digitsToString(t.d).slice(0, wpr) === (n = digitsToString(r.d)).slice(0, wpr)) { - n = n.slice(wpr - 3, wpr + 1); - - // The 4th rounding digit may be in error by -1 so if the 4 rounding digits are 9999 or - // 4999, i.e. approaching a rounding boundary, continue the iteration. - if (s == wpr && n == '4999') { - - // On the first iteration only, check to see if rounding up gives the exact result as the - // nines may infinitely repeat. - round(t, pr + 1, 0); - - if (t.times(t).eq(x)) { - r = t; - break; - } - } else if (n != '9999') { - break; - } - - wpr += 4; - } - } - - external = true; - - return round(r, pr); -}; - - -/* - * Return a new Decimal whose value is the value of this Decimal times `y`, truncated to - * `precision` significant digits. - * - */ -P.times = P.mul = function (y) { - var carry, e, i, k, r, rL, t, xdL, ydL, - x = this, - Ctor = x.constructor, - xd = x.d, - yd = (y = new Ctor(y)).d; - - // Return 0 if either is 0. - if (!x.s || !y.s) return new Ctor(0); - - y.s *= x.s; - e = x.e + y.e; - xdL = xd.length; - ydL = yd.length; - - // Ensure xd points to the longer array. - if (xdL < ydL) { - r = xd; - xd = yd; - yd = r; - rL = xdL; - xdL = ydL; - ydL = rL; - } - - // Initialise the result array with zeros. - r = []; - rL = xdL + ydL; - for (i = rL; i--;) r.push(0); - - // Multiply! - for (i = ydL; --i >= 0;) { - carry = 0; - for (k = xdL + i; k > i;) { - t = r[k] + yd[i] * xd[k - i - 1] + carry; - r[k--] = t % BASE | 0; - carry = t / BASE | 0; - } - - r[k] = (r[k] + carry) % BASE | 0; - } - - // Remove trailing zeros. - for (; !r[--rL];) r.pop(); - - if (carry) ++e; - else r.shift(); - - y.d = r; - y.e = e; - - return external ? round(y, Ctor.precision) : y; -}; - - -/* - * Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `dp` - * decimal places using rounding mode `rm` or `rounding` if `rm` is omitted. - * - * If `dp` is omitted, return a new Decimal whose value is the value of this Decimal. - * - * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - */ -P.toDecimalPlaces = P.todp = function (dp, rm) { - var x = this, - Ctor = x.constructor; - - x = new Ctor(x); - if (dp === void 0) return x; - - checkInt32(dp, 0, MAX_DIGITS); - - if (rm === void 0) rm = Ctor.rounding; - else checkInt32(rm, 0, 8); - - return round(x, dp + getBase10Exponent(x) + 1, rm); -}; - - -/* - * Return a string representing the value of this Decimal in exponential notation rounded to - * `dp` fixed decimal places using rounding mode `rounding`. - * - * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - */ -P.toExponential = function (dp, rm) { - var str, - x = this, - Ctor = x.constructor; - - if (dp === void 0) { - str = toString$3(x, true); - } else { - checkInt32(dp, 0, MAX_DIGITS); - - if (rm === void 0) rm = Ctor.rounding; - else checkInt32(rm, 0, 8); - - x = round(new Ctor(x), dp + 1, rm); - str = toString$3(x, true, dp + 1); - } - - return str; -}; - - -/* - * Return a string representing the value of this Decimal in normal (fixed-point) notation to - * `dp` fixed decimal places and rounded using rounding mode `rm` or `rounding` if `rm` is - * omitted. - * - * As with JavaScript numbers, (-0).toFixed(0) is '0', but e.g. (-0.00001).toFixed(0) is '-0'. - * - * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - * (-0).toFixed(0) is '0', but (-0.1).toFixed(0) is '-0'. - * (-0).toFixed(1) is '0.0', but (-0.01).toFixed(1) is '-0.0'. - * (-0).toFixed(3) is '0.000'. - * (-0.5).toFixed(0) is '-0'. - * - */ -P.toFixed = function (dp, rm) { - var str, y, - x = this, - Ctor = x.constructor; - - if (dp === void 0) return toString$3(x); - - checkInt32(dp, 0, MAX_DIGITS); - - if (rm === void 0) rm = Ctor.rounding; - else checkInt32(rm, 0, 8); - - y = round(new Ctor(x), dp + getBase10Exponent(x) + 1, rm); - str = toString$3(y.abs(), false, dp + getBase10Exponent(y) + 1); - - // To determine whether to add the minus sign look at the value before it was rounded, - // i.e. look at `x` rather than `y`. - return x.isneg() && !x.isZero() ? '-' + str : str; -}; - - -/* - * Return a new Decimal whose value is the value of this Decimal rounded to a whole number using - * rounding mode `rounding`. - * - */ -P.toInteger = P.toint = function () { - var x = this, - Ctor = x.constructor; - return round(new Ctor(x), getBase10Exponent(x) + 1, Ctor.rounding); -}; - - -/* - * Return the value of this Decimal converted to a number primitive. - * - */ -P.toNumber = function () { - return +this; -}; - - -/* - * Return a new Decimal whose value is the value of this Decimal raised to the power `y`, - * truncated to `precision` significant digits. - * - * For non-integer or very large exponents pow(x, y) is calculated using - * - * x^y = exp(y*ln(x)) - * - * The maximum error is 1 ulp (unit in last place). - * - * y {number|string|Decimal} The power to which to raise this Decimal. - * - */ -P.toPower = P.pow = function (y) { - var e, k, pr, r, sign, yIsInt, - x = this, - Ctor = x.constructor, - guard = 12, - yn = +(y = new Ctor(y)); - - // pow(x, 0) = 1 - if (!y.s) return new Ctor(ONE); - - x = new Ctor(x); - - // pow(0, y > 0) = 0 - // pow(0, y < 0) = Infinity - if (!x.s) { - if (y.s < 1) throw Error(decimalError + 'Infinity'); - return x; - } - - // pow(1, y) = 1 - if (x.eq(ONE)) return x; - - pr = Ctor.precision; - - // pow(x, 1) = x - if (y.eq(ONE)) return round(x, pr); - - e = y.e; - k = y.d.length - 1; - yIsInt = e >= k; - sign = x.s; - - if (!yIsInt) { - - // pow(x < 0, y non-integer) = NaN - if (sign < 0) throw Error(decimalError + 'NaN'); - - // If y is a small integer use the 'exponentiation by squaring' algorithm. - } else if ((k = yn < 0 ? -yn : yn) <= MAX_SAFE_INTEGER$2) { - r = new Ctor(ONE); - - // Max k of 9007199254740991 takes 53 loop iterations. - // Maximum digits array length; leaves [28, 34] guard digits. - e = Math.ceil(pr / LOG_BASE + 4); - - external = false; - - for (;;) { - if (k % 2) { - r = r.times(x); - truncate(r.d, e); - } - - k = mathfloor(k / 2); - if (k === 0) break; - - x = x.times(x); - truncate(x.d, e); - } - - external = true; - - return y.s < 0 ? new Ctor(ONE).div(r) : round(r, pr); - } - - // Result is negative if x is negative and the last digit of integer y is odd. - sign = sign < 0 && y.d[Math.max(e, k)] & 1 ? -1 : 1; - - x.s = 1; - external = false; - r = y.times(ln(x, pr + guard)); - external = true; - r = exp(r); - r.s = sign; - - return r; -}; - - -/* - * Return a string representing the value of this Decimal rounded to `sd` significant digits - * using rounding mode `rounding`. - * - * Return exponential notation if `sd` is less than the number of digits necessary to represent - * the integer part of the value in normal notation. - * - * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - */ -P.toPrecision = function (sd, rm) { - var e, str, - x = this, - Ctor = x.constructor; - - if (sd === void 0) { - e = getBase10Exponent(x); - str = toString$3(x, e <= Ctor.toExpNeg || e >= Ctor.toExpPos); - } else { - checkInt32(sd, 1, MAX_DIGITS); - - if (rm === void 0) rm = Ctor.rounding; - else checkInt32(rm, 0, 8); - - x = round(new Ctor(x), sd, rm); - e = getBase10Exponent(x); - str = toString$3(x, sd <= e || e <= Ctor.toExpNeg, sd); - } - - return str; -}; - - -/* - * Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `sd` - * significant digits using rounding mode `rm`, or to `precision` and `rounding` respectively if - * omitted. - * - * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - */ -P.toSignificantDigits = P.tosd = function (sd, rm) { - var x = this, - Ctor = x.constructor; - - if (sd === void 0) { - sd = Ctor.precision; - rm = Ctor.rounding; - } else { - checkInt32(sd, 1, MAX_DIGITS); - - if (rm === void 0) rm = Ctor.rounding; - else checkInt32(rm, 0, 8); - } - - return round(new Ctor(x), sd, rm); -}; - - -/* - * Return a string representing the value of this Decimal. - * - * Return exponential notation if this Decimal has a positive exponent equal to or greater than - * `toExpPos`, or a negative exponent equal to or less than `toExpNeg`. - * - */ -P.toString = P.valueOf = P.val = P.toJSON = P[Symbol.for('nodejs.util.inspect.custom')] = function () { - var x = this, - e = getBase10Exponent(x), - Ctor = x.constructor; - - return toString$3(x, e <= Ctor.toExpNeg || e >= Ctor.toExpPos); -}; - - -// Helper functions for Decimal.prototype (P) and/or Decimal methods, and their callers. - - -/* - * add P.minus, P.plus - * checkInt32 P.todp, P.toExponential, P.toFixed, P.toPrecision, P.tosd - * digitsToString P.log, P.sqrt, P.pow, toString, exp, ln - * divide P.div, P.idiv, P.log, P.mod, P.sqrt, exp, ln - * exp P.exp, P.pow - * getBase10Exponent P.exponent, P.sd, P.toint, P.sqrt, P.todp, P.toFixed, P.toPrecision, - * P.toString, divide, round, toString, exp, ln - * getLn10 P.log, ln - * getZeroString digitsToString, toString - * ln P.log, P.ln, P.pow, exp - * parseDecimal Decimal - * round P.abs, P.idiv, P.log, P.minus, P.mod, P.neg, P.plus, P.toint, P.sqrt, - * P.times, P.todp, P.toExponential, P.toFixed, P.pow, P.toPrecision, P.tosd, - * divide, getLn10, exp, ln - * subtract P.minus, P.plus - * toString P.toExponential, P.toFixed, P.toPrecision, P.toString, P.valueOf - * truncate P.pow - * - * Throws: P.log, P.mod, P.sd, P.sqrt, P.pow, checkInt32, divide, round, - * getLn10, exp, ln, parseDecimal, Decimal, config - */ - - -function add(x, y) { - var carry, d, e, i, k, len, xd, yd, - Ctor = x.constructor, - pr = Ctor.precision; - - // If either is zero... - if (!x.s || !y.s) { - - // Return x if y is zero. - // Return y if y is non-zero. - if (!y.s) y = new Ctor(x); - return external ? round(y, pr) : y; - } - - xd = x.d; - yd = y.d; - - // x and y are finite, non-zero numbers with the same sign. - - k = x.e; - e = y.e; - xd = xd.slice(); - i = k - e; - - // If base 1e7 exponents differ... - if (i) { - if (i < 0) { - d = xd; - i = -i; - len = yd.length; - } else { - d = yd; - e = k; - len = xd.length; - } - - // Limit number of zeros prepended to max(ceil(pr / LOG_BASE), len) + 1. - k = Math.ceil(pr / LOG_BASE); - len = k > len ? k + 1 : len + 1; - - if (i > len) { - i = len; - d.length = 1; - } - - // Prepend zeros to equalise exponents. Note: Faster to use reverse then do unshifts. - d.reverse(); - for (; i--;) d.push(0); - d.reverse(); - } - - len = xd.length; - i = yd.length; - - // If yd is longer than xd, swap xd and yd so xd points to the longer array. - if (len - i < 0) { - i = len; - d = yd; - yd = xd; - xd = d; - } - - // Only start adding at yd.length - 1 as the further digits of xd can be left as they are. - for (carry = 0; i;) { - carry = (xd[--i] = xd[i] + yd[i] + carry) / BASE | 0; - xd[i] %= BASE; - } - - if (carry) { - xd.unshift(carry); - ++e; - } - - // Remove trailing zeros. - // No need to check for zero, as +x + +y != 0 && -x + -y != 0 - for (len = xd.length; xd[--len] == 0;) xd.pop(); - - y.d = xd; - y.e = e; - - return external ? round(y, pr) : y; -} - - -function checkInt32(i, min, max) { - if (i !== ~~i || i < min || i > max) { - throw Error(invalidArgument + i); - } -} - - -function digitsToString(d) { - var i, k, ws, - indexOfLastWord = d.length - 1, - str = '', - w = d[0]; - - if (indexOfLastWord > 0) { - str += w; - for (i = 1; i < indexOfLastWord; i++) { - ws = d[i] + ''; - k = LOG_BASE - ws.length; - if (k) str += getZeroString(k); - str += ws; - } - - w = d[i]; - ws = w + ''; - k = LOG_BASE - ws.length; - if (k) str += getZeroString(k); - } else if (w === 0) { - return '0'; - } - - // Remove trailing zeros of last w. - for (; w % 10 === 0;) w /= 10; - - return str + w; -} - - -var divide = (function () { - - // Assumes non-zero x and k, and hence non-zero result. - function multiplyInteger(x, k) { - var temp, - carry = 0, - i = x.length; - - for (x = x.slice(); i--;) { - temp = x[i] * k + carry; - x[i] = temp % BASE | 0; - carry = temp / BASE | 0; - } - - if (carry) x.unshift(carry); - - return x; - } - - function compare(a, b, aL, bL) { - var i, r; - - if (aL != bL) { - r = aL > bL ? 1 : -1; - } else { - for (i = r = 0; i < aL; i++) { - if (a[i] != b[i]) { - r = a[i] > b[i] ? 1 : -1; - break; - } - } - } - - return r; - } - - function subtract(a, b, aL) { - var i = 0; - - // Subtract b from a. - for (; aL--;) { - a[aL] -= i; - i = a[aL] < b[aL] ? 1 : 0; - a[aL] = i * BASE + a[aL] - b[aL]; - } - - // Remove leading zeros. - for (; !a[0] && a.length > 1;) a.shift(); - } - - return function (x, y, pr, dp) { - var cmp, e, i, k, prod, prodL, q, qd, rem, remL, rem0, sd, t, xi, xL, yd0, yL, yz, - Ctor = x.constructor, - sign = x.s == y.s ? 1 : -1, - xd = x.d, - yd = y.d; - - // Either 0? - if (!x.s) return new Ctor(x); - if (!y.s) throw Error(decimalError + 'Division by zero'); - - e = x.e - y.e; - yL = yd.length; - xL = xd.length; - q = new Ctor(sign); - qd = q.d = []; - - // Result exponent may be one less than e. - for (i = 0; yd[i] == (xd[i] || 0); ) ++i; - if (yd[i] > (xd[i] || 0)) --e; - - if (pr == null) { - sd = pr = Ctor.precision; - } else if (dp) { - sd = pr + (getBase10Exponent(x) - getBase10Exponent(y)) + 1; - } else { - sd = pr; - } - - if (sd < 0) return new Ctor(0); - - // Convert precision in number of base 10 digits to base 1e7 digits. - sd = sd / LOG_BASE + 2 | 0; - i = 0; - - // divisor < 1e7 - if (yL == 1) { - k = 0; - yd = yd[0]; - sd++; - - // k is the carry. - for (; (i < xL || k) && sd--; i++) { - t = k * BASE + (xd[i] || 0); - qd[i] = t / yd | 0; - k = t % yd | 0; - } - - // divisor >= 1e7 - } else { - - // Normalise xd and yd so highest order digit of yd is >= BASE/2 - k = BASE / (yd[0] + 1) | 0; - - if (k > 1) { - yd = multiplyInteger(yd, k); - xd = multiplyInteger(xd, k); - yL = yd.length; - xL = xd.length; - } - - xi = yL; - rem = xd.slice(0, yL); - remL = rem.length; - - // Add zeros to make remainder as long as divisor. - for (; remL < yL;) rem[remL++] = 0; - - yz = yd.slice(); - yz.unshift(0); - yd0 = yd[0]; - - if (yd[1] >= BASE / 2) ++yd0; - - do { - k = 0; - - // Compare divisor and remainder. - cmp = compare(yd, rem, yL, remL); - - // If divisor < remainder. - if (cmp < 0) { - - // Calculate trial digit, k. - rem0 = rem[0]; - if (yL != remL) rem0 = rem0 * BASE + (rem[1] || 0); - - // k will be how many times the divisor goes into the current remainder. - k = rem0 / yd0 | 0; - - // Algorithm: - // 1. product = divisor * trial digit (k) - // 2. if product > remainder: product -= divisor, k-- - // 3. remainder -= product - // 4. if product was < remainder at 2: - // 5. compare new remainder and divisor - // 6. If remainder > divisor: remainder -= divisor, k++ - - if (k > 1) { - if (k >= BASE) k = BASE - 1; - - // product = divisor * trial digit. - prod = multiplyInteger(yd, k); - prodL = prod.length; - remL = rem.length; - - // Compare product and remainder. - cmp = compare(prod, rem, prodL, remL); - - // product > remainder. - if (cmp == 1) { - k--; - - // Subtract divisor from product. - subtract(prod, yL < prodL ? yz : yd, prodL); - } - } else { - - // cmp is -1. - // If k is 0, there is no need to compare yd and rem again below, so change cmp to 1 - // to avoid it. If k is 1 there is a need to compare yd and rem again below. - if (k == 0) cmp = k = 1; - prod = yd.slice(); - } - - prodL = prod.length; - if (prodL < remL) prod.unshift(0); - - // Subtract product from remainder. - subtract(rem, prod, remL); - - // If product was < previous remainder. - if (cmp == -1) { - remL = rem.length; - - // Compare divisor and new remainder. - cmp = compare(yd, rem, yL, remL); - - // If divisor < new remainder, subtract divisor from remainder. - if (cmp < 1) { - k++; - - // Subtract divisor from remainder. - subtract(rem, yL < remL ? yz : yd, remL); - } - } - - remL = rem.length; - } else if (cmp === 0) { - k++; - rem = [0]; - } // if cmp === 1, k will be 0 - - // Add the next digit, k, to the result array. - qd[i++] = k; - - // Update the remainder. - if (cmp && rem[0]) { - rem[remL++] = xd[xi] || 0; - } else { - rem = [xd[xi]]; - remL = 1; - } - - } while ((xi++ < xL || rem[0] !== void 0) && sd--); - } - - // Leading zero? - if (!qd[0]) qd.shift(); - - q.e = e; - - return round(q, dp ? pr + getBase10Exponent(q) + 1 : pr); - }; -})(); - - -/* - * Return a new Decimal whose value is the natural exponential of `x` truncated to `sd` - * significant digits. - * - * Taylor/Maclaurin series. - * - * exp(x) = x^0/0! + x^1/1! + x^2/2! + x^3/3! + ... - * - * Argument reduction: - * Repeat x = x / 32, k += 5, until |x| < 0.1 - * exp(x) = exp(x / 2^k)^(2^k) - * - * Previously, the argument was initially reduced by - * exp(x) = exp(r) * 10^k where r = x - k * ln10, k = floor(x / ln10) - * to first put r in the range [0, ln10], before dividing by 32 until |x| < 0.1, but this was - * found to be slower than just dividing repeatedly by 32 as above. - * - * (Math object integer min/max: Math.exp(709) = 8.2e+307, Math.exp(-745) = 5e-324) - * - * exp(x) is non-terminating for any finite, non-zero x. - * - */ -function exp(x, sd) { - var denominator, guard, pow, sum, t, wpr, - i = 0, - k = 0, - Ctor = x.constructor, - pr = Ctor.precision; - - if (getBase10Exponent(x) > 16) throw Error(exponentOutOfRange + getBase10Exponent(x)); - - // exp(0) = 1 - if (!x.s) return new Ctor(ONE); - - if (sd == null) { - external = false; - wpr = pr; - } else { - wpr = sd; - } - - t = new Ctor(0.03125); - - while (x.abs().gte(0.1)) { - x = x.times(t); // x = x / 2^5 - k += 5; - } - - // Estimate the precision increase necessary to ensure the first 4 rounding digits are correct. - guard = Math.log(mathpow(2, k)) / Math.LN10 * 2 + 5 | 0; - wpr += guard; - denominator = pow = sum = new Ctor(ONE); - Ctor.precision = wpr; - - for (;;) { - pow = round(pow.times(x), wpr); - denominator = denominator.times(++i); - t = sum.plus(divide(pow, denominator, wpr)); - - if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) { - while (k--) sum = round(sum.times(sum), wpr); - Ctor.precision = pr; - return sd == null ? (external = true, round(sum, pr)) : sum; - } - - sum = t; - } -} - - -// Calculate the base 10 exponent from the base 1e7 exponent. -function getBase10Exponent(x) { - var e = x.e * LOG_BASE, - w = x.d[0]; - - // Add the number of digits of the first word of the digits array. - for (; w >= 10; w /= 10) e++; - return e; -} - - -function getLn10(Ctor, sd, pr) { - - if (sd > Ctor.LN10.sd()) { - - - // Reset global state in case the exception is caught. - external = true; - if (pr) Ctor.precision = pr; - throw Error(decimalError + 'LN10 precision limit exceeded'); - } - - return round(new Ctor(Ctor.LN10), sd); -} - - -function getZeroString(k) { - var zs = ''; - for (; k--;) zs += '0'; - return zs; -} - - -/* - * Return a new Decimal whose value is the natural logarithm of `x` truncated to `sd` significant - * digits. - * - * ln(n) is non-terminating (n != 1) - * - */ -function ln(y, sd) { - var c, c0, denominator, e, numerator, sum, t, wpr, x2, - n = 1, - guard = 10, - x = y, - xd = x.d, - Ctor = x.constructor, - pr = Ctor.precision; - - // ln(-x) = NaN - // ln(0) = -Infinity - if (x.s < 1) throw Error(decimalError + (x.s ? 'NaN' : '-Infinity')); - - // ln(1) = 0 - if (x.eq(ONE)) return new Ctor(0); - - if (sd == null) { - external = false; - wpr = pr; - } else { - wpr = sd; - } - - if (x.eq(10)) { - if (sd == null) external = true; - return getLn10(Ctor, wpr); - } - - wpr += guard; - Ctor.precision = wpr; - c = digitsToString(xd); - c0 = c.charAt(0); - e = getBase10Exponent(x); - - if (Math.abs(e) < 1.5e15) { - - // Argument reduction. - // The series converges faster the closer the argument is to 1, so using - // ln(a^b) = b * ln(a), ln(a) = ln(a^b) / b - // multiply the argument by itself until the leading digits of the significand are 7, 8, 9, - // 10, 11, 12 or 13, recording the number of multiplications so the sum of the series can - // later be divided by this number, then separate out the power of 10 using - // ln(a*10^b) = ln(a) + b*ln(10). - - // max n is 21 (gives 0.9, 1.0 or 1.1) (9e15 / 21 = 4.2e14). - //while (c0 < 9 && c0 != 1 || c0 == 1 && c.charAt(1) > 1) { - // max n is 6 (gives 0.7 - 1.3) - while (c0 < 7 && c0 != 1 || c0 == 1 && c.charAt(1) > 3) { - x = x.times(y); - c = digitsToString(x.d); - c0 = c.charAt(0); - n++; - } - - e = getBase10Exponent(x); - - if (c0 > 1) { - x = new Ctor('0.' + c); - e++; - } else { - x = new Ctor(c0 + '.' + c.slice(1)); - } - } else { - - // The argument reduction method above may result in overflow if the argument y is a massive - // number with exponent >= 1500000000000000 (9e15 / 6 = 1.5e15), so instead recall this - // function using ln(x*10^e) = ln(x) + e*ln(10). - t = getLn10(Ctor, wpr + 2, pr).times(e + ''); - x = ln(new Ctor(c0 + '.' + c.slice(1)), wpr - guard).plus(t); - - Ctor.precision = pr; - return sd == null ? (external = true, round(x, pr)) : x; - } - - // x is reduced to a value near 1. - - // Taylor series. - // ln(y) = ln((1 + x)/(1 - x)) = 2(x + x^3/3 + x^5/5 + x^7/7 + ...) - // where x = (y - 1)/(y + 1) (|x| < 1) - sum = numerator = x = divide(x.minus(ONE), x.plus(ONE), wpr); - x2 = round(x.times(x), wpr); - denominator = 3; - - for (;;) { - numerator = round(numerator.times(x2), wpr); - t = sum.plus(divide(numerator, new Ctor(denominator), wpr)); - - if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) { - sum = sum.times(2); - - // Reverse the argument reduction. - if (e !== 0) sum = sum.plus(getLn10(Ctor, wpr + 2, pr).times(e + '')); - sum = divide(sum, new Ctor(n), wpr); - - Ctor.precision = pr; - return sd == null ? (external = true, round(sum, pr)) : sum; - } - - sum = t; - denominator += 2; - } -} - - -/* - * Parse the value of a new Decimal `x` from string `str`. - */ -function parseDecimal(x, str) { - var e, i, len; - - // Decimal point? - if ((e = str.indexOf('.')) > -1) str = str.replace('.', ''); - - // Exponential form? - if ((i = str.search(/e/i)) > 0) { - - // Determine exponent. - if (e < 0) e = i; - e += +str.slice(i + 1); - str = str.substring(0, i); - } else if (e < 0) { - - // Integer. - e = str.length; - } - - // Determine leading zeros. - for (i = 0; str.charCodeAt(i) === 48;) ++i; - - // Determine trailing zeros. - for (len = str.length; str.charCodeAt(len - 1) === 48;) --len; - str = str.slice(i, len); - - if (str) { - len -= i; - e = e - i - 1; - x.e = mathfloor(e / LOG_BASE); - x.d = []; - - // Transform base - - // e is the base 10 exponent. - // i is where to slice str to get the first word of the digits array. - i = (e + 1) % LOG_BASE; - if (e < 0) i += LOG_BASE; - - if (i < len) { - if (i) x.d.push(+str.slice(0, i)); - for (len -= LOG_BASE; i < len;) x.d.push(+str.slice(i, i += LOG_BASE)); - str = str.slice(i); - i = LOG_BASE - str.length; - } else { - i -= len; - } - - for (; i--;) str += '0'; - x.d.push(+str); - - if (external && (x.e > MAX_E || x.e < -MAX_E)) throw Error(exponentOutOfRange + e); - } else { - - // Zero. - x.s = 0; - x.e = 0; - x.d = [0]; - } - - return x; -} - - -/* - * Round `x` to `sd` significant digits, using rounding mode `rm` if present (truncate otherwise). - */ - function round(x, sd, rm) { - var i, j, k, n, rd, doRound, w, xdi, - xd = x.d; - - // rd: the rounding digit, i.e. the digit after the digit that may be rounded up. - // w: the word of xd which contains the rounding digit, a base 1e7 number. - // xdi: the index of w within xd. - // n: the number of digits of w. - // i: what would be the index of rd within w if all the numbers were 7 digits long (i.e. if - // they had leading zeros) - // j: if > 0, the actual index of rd within w (if < 0, rd is a leading zero). - - // Get the length of the first word of the digits array xd. - for (n = 1, k = xd[0]; k >= 10; k /= 10) n++; - i = sd - n; - - // Is the rounding digit in the first word of xd? - if (i < 0) { - i += LOG_BASE; - j = sd; - w = xd[xdi = 0]; - } else { - xdi = Math.ceil((i + 1) / LOG_BASE); - k = xd.length; - if (xdi >= k) return x; - w = k = xd[xdi]; - - // Get the number of digits of w. - for (n = 1; k >= 10; k /= 10) n++; - - // Get the index of rd within w. - i %= LOG_BASE; - - // Get the index of rd within w, adjusted for leading zeros. - // The number of leading zeros of w is given by LOG_BASE - n. - j = i - LOG_BASE + n; - } - - if (rm !== void 0) { - k = mathpow(10, n - j - 1); - - // Get the rounding digit at index j of w. - rd = w / k % 10 | 0; - - // Are there any non-zero digits after the rounding digit? - doRound = sd < 0 || xd[xdi + 1] !== void 0 || w % k; - - // The expression `w % mathpow(10, n - j - 1)` returns all the digits of w to the right of the - // digit at (left-to-right) index j, e.g. if w is 908714 and j is 2, the expression will give - // 714. - - doRound = rm < 4 - ? (rd || doRound) && (rm == 0 || rm == (x.s < 0 ? 3 : 2)) - : rd > 5 || rd == 5 && (rm == 4 || doRound || rm == 6 && - - // Check whether the digit to the left of the rounding digit is odd. - ((i > 0 ? j > 0 ? w / mathpow(10, n - j) : 0 : xd[xdi - 1]) % 10) & 1 || - rm == (x.s < 0 ? 8 : 7)); - } - - if (sd < 1 || !xd[0]) { - if (doRound) { - k = getBase10Exponent(x); - xd.length = 1; - - // Convert sd to decimal places. - sd = sd - k - 1; - - // 1, 0.1, 0.01, 0.001, 0.0001 etc. - xd[0] = mathpow(10, (LOG_BASE - sd % LOG_BASE) % LOG_BASE); - x.e = mathfloor(-sd / LOG_BASE) || 0; - } else { - xd.length = 1; - - // Zero. - xd[0] = x.e = x.s = 0; - } - - return x; - } - - // Remove excess digits. - if (i == 0) { - xd.length = xdi; - k = 1; - xdi--; - } else { - xd.length = xdi + 1; - k = mathpow(10, LOG_BASE - i); - - // E.g. 56700 becomes 56000 if 7 is the rounding digit. - // j > 0 means i > number of leading zeros of w. - xd[xdi] = j > 0 ? (w / mathpow(10, n - j) % mathpow(10, j) | 0) * k : 0; - } - - if (doRound) { - for (;;) { - - // Is the digit to be rounded up in the first word of xd? - if (xdi == 0) { - if ((xd[0] += k) == BASE) { - xd[0] = 1; - ++x.e; - } - - break; - } else { - xd[xdi] += k; - if (xd[xdi] != BASE) break; - xd[xdi--] = 0; - k = 1; - } - } - } - - // Remove trailing zeros. - for (i = xd.length; xd[--i] === 0;) xd.pop(); - - if (external && (x.e > MAX_E || x.e < -MAX_E)) { - throw Error(exponentOutOfRange + getBase10Exponent(x)); - } - - return x; -} - - -function subtract(x, y) { - var d, e, i, j, k, len, xd, xe, xLTy, yd, - Ctor = x.constructor, - pr = Ctor.precision; - - // Return y negated if x is zero. - // Return x if y is zero and x is non-zero. - if (!x.s || !y.s) { - if (y.s) y.s = -y.s; - else y = new Ctor(x); - return external ? round(y, pr) : y; - } - - xd = x.d; - yd = y.d; - - // x and y are non-zero numbers with the same sign. - - e = y.e; - xe = x.e; - xd = xd.slice(); - k = xe - e; - - // If exponents differ... - if (k) { - xLTy = k < 0; - - if (xLTy) { - d = xd; - k = -k; - len = yd.length; - } else { - d = yd; - e = xe; - len = xd.length; - } - - // Numbers with massively different exponents would result in a very high number of zeros - // needing to be prepended, but this can be avoided while still ensuring correct rounding by - // limiting the number of zeros to `Math.ceil(pr / LOG_BASE) + 2`. - i = Math.max(Math.ceil(pr / LOG_BASE), len) + 2; - - if (k > i) { - k = i; - d.length = 1; - } - - // Prepend zeros to equalise exponents. - d.reverse(); - for (i = k; i--;) d.push(0); - d.reverse(); - - // Base 1e7 exponents equal. - } else { - - // Check digits to determine which is the bigger number. - - i = xd.length; - len = yd.length; - xLTy = i < len; - if (xLTy) len = i; - - for (i = 0; i < len; i++) { - if (xd[i] != yd[i]) { - xLTy = xd[i] < yd[i]; - break; - } - } - - k = 0; - } - - if (xLTy) { - d = xd; - xd = yd; - yd = d; - y.s = -y.s; - } - - len = xd.length; - - // Append zeros to xd if shorter. - // Don't add zeros to yd if shorter as subtraction only needs to start at yd length. - for (i = yd.length - len; i > 0; --i) xd[len++] = 0; - - // Subtract yd from xd. - for (i = yd.length; i > k;) { - if (xd[--i] < yd[i]) { - for (j = i; j && xd[--j] === 0;) xd[j] = BASE - 1; - --xd[j]; - xd[i] += BASE; - } - - xd[i] -= yd[i]; - } - - // Remove trailing zeros. - for (; xd[--len] === 0;) xd.pop(); - - // Remove leading zeros and adjust exponent accordingly. - for (; xd[0] === 0; xd.shift()) --e; - - // Zero? - if (!xd[0]) return new Ctor(0); - - y.d = xd; - y.e = e; - - //return external && xd.length >= pr / LOG_BASE ? round(y, pr) : y; - return external ? round(y, pr) : y; -} - - -function toString$3(x, isExp, sd) { - var k, - e = getBase10Exponent(x), - str = digitsToString(x.d), - len = str.length; - - if (isExp) { - if (sd && (k = sd - len) > 0) { - str = str.charAt(0) + '.' + str.slice(1) + getZeroString(k); - } else if (len > 1) { - str = str.charAt(0) + '.' + str.slice(1); - } - - str = str + (e < 0 ? 'e' : 'e+') + e; - } else if (e < 0) { - str = '0.' + getZeroString(-e - 1) + str; - if (sd && (k = sd - len) > 0) str += getZeroString(k); - } else if (e >= len) { - str += getZeroString(e + 1 - len); - if (sd && (k = sd - e - 1) > 0) str = str + '.' + getZeroString(k); - } else { - if ((k = e + 1) < len) str = str.slice(0, k) + '.' + str.slice(k); - if (sd && (k = sd - len) > 0) { - if (e + 1 === len) str += '.'; - str += getZeroString(k); - } - } - - return x.s < 0 ? '-' + str : str; -} - - -// Does not strip trailing zeros. -function truncate(arr, len) { - if (arr.length > len) { - arr.length = len; - return true; - } -} - - -// Decimal methods - - -/* - * clone - * config/set - */ - - -/* - * Create and return a Decimal constructor with the same configuration properties as this Decimal - * constructor. - * - */ -function clone(obj) { - var i, p, ps; - - /* - * The Decimal constructor and exported function. - * Return a new Decimal instance. - * - * value {number|string|Decimal} A numeric value. - * - */ - function Decimal(value) { - var x = this; - - // Decimal called without new. - if (!(x instanceof Decimal)) return new Decimal(value); - - // Retain a reference to this Decimal constructor, and shadow Decimal.prototype.constructor - // which points to Object. - x.constructor = Decimal; - - // Duplicate. - if (value instanceof Decimal) { - x.s = value.s; - x.e = value.e; - x.d = (value = value.d) ? value.slice() : value; - return; - } - - if (typeof value === 'number') { - - // Reject Infinity/NaN. - if (value * 0 !== 0) { - throw Error(invalidArgument + value); - } - - if (value > 0) { - x.s = 1; - } else if (value < 0) { - value = -value; - x.s = -1; - } else { - x.s = 0; - x.e = 0; - x.d = [0]; - return; - } - - // Fast path for small integers. - if (value === ~~value && value < 1e7) { - x.e = 0; - x.d = [value]; - return; - } - - return parseDecimal(x, value.toString()); - } else if (typeof value !== 'string') { - throw Error(invalidArgument + value); - } - - // Minus sign? - if (value.charCodeAt(0) === 45) { - value = value.slice(1); - x.s = -1; - } else { - x.s = 1; - } - - if (isDecimal.test(value)) parseDecimal(x, value); - else throw Error(invalidArgument + value); - } - - Decimal.prototype = P; - - Decimal.ROUND_UP = 0; - Decimal.ROUND_DOWN = 1; - Decimal.ROUND_CEIL = 2; - Decimal.ROUND_FLOOR = 3; - Decimal.ROUND_HALF_UP = 4; - Decimal.ROUND_HALF_DOWN = 5; - Decimal.ROUND_HALF_EVEN = 6; - Decimal.ROUND_HALF_CEIL = 7; - Decimal.ROUND_HALF_FLOOR = 8; - - Decimal.clone = clone; - Decimal.config = Decimal.set = config; - - if (obj === void 0) obj = {}; - if (obj) { - ps = ['precision', 'rounding', 'toExpNeg', 'toExpPos', 'LN10']; - for (i = 0; i < ps.length;) if (!obj.hasOwnProperty(p = ps[i++])) obj[p] = this[p]; - } - - Decimal.config(obj); - - return Decimal; -} - - -/* - * Configure global settings for a Decimal constructor. - * - * `obj` is an object with one or more of the following properties, - * - * precision {number} - * rounding {number} - * toExpNeg {number} - * toExpPos {number} - * - * E.g. Decimal.config({ precision: 20, rounding: 4 }) - * - */ -function config(obj) { - if (!obj || typeof obj !== 'object') { - throw Error(decimalError + 'Object expected'); - } - var i, p, v, - ps = [ - 'precision', 1, MAX_DIGITS, - 'rounding', 0, 8, - 'toExpNeg', -1 / 0, 0, - 'toExpPos', 0, 1 / 0 - ]; - - for (i = 0; i < ps.length; i += 3) { - if ((v = obj[p = ps[i]]) !== void 0) { - if (mathfloor(v) === v && v >= ps[i + 1] && v <= ps[i + 2]) this[p] = v; - else throw Error(invalidArgument + p + ': ' + v); - } - } - - if ((v = obj[p = 'LN10']) !== void 0) { - if (v == Math.LN10) this[p] = new this(v); - else throw Error(invalidArgument + p + ': ' + v); - } - - return this; -} - - -// Create and configure initial Decimal constructor. -var Decimal = clone(defaults); - -// Internal constant. -ONE = new Decimal(1); - -Decimal.set({ - precision: 30, - toExpNeg: -7, - toExpPos: 29, -}); -var n = new Decimal(60 * 60 * 24 * 365); -var lookup = {}; -/** - * Get interest rate in percentage points for a specified fee. - * This function uses a lookup table for performance reasons. - * This function uses decimal.js-light, since we need non-integer powers for our calculations here. - * We can remove that dependency in the future if we decide to either add a hardcoded - * lookup table for fees and interest rates or if we decide to implement the relevant - * functions here by hand. - * @param fee Fee - */ -var feeToInterestRate = function (fee) { - // tslint:disable-next-line:no-parameter-reassignment - if (typeof fee !== 'string' && typeof fee !== 'number') { - fee = fee.toString(); - } - if (lookup[fee]) { - return lookup[fee]; - } - var i = new Decimal(fee).div('1e27').pow(n); - var interestRate = i.minus(1).mul(100).toSignificantDigits(2); - var interestRateString = interestRate.toString(); - lookup[fee] = interestRateString; - return interestRateString; -}; - -function getLoanStatus(principal, debt) { - if (!principal.isZero()) { - return 'Whitelisted'; - } - if (principal.isZero() && !debt.isZero()) { - return 'Ongoing'; - } - if (principal.isZero() && debt.isZero()) { - return 'Repaid'; - } - throw Error('Unknown loan status'); -} - -Decimal.set({ - precision: 28, - toExpNeg: -7, - toExpPos: 29, -}); -var n$1 = new Decimal(60 * 60 * 24 * 365); -var lookup$1 = {}; -/** - * Get fee for a specified interest rate. This function uses a lookup table for performance reasons. - * This function uses decimal.js-light, since we need non-integer powers for our calculations here. - * We can remove that dependency in the future if we decide to either add a hardcoded - * lookup table for fees and interest rates or if we decide to implement the relevant - * functions here by hand. - * @param interestRate Interest rate in percentage points, i. e. "5" for 5 % (= 0.05) - */ -var interestRateToFee = function (interestRate) { - if (lookup$1[interestRate]) { - return lookup$1[interestRate]; - } - var i = new Decimal(interestRate).div(100).plus(1); - var fee = i.pow(new Decimal(1).div(n$1)).mul('1e27').toDecimalPlaces(0); - var feeString = fee.toString(); - lookup$1[interestRate] = feeString; - return feeString; -}; - -var _this = undefined; -var abiCoder$1 = new AbiCoder$1(); -var pollingInterval = 1000; -var LOAN_ID_IDX = 2; -var Tinlake = /** @class */ (function () { - function Tinlake(provider, contractAddresses, nftDataOutputs, transactionTimeout, _a) { - var _this = this; - var _b = _a === void 0 ? {} : _a, contractAbis = _b.contractAbis, ethOptions = _b.ethOptions, ethConfig = _b.ethConfig; - this.setProvider = function (provider, ethOptions) { - _this.provider = provider; - _this.ethOptions = ethOptions || {}; - _this.eth = new lib$a(_this.provider, _this.ethOptions); - _this.contracts = { - nft: _this.eth.contract(_this.contractAbis.nft) - .at(_this.contractAddresses['NFT_COLLATERAL']), - title: _this.eth.contract(_this.contractAbis.title) - .at(_this.contractAddresses['TITLE']), - currency: _this.eth.contract(_this.contractAbis.currency) - .at(_this.contractAddresses['CURRENCY']), - admit: _this.eth.contract(_this.contractAbis.admit) - .at(_this.contractAddresses['ADMIT']), - reception: _this.eth.contract(_this.contractAbis.reception) - .at(_this.contractAddresses['RECEPTION']), - desk: _this.eth.contract(_this.contractAbis.desk) - .at(_this.contractAddresses['DESK']), - shelf: _this.eth.contract(_this.contractAbis.shelf) - .at(_this.contractAddresses['SHELF']), - appraiser: _this.eth.contract(_this.contractAbis.appraiser) - .at(_this.contractAddresses['APPRAISER']), - lender: _this.eth.contract(_this.contractAbis.lender) - .at(_this.contractAddresses['LENDER']), - collateral: _this.eth.contract(_this.contractAbis.collateral) - .at(_this.contractAddresses['COLLATERAL']), - pile: _this.eth.contract(_this.contractAbis.pile) - .at(_this.contractAddresses['PILE']), - pileForAdd: _this.eth.contract(_this.contractAbis.pileForAdd) - .at(_this.contractAddresses['PILE']), - pileForInit: _this.eth.contract(_this.contractAbis.pileForInit) - .at(_this.contractAddresses['PILE']), - admin: _this.eth.contract(_this.contractAbis.admin) - .at(_this.contractAddresses['ADMIN']), - nftData: _this.eth.contract(_this.contractAbis.nftData) - .at(_this.contractAddresses['NFT_COLLATERAL']), - }; - }; - this.setEthConfig = function (ethConfig) { - _this.ethConfig = ethConfig; - }; - this.isAdmin = function (address) { return __awaiter(_this, void 0, void 0, function () { - var res; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.admin.wards, [address])]; - case 1: - res = _a.sent(); - return [2 /*return*/, !res[0].isZero()]; - } - }); - }); }; - this.loanCount = function () { return __awaiter(_this, void 0, void 0, function () { - var res; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.title.count, [])]; - case 1: - res = _a.sent(); - return [2 /*return*/, res[0]]; - } - }); - }); }; - this.getLoan = function (loanId) { return __awaiter(_this, void 0, void 0, function () { - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.shelf.shelf, [loanId])]; - case 1: return [2 /*return*/, _a.sent()]; - } - }); - }); }; - this.getBalanceDebt = function (loanId) { return __awaiter(_this, void 0, void 0, function () { - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.pile.loans, [loanId])]; - case 1: return [2 /*return*/, _a.sent()]; - } - }); - }); }; - this.approveNFT = function (tokenId, to) { return __awaiter(_this, void 0, void 0, function () { - var txHash; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.nft.approve, [to, tokenId, this.ethConfig])]; - case 1: - txHash = _a.sent(); - console.log("[NFT Approve] txHash: " + txHash); - return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['nft'].abi, this.transactionTimeout)]; - } - }); - }); }; - this.approveCollateral = function (usr, wad) { return __awaiter(_this, void 0, void 0, function () { - var txHash; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.collateral.approve, [usr, wad, this.ethConfig])]; - case 1: - txHash = _a.sent(); - console.log("[Collateral Approve] txHash: " + txHash); - return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['collateral'].abi, this.transactionTimeout)]; - } - }); - }); }; - this.ownerOfNFT = function (tokenId) { return __awaiter(_this, void 0, void 0, function () { - var res; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.nft.ownerOf, [tokenId])]; - case 1: - res = _a.sent(); - return [2 /*return*/, res['0']]; - } - }); - }); }; - this.ownerOfLoan = function (loanId) { return __awaiter(_this, void 0, void 0, function () { - var res; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.title.ownerOf, [loanId])]; - case 1: - res = _a.sent(); - return [2 /*return*/, res['0']]; - } - }); - }); }; - this.balanceOfCurrency = function (usr) { return __awaiter(_this, void 0, void 0, function () { - return __generator(this, function (_a) { - return [2 /*return*/, executeAndRetry(this.contracts.currency.balanceOf, [usr])]; - }); - }); }; - this.mintCurrency = function (usr, wad) { return __awaiter(_this, void 0, void 0, function () { - var txHash; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.currency.mint, [usr, wad, this.ethConfig])]; - case 1: - txHash = _a.sent(); - console.log("[Currency.mint] txHash: " + txHash); - return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['currency'].abi, this.transactionTimeout)]; - } - }); - }); }; - /** - * @param owner Owner of the new NFT - */ - this.mintNFT = function (owner, tokenId) { - var tkn = abiCoder$1.encodeParameter('uint', tokenId); - return _this.contracts.nft.mint(owner, tkn, _this.ethConfig).then(function (txHash) { - console.log("[NFT.mint] txHash: " + txHash); - return waitAndReturnEvents(_this.eth, txHash, _this.contracts['nft'].abi, _this.transactionTimeout); - }); - }; - /** - * @param owner Owner of the created loan - */ - this.adminAdmit = function (registry, nft, principal, owner) { return __awaiter(_this, void 0, void 0, function () { - var txHash; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.admit.admit, [registry, nft, principal, owner, this.ethConfig])]; - case 1: - txHash = _a.sent(); - console.log("[Admit.admit] txHash: " + txHash); - return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['nft'].abi, this.transactionTimeout)]; - } - }); - }); }; - this.adminAppraise = function (loanID, appraisal) { return __awaiter(_this, void 0, void 0, function () { - var txHash; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.appraiser.file, [loanID, appraisal, this.ethConfig])]; - case 1: - txHash = _a.sent(); - console.log("[Appraisal.file] txHash: " + txHash); - return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['nft'].abi, this.transactionTimeout)]; - } - }); - }); }; - this.getAppraisal = function (loanID) { return __awaiter(_this, void 0, void 0, function () { - var res; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.appraiser.value, [loanID])]; - case 1: - res = _a.sent(); - return [2 /*return*/, res['0']]; - } - }); - }); }; - /** - * @param to Address that should receive the currency (e. g. DAI) - */ - this.borrow = function (loanId, to) { return __awaiter(_this, void 0, void 0, function () { - var txHash; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.reception.borrow, [loanId, to, this.ethConfig])]; - case 1: - txHash = _a.sent(); - console.log("[Reception.borrow] txHash: " + txHash); - return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['reception'].abi, this.transactionTimeout)]; - } - }); - }); }; - /** - * @param wad Amount which should be repaid - * @param usr Address that receives the NFT - */ - this.repay = function (loanId, wad, usr) { return __awaiter(_this, void 0, void 0, function () { - var txHash; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.reception.repay, [loanId, wad, usr, this.ethConfig])]; - case 1: - txHash = _a.sent(); - console.log("[Reception.repay] txHash: " + txHash); - return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['reception'].abi, this.transactionTimeout)]; - } - }); - }); }; - /** - * @param wad Amount which should be repaid - * @param usr Address that receives the NFT - */ - this.close = function (loanId, usr) { return __awaiter(_this, void 0, void 0, function () { - var txHash; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.reception.close, [loanId, usr, this.ethConfig])]; - case 1: - txHash = _a.sent(); - console.log("[Reception.close] txHash: " + txHash); - return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['reception'].abi, this.transactionTimeout)]; - } - }); - }); }; - this.approveCurrency = function (usr, wad) { return __awaiter(_this, void 0, void 0, function () { - var txHash; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.currency.approve, [usr, wad, this.ethConfig])]; - case 1: - txHash = _a.sent(); - console.log("[Currency.approve] txHash: " + txHash); - return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['currency'].abi, this.transactionTimeout)]; - } - }); - }); }; - this.lenderRely = function (usr) { return __awaiter(_this, void 0, void 0, function () { - var txHash; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.lender.rely, [usr, this.ethConfig])]; - case 1: - txHash = _a.sent(); - console.log("[Lender.rely] txHash: " + txHash); - return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['lender'].abi, this.transactionTimeout)]; - } - }); - }); }; - this.initFee = function (fee) { return __awaiter(_this, void 0, void 0, function () { - var txHash; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.pileForInit.file, [fee, fee, this.ethConfig])]; - case 1: - txHash = _a.sent(); - console.log("[Pile.file] txHash: " + txHash); - return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts.pileForInit.abi, this.transactionTimeout)]; - } - }); - }); }; - this.existsFee = function (fee) { return __awaiter(_this, void 0, void 0, function () { - var res; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.pile.fees, [fee])]; - case 1: - res = _a.sent(); - return [2 /*return*/, !res.speed.isZero()]; - } - }); - }); }; - this.addFee = function (loanId, fee, balance) { return __awaiter(_this, void 0, void 0, function () { - var txHash; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.pileForAdd.file, [loanId, fee, balance, this.ethConfig])]; - case 1: - txHash = _a.sent(); - console.log("[Pile.file] txHash: " + txHash); - return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts.pileForAdd.abi, this.transactionTimeout)]; - } - }); - }); }; - this.getCurrentDebt = function (loanId) { return __awaiter(_this, void 0, void 0, function () { - var res; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.pile.burden, [loanId])]; - case 1: - res = _a.sent(); - return [2 /*return*/, res['0']]; - } - }); - }); }; - /** - * whitelist is a shortcut contract that calls adminAdmit (admit.admit), - * adminAppraise (appraiser.file) and addFee (pile.file) to prevent additional - * transactions. It is required though that the fee is already initialized - * using initFee - * @param owner Owner of the created loan - */ - this.whitelist = function (registry, nft, principal, appraisal, fee, owner) { return __awaiter(_this, void 0, void 0, function () { - var txHash; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.admin.whitelist, [registry, nft, principal, appraisal, fee, owner, this.ethConfig])]; - case 1: - txHash = _a.sent(); - console.log("[Admin.whitelist] txHash: " + txHash); - return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['nft'].abi, this.transactionTimeout)]; - } - }); - }); }; - this.unwhitelist = function (loanId, registry, nft) { return __awaiter(_this, void 0, void 0, function () { - var txHash; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.shelf.file, [loanId, registry, nft, '0', this.ethConfig])]; - case 1: - txHash = _a.sent(); - console.log("[Shelf.file] txHash: " + txHash); - return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['shelf'].abi, this.transactionTimeout)]; - } - }); - }); }; - this.getTotalDebt = function () { return __awaiter(_this, void 0, void 0, function () { - var res; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.pile.Debt, [])]; - case 1: - res = _a.sent(); - return [2 /*return*/, res['0']]; - } - }); - }); }; - this.getTotalBalance = function () { return __awaiter(_this, void 0, void 0, function () { - var res; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.pile.Balance, [])]; - case 1: - res = _a.sent(); - return [2 /*return*/, res['0']]; - } - }); - }); }; - this.getTotalValueOfNFTs = function () { return __awaiter(_this, void 0, void 0, function () { - var res; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.collateral.totalSupply, [])]; - case 1: - res = _a.sent(); - return [2 /*return*/, res['0']]; - } - }); - }); }; - this.getNFTData = function (tokenId) { return __awaiter(_this, void 0, void 0, function () { - var res; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, executeAndRetry(this.contracts.nftData.data, [tokenId])]; - case 1: - res = _a.sent(); - return [2 /*return*/, res]; - } - }); - }); }; - this.contractAbis = contractAbis || { - nft: contractAbiNft, - title: contractAbiTitle, - currency: contractAbiCurrency, - admit: contractAbiAdmit, - reception: contractAbiReception, - desk: contractAbiDesk, - shelf: contractAbiShelf, - appraiser: contractAbiAppraiser, - lender: contractAbiLender, - collateral: contractAbiCollateral, - pile: contractAbiPile, - pileForAdd: contractAbiPileForAdd, - pileForInit: contractAbiPileForInit, - admin: contractAbiAdmin, - nftData: [{ - constant: true, - inputs: [ - { - name: '', - type: 'uint256', - }, - ], - name: 'data', - outputs: nftDataOutputs, - payable: false, - stateMutability: 'view', - type: 'function', - }], - }; - this.contractAddresses = contractAddresses; - this.transactionTimeout = transactionTimeout; - this.setProvider(provider, ethOptions); - this.setEthConfig(ethConfig || {}); - } - return Tinlake; -}()); -function executeAndRetry(f, args) { - if (args === void 0) { args = []; } - return __awaiter(this, void 0, void 0, function () { - var result, e_1; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - _a.trys.push([0, 2, , 3]); - return [4 /*yield*/, f.apply(void 0, args)]; - case 1: - result = _a.sent(); - return [2 /*return*/, result]; - case 2: - e_1 = _a.sent(); - // using error message, since error code -32603 is not unique enough - // todo introduce retry limit - if (e_1 && e_1.message && (e_1.message.indexOf("Cannot read property 'number' of null") !== -1 || - e_1.message.indexOf('error with payload') !== -1)) { - console.log("internal RPC error detected, retry triggered...", e_1); - throw (new Error("Internal RPC Error. Please try again.")); - // await sleep(1000); - // return executeAndRetry(f, args); - } - else { - throw (e_1); - } - return [3 /*break*/, 3]; - case 3: return [2 /*return*/]; - } - }); - }); -} -var waitAndReturnEvents = function (eth, txHash, abi, transactionTimeout) { return __awaiter(_this, void 0, void 0, function () { - var tx; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, waitForTransaction(eth, txHash, transactionTimeout)]; - case 1: - tx = _a.sent(); - return [2 /*return*/, new Promise(function (resolve, reject) { - eth.getTransactionReceipt(tx.hash, function (err, receipt) { - if (err != null) { - reject('failed to get receipt'); - } - var events = getEvents(receipt, abi); - resolve({ events: events, txHash: tx.hash, status: receipt.status }); - }); - })]; - } - }); -}); }; -// todo replace with a better polling -var waitForTransaction = function (eth, txHash, transactionTimeout) { - return new Promise(function (resolve, reject) { - var secMax = transactionTimeout; - var sec = 0; - var wait = function (txHash) { - setTimeout(function () { - eth.getTransactionByHash(txHash, function (err, tx) { - if (err) { - reject(err); - return; - } - if (tx && tx.blockHash != null) { - resolve(tx); - return; - } - console.log("waiting for tx :" + txHash); - sec = sec + 1; - if (sec < secMax) { - wait(txHash); - } - else { - reject(new Error("waiting for transaction tx " + txHash + " timed out after " + secMax + " seconds")); - } - }); - }, pollingInterval); - }; - wait(txHash); - }); -}; -var findEvent = function (abi, funcSignature) { - return abi.filter(function (item) { - if (item.type !== 'event') - return false; - var signature = item.name + "(" + item.inputs.map(function (input) { return input.type; }).join(',') + ")"; - var hash = src_11(signature); - if (hash === funcSignature) - return true; - }); -}; -var getEvents = function (receipt, abi) { - if (receipt.logs.length === 0) { - return null; - } - var events = []; - receipt.logs.forEach(function (log) { - var funcSignature = log.topics[0]; - var matches = findEvent(abi, funcSignature); - if (matches.length === 1) { - var event = matches[0]; - var inputs = event.inputs.filter(function (input) { return input.indexed; }) - .map(function (input) { return input.type; }); - // remove 0x prefix from topics - var topics = log.topics.map(function (t) { - return t.replace('0x', ''); - }); - // concat topics without first topic (func signature) - var bytes = "0x" + topics.slice(1).join(''); - var data = abiCoder$1.decodeParameters(inputs, bytes); - events.push({ event: event, data: data }); - } - }); - return events; +var _this = undefined; +var abiCoder$1 = new AbiCoder$1(); +var pollingInterval = 1000; +var LOAN_ID_IDX = 2; +var Tinlake = /** @class */ (function () { + function Tinlake(provider, contractAddresses, nftDataOutputs, transactionTimeout, _a) { + var _this = this; + var _b = _a === void 0 ? {} : _a, contractAbis = _b.contractAbis, ethOptions = _b.ethOptions, ethConfig = _b.ethConfig; + this.setProvider = function (provider, ethOptions) { + _this.provider = provider; + _this.ethOptions = ethOptions || {}; + _this.eth = new lib$a(_this.provider, _this.ethOptions); + _this.contracts = { + nft: _this.eth.contract(_this.contractAbis.nft) + .at(_this.contractAddresses['NFT_COLLATERAL']), + title: _this.eth.contract(_this.contractAbis.title) + .at(_this.contractAddresses['TITLE']), + currency: _this.eth.contract(_this.contractAbis.currency) + .at(_this.contractAddresses['CURRENCY']), + admit: _this.eth.contract(_this.contractAbis.admit) + .at(_this.contractAddresses['ADMIT']), + reception: _this.eth.contract(_this.contractAbis.reception) + .at(_this.contractAddresses['RECEPTION']), + desk: _this.eth.contract(_this.contractAbis.desk) + .at(_this.contractAddresses['DESK']), + shelf: _this.eth.contract(_this.contractAbis.shelf) + .at(_this.contractAddresses['SHELF']), + appraiser: _this.eth.contract(_this.contractAbis.appraiser) + .at(_this.contractAddresses['APPRAISER']), + lender: _this.eth.contract(_this.contractAbis.lender) + .at(_this.contractAddresses['LENDER']), + collateral: _this.eth.contract(_this.contractAbis.collateral) + .at(_this.contractAddresses['COLLATERAL']), + pile: _this.eth.contract(_this.contractAbis.pile) + .at(_this.contractAddresses['PILE']), + pileForAdd: _this.eth.contract(_this.contractAbis.pileForAdd) + .at(_this.contractAddresses['PILE']), + pileForInit: _this.eth.contract(_this.contractAbis.pileForInit) + .at(_this.contractAddresses['PILE']), + admin: _this.eth.contract(_this.contractAbis.admin) + .at(_this.contractAddresses['ADMIN']), + nftData: _this.eth.contract(_this.contractAbis.nftData) + .at(_this.contractAddresses['NFT_COLLATERAL']), + }; + }; + this.setEthConfig = function (ethConfig) { + _this.ethConfig = ethConfig; + }; + this.isAdmin = function (address) { return __awaiter(_this, void 0, void 0, function () { + var res; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.admin.wards, [address])]; + case 1: + res = _a.sent(); + return [2 /*return*/, !res[0].isZero()]; + } + }); + }); }; + this.loanCount = function () { return __awaiter(_this, void 0, void 0, function () { + var res; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.title.count, [])]; + case 1: + res = _a.sent(); + return [2 /*return*/, res[0]]; + } + }); + }); }; + this.getLoan = function (loanId) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.shelf.shelf, [loanId])]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); }; + this.getBalanceDebt = function (loanId) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.pile.loans, [loanId])]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); }; + this.approveNFT = function (tokenId, to) { return __awaiter(_this, void 0, void 0, function () { + var txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.nft.approve, [to, tokenId, this.ethConfig])]; + case 1: + txHash = _a.sent(); + console.log("[NFT Approve] txHash: " + txHash); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['nft'].abi, this.transactionTimeout)]; + } + }); + }); }; + this.approveCollateral = function (usr, wad) { return __awaiter(_this, void 0, void 0, function () { + var txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.collateral.approve, [usr, wad, this.ethConfig])]; + case 1: + txHash = _a.sent(); + console.log("[Collateral Approve] txHash: " + txHash); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['collateral'].abi, this.transactionTimeout)]; + } + }); + }); }; + this.ownerOfNFT = function (tokenId) { return __awaiter(_this, void 0, void 0, function () { + var res; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.nft.ownerOf, [tokenId])]; + case 1: + res = _a.sent(); + return [2 /*return*/, res['0']]; + } + }); + }); }; + this.ownerOfLoan = function (loanId) { return __awaiter(_this, void 0, void 0, function () { + var res; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.title.ownerOf, [loanId])]; + case 1: + res = _a.sent(); + return [2 /*return*/, res['0']]; + } + }); + }); }; + this.balanceOfCurrency = function (usr) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, executeAndRetry(this.contracts.currency.balanceOf, [usr])]; + }); + }); }; + this.mintCurrency = function (usr, wad) { return __awaiter(_this, void 0, void 0, function () { + var txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.currency.mint, [usr, wad, this.ethConfig])]; + case 1: + txHash = _a.sent(); + console.log("[Currency.mint] txHash: " + txHash); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['currency'].abi, this.transactionTimeout)]; + } + }); + }); }; + /** + * @param owner Owner of the new NFT + */ + this.mintNFT = function (owner, tokenId) { return __awaiter(_this, void 0, void 0, function () { + var tkn, txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + tkn = abiCoder$1.encodeParameter('uint', tokenId); + return [4 /*yield*/, this.contracts.nft.mint(owner, tkn, this.ethConfig)]; + case 1: + txHash = _a.sent(); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['nft'].abi, this.transactionTimeout)]; + } + }); + }); }; + /** + * @param owner Owner of the created loan + */ + this.adminAdmit = function (registry, nft, principal, owner) { return __awaiter(_this, void 0, void 0, function () { + var txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.admit.admit, [registry, nft, principal, owner, this.ethConfig])]; + case 1: + txHash = _a.sent(); + console.log("[Admit.admit] txHash: " + txHash); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['nft'].abi, this.transactionTimeout)]; + } + }); + }); }; + this.adminAppraise = function (loanID, appraisal) { return __awaiter(_this, void 0, void 0, function () { + var txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.appraiser.file, [loanID, appraisal, this.ethConfig])]; + case 1: + txHash = _a.sent(); + console.log("[Appraisal.file] txHash: " + txHash); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['nft'].abi, this.transactionTimeout)]; + } + }); + }); }; + this.getAppraisal = function (loanID) { return __awaiter(_this, void 0, void 0, function () { + var res; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.appraiser.value, [loanID])]; + case 1: + res = _a.sent(); + return [2 /*return*/, res['0']]; + } + }); + }); }; + /** + * @param to Address that should receive the currency (e. g. DAI) + */ + this.borrow = function (loanId, to) { return __awaiter(_this, void 0, void 0, function () { + var txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.reception.borrow, [loanId, to, this.ethConfig])]; + case 1: + txHash = _a.sent(); + console.log("[Reception.borrow] txHash: " + txHash); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['reception'].abi, this.transactionTimeout)]; + } + }); + }); }; + /** + * @param wad Amount which should be repaid + * @param usr Address that receives the NFT + */ + this.repay = function (loanId, wad, usr) { return __awaiter(_this, void 0, void 0, function () { + var txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.reception.repay, [loanId, wad, usr, this.ethConfig])]; + case 1: + txHash = _a.sent(); + console.log("[Reception.repay] txHash: " + txHash); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['reception'].abi, this.transactionTimeout)]; + } + }); + }); }; + /** + * @param wad Amount which should be repaid + * @param usr Address that receives the NFT + */ + this.close = function (loanId, usr) { return __awaiter(_this, void 0, void 0, function () { + var txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.reception.close, [loanId, usr, this.ethConfig])]; + case 1: + txHash = _a.sent(); + console.log("[Reception.close] txHash: " + txHash); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['reception'].abi, this.transactionTimeout)]; + } + }); + }); }; + this.approveCurrency = function (usr, wad) { return __awaiter(_this, void 0, void 0, function () { + var txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.currency.approve, [usr, wad, this.ethConfig])]; + case 1: + txHash = _a.sent(); + console.log("[Currency.approve] txHash: " + txHash); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['currency'].abi, this.transactionTimeout)]; + } + }); + }); }; + this.lenderRely = function (usr) { return __awaiter(_this, void 0, void 0, function () { + var txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.lender.rely, [usr, this.ethConfig])]; + case 1: + txHash = _a.sent(); + console.log("[Lender.rely] txHash: " + txHash); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['lender'].abi, this.transactionTimeout)]; + } + }); + }); }; + this.initFee = function (fee) { return __awaiter(_this, void 0, void 0, function () { + var txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.pileForInit.file, [fee, fee, this.ethConfig])]; + case 1: + txHash = _a.sent(); + console.log("[Pile.file] txHash: " + txHash); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts.pileForInit.abi, this.transactionTimeout)]; + } + }); + }); }; + this.existsFee = function (fee) { return __awaiter(_this, void 0, void 0, function () { + var res; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.pile.fees, [fee])]; + case 1: + res = _a.sent(); + return [2 /*return*/, !res.speed.isZero()]; + } + }); + }); }; + this.addFee = function (loanId, fee, balance) { return __awaiter(_this, void 0, void 0, function () { + var txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.pileForAdd.file, [loanId, fee, balance, this.ethConfig])]; + case 1: + txHash = _a.sent(); + console.log("[Pile.file] txHash: " + txHash); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts.pileForAdd.abi, this.transactionTimeout)]; + } + }); + }); }; + this.getCurrentDebt = function (loanId) { return __awaiter(_this, void 0, void 0, function () { + var res; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.pile.burden, [loanId])]; + case 1: + res = _a.sent(); + return [2 /*return*/, res['0']]; + } + }); + }); }; + /** + * whitelist is a shortcut contract that calls adminAdmit (admit.admit), + * adminAppraise (appraiser.file) and addFee (pile.file) to prevent additional + * transactions. It is required though that the fee is already initialized + * using initFee + * @param owner Owner of the created loan + */ + this.whitelist = function (registry, nft, principal, appraisal, fee, owner) { return __awaiter(_this, void 0, void 0, function () { + var txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.admin.whitelist, [registry, nft, principal, appraisal, fee, owner, this.ethConfig])]; + case 1: + txHash = _a.sent(); + console.log("[Admin.whitelist] txHash: " + txHash); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['nft'].abi, this.transactionTimeout)]; + } + }); + }); }; + this.unwhitelist = function (loanId, registry, nft) { return __awaiter(_this, void 0, void 0, function () { + var txHash; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.shelf.file, [loanId, registry, nft, '0', this.ethConfig])]; + case 1: + txHash = _a.sent(); + console.log("[Shelf.file] txHash: " + txHash); + return [2 /*return*/, waitAndReturnEvents(this.eth, txHash, this.contracts['shelf'].abi, this.transactionTimeout)]; + } + }); + }); }; + this.getTotalDebt = function () { return __awaiter(_this, void 0, void 0, function () { + var res; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.pile.Debt, [])]; + case 1: + res = _a.sent(); + return [2 /*return*/, res['0']]; + } + }); + }); }; + this.getTotalBalance = function () { return __awaiter(_this, void 0, void 0, function () { + var res; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.pile.Balance, [])]; + case 1: + res = _a.sent(); + return [2 /*return*/, res['0']]; + } + }); + }); }; + this.getTotalValueOfNFTs = function () { return __awaiter(_this, void 0, void 0, function () { + var res; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.collateral.totalSupply, [])]; + case 1: + res = _a.sent(); + return [2 /*return*/, res['0']]; + } + }); + }); }; + this.getNFTData = function (tokenId) { return __awaiter(_this, void 0, void 0, function () { + var res; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, executeAndRetry(this.contracts.nftData.data, [tokenId])]; + case 1: + res = _a.sent(); + return [2 /*return*/, res]; + } + }); + }); }; + this.contractAbis = contractAbis || { + nft: contractAbiNft, + title: contractAbiTitle, + currency: contractAbiCurrency, + admit: contractAbiAdmit, + reception: contractAbiReception, + desk: contractAbiDesk, + shelf: contractAbiShelf, + appraiser: contractAbiAppraiser, + lender: contractAbiLender, + collateral: contractAbiCollateral, + pile: contractAbiPile, + pileForAdd: contractAbiPileForAdd, + pileForInit: contractAbiPileForInit, + admin: contractAbiAdmin, + nftData: [{ + constant: true, + inputs: [ + { + name: '', + type: 'uint256', + }, + ], + name: 'data', + outputs: nftDataOutputs, + payable: false, + stateMutability: 'view', + type: 'function', + }], + }; + this.contractAddresses = contractAddresses; + this.transactionTimeout = transactionTimeout; + this.setProvider(provider, ethOptions); + this.setEthConfig(ethConfig || {}); + } + return Tinlake; +}()); +function executeAndRetry(f, args) { + if (args === void 0) { args = []; } + return __awaiter(this, void 0, void 0, function () { + var result, e_1; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + _a.trys.push([0, 2, , 3]); + return [4 /*yield*/, f.apply(void 0, args)]; + case 1: + result = _a.sent(); + return [2 /*return*/, result]; + case 2: + e_1 = _a.sent(); + // using error message, since error code -32603 is not unique enough + // todo introduce retry limit + if (e_1 && e_1.message && (e_1.message.indexOf("Cannot read property 'number' of null") !== -1 || + e_1.message.indexOf('error with payload') !== -1)) { + console.log("internal RPC error detected, retry triggered...", e_1); + throw (new Error("Internal RPC Error. Please try again.")); + // await sleep(1000); + // return executeAndRetry(f, args); + } + else { + throw (e_1); + } + return [3 /*break*/, 3]; + case 3: return [2 /*return*/]; + } + }); + }); +} +var waitAndReturnEvents = function (eth, txHash, abi, transactionTimeout) { return __awaiter(_this, void 0, void 0, function () { + var tx; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, waitForTransaction(eth, txHash, transactionTimeout)]; + case 1: + tx = _a.sent(); + return [2 /*return*/, new Promise(function (resolve, reject) { + eth.getTransactionReceipt(tx.hash, function (err, receipt) { + if (err != null) { + reject('failed to get receipt'); + } + var events = getEvents(receipt, abi); + resolve({ events: events, txHash: tx.hash, status: receipt.status }); + }); + })]; + } + }); +}); }; +// todo replace with a better polling +var waitForTransaction = function (eth, txHash, transactionTimeout) { + return new Promise(function (resolve, reject) { + var secMax = transactionTimeout; + var sec = 0; + var wait = function (txHash) { + setTimeout(function () { + eth.getTransactionByHash(txHash, function (err, tx) { + if (err) { + reject(err); + return; + } + if (tx && tx.blockHash != null) { + resolve(tx); + return; + } + console.log("waiting for tx :" + txHash); + sec = sec + 1; + if (sec < secMax) { + wait(txHash); + } + else { + reject(new Error("waiting for transaction tx " + txHash + " timed out after " + secMax + " seconds")); + } + }); + }, pollingInterval); + }; + wait(txHash); + }); +}; +var findEvent = function (abi, funcSignature) { + return abi.filter(function (item) { + if (item.type !== 'event') + return false; + var signature = item.name + "(" + item.inputs.map(function (input) { return input.type; }).join(',') + ")"; + var hash = src_11(signature); + if (hash === funcSignature) + return true; + }); +}; +var getEvents = function (receipt, abi) { + if (receipt.logs.length === 0) { + return null; + } + var events = []; + receipt.logs.forEach(function (log) { + var funcSignature = log.topics[0]; + var matches = findEvent(abi, funcSignature); + if (matches.length === 1) { + var event = matches[0]; + var inputs = event.inputs.filter(function (input) { return input.indexed; }) + .map(function (input) { return input.type; }); + // remove 0x prefix from topics + var topics = log.topics.map(function (t) { + return t.replace('0x', ''); + }); + // concat topics without first topic (func signature) + var bytes = "0x" + topics.slice(1).join(''); + var data = abiCoder$1.decodeParameters(inputs, bytes); + events.push({ event: event, data: data }); + } + }); + return events; }; exports.LOAN_ID_IDX = LOAN_ID_IDX; diff --git a/src/Tinlake.ts b/src/Tinlake.ts index 350c79b..68d020b 100644 --- a/src/Tinlake.ts +++ b/src/Tinlake.ts @@ -269,14 +269,11 @@ export class Tinlake { /** * @param owner Owner of the new NFT */ - mintNFT = (owner: string, tokenId: string): Promise => { + mintNFT = async (owner: string, tokenId: string) => { const tkn = abiCoder.encodeParameter('uint', tokenId) - return this.contracts.nft.mint(owner, tkn, this.ethConfig).then((txHash: string) => { - console.log(`[NFT.mint] txHash: ${txHash}`); - return waitAndReturnEvents(this.eth, txHash, this.contracts['nft'].abi, this.transactionTimeout); - }); + const txHash = await this.contracts.nft.mint(owner, tkn, this.ethConfig); + return waitAndReturnEvents(this.eth, txHash, this.contracts['nft'].abi, this.transactionTimeout); } - /** * @param owner Owner of the created loan */