<html>
  <head>
    <meta
      name="viewport"
      content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
    <title>Nano Currency (RaiBlocks) Paper Wallet Generator</title>
    <script type="application/javascript">
      ;(function (nacl) {
        'use strict'

        // Ported in 2014 by Dmitry Chestnykh and Devi Mandiri.
        // Public domain.
        //
        // Implementation derived from TweetNaCl version 20140427.
        // See for details: http://tweetnacl.cr.yp.to/

        var u64 = function (h, l) {
          this.hi = h | (0 >>> 0)
          this.lo = l | (0 >>> 0)
        }
        var gf = function (init) {
          var i,
            r = new Float64Array(16)
          if (init) for (i = 0; i < init.length; i++) r[i] = init[i]
          return r
        }

        //  Pluggable, initialized in high-level API below.
        var randombytes = function (/* x, n */) {
          throw new Error('no PRNG')
        }

        var _0 = new Uint8Array(16)
        var _9 = new Uint8Array(32)
        _9[0] = 9

        var gf0 = gf(),
          gf1 = gf([1]),
          _121665 = gf([0xdb41, 1]),
          D = gf([
            0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070,
            0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203
          ]),
          D2 = gf([
            0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0,
            0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406
          ]),
          X = gf([
            0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c,
            0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169
          ]),
          Y = gf([
            0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666,
            0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666
          ]),
          I = gf([
            0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43,
            0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83
          ])

        function L32(x, c) {
          return (x << c) | (x >>> (32 - c))
        }

        function ld32(x, i) {
          var u = x[i + 3] & 0xff
          u = (u << 8) | (x[i + 2] & 0xff)
          u = (u << 8) | (x[i + 1] & 0xff)
          return (u << 8) | (x[i + 0] & 0xff)
        }

        function dl64(x, i) {
          var h = (x[i] << 24) | (x[i + 1] << 16) | (x[i + 2] << 8) | x[i + 3]
          var l =
            (x[i + 4] << 24) | (x[i + 5] << 16) | (x[i + 6] << 8) | x[i + 7]
          return new u64(h, l)
        }

        function st32(x, j, u) {
          var i
          for (i = 0; i < 4; i++) {
            x[j + i] = u & 255
            u >>>= 8
          }
        }

        function ts64(x, i, u) {
          x[i] = (u.hi >> 24) & 0xff
          x[i + 1] = (u.hi >> 16) & 0xff
          x[i + 2] = (u.hi >> 8) & 0xff
          x[i + 3] = u.hi & 0xff
          x[i + 4] = (u.lo >> 24) & 0xff
          x[i + 5] = (u.lo >> 16) & 0xff
          x[i + 6] = (u.lo >> 8) & 0xff
          x[i + 7] = u.lo & 0xff
        }

        function vn(x, xi, y, yi, n) {
          var i,
            d = 0
          for (i = 0; i < n; i++) d |= x[xi + i] ^ y[yi + i]
          return (1 & ((d - 1) >>> 8)) - 1
        }

        function crypto_verify_16(x, xi, y, yi) {
          return vn(x, xi, y, yi, 16)
        }

        function crypto_verify_32(x, xi, y, yi) {
          return vn(x, xi, y, yi, 32)
        }

        function core(out, inp, k, c, h) {
          var w = new Uint32Array(16),
            x = new Uint32Array(16),
            y = new Uint32Array(16),
            t = new Uint32Array(4)
          var i, j, m

          for (i = 0; i < 4; i++) {
            x[5 * i] = ld32(c, 4 * i)
            x[1 + i] = ld32(k, 4 * i)
            x[6 + i] = ld32(inp, 4 * i)
            x[11 + i] = ld32(k, 16 + 4 * i)
          }

          for (i = 0; i < 16; i++) y[i] = x[i]

          for (i = 0; i < 20; i++) {
            for (j = 0; j < 4; j++) {
              for (m = 0; m < 4; m++) t[m] = x[(5 * j + 4 * m) % 16]
              t[1] ^= L32((t[0] + t[3]) | 0, 7)
              t[2] ^= L32((t[1] + t[0]) | 0, 9)
              t[3] ^= L32((t[2] + t[1]) | 0, 13)
              t[0] ^= L32((t[3] + t[2]) | 0, 18)
              for (m = 0; m < 4; m++) w[4 * j + ((j + m) % 4)] = t[m]
            }
            for (m = 0; m < 16; m++) x[m] = w[m]
          }

          if (h) {
            for (i = 0; i < 16; i++) x[i] = (x[i] + y[i]) | 0
            for (i = 0; i < 4; i++) {
              x[5 * i] = (x[5 * i] - ld32(c, 4 * i)) | 0
              x[6 + i] = (x[6 + i] - ld32(inp, 4 * i)) | 0
            }
            for (i = 0; i < 4; i++) {
              st32(out, 4 * i, x[5 * i])
              st32(out, 16 + 4 * i, x[6 + i])
            }
          } else {
            for (i = 0; i < 16; i++) st32(out, 4 * i, (x[i] + y[i]) | 0)
          }
        }

        function crypto_core_salsa20(out, inp, k, c) {
          core(out, inp, k, c, false)
          return 0
        }

        function crypto_core_hsalsa20(out, inp, k, c) {
          core(out, inp, k, c, true)
          return 0
        }

        var sigma = new Uint8Array([
          101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32,
          107
        ])
        // "expand 32-byte k"

        function crypto_stream_salsa20_xor(c, cpos, m, mpos, b, n, k) {
          var z = new Uint8Array(16),
            x = new Uint8Array(64)
          var u, i
          if (!b) return 0
          for (i = 0; i < 16; i++) z[i] = 0
          for (i = 0; i < 8; i++) z[i] = n[i]
          while (b >= 64) {
            crypto_core_salsa20(x, z, k, sigma)
            for (i = 0; i < 64; i++) c[cpos + i] = (m ? m[mpos + i] : 0) ^ x[i]
            u = 1
            for (i = 8; i < 16; i++) {
              u = (u + (z[i] & 0xff)) | 0
              z[i] = u & 0xff
              u >>>= 8
            }
            b -= 64
            cpos += 64
            if (m) mpos += 64
          }
          if (b > 0) {
            crypto_core_salsa20(x, z, k, sigma)
            for (i = 0; i < b; i++) c[cpos + i] = (m ? m[mpos + i] : 0) ^ x[i]
          }
          return 0
        }

        function crypto_stream_salsa20(c, cpos, d, n, k) {
          return crypto_stream_salsa20_xor(c, cpos, null, 0, d, n, k)
        }

        function crypto_stream(c, cpos, d, n, k) {
          var s = new Uint8Array(32)
          crypto_core_hsalsa20(s, n, k, sigma)
          return crypto_stream_salsa20(c, cpos, d, n.subarray(16), s)
        }

        function crypto_stream_xor(c, cpos, m, mpos, d, n, k) {
          var s = new Uint8Array(32)
          crypto_core_hsalsa20(s, n, k, sigma)
          return crypto_stream_salsa20_xor(
            c,
            cpos,
            m,
            mpos,
            d,
            n.subarray(16),
            s
          )
        }

        function add1305(h, c) {
          var j,
            u = 0
          for (j = 0; j < 17; j++) {
            u = (u + ((h[j] + c[j]) | 0)) | 0
            h[j] = u & 255
            u >>>= 8
          }
        }

        var minusp = new Uint32Array([
          5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252
        ])

        function crypto_onetimeauth(out, outpos, m, mpos, n, k) {
          var s, i, j, u
          var x = new Uint32Array(17),
            r = new Uint32Array(17),
            h = new Uint32Array(17),
            c = new Uint32Array(17),
            g = new Uint32Array(17)
          for (j = 0; j < 17; j++) r[j] = h[j] = 0
          for (j = 0; j < 16; j++) r[j] = k[j]
          r[3] &= 15
          r[4] &= 252
          r[7] &= 15
          r[8] &= 252
          r[11] &= 15
          r[12] &= 252
          r[15] &= 15

          while (n > 0) {
            for (j = 0; j < 17; j++) c[j] = 0
            for (j = 0; j < 16 && j < n; ++j) c[j] = m[mpos + j]
            c[j] = 1
            mpos += j
            n -= j
            add1305(h, c)
            for (i = 0; i < 17; i++) {
              x[i] = 0
              for (j = 0; j < 17; j++)
                x[i] =
                  (x[i] +
                    h[j] * (j <= i ? r[i - j] : (320 * r[i + 17 - j]) | 0)) |
                  0 |
                  0
            }
            for (i = 0; i < 17; i++) h[i] = x[i]
            u = 0
            for (j = 0; j < 16; j++) {
              u = (u + h[j]) | 0
              h[j] = u & 255
              u >>>= 8
            }
            u = (u + h[16]) | 0
            h[16] = u & 3
            u = (5 * (u >>> 2)) | 0
            for (j = 0; j < 16; j++) {
              u = (u + h[j]) | 0
              h[j] = u & 255
              u >>>= 8
            }
            u = (u + h[16]) | 0
            h[16] = u
          }

          for (j = 0; j < 17; j++) g[j] = h[j]
          add1305(h, minusp)
          s = -(h[16] >>> 7) | 0
          for (j = 0; j < 17; j++) h[j] ^= s & (g[j] ^ h[j])

          for (j = 0; j < 16; j++) c[j] = k[j + 16]
          c[16] = 0
          add1305(h, c)
          for (j = 0; j < 16; j++) out[outpos + j] = h[j]
          return 0
        }

        function crypto_onetimeauth_verify(h, hpos, m, mpos, n, k) {
          var x = new Uint8Array(16)
          crypto_onetimeauth(x, 0, m, mpos, n, k)
          return crypto_verify_16(h, hpos, x, 0)
        }

        function crypto_secretbox(c, m, d, n, k) {
          var i
          if (d < 32) return -1
          crypto_stream_xor(c, 0, m, 0, d, n, k)
          crypto_onetimeauth(c, 16, c, 32, d - 32, c)
          for (i = 0; i < 16; i++) c[i] = 0
          return 0
        }

        function crypto_secretbox_open(m, c, d, n, k) {
          var i
          var x = new Uint8Array(32)
          if (d < 32) return -1
          crypto_stream(x, 0, 32, n, k)
          if (crypto_onetimeauth_verify(c, 16, c, 32, d - 32, x) !== 0)
            return -1
          crypto_stream_xor(m, 0, c, 0, d, n, k)
          for (i = 0; i < 32; i++) m[i] = 0
          return 0
        }

        function set25519(r, a) {
          var i
          for (i = 0; i < 16; i++) r[i] = a[i] | 0
        }

        function car25519(o) {
          var c
          var i
          for (i = 0; i < 16; i++) {
            o[i] += 65536
            c = Math.floor(o[i] / 65536)
            o[(i + 1) * (i < 15 ? 1 : 0)] +=
              c - 1 + 37 * (c - 1) * (i === 15 ? 1 : 0)
            o[i] -= c * 65536
          }
        }

        function sel25519(p, q, b) {
          var t,
            c = ~(b - 1)
          for (var i = 0; i < 16; i++) {
            t = c & (p[i] ^ q[i])
            p[i] ^= t
            q[i] ^= t
          }
        }

        function pack25519(o, n) {
          var i, j, b
          var m = gf(),
            t = gf()
          for (i = 0; i < 16; i++) t[i] = n[i]
          car25519(t)
          car25519(t)
          car25519(t)
          for (j = 0; j < 2; j++) {
            m[0] = t[0] - 0xffed
            for (i = 1; i < 15; i++) {
              m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1)
              m[i - 1] &= 0xffff
            }
            m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1)
            b = (m[15] >> 16) & 1
            m[14] &= 0xffff
            sel25519(t, m, 1 - b)
          }
          for (i = 0; i < 16; i++) {
            o[2 * i] = t[i] & 0xff
            o[2 * i + 1] = t[i] >> 8
          }
        }

        function neq25519(a, b) {
          var c = new Uint8Array(32),
            d = new Uint8Array(32)
          pack25519(c, a)
          pack25519(d, b)
          return crypto_verify_32(c, 0, d, 0)
        }

        function par25519(a) {
          var d = new Uint8Array(32)
          pack25519(d, a)
          return d[0] & 1
        }

        function unpack25519(o, n) {
          var i
          for (i = 0; i < 16; i++) o[i] = n[2 * i] + (n[2 * i + 1] << 8)
          o[15] &= 0x7fff
        }

        function A(o, a, b) {
          var i
          for (i = 0; i < 16; i++) o[i] = (a[i] + b[i]) | 0
        }

        function Z(o, a, b) {
          var i
          for (i = 0; i < 16; i++) o[i] = (a[i] - b[i]) | 0
        }

        function M(o, a, b) {
          var i,
            j,
            t = new Float64Array(31)
          for (i = 0; i < 31; i++) t[i] = 0
          for (i = 0; i < 16; i++) {
            for (j = 0; j < 16; j++) {
              t[i + j] += a[i] * b[j]
            }
          }
          for (i = 0; i < 15; i++) {
            t[i] += 38 * t[i + 16]
          }
          for (i = 0; i < 16; i++) o[i] = t[i]
          car25519(o)
          car25519(o)
        }

        function S(o, a) {
          M(o, a, a)
        }

        function inv25519(o, i) {
          var c = gf()
          var a
          for (a = 0; a < 16; a++) c[a] = i[a]
          for (a = 253; a >= 0; a--) {
            S(c, c)
            if (a !== 2 && a !== 4) M(c, c, i)
          }
          for (a = 0; a < 16; a++) o[a] = c[a]
        }

        function pow2523(o, i) {
          var c = gf()
          var a
          for (a = 0; a < 16; a++) c[a] = i[a]
          for (a = 250; a >= 0; a--) {
            S(c, c)
            if (a !== 1) M(c, c, i)
          }
          for (a = 0; a < 16; a++) o[a] = c[a]
        }

        function crypto_scalarmult(q, n, p) {
          var z = new Uint8Array(32)
          var x = new Float64Array(80),
            r,
            i
          var a = gf(),
            b = gf(),
            c = gf(),
            d = gf(),
            e = gf(),
            f = gf()
          for (i = 0; i < 31; i++) z[i] = n[i]
          z[31] = (n[31] & 127) | 64
          z[0] &= 248
          unpack25519(x, p)
          for (i = 0; i < 16; i++) {
            b[i] = x[i]
            d[i] = a[i] = c[i] = 0
          }
          a[0] = d[0] = 1
          for (i = 254; i >= 0; --i) {
            r = (z[i >>> 3] >>> (i & 7)) & 1
            sel25519(a, b, r)
            sel25519(c, d, r)
            A(e, a, c)
            Z(a, a, c)
            A(c, b, d)
            Z(b, b, d)
            S(d, e)
            S(f, a)
            M(a, c, a)
            M(c, b, e)
            A(e, a, c)
            Z(a, a, c)
            S(b, a)
            Z(c, d, f)
            M(a, c, _121665)
            A(a, a, d)
            M(c, c, a)
            M(a, d, f)
            M(d, b, x)
            S(b, e)
            sel25519(a, b, r)
            sel25519(c, d, r)
          }
          for (i = 0; i < 16; i++) {
            x[i + 16] = a[i]
            x[i + 32] = c[i]
            x[i + 48] = b[i]
            x[i + 64] = d[i]
          }
          var x32 = x.subarray(32)
          var x16 = x.subarray(16)
          inv25519(x32, x32)
          M(x16, x16, x32)
          pack25519(q, x16)
          return 0
        }

        function crypto_scalarmult_base(q, n) {
          return crypto_scalarmult(q, n, _9)
        }

        function crypto_box_keypair(y, x) {
          randombytes(x, 32)
          return crypto_scalarmult_base(y, x)
        }

        function crypto_box_beforenm(k, y, x) {
          var s = new Uint8Array(32)
          crypto_scalarmult(s, x, y)
          return crypto_core_hsalsa20(k, _0, s, sigma)
        }

        var crypto_box_afternm = crypto_secretbox
        var crypto_box_open_afternm = crypto_secretbox_open

        function crypto_box(c, m, d, n, y, x) {
          var k = new Uint8Array(32)
          crypto_box_beforenm(k, y, x)
          return crypto_box_afternm(c, m, d, n, k)
        }

        function crypto_box_open(m, c, d, n, y, x) {
          var k = new Uint8Array(32)
          crypto_box_beforenm(k, y, x)
          return crypto_box_open_afternm(m, c, d, n, k)
        }

        function add64() {
          var a = 0,
            b = 0,
            c = 0,
            d = 0,
            m16 = 65535,
            l,
            h,
            i
          for (i = 0; i < arguments.length; i++) {
            l = arguments[i].lo
            h = arguments[i].hi
            a += l & m16
            b += l >>> 16
            c += h & m16
            d += h >>> 16
          }

          b += a >>> 16
          c += b >>> 16
          d += c >>> 16

          return new u64((c & m16) | (d << 16), (a & m16) | (b << 16))
        }

        function shr64(x, c) {
          return new u64(x.hi >>> c, (x.lo >>> c) | (x.hi << (32 - c)))
        }

        function xor64() {
          var l = 0,
            h = 0,
            i
          for (i = 0; i < arguments.length; i++) {
            l ^= arguments[i].lo
            h ^= arguments[i].hi
          }
          return new u64(h, l)
        }

        function R(x, c) {
          var h,
            l,
            c1 = 32 - c
          if (c < 32) {
            h = (x.hi >>> c) | (x.lo << c1)
            l = (x.lo >>> c) | (x.hi << c1)
          } else if (c < 64) {
            h = (x.lo >>> c) | (x.hi << c1)
            l = (x.hi >>> c) | (x.lo << c1)
          }
          return new u64(h, l)
        }

        function Ch(x, y, z) {
          var h = (x.hi & y.hi) ^ (~x.hi & z.hi),
            l = (x.lo & y.lo) ^ (~x.lo & z.lo)
          return new u64(h, l)
        }

        function Maj(x, y, z) {
          var h = (x.hi & y.hi) ^ (x.hi & z.hi) ^ (y.hi & z.hi),
            l = (x.lo & y.lo) ^ (x.lo & z.lo) ^ (y.lo & z.lo)
          return new u64(h, l)
        }

        function Sigma0(x) {
          return xor64(R(x, 28), R(x, 34), R(x, 39))
        }
        function Sigma1(x) {
          return xor64(R(x, 14), R(x, 18), R(x, 41))
        }
        function sigma0(x) {
          return xor64(R(x, 1), R(x, 8), shr64(x, 7))
        }
        function sigma1(x) {
          return xor64(R(x, 19), R(x, 61), shr64(x, 6))
        }

        var K = [
          new u64(0x428a2f98, 0xd728ae22),
          new u64(0x71374491, 0x23ef65cd),
          new u64(0xb5c0fbcf, 0xec4d3b2f),
          new u64(0xe9b5dba5, 0x8189dbbc),
          new u64(0x3956c25b, 0xf348b538),
          new u64(0x59f111f1, 0xb605d019),
          new u64(0x923f82a4, 0xaf194f9b),
          new u64(0xab1c5ed5, 0xda6d8118),
          new u64(0xd807aa98, 0xa3030242),
          new u64(0x12835b01, 0x45706fbe),
          new u64(0x243185be, 0x4ee4b28c),
          new u64(0x550c7dc3, 0xd5ffb4e2),
          new u64(0x72be5d74, 0xf27b896f),
          new u64(0x80deb1fe, 0x3b1696b1),
          new u64(0x9bdc06a7, 0x25c71235),
          new u64(0xc19bf174, 0xcf692694),
          new u64(0xe49b69c1, 0x9ef14ad2),
          new u64(0xefbe4786, 0x384f25e3),
          new u64(0x0fc19dc6, 0x8b8cd5b5),
          new u64(0x240ca1cc, 0x77ac9c65),
          new u64(0x2de92c6f, 0x592b0275),
          new u64(0x4a7484aa, 0x6ea6e483),
          new u64(0x5cb0a9dc, 0xbd41fbd4),
          new u64(0x76f988da, 0x831153b5),
          new u64(0x983e5152, 0xee66dfab),
          new u64(0xa831c66d, 0x2db43210),
          new u64(0xb00327c8, 0x98fb213f),
          new u64(0xbf597fc7, 0xbeef0ee4),
          new u64(0xc6e00bf3, 0x3da88fc2),
          new u64(0xd5a79147, 0x930aa725),
          new u64(0x06ca6351, 0xe003826f),
          new u64(0x14292967, 0x0a0e6e70),
          new u64(0x27b70a85, 0x46d22ffc),
          new u64(0x2e1b2138, 0x5c26c926),
          new u64(0x4d2c6dfc, 0x5ac42aed),
          new u64(0x53380d13, 0x9d95b3df),
          new u64(0x650a7354, 0x8baf63de),
          new u64(0x766a0abb, 0x3c77b2a8),
          new u64(0x81c2c92e, 0x47edaee6),
          new u64(0x92722c85, 0x1482353b),
          new u64(0xa2bfe8a1, 0x4cf10364),
          new u64(0xa81a664b, 0xbc423001),
          new u64(0xc24b8b70, 0xd0f89791),
          new u64(0xc76c51a3, 0x0654be30),
          new u64(0xd192e819, 0xd6ef5218),
          new u64(0xd6990624, 0x5565a910),
          new u64(0xf40e3585, 0x5771202a),
          new u64(0x106aa070, 0x32bbd1b8),
          new u64(0x19a4c116, 0xb8d2d0c8),
          new u64(0x1e376c08, 0x5141ab53),
          new u64(0x2748774c, 0xdf8eeb99),
          new u64(0x34b0bcb5, 0xe19b48a8),
          new u64(0x391c0cb3, 0xc5c95a63),
          new u64(0x4ed8aa4a, 0xe3418acb),
          new u64(0x5b9cca4f, 0x7763e373),
          new u64(0x682e6ff3, 0xd6b2b8a3),
          new u64(0x748f82ee, 0x5defb2fc),
          new u64(0x78a5636f, 0x43172f60),
          new u64(0x84c87814, 0xa1f0ab72),
          new u64(0x8cc70208, 0x1a6439ec),
          new u64(0x90befffa, 0x23631e28),
          new u64(0xa4506ceb, 0xde82bde9),
          new u64(0xbef9a3f7, 0xb2c67915),
          new u64(0xc67178f2, 0xe372532b),
          new u64(0xca273ece, 0xea26619c),
          new u64(0xd186b8c7, 0x21c0c207),
          new u64(0xeada7dd6, 0xcde0eb1e),
          new u64(0xf57d4f7f, 0xee6ed178),
          new u64(0x06f067aa, 0x72176fba),
          new u64(0x0a637dc5, 0xa2c898a6),
          new u64(0x113f9804, 0xbef90dae),
          new u64(0x1b710b35, 0x131c471b),
          new u64(0x28db77f5, 0x23047d84),
          new u64(0x32caab7b, 0x40c72493),
          new u64(0x3c9ebe0a, 0x15c9bebc),
          new u64(0x431d67c4, 0x9c100d4c),
          new u64(0x4cc5d4be, 0xcb3e42b6),
          new u64(0x597f299c, 0xfc657e2a),
          new u64(0x5fcb6fab, 0x3ad6faec),
          new u64(0x6c44198c, 0x4a475817)
        ]

        function crypto_hashblocks(x, m, n) {
          var z = [],
            b = [],
            a = [],
            w = [],
            t,
            i,
            j

          for (i = 0; i < 8; i++) z[i] = a[i] = dl64(x, 8 * i)

          var pos = 0
          while (n >= 128) {
            for (i = 0; i < 16; i++) w[i] = dl64(m, 8 * i + pos)
            for (i = 0; i < 80; i++) {
              for (j = 0; j < 8; j++) b[j] = a[j]
              t = add64(
                a[7],
                Sigma1(a[4]),
                Ch(a[4], a[5], a[6]),
                K[i],
                w[i % 16]
              )
              b[7] = add64(t, Sigma0(a[0]), Maj(a[0], a[1], a[2]))
              b[3] = add64(b[3], t)
              for (j = 0; j < 8; j++) a[(j + 1) % 8] = b[j]
              if (i % 16 === 15) {
                for (j = 0; j < 16; j++) {
                  w[j] = add64(
                    w[j],
                    w[(j + 9) % 16],
                    sigma0(w[(j + 1) % 16]),
                    sigma1(w[(j + 14) % 16])
                  )
                }
              }
            }

            for (i = 0; i < 8; i++) {
              a[i] = add64(a[i], z[i])
              z[i] = a[i]
            }

            pos += 128
            n -= 128
          }

          for (i = 0; i < 8; i++) ts64(x, 8 * i, z[i])
          return n
        }

        var iv = new Uint8Array([
          0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08, 0xbb, 0x67, 0xae,
          0x85, 0x84, 0xca, 0xa7, 0x3b, 0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94,
          0xf8, 0x2b, 0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1, 0x51,
          0x0e, 0x52, 0x7f, 0xad, 0xe6, 0x82, 0xd1, 0x9b, 0x05, 0x68, 0x8c,
          0x2b, 0x3e, 0x6c, 0x1f, 0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd,
          0x6b, 0x5b, 0xe0, 0xcd, 0x19, 0x13, 0x7e, 0x21, 0x79
        ])

        function crypto_hash(out, m, n) {
          var h = new Uint8Array(64),
            x = new Uint8Array(256)
          var i,
            b = n

          for (i = 0; i < 64; i++) h[i] = iv[i]

          crypto_hashblocks(h, m, n)
          n %= 128

          for (i = 0; i < 256; i++) x[i] = 0
          for (i = 0; i < n; i++) x[i] = m[b - n + i]
          x[n] = 128

          n = 256 - 128 * (n < 112 ? 1 : 0)
          x[n - 9] = 0
          ts64(x, n - 8, new u64((b / 0x20000000) | 0, b << 3))
          crypto_hashblocks(h, x, n)

          for (i = 0; i < 64; i++) out[i] = h[i]

          return 0
        }

        function add(p, q) {
          var a = gf(),
            b = gf(),
            c = gf(),
            d = gf(),
            e = gf(),
            f = gf(),
            g = gf(),
            h = gf(),
            t = gf()

          Z(a, p[1], p[0])
          Z(t, q[1], q[0])
          M(a, a, t)
          A(b, p[0], p[1])
          A(t, q[0], q[1])
          M(b, b, t)
          M(c, p[3], q[3])
          M(c, c, D2)
          M(d, p[2], q[2])
          A(d, d, d)
          Z(e, b, a)
          Z(f, d, c)
          A(g, d, c)
          A(h, b, a)

          M(p[0], e, f)
          M(p[1], h, g)
          M(p[2], g, f)
          M(p[3], e, h)
        }

        function cswap(p, q, b) {
          var i
          for (i = 0; i < 4; i++) {
            sel25519(p[i], q[i], b)
          }
        }

        function pack(r, p) {
          var tx = gf(),
            ty = gf(),
            zi = gf()
          inv25519(zi, p[2])
          M(tx, p[0], zi)
          M(ty, p[1], zi)
          pack25519(r, ty)
          r[31] ^= par25519(tx) << 7
        }

        function scalarmult(p, q, s) {
          var b, i
          set25519(p[0], gf0)
          set25519(p[1], gf1)
          set25519(p[2], gf1)
          set25519(p[3], gf0)
          for (i = 255; i >= 0; --i) {
            b = (s[(i / 8) | 0] >> (i & 7)) & 1
            cswap(p, q, b)
            add(q, p)
            add(p, p)
            cswap(p, q, b)
          }
        }

        function scalarbase(p, s) {
          var q = [gf(), gf(), gf(), gf()]
          set25519(q[0], X)
          set25519(q[1], Y)
          set25519(q[2], gf1)
          M(q[3], X, Y)
          scalarmult(p, q, s)
        }

        function crypto_sign_keypair(pk, sk, seeded) {
          var d = new Uint8Array(64)
          var p = [gf(), gf(), gf(), gf()]
          var i

          if (!seeded) randombytes(sk, 32)

          var context = blake2bInit(64)
          blake2bUpdate(context, sk)
          d = blake2bFinal(context)

          d[0] &= 248
          d[31] &= 127
          d[31] |= 64

          scalarbase(p, d)
          pack(pk, p)

          return 0
        }

        function derivePublicFromSecret(sk) {
          var d = new Uint8Array(64)
          var p = [gf(), gf(), gf(), gf()]
          var i
          var pk = new Uint8Array(32)
          var context = blake2bInit(64)
          blake2bUpdate(context, sk)
          d = blake2bFinal(context)

          d[0] &= 248
          d[31] &= 127
          d[31] |= 64

          scalarbase(p, d)
          pack(pk, p)
          return pk
        }

        var L = new Float64Array([
          0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7,
          0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0, 0x10
        ])

        function modL(r, x) {
          var carry, i, j, k
          for (i = 63; i >= 32; --i) {
            carry = 0
            for (j = i - 32, k = i - 12; j < k; ++j) {
              x[j] += carry - 16 * x[i] * L[j - (i - 32)]
              carry = (x[j] + 128) >> 8
              x[j] -= carry * 256
            }
            x[j] += carry
            x[i] = 0
          }
          carry = 0
          for (j = 0; j < 32; j++) {
            x[j] += carry - (x[31] >> 4) * L[j]
            carry = x[j] >> 8
            x[j] &= 255
          }
          for (j = 0; j < 32; j++) x[j] -= carry * L[j]
          for (i = 0; i < 32; i++) {
            x[i + 1] += x[i] >> 8
            r[i] = x[i] & 255
          }
        }

        function reduce(r) {
          var x = new Float64Array(64),
            i
          for (i = 0; i < 64; i++) x[i] = r[i]
          for (i = 0; i < 64; i++) r[i] = 0
          modL(r, x)
        }

        // Note: difference from C - smlen returned, not passed as argument.
        function crypto_sign(sm, m, n, sk) {
          var d = new Uint8Array(64),
            h = new Uint8Array(64),
            r = new Uint8Array(64)
          var i,
            j,
            x = new Float64Array(64)
          var p = [gf(), gf(), gf(), gf()]

          var pk = derivePublicFromSecret(sk)

          var context = blake2bInit(64, null)
          blake2bUpdate(context, sk)
          d = blake2bFinal(context)
          d[0] &= 248
          d[31] &= 127
          d[31] |= 64

          var smlen = n + 64
          for (i = 0; i < n; i++) sm[64 + i] = m[i]
          for (i = 0; i < 32; i++) sm[32 + i] = d[32 + i]

          context = blake2bInit(64, null)
          blake2bUpdate(context, sm.subarray(32))
          r = blake2bFinal(context)

          reduce(r)
          scalarbase(p, r)
          pack(sm, p)

          for (i = 32; i < 64; i++) sm[i] = pk[i - 32]

          context = blake2bInit(64, null)
          blake2bUpdate(context, sm)
          h = blake2bFinal(context)

          reduce(h)

          for (i = 0; i < 64; i++) x[i] = 0
          for (i = 0; i < 32; i++) x[i] = r[i]
          for (i = 0; i < 32; i++) {
            for (j = 0; j < 32; j++) {
              x[i + j] += h[i] * d[j]
            }
          }

          modL(sm.subarray(32), x)
          return smlen
        }

        function unpackneg(r, p) {
          var t = gf(),
            chk = gf(),
            num = gf(),
            den = gf(),
            den2 = gf(),
            den4 = gf(),
            den6 = gf()

          set25519(r[2], gf1)
          unpack25519(r[1], p)
          S(num, r[1])
          M(den, num, D)
          Z(num, num, r[2])
          A(den, r[2], den)

          S(den2, den)
          S(den4, den2)
          M(den6, den4, den2)
          M(t, den6, num)
          M(t, t, den)

          pow2523(t, t)
          M(t, t, num)
          M(t, t, den)
          M(t, t, den)
          M(r[0], t, den)

          S(chk, r[0])
          M(chk, chk, den)
          if (neq25519(chk, num)) M(r[0], r[0], I)

          S(chk, r[0])
          M(chk, chk, den)
          if (neq25519(chk, num)) return -1

          if (par25519(r[0]) === p[31] >> 7) Z(r[0], gf0, r[0])

          M(r[3], r[0], r[1])
          return 0
        }

        function crypto_sign_open(m, sm, n, pk) {
          var i, mlen
          var t = new Uint8Array(32),
            h = new Uint8Array(64)
          var p = [gf(), gf(), gf(), gf()],
            q = [gf(), gf(), gf(), gf()]

          mlen = -1
          if (n < 64) return -1

          if (unpackneg(q, pk)) return -1

          for (i = 0; i < n; i++) m[i] = sm[i]
          for (i = 0; i < 32; i++) m[i + 32] = pk[i]
          //crypto_hash(h, m, n);

          context = blake2bInit(64, null)
          blake2bUpdate(context, m)
          h = blake2bFinal(context)

          reduce(h)
          scalarmult(p, q, h)

          scalarbase(q, sm.subarray(32))
          add(p, q)
          pack(t, p)

          n -= 64
          if (crypto_verify_32(sm, 0, t, 0)) {
            for (i = 0; i < n; i++) m[i] = 0
            return -1
          }

          for (i = 0; i < n; i++) m[i] = sm[i + 64]
          mlen = n
          return mlen
        }

        var crypto_secretbox_KEYBYTES = 32,
          crypto_secretbox_NONCEBYTES = 24,
          crypto_secretbox_ZEROBYTES = 32,
          crypto_secretbox_BOXZEROBYTES = 16,
          crypto_scalarmult_BYTES = 32,
          crypto_scalarmult_SCALARBYTES = 32,
          crypto_box_PUBLICKEYBYTES = 32,
          crypto_box_SECRETKEYBYTES = 32,
          crypto_box_BEFORENMBYTES = 32,
          crypto_box_NONCEBYTES = crypto_secretbox_NONCEBYTES,
          crypto_box_ZEROBYTES = crypto_secretbox_ZEROBYTES,
          crypto_box_BOXZEROBYTES = crypto_secretbox_BOXZEROBYTES,
          crypto_sign_BYTES = 64,
          crypto_sign_PUBLICKEYBYTES = 32,
          crypto_sign_SECRETKEYBYTES = 32,
          crypto_sign_SEEDBYTES = 32,
          crypto_hash_BYTES = 64

        nacl.lowlevel = {
          crypto_core_hsalsa20: crypto_core_hsalsa20,
          crypto_stream_xor: crypto_stream_xor,
          crypto_stream: crypto_stream,
          crypto_stream_salsa20_xor: crypto_stream_salsa20_xor,
          crypto_stream_salsa20: crypto_stream_salsa20,
          crypto_onetimeauth: crypto_onetimeauth,
          crypto_onetimeauth_verify: crypto_onetimeauth_verify,
          crypto_verify_16: crypto_verify_16,
          crypto_verify_32: crypto_verify_32,
          crypto_secretbox: crypto_secretbox,
          crypto_secretbox_open: crypto_secretbox_open,
          crypto_scalarmult: crypto_scalarmult,
          crypto_scalarmult_base: crypto_scalarmult_base,
          crypto_box_beforenm: crypto_box_beforenm,
          crypto_box_afternm: crypto_box_afternm,
          crypto_box: crypto_box,
          crypto_box_open: crypto_box_open,
          crypto_box_keypair: crypto_box_keypair,
          crypto_hash: crypto_hash,
          crypto_sign: crypto_sign,
          crypto_sign_keypair: crypto_sign_keypair,
          crypto_sign_open: crypto_sign_open,

          crypto_secretbox_KEYBYTES: crypto_secretbox_KEYBYTES,
          crypto_secretbox_NONCEBYTES: crypto_secretbox_NONCEBYTES,
          crypto_secretbox_ZEROBYTES: crypto_secretbox_ZEROBYTES,
          crypto_secretbox_BOXZEROBYTES: crypto_secretbox_BOXZEROBYTES,
          crypto_scalarmult_BYTES: crypto_scalarmult_BYTES,
          crypto_scalarmult_SCALARBYTES: crypto_scalarmult_SCALARBYTES,
          crypto_box_PUBLICKEYBYTES: crypto_box_PUBLICKEYBYTES,
          crypto_box_SECRETKEYBYTES: crypto_box_SECRETKEYBYTES,
          crypto_box_BEFORENMBYTES: crypto_box_BEFORENMBYTES,
          crypto_box_NONCEBYTES: crypto_box_NONCEBYTES,
          crypto_box_ZEROBYTES: crypto_box_ZEROBYTES,
          crypto_box_BOXZEROBYTES: crypto_box_BOXZEROBYTES,
          crypto_sign_BYTES: crypto_sign_BYTES,
          crypto_sign_PUBLICKEYBYTES: crypto_sign_PUBLICKEYBYTES,
          crypto_sign_SECRETKEYBYTES: crypto_sign_SECRETKEYBYTES,
          crypto_sign_SEEDBYTES: crypto_sign_SEEDBYTES,
          crypto_hash_BYTES: crypto_hash_BYTES
        }

        /* High-level API */

        function checkLengths(k, n) {
          if (k.length !== crypto_secretbox_KEYBYTES)
            throw new Error('bad key size')
          if (n.length !== crypto_secretbox_NONCEBYTES)
            throw new Error('bad nonce size')
        }

        function checkBoxLengths(pk, sk) {
          if (pk.length !== crypto_box_PUBLICKEYBYTES)
            throw new Error('bad public key size')
          if (sk.length !== crypto_box_SECRETKEYBYTES)
            throw new Error('bad secret key size')
        }

        function checkArrayTypes() {
          for (var i = 0; i < arguments.length; i++) {
            if (!(arguments[i] instanceof Uint8Array))
              throw new TypeError('unexpected type, use Uint8Array')
          }
        }

        function cleanup(arr) {
          for (var i = 0; i < arr.length; i++) arr[i] = 0
        }

        nacl.randomBytes = function (n) {
          var b = new Uint8Array(n)
          randombytes(b, n)
          return b
        }

        nacl.secretbox = function (msg, nonce, key) {
          checkArrayTypes(msg, nonce, key)
          checkLengths(key, nonce)
          var m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length)
          var c = new Uint8Array(m.length)
          for (var i = 0; i < msg.length; i++)
            m[i + crypto_secretbox_ZEROBYTES] = msg[i]
          crypto_secretbox(c, m, m.length, nonce, key)
          return c.subarray(crypto_secretbox_BOXZEROBYTES)
        }

        nacl.secretbox.open = function (box, nonce, key) {
          checkArrayTypes(box, nonce, key)
          checkLengths(key, nonce)
          var c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.length)
          var m = new Uint8Array(c.length)
          for (var i = 0; i < box.length; i++)
            c[i + crypto_secretbox_BOXZEROBYTES] = box[i]
          if (c.length < 32) return null
          if (crypto_secretbox_open(m, c, c.length, nonce, key) !== 0)
            return null
          return m.subarray(crypto_secretbox_ZEROBYTES)
        }

        nacl.secretbox.keyLength = crypto_secretbox_KEYBYTES
        nacl.secretbox.nonceLength = crypto_secretbox_NONCEBYTES
        nacl.secretbox.overheadLength = crypto_secretbox_BOXZEROBYTES

        nacl.scalarMult = function (n, p) {
          checkArrayTypes(n, p)
          if (n.length !== crypto_scalarmult_SCALARBYTES)
            throw new Error('bad n size')
          if (p.length !== crypto_scalarmult_BYTES)
            throw new Error('bad p size')
          var q = new Uint8Array(crypto_scalarmult_BYTES)
          crypto_scalarmult(q, n, p)
          return q
        }

        nacl.scalarMult.base = function (n) {
          checkArrayTypes(n)
          if (n.length !== crypto_scalarmult_SCALARBYTES)
            throw new Error('bad n size')
          var q = new Uint8Array(crypto_scalarmult_BYTES)
          crypto_scalarmult_base(q, n)
          return q
        }

        nacl.scalarMult.scalarLength = crypto_scalarmult_SCALARBYTES
        nacl.scalarMult.groupElementLength = crypto_scalarmult_BYTES

        nacl.box = function (msg, nonce, publicKey, secretKey) {
          var k = nacl.box.before(publicKey, secretKey)
          return nacl.secretbox(msg, nonce, k)
        }

        nacl.box.before = function (publicKey, secretKey) {
          checkArrayTypes(publicKey, secretKey)
          checkBoxLengths(publicKey, secretKey)
          var k = new Uint8Array(crypto_box_BEFORENMBYTES)
          crypto_box_beforenm(k, publicKey, secretKey)
          return k
        }

        nacl.box.after = nacl.secretbox

        nacl.box.open = function (msg, nonce, publicKey, secretKey) {
          var k = nacl.box.before(publicKey, secretKey)
          return nacl.secretbox.open(msg, nonce, k)
        }

        nacl.box.open.after = nacl.secretbox.open

        nacl.box.keyPair = function () {
          var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES)
          var sk = new Uint8Array(crypto_box_SECRETKEYBYTES)
          crypto_box_keypair(pk, sk)
          return { publicKey: pk, secretKey: sk }
        }

        nacl.box.keyPair.fromSecretKey = function (secretKey) {
          checkArrayTypes(secretKey)
          if (secretKey.length !== crypto_box_SECRETKEYBYTES)
            throw new Error('bad secret key size')
          var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES)
          crypto_scalarmult_base(pk, secretKey)
          return { publicKey: pk, secretKey: new Uint8Array(secretKey) }
        }

        nacl.box.publicKeyLength = crypto_box_PUBLICKEYBYTES
        nacl.box.secretKeyLength = crypto_box_SECRETKEYBYTES
        nacl.box.sharedKeyLength = crypto_box_BEFORENMBYTES
        nacl.box.nonceLength = crypto_box_NONCEBYTES
        nacl.box.overheadLength = nacl.secretbox.overheadLength

        nacl.sign = function (msg, secretKey) {
          checkArrayTypes(msg, secretKey)
          if (secretKey.length !== crypto_sign_SECRETKEYBYTES)
            throw new Error('bad secret key size')
          var signedMsg = new Uint8Array(crypto_sign_BYTES + msg.length)
          crypto_sign(signedMsg, msg, msg.length, secretKey)
          return signedMsg
        }

        nacl.sign.open = function (signedMsg, publicKey) {
          checkArrayTypes(signedMsg, publicKey)
          if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)
            throw new Error('bad public key size')
          var tmp = new Uint8Array(signedMsg.length)
          var mlen = crypto_sign_open(
            tmp,
            signedMsg,
            signedMsg.length,
            publicKey
          )
          if (mlen < 0) return null
          var m = new Uint8Array(mlen)
          for (var i = 0; i < m.length; i++) m[i] = tmp[i]
          return m
        }

        nacl.sign.detached = function (msg, secretKey) {
          var signedMsg = nacl.sign(msg, secretKey)
          var sig = new Uint8Array(crypto_sign_BYTES)
          for (var i = 0; i < sig.length; i++) sig[i] = signedMsg[i]
          return sig
        }

        nacl.sign.detached.verify = function (msg, sig, publicKey) {
          checkArrayTypes(msg, sig, publicKey)
          if (sig.length !== crypto_sign_BYTES)
            throw new Error('bad signature size')
          if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)
            throw new Error('bad public key size')
          var sm = new Uint8Array(crypto_sign_BYTES + msg.length)
          var m = new Uint8Array(crypto_sign_BYTES + msg.length)
          var i
          for (i = 0; i < crypto_sign_BYTES; i++) sm[i] = sig[i]
          for (i = 0; i < msg.length; i++) sm[i + crypto_sign_BYTES] = msg[i]
          return crypto_sign_open(m, sm, sm.length, publicKey) >= 0
        }

        nacl.sign.keyPair = function () {
          var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES)
          var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES)
          crypto_sign_keypair(pk, sk)
          return { publicKey: pk, secretKey: sk }
        }

        nacl.sign.keyPair.fromSecretKey = function (secretKey) {
          checkArrayTypes(secretKey)
          if (secretKey.length !== crypto_sign_SECRETKEYBYTES)
            throw new Error('bad secret key size')
          var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES)
          pk = derivePublicFromSecret(secretKey)
          return { publicKey: pk, secretKey: new Uint8Array(secretKey) }
        }

        nacl.sign.keyPair.fromSeed = function (seed) {
          checkArrayTypes(seed)
          if (seed.length !== crypto_sign_SEEDBYTES)
            throw new Error('bad seed size')
          var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES)
          var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES)
          for (var i = 0; i < 32; i++) sk[i] = seed[i]
          crypto_sign_keypair(pk, sk, true)
          return { publicKey: pk, secretKey: sk }
        }

        nacl.sign.publicKeyLength = crypto_sign_PUBLICKEYBYTES
        nacl.sign.secretKeyLength = crypto_sign_SECRETKEYBYTES
        nacl.sign.seedLength = crypto_sign_SEEDBYTES
        nacl.sign.signatureLength = crypto_sign_BYTES

        nacl.hash = function (msg) {
          checkArrayTypes(msg)
          var h = new Uint8Array(crypto_hash_BYTES)
          crypto_hash(h, msg, msg.length)
          return h
        }

        nacl.hash.hashLength = crypto_hash_BYTES

        nacl.verify = function (x, y) {
          checkArrayTypes(x, y)
          // Zero length arguments are considered not equal.
          if (x.length === 0 || y.length === 0) return false
          if (x.length !== y.length) return false
          return vn(x, 0, y, 0, x.length) === 0 ? true : false
        }

        nacl.setPRNG = function (fn) {
          randombytes = fn
        }
        ;(function () {
          // Initialize PRNG if environment provides CSPRNG.
          // If not, methods calling randombytes will throw.
          var crypto =
            typeof self !== 'undefined' ? self.crypto || self.msCrypto : null
          if (crypto && crypto.getRandomValues) {
            // Browsers.
            var QUOTA = 65536
            nacl.setPRNG(function (x, n) {
              var i,
                v = new Uint8Array(n)
              for (i = 0; i < n; i += QUOTA) {
                crypto.getRandomValues(
                  v.subarray(i, i + Math.min(n - i, QUOTA))
                )
              }
              for (i = 0; i < n; i++) x[i] = v[i]
              cleanup(v)
            })
          } else if (typeof require !== 'undefined') {
            // Node.js.
            crypto = require('crypto')
            if (crypto && crypto.randomBytes) {
              nacl.setPRNG(function (x, n) {
                var i,
                  v = crypto.randomBytes(n)
                for (i = 0; i < n; i++) x[i] = v[i]
                cleanup(v)
              })
            }
          }
        })()
      })(
        typeof module !== 'undefined' && module.exports
          ? module.exports
          : (self.nacl = self.nacl || {})
      )
    </script>
    <script type="application/javascript">
      // BLAKE.js v1.0.1
      // Adaptation of https://github.com/dcposch/blakejs
      //
      // Blake2B in pure Javascript
      // Adapted from the reference implementation in RFC7693
      // Ported to Javascript by DC - https://github.com/dcposch

      var ERROR_MSG_INPUT = 'Input must be an string, Buffer or Uint8Array'

      // For convenience, let people hash a string, not just a Uint8Array
      function normalizeInput(input) {
        var ret
        if (input instanceof Uint8Array) {
          ret = input
          /*} else if (input instanceof Buffer) {
    ret = new Uint8Array(input)
  } else if (typeof (input) === 'string') {
    ret = new Uint8Array(new Buffer(input, 'utf8'))*/
        } else {
          throw new Error(ERROR_MSG_INPUT)
        }
        return ret
      }

      // Converts a Uint8Array to a hexadecimal string
      // For example, toHex([255, 0, 255]) returns "ff00ff"
      function toHex(bytes) {
        return Array.prototype.map
          .call(bytes, function (n) {
            return (n < 16 ? '0' : '') + n.toString(16)
          })
          .join('')
      }

      // Converts any value in [0...2^32-1] to an 8-character hex string
      function uint32ToHex(val) {
        return (0x100000000 + val).toString(16).substring(1)
      }

      // 64-bit unsigned addition
      // Sets v[a,a+1] += v[b,b+1]
      // v should be a Uint32Array
      function ADD64AA(v, a, b) {
        var o0 = v[a] + v[b]
        var o1 = v[a + 1] + v[b + 1]
        if (o0 >= 0x100000000) {
          o1++
        }
        v[a] = o0
        v[a + 1] = o1
      }

      // 64-bit unsigned addition
      // Sets v[a,a+1] += b
      // b0 is the low 32 bits of b, b1 represents the high 32 bits
      function ADD64AC(v, a, b0, b1) {
        var o0 = v[a] + b0
        if (b0 < 0) {
          o0 += 0x100000000
        }
        var o1 = v[a + 1] + b1
        if (o0 >= 0x100000000) {
          o1++
        }
        v[a] = o0
        v[a + 1] = o1
      }

      // Little-endian byte access
      function B2B_GET32(arr, i) {
        return (
          arr[i] ^ (arr[i + 1] << 8) ^ (arr[i + 2] << 16) ^ (arr[i + 3] << 24)
        )
      }

      // G Mixing function
      // The ROTRs are inlined for speed
      function B2B_G(a, b, c, d, ix, iy) {
        var x0 = m[ix]
        var x1 = m[ix + 1]
        var y0 = m[iy]
        var y1 = m[iy + 1]

        ADD64AA(v, a, b) // v[a,a+1] += v[b,b+1] ... in JS we must store a uint64 as two uint32s
        ADD64AC(v, a, x0, x1) // v[a, a+1] += x ... x0 is the low 32 bits of x, x1 is the high 32 bits

        // v[d,d+1] = (v[d,d+1] xor v[a,a+1]) rotated to the right by 32 bits
        var xor0 = v[d] ^ v[a]
        var xor1 = v[d + 1] ^ v[a + 1]
        v[d] = xor1
        v[d + 1] = xor0

        ADD64AA(v, c, d)

        // v[b,b+1] = (v[b,b+1] xor v[c,c+1]) rotated right by 24 bits
        xor0 = v[b] ^ v[c]
        xor1 = v[b + 1] ^ v[c + 1]
        v[b] = (xor0 >>> 24) ^ (xor1 << 8)
        v[b + 1] = (xor1 >>> 24) ^ (xor0 << 8)

        ADD64AA(v, a, b)
        ADD64AC(v, a, y0, y1)

        // v[d,d+1] = (v[d,d+1] xor v[a,a+1]) rotated right by 16 bits
        xor0 = v[d] ^ v[a]
        xor1 = v[d + 1] ^ v[a + 1]
        v[d] = (xor0 >>> 16) ^ (xor1 << 16)
        v[d + 1] = (xor1 >>> 16) ^ (xor0 << 16)

        ADD64AA(v, c, d)

        // v[b,b+1] = (v[b,b+1] xor v[c,c+1]) rotated right by 63 bits
        xor0 = v[b] ^ v[c]
        xor1 = v[b + 1] ^ v[c + 1]
        v[b] = (xor1 >>> 31) ^ (xor0 << 1)
        v[b + 1] = (xor0 >>> 31) ^ (xor1 << 1)
      }

      // Initialization Vector
      var BLAKE2B_IV32 = new Uint32Array([
        0xf3bcc908, 0x6a09e667, 0x84caa73b, 0xbb67ae85, 0xfe94f82b, 0x3c6ef372,
        0x5f1d36f1, 0xa54ff53a, 0xade682d1, 0x510e527f, 0x2b3e6c1f, 0x9b05688c,
        0xfb41bd6b, 0x1f83d9ab, 0x137e2179, 0x5be0cd19
      ])

      var SIGMA8 = [
        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 14, 10, 4, 8, 9,
        15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3, 11, 8, 12, 0, 5, 2, 15, 13, 10, 14,
        3, 6, 7, 1, 9, 4, 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8,
        9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13, 2, 12, 6, 10, 0,
        11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9, 12, 5, 1, 15, 14, 13, 4, 10, 0, 7,
        6, 3, 9, 2, 8, 11, 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10,
        6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5, 10, 2, 8, 4, 7, 6,
        1, 5, 15, 11, 9, 14, 3, 12, 13, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
        12, 13, 14, 15, 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3
      ]

      // These are offsets into a uint64 buffer.
      // Multiply them all by 2 to make them offsets into a uint32 buffer,
      // because this is Javascript and we don't have uint64s
      var SIGMA82 = new Uint8Array(
        SIGMA8.map(function (x) {
          return x * 2
        })
      )

      // Compression function. 'last' flag indicates last block.
      // Note we're representing 16 uint64s as 32 uint32s
      var v = new Uint32Array(32)
      var m = new Uint32Array(32)
      function blake2bCompress(ctx, last) {
        var i = 0

        // init work variables
        for (i = 0; i < 16; i++) {
          v[i] = ctx.h[i]
          v[i + 16] = BLAKE2B_IV32[i]
        }

        // low 64 bits of offset
        v[24] = v[24] ^ ctx.t
        v[25] = v[25] ^ (ctx.t / 0x100000000)
        // high 64 bits not supported, offset may not be higher than 2**53-1

        // last block flag set ?
        if (last) {
          v[28] = ~v[28]
          v[29] = ~v[29]
        }

        // get little-endian words
        for (i = 0; i < 32; i++) {
          m[i] = B2B_GET32(ctx.b, 4 * i)
        }

        // twelve rounds of mixing
        // uncomment the DebugPrint calls to log the computation
        // and match the RFC sample documentation
        // util.debugPrint('          m[16]', m, 64)
        for (i = 0; i < 12; i++) {
          // util.debugPrint('   (i=' + (i < 10 ? ' ' : '') + i + ') v[16]', v, 64)
          B2B_G(0, 8, 16, 24, SIGMA82[i * 16 + 0], SIGMA82[i * 16 + 1])
          B2B_G(2, 10, 18, 26, SIGMA82[i * 16 + 2], SIGMA82[i * 16 + 3])
          B2B_G(4, 12, 20, 28, SIGMA82[i * 16 + 4], SIGMA82[i * 16 + 5])
          B2B_G(6, 14, 22, 30, SIGMA82[i * 16 + 6], SIGMA82[i * 16 + 7])
          B2B_G(0, 10, 20, 30, SIGMA82[i * 16 + 8], SIGMA82[i * 16 + 9])
          B2B_G(2, 12, 22, 24, SIGMA82[i * 16 + 10], SIGMA82[i * 16 + 11])
          B2B_G(4, 14, 16, 26, SIGMA82[i * 16 + 12], SIGMA82[i * 16 + 13])
          B2B_G(6, 8, 18, 28, SIGMA82[i * 16 + 14], SIGMA82[i * 16 + 15])
        }
        // util.debugPrint('   (i=12) v[16]', v, 64)

        for (i = 0; i < 16; i++) {
          ctx.h[i] = ctx.h[i] ^ v[i] ^ v[i + 16]
        }
        // util.debugPrint('h[8]', ctx.h, 64)
      }

      // Creates a BLAKE2b hashing context
      // Requires an output length between 1 and 64 bytes
      // Takes an optional Uint8Array key
      function blake2bInit(outlen, key) {
        if (outlen === 0 || outlen > 64) {
          throw new Error('Illegal output length, expected 0 < length <= 64')
        }
        if (key && key.length > 64) {
          throw new Error(
            'Illegal key, expected Uint8Array with 0 < length <= 64'
          )
        }

        // state, 'param block'
        var ctx = {
          b: new Uint8Array(128),
          h: new Uint32Array(16),
          t: 0, // input count
          c: 0, // pointer within buffer
          outlen: outlen // output length in bytes
        }

        // initialize hash state
        for (var i = 0; i < 16; i++) {
          ctx.h[i] = BLAKE2B_IV32[i]
        }
        var keylen = key ? key.length : 0
        ctx.h[0] ^= 0x01010000 ^ (keylen << 8) ^ outlen

        // key the hash, if applicable
        if (key) {
          blake2bUpdate(ctx, key)
          // at the end
          ctx.c = 128
        }

        return ctx
      }

      // Updates a BLAKE2b streaming hash
      // Requires hash context and Uint8Array (byte array)
      function blake2bUpdate(ctx, input) {
        for (var i = 0; i < input.length; i++) {
          if (ctx.c === 128) {
            // buffer full ?
            ctx.t += ctx.c // add counters
            blake2bCompress(ctx, false) // compress (not last)
            ctx.c = 0 // counter to zero
          }
          ctx.b[ctx.c++] = input[i]
        }
      }

      // Completes a BLAKE2b streaming hash
      // Returns a Uint8Array containing the message digest
      function blake2bFinal(ctx) {
        ctx.t += ctx.c // mark last block offset

        while (ctx.c < 128) {
          // fill up with zeros
          ctx.b[ctx.c++] = 0
        }
        blake2bCompress(ctx, true) // final block flag = 1

        // little endian convert and store
        var out = new Uint8Array(ctx.outlen)
        for (var i = 0; i < ctx.outlen; i++) {
          out[i] = ctx.h[i >> 2] >> (8 * (i & 3))
        }
        return out
      }

      // Computes the BLAKE2B hash of a string or byte array, and returns a Uint8Array
      //
      // Returns a n-byte Uint8Array
      //
      // Parameters:
      // - input - the input bytes, as a string, Buffer or Uint8Array
      // - key - optional key Uint8Array, up to 64 bytes
      // - outlen - optional output length in bytes, default 64
      function blake2b(input, key, outlen) {
        // preprocess inputs
        outlen = outlen || 64
        input = normalizeInput(input)

        // do the math
        var ctx = blake2bInit(outlen, key)
        blake2bUpdate(ctx, input)
        return blake2bFinal(ctx)
      }

      // Computes the BLAKE2B hash of a string or byte array
      //
      // Returns an n-byte hash in hex, all lowercase
      //
      // Parameters:
      // - input - the input bytes, as a string, Buffer, or Uint8Array
      // - key - optional key Uint8Array, up to 64 bytes
      // - outlen - optional output length in bytes, default 64
      function blake2bHex(input, key, outlen) {
        var output = blake2b(input, key, outlen)
        return toHex(output)
      }
    </script>
    <script type="application/javascript">
      // general functions

      function stringFromHex(hex) {
        var hex = hex.toString() //force conversion
        var str = ''
        for (var i = 0; i < hex.length; i += 2)
          str += String.fromCharCode(parseInt(hex.substr(i, 2), 16))
        return str
      }

      function stringToHex(str) {
        var hex = ''
        for (var i = 0; i < str.length; i++) {
          hex += '' + str.charCodeAt(i).toString(16)
        }
        return hex
      }

      function accountFromHexKey(hex) {
        var checksum = ''
        var key_bytes = uint4_uint8(hex_uint4(hex))
        var checksum = uint5_string(
          uint4_uint5(uint8_uint4(blake2b(key_bytes, null, 5).reverse()))
        )
        var c_account = uint5_string(uint4_uint5(hex_uint4('0' + hex)))
        return 'xrb_' + c_account + checksum
      }

      function parseXRBAccount(str) {
        var i = str.indexOf('xrb_')
        if (i != -1) {
          var acc = str.slice(i, i + 64)
          try {
            keyFromAccount(acc)
            return acc
          } catch (e) {
            return false
          }
        }
        return false
      }

      function dec2hex(str, bytes = null) {
        var dec = str.toString().split(''),
          sum = [],
          hex = [],
          i,
          s
        while (dec.length) {
          s = 1 * dec.shift()
          for (i = 0; s || i < sum.length; i++) {
            s += (sum[i] || 0) * 10
            sum[i] = s % 16
            s = (s - sum[i]) / 16
          }
        }
        while (sum.length) {
          hex.push(sum.pop().toString(16))
        }

        hex = hex.join('')

        if (hex.length % 2 != 0) hex = '0' + hex

        if (bytes > hex.length / 2) {
          var diff = bytes - hex.length / 2
          for (var i = 0; i < diff; i++) hex = '00' + hex
        }

        return hex
      }

      function hex2dec(s) {
        function add(x, y) {
          var c = 0,
            r = []
          var x = x.split('').map(Number)
          var y = y.split('').map(Number)
          while (x.length || y.length) {
            var s = (x.pop() || 0) + (y.pop() || 0) + c
            r.unshift(s < 10 ? s : s - 10)
            c = s < 10 ? 0 : 1
          }
          if (c) r.unshift(c)
          return r.join('')
        }

        var dec = '0'
        s.split('').forEach(function (chr) {
          var n = parseInt(chr, 16)
          for (var t = 8; t; t >>= 1) {
            dec = add(dec, dec)
            if (n & t) dec = add(dec, '1')
          }
        })
        return dec
      }

      /*
BSD 3-Clause License

Copyright (c) 2017, SergiySW
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

* Neither the name of the copyright holder nor the names of its
  contributors may be used to endorse or promote products derived from
  this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

      // Arrays manipulations
      function uint8_uint4(uint8) {
        var length = uint8.length
        var uint4 = new Uint8Array(length * 2)
        for (let i = 0; i < length; i++) {
          uint4[i * 2] = (uint8[i] / 16) | 0
          uint4[i * 2 + 1] = uint8[i] % 16
        }
        return uint4
      }

      function uint4_uint8(uint4) {
        var length = uint4.length / 2
        var uint8 = new Uint8Array(length)
        for (let i = 0; i < length; i++)
          uint8[i] = uint4[i * 2] * 16 + uint4[i * 2 + 1]
        return uint8
      }

      function uint4_uint5(uint4) {
        var length = (uint4.length / 5) * 4
        var uint5 = new Uint8Array(length)
        for (let i = 1; i <= length; i++) {
          let n = i - 1
          let m = i % 4
          let z = n + (i - m) / 4
          let right = uint4[z] << m
          let left
          if ((length - i) % 4 == 0) left = uint4[z - 1] << 4
          else left = uint4[z + 1] >> (4 - m)
          uint5[n] = (left + right) % 32
        }
        return uint5
      }

      function uint5_uint4(uint5) {
        var length = (uint5.length / 4) * 5
        var uint4 = new Uint8Array(length)
        for (let i = 1; i <= length; i++) {
          let n = i - 1
          let m = i % 5
          let z = n - (i - m) / 5
          let right = uint5[z - 1] << (5 - m)
          let left = uint5[z] >> m
          uint4[n] = (left + right) % 16
        }
        return uint4
      }

      function string_uint5(string) {
        var letter_list = (letter_list =
          '13456789abcdefghijkmnopqrstuwxyz'.split(''))
        var length = string.length
        var string_array = string.split('')
        var uint5 = new Uint8Array(length)
        for (let i = 0; i < length; i++)
          uint5[i] = letter_list.indexOf(string_array[i])
        return uint5
      }

      function uint5_string(uint5) {
        var letter_list = (letter_list =
          '13456789abcdefghijkmnopqrstuwxyz'.split(''))
        var string = ''
        for (let i = 0; i < uint5.length; i++) string += letter_list[uint5[i]]
        return string
      }

      function hex_uint8(hex) {
        var length = (hex.length / 2) | 0
        var uint8 = new Uint8Array(length)
        for (let i = 0; i < length; i++)
          uint8[i] = parseInt(hex.substr(i * 2, 2), 16)
        return uint8
      }

      function hex_uint4(hex) {
        var length = hex.length
        var uint4 = new Uint8Array(length)
        for (let i = 0; i < length; i++)
          uint4[i] = parseInt(hex.substr(i, 1), 16)
        return uint4
      }

      function uint8_hex(uint8) {
        var hex = ''
        for (let i = 0; i < uint8.length; i++) {
          aux = uint8[i].toString(16).toUpperCase()
          if (aux.length == 1) aux = '0' + aux
          hex += aux
          aux = ''
        }
        return hex
      }

      function uint4_hex(uint4) {
        var hex = ''
        for (let i = 0; i < uint4.length; i++)
          hex += uint4[i].toString(16).toUpperCase()
        return hex
      }

      function equal_arrays(array1, array2) {
        for (let i = 0; i < array1.length; i++) {
          if (array1[i] != array2[i]) return false
        }
        return true
      }

      function array_crop(array) {
        var length = array.length - 1
        var cropped_array = new Uint8Array(length)
        for (let i = 0; i < length; i++) cropped_array[i] = array[i + 1]
        return cropped_array
      }

      function keyFromAccount(account) {
        if (
          (account.startsWith('xrb_1') || account.startsWith('xrb_3')) &&
          account.length == 64
        ) {
          var account_crop = account.substring(4, 64)
          var isValid = /^[13456789abcdefghijkmnopqrstuwxyz]+$/.test(
            account_crop
          )
          if (isValid) {
            var key_uint4 = array_crop(
              uint5_uint4(string_uint5(account_crop.substring(0, 52)))
            )
            var hash_uint4 = uint5_uint4(
              string_uint5(account_crop.substring(52, 60))
            )
            var key_array = uint4_uint8(key_uint4)
            var blake_hash = blake2b(key_array, null, 5).reverse()
            if (equal_arrays(hash_uint4, uint8_uint4(blake_hash))) {
              var key = uint4_hex(key_uint4)
              return key
            } else throw 'Checksum incorrect.'
          } else throw 'Invalid XRB account.'
        }
        throw 'Invalid XRB account.'
      }
    </script>
    <style>
      body {
        max-width: 960px;
        margin: 10px auto 50px;
        font-family: sans-serif;
        padding: 0 10px;
      }
      input {
        width: 100%;
        padding: 3px;
        margin: 2px 0 0 0;
      }
      input.param {
        width: auto;
        margin-right: 5px;
      }
      .dont-break-out {
        overflow-wrap: break-word;
        word-wrap: break-word;
        -ms-word-break: break-all;
        word-break: break-all;
        word-break: break-word;
        -ms-hyphens: auto;
        -moz-hyphens: auto;
        -webkit-hyphens: auto;
        hyphens: auto;
      }
    </style>
    <style media="print">
      #pairs li {
        page-break-inside: avoid;
      }
      .no-print {
        display: none;
      }
    </style>
  </head>
  <body>
    <h1>Nano Currency (RaiBlocks) Paper Wallet Generator</h1>
    <div class="no-print">
      <p>
        Based on the
        <a href="https://github.com/jaimehgb/RaiWebWallet">RaiWebWallet</a>
        source code.
        <a href="https://github.com/numtel/rai-paper-wallet/">This code</a> is
        licensed GPL v3.
      </p>
      <p>
        This page may be used offline,
        <a href="https://github.com/numtel/rai-paper-wallet/archive/master.zip"
          >download the source code zip</a
        >
        and open index.html in your web browser.
      </p>
      <hr />
    </div>
    <ol class="no-print">
      <li>
        <p>
          The wallet accounts are generated from a 32 byte seed input as a 64
          character long hexadecimal string.
        </p>
        <p>
          Click "Use Random" to select a random value using
          <a href="https://github.com/dchest/tweetnacl-js#naclrandombyteslength"
            >nacl.js</a
          >.
        </p>
        <p>
          <label
            >Seed: <input autocomplete="off" class="param" id="seed" /></label
          ><button id="randomSeed">Use Random</button>
        </p>
        <p>
          <strong>Back up the wallet seed somewhere safe.</strong> You may also
          print this page after generation.
        </p>
        <p>
          Anyone who knows it is able to generate your private keys, thus having
          access to your funds.
        </p>
      </li>
      <li>
        <p>
          Up to 2<sup>32</sup> accounts may be addressed from a single seed.
          Please select which account to generate a private key/address pair.
        </p>
        <p>
          By default, <a href="https://raiwallet.com/">RaiWallet</a> uses the
          0th account. The desktop wallet seems to start with 0-2.
        </p>
        <p>
          <label>Account Number:</label>
          <input
            class="param"
            id="accountIndex"
            type="number"
            min="0"
            max="4294967295"
            value="0" />
        </p>
      </li>
      <li>
        <p>
          Click the button to generate a account key/address pair that you may
          import into other wallet applications.
        </p>
        <p><button id="generatePair">Generate account pair</button></p>
      </li>
    </ol>
    <hr />
    <ol id="pairs"></ol>
    <script>
      function newPair(seed, accountIndex) {
        var index = hex_uint8(dec2hex(accountIndex, 4))

        var context = blake2bInit(32)
        blake2bUpdate(context, seed)
        blake2bUpdate(context, index)

        var newKey = blake2bFinal(context)

        return {
          secret: uint8_hex(newKey),
          address: accountFromHexKey(
            uint8_hex(nacl.sign.keyPair.fromSecretKey(newKey).publicKey)
          )
        }
      }

      var pairList = document.getElementById('pairs')
      var seedInput = document.getElementById('seed')
      var accountIndexInput = document.getElementById('accountIndex')

      document.getElementById('randomSeed').addEventListener(
        'click',
        function () {
          seedInput.value = uint8_hex(nacl.randomBytes(32))
        },
        false
      )

      document.getElementById('generatePair').addEventListener(
        'click',
        function () {
          if (!/[0-9A-F]{64}/i.test(seedInput.value)) {
            alert('Seed must be 64 character hexadecimal string!')
            return
          }

          var accountIndex = parseInt(accountIndexInput.value, 10)
          if (accountIndex < 0 || accountIndex >= Math.pow(2, 32)) {
            alert('Account index must be 32 bit unsigned integer!')
            return
          }

          var pair = newPair(hex_uint8(seedInput.value), accountIndex)

          pairList.innerHTML +=
            '<li><dl>' +
            [
              { label: 'Wallet Seed', value: seedInput.value },
              { label: 'Account Key #' + accountIndex, value: pair.secret },
              { label: 'Address', value: pair.address }
            ]
              .map(function (item) {
                return (
                  '<div><dt>' +
                  item.label +
                  ':</dt></div>' +
                  '<div><dd>' +
                  '<span class="dont-break-out">' +
                  item.value +
                  '</span>' +
                  '</dd></div>'
                )
              })
              .join('') +
            '</dl></li>'
        },
        false
      )
    </script>
  </body>
</html>