import { createRequire as _createRequire } from 'module'; import { fileURLToPath as _fileURLToPath } from 'url'; import { dirname as _dirname } from 'path'; const __filename = _fileURLToPath(import.meta.url); const __dirname = _dirname(__filename); const _originalRequire = _createRequire(import.meta.url); const require = (moduleName) => { if (moduleName === 'pako') return global.pako; return _originalRequire(moduleName); }; import { createRequire } from "node:module"; import crypto$1, { createHash } from "crypto"; import path, { join, sep } from "path"; import url, { fileURLToPath, pathToFileURL } from "url"; import fs, { access, constants, createReadStream, createWriteStream, existsSync, mkdirSync, readFileSync, unlinkSync, watch, writeFileSync } from "fs"; import fs$1, { mkdir, open, readFile, rename, stat, unlink, writeFile } from "fs/promises"; import { exec, execFile } from "child_process"; import http from "http"; import https from "https"; import { EventEmitter } from "events"; import stream, { PassThrough, Readable, Writable } from "stream"; import * as realZlib from "zlib"; import zlib, { createGzip } from "zlib"; import { Buffer as Buffer$1 } from "buffer"; import vm from "vm"; import assert from "assert"; import { EventEmitter as EventEmitter$1 } from "node:events"; import Stream, { Transform, Writable as Writable$1, finished } from "node:stream"; import { StringDecoder } from "node:string_decoder"; import util, { TextDecoder as TextDecoder$1, promisify } from "util"; import process$1 from "node:process"; import os from "node:os"; import tty from "node:tty"; import util$1 from "node:util"; import { createRequire as createRequire$1 } from "module"; import { setTimeout as setTimeout$1 } from "timers"; import { pipeline } from "stream/promises"; import diagnosticsChannel from "diagnostics_channel"; //#region \0rolldown/runtime.js var __create = Object.create; var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __esm = (fn, res) => function() { return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; }; var __esmMin = (fn, res) => () => (fn && (res = fn(fn = 0)), res); var __commonJS = (cb, mod) => function() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports); var __exportAll = (all, no_symbols) => { let target = {}; for (var name in all) { __defProp(target, name, { get: all[name], enumerable: true }); } if (!no_symbols) { __defProp(target, Symbol.toStringTag, { value: "Module" }); } return target; }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) { key = keys[i]; if (!__hasOwnProp.call(to, key) && key !== except) { __defProp(to, key, { get: ((k) => from[k]).bind(null, key), enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } } } return to; }; var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default")); var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod)); var __toCommonJS = (mod) => __hasOwnProp.call(mod, "module.exports") ? mod["module.exports"] : __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __toBinaryNode = (base64) => new Uint8Array(Buffer.from(base64, "base64")); var __toBinary = /* @__PURE__ */ (() => { var table = new Uint8Array(128); for (var i = 0; i < 64; i++) { table[i < 26 ? i + 65 : i < 52 ? i + 71 : i < 62 ? i - 4 : i * 4 - 205] = i; } return (base64) => { var n = base64.length, bytes = new Uint8Array((n - (base64[n - 1] == "=") - (base64[n - 2] == "=")) * 3 / 4 | 0); for (var i = 0, j = 0; i < n;) { var c0 = table[base64.charCodeAt(i++)], c1 = table[base64.charCodeAt(i++)]; var c2 = table[base64.charCodeAt(i++)], c3 = table[base64.charCodeAt(i++)]; bytes[j++] = c0 << 2 | c1 >> 4; bytes[j++] = c1 << 4 | c2 >> 2; bytes[j++] = c2 << 6 | c3; } return bytes; }; })(); var __require = /* @__PURE__ */ createRequire(import.meta.url); //#endregion //#region ../libs_drpy/pako.min.js var require_pako_min = /* @__PURE__ */ __commonJSMin(((exports, module) => { !function(t) { if ("object" == typeof exports && "undefined" != typeof module) module.exports = t(); else if ("function" == typeof define && define.amd) define([], t); else { ("undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof self ? self : this).pako = t(); } }(function() { return function r(s, o, l) { function h(e, t) { if (!o[e]) { if (!s[e]) { var a = "function" == typeof __require && __require; if (!t && a) return a(e, !0); if (d) return d(e, !0); var i = new Error("Cannot find module '" + e + "'"); throw i.code = "MODULE_NOT_FOUND", i; } var n = o[e] = { exports: {} }; s[e][0].call(n.exports, function(t) { return h(s[e][1][t] || t); }, n, n.exports, r, s, o, l); } return o[e].exports; } for (var d = "function" == typeof __require && __require, t = 0; t < l.length; t++) h(l[t]); return h; }({ 1: [function(t, e, a) { "use strict"; var s = t("./zlib/deflate"), o = t("./utils/common"), l = t("./utils/strings"), n = t("./zlib/messages"), r = t("./zlib/zstream"), h = Object.prototype.toString, d = 0, f = -1, _ = 0, u = 8; function c(t) { if (!(this instanceof c)) return new c(t); this.options = o.assign({ level: f, method: u, chunkSize: 16384, windowBits: 15, memLevel: 8, strategy: _, to: "" }, t || {}); var e = this.options; e.raw && 0 < e.windowBits ? e.windowBits = -e.windowBits : e.gzip && 0 < e.windowBits && e.windowBits < 16 && (e.windowBits += 16), this.err = 0, this.msg = "", this.ended = !1, this.chunks = [], this.strm = new r(), this.strm.avail_out = 0; var a = s.deflateInit2(this.strm, e.level, e.method, e.windowBits, e.memLevel, e.strategy); if (a !== d) throw new Error(n[a]); if (e.header && s.deflateSetHeader(this.strm, e.header), e.dictionary) { var i; if (i = "string" == typeof e.dictionary ? l.string2buf(e.dictionary) : "[object ArrayBuffer]" === h.call(e.dictionary) ? new Uint8Array(e.dictionary) : e.dictionary, (a = s.deflateSetDictionary(this.strm, i)) !== d) throw new Error(n[a]); this._dict_set = !0; } } function i(t, e) { var a = new c(e); if (a.push(t, !0), a.err) throw a.msg || n[a.err]; return a.result; } c.prototype.push = function(t, e) { var a, i, n = this.strm, r = this.options.chunkSize; if (this.ended) return !1; i = e === ~~e ? e : !0 === e ? 4 : 0, "string" == typeof t ? n.input = l.string2buf(t) : "[object ArrayBuffer]" === h.call(t) ? n.input = new Uint8Array(t) : n.input = t, n.next_in = 0, n.avail_in = n.input.length; do { if (0 === n.avail_out && (n.output = new o.Buf8(r), n.next_out = 0, n.avail_out = r), 1 !== (a = s.deflate(n, i)) && a !== d) return this.onEnd(a), !(this.ended = !0); 0 !== n.avail_out && (0 !== n.avail_in || 4 !== i && 2 !== i) || ("string" === this.options.to ? this.onData(l.buf2binstring(o.shrinkBuf(n.output, n.next_out))) : this.onData(o.shrinkBuf(n.output, n.next_out))); } while ((0 < n.avail_in || 0 === n.avail_out) && 1 !== a); return 4 === i ? (a = s.deflateEnd(this.strm), this.onEnd(a), this.ended = !0, a === d) : 2 !== i || (this.onEnd(d), !(n.avail_out = 0)); }, c.prototype.onData = function(t) { this.chunks.push(t); }, c.prototype.onEnd = function(t) { t === d && ("string" === this.options.to ? this.result = this.chunks.join("") : this.result = o.flattenChunks(this.chunks)), this.chunks = [], this.err = t, this.msg = this.strm.msg; }, a.Deflate = c, a.deflate = i, a.deflateRaw = function(t, e) { return (e = e || {}).raw = !0, i(t, e); }, a.gzip = function(t, e) { return (e = e || {}).gzip = !0, i(t, e); }; }, { "./utils/common": 3, "./utils/strings": 4, "./zlib/deflate": 8, "./zlib/messages": 13, "./zlib/zstream": 15 }], 2: [function(t, e, a) { "use strict"; var f = t("./zlib/inflate"), _ = t("./utils/common"), u = t("./utils/strings"), c = t("./zlib/constants"), i = t("./zlib/messages"), n = t("./zlib/zstream"), r = t("./zlib/gzheader"), b = Object.prototype.toString; function s(t) { if (!(this instanceof s)) return new s(t); this.options = _.assign({ chunkSize: 16384, windowBits: 0, to: "" }, t || {}); var e = this.options; e.raw && 0 <= e.windowBits && e.windowBits < 16 && (e.windowBits = -e.windowBits, 0 === e.windowBits && (e.windowBits = -15)), !(0 <= e.windowBits && e.windowBits < 16) || t && t.windowBits || (e.windowBits += 32), 15 < e.windowBits && e.windowBits < 48 && 0 == (15 & e.windowBits) && (e.windowBits |= 15), this.err = 0, this.msg = "", this.ended = !1, this.chunks = [], this.strm = new n(), this.strm.avail_out = 0; var a = f.inflateInit2(this.strm, e.windowBits); if (a !== c.Z_OK) throw new Error(i[a]); if (this.header = new r(), f.inflateGetHeader(this.strm, this.header), e.dictionary && ("string" == typeof e.dictionary ? e.dictionary = u.string2buf(e.dictionary) : "[object ArrayBuffer]" === b.call(e.dictionary) && (e.dictionary = new Uint8Array(e.dictionary)), e.raw && (a = f.inflateSetDictionary(this.strm, e.dictionary)) !== c.Z_OK)) throw new Error(i[a]); } function o(t, e) { var a = new s(e); if (a.push(t, !0), a.err) throw a.msg || i[a.err]; return a.result; } s.prototype.push = function(t, e) { var a, i, n, r, s, o = this.strm, l = this.options.chunkSize, h = this.options.dictionary, d = !1; if (this.ended) return !1; i = e === ~~e ? e : !0 === e ? c.Z_FINISH : c.Z_NO_FLUSH, "string" == typeof t ? o.input = u.binstring2buf(t) : "[object ArrayBuffer]" === b.call(t) ? o.input = new Uint8Array(t) : o.input = t, o.next_in = 0, o.avail_in = o.input.length; do { if (0 === o.avail_out && (o.output = new _.Buf8(l), o.next_out = 0, o.avail_out = l), (a = f.inflate(o, c.Z_NO_FLUSH)) === c.Z_NEED_DICT && h && (a = f.inflateSetDictionary(this.strm, h)), a === c.Z_BUF_ERROR && !0 === d && (a = c.Z_OK, d = !1), a !== c.Z_STREAM_END && a !== c.Z_OK) return this.onEnd(a), !(this.ended = !0); o.next_out && (0 !== o.avail_out && a !== c.Z_STREAM_END && (0 !== o.avail_in || i !== c.Z_FINISH && i !== c.Z_SYNC_FLUSH) || ("string" === this.options.to ? (n = u.utf8border(o.output, o.next_out), r = o.next_out - n, s = u.buf2string(o.output, n), o.next_out = r, o.avail_out = l - r, r && _.arraySet(o.output, o.output, n, r, 0), this.onData(s)) : this.onData(_.shrinkBuf(o.output, o.next_out)))), 0 === o.avail_in && 0 === o.avail_out && (d = !0); } while ((0 < o.avail_in || 0 === o.avail_out) && a !== c.Z_STREAM_END); return a === c.Z_STREAM_END && (i = c.Z_FINISH), i === c.Z_FINISH ? (a = f.inflateEnd(this.strm), this.onEnd(a), this.ended = !0, a === c.Z_OK) : i !== c.Z_SYNC_FLUSH || (this.onEnd(c.Z_OK), !(o.avail_out = 0)); }, s.prototype.onData = function(t) { this.chunks.push(t); }, s.prototype.onEnd = function(t) { t === c.Z_OK && ("string" === this.options.to ? this.result = this.chunks.join("") : this.result = _.flattenChunks(this.chunks)), this.chunks = [], this.err = t, this.msg = this.strm.msg; }, a.Inflate = s, a.inflate = o, a.inflateRaw = function(t, e) { return (e = e || {}).raw = !0, o(t, e); }, a.ungzip = o; }, { "./utils/common": 3, "./utils/strings": 4, "./zlib/constants": 6, "./zlib/gzheader": 9, "./zlib/inflate": 11, "./zlib/messages": 13, "./zlib/zstream": 15 }], 3: [function(t, e, a) { "use strict"; var i = "undefined" != typeof Uint8Array && "undefined" != typeof Uint16Array && "undefined" != typeof Int32Array; a.assign = function(t) { for (var e, a, i = Array.prototype.slice.call(arguments, 1); i.length;) { var n = i.shift(); if (n) { if ("object" != typeof n) throw new TypeError(n + "must be non-object"); for (var r in n) e = n, a = r, Object.prototype.hasOwnProperty.call(e, a) && (t[r] = n[r]); } } return t; }, a.shrinkBuf = function(t, e) { return t.length === e ? t : t.subarray ? t.subarray(0, e) : (t.length = e, t); }; var n = { arraySet: function(t, e, a, i, n) { if (e.subarray && t.subarray) t.set(e.subarray(a, a + i), n); else for (var r = 0; r < i; r++) t[n + r] = e[a + r]; }, flattenChunks: function(t) { var e, a, i, n, r, s; for (e = i = 0, a = t.length; e < a; e++) i += t[e].length; for (s = new Uint8Array(i), e = n = 0, a = t.length; e < a; e++) r = t[e], s.set(r, n), n += r.length; return s; } }, r = { arraySet: function(t, e, a, i, n) { for (var r = 0; r < i; r++) t[n + r] = e[a + r]; }, flattenChunks: function(t) { return [].concat.apply([], t); } }; a.setTyped = function(t) { t ? (a.Buf8 = Uint8Array, a.Buf16 = Uint16Array, a.Buf32 = Int32Array, a.assign(a, n)) : (a.Buf8 = Array, a.Buf16 = Array, a.Buf32 = Array, a.assign(a, r)); }, a.setTyped(i); }, {}], 4: [function(t, e, a) { "use strict"; var l = t("./common"), n = !0, r = !0; try { String.fromCharCode.apply(null, [0]); } catch (t) { n = !1; } try { String.fromCharCode.apply(null, new Uint8Array(1)); } catch (t) { r = !1; } for (var h = new l.Buf8(256), i = 0; i < 256; i++) h[i] = 252 <= i ? 6 : 248 <= i ? 5 : 240 <= i ? 4 : 224 <= i ? 3 : 192 <= i ? 2 : 1; function d(t, e) { if (e < 65534 && (t.subarray && r || !t.subarray && n)) return String.fromCharCode.apply(null, l.shrinkBuf(t, e)); for (var a = "", i = 0; i < e; i++) a += String.fromCharCode(t[i]); return a; } h[254] = h[254] = 1, a.string2buf = function(t) { var e, a, i, n, r, s = t.length, o = 0; for (n = 0; n < s; n++) 55296 == (64512 & (a = t.charCodeAt(n))) && n + 1 < s && 56320 == (64512 & (i = t.charCodeAt(n + 1))) && (a = 65536 + (a - 55296 << 10) + (i - 56320), n++), o += a < 128 ? 1 : a < 2048 ? 2 : a < 65536 ? 3 : 4; for (e = new l.Buf8(o), n = r = 0; r < o; n++) 55296 == (64512 & (a = t.charCodeAt(n))) && n + 1 < s && 56320 == (64512 & (i = t.charCodeAt(n + 1))) && (a = 65536 + (a - 55296 << 10) + (i - 56320), n++), a < 128 ? e[r++] = a : (a < 2048 ? e[r++] = 192 | a >>> 6 : (a < 65536 ? e[r++] = 224 | a >>> 12 : (e[r++] = 240 | a >>> 18, e[r++] = 128 | a >>> 12 & 63), e[r++] = 128 | a >>> 6 & 63), e[r++] = 128 | 63 & a); return e; }, a.buf2binstring = function(t) { return d(t, t.length); }, a.binstring2buf = function(t) { for (var e = new l.Buf8(t.length), a = 0, i = e.length; a < i; a++) e[a] = t.charCodeAt(a); return e; }, a.buf2string = function(t, e) { var a, i, n, r, s = e || t.length, o = new Array(2 * s); for (a = i = 0; a < s;) if ((n = t[a++]) < 128) o[i++] = n; else if (4 < (r = h[n])) o[i++] = 65533, a += r - 1; else { for (n &= 2 === r ? 31 : 3 === r ? 15 : 7; 1 < r && a < s;) n = n << 6 | 63 & t[a++], r--; 1 < r ? o[i++] = 65533 : n < 65536 ? o[i++] = n : (n -= 65536, o[i++] = 55296 | n >> 10 & 1023, o[i++] = 56320 | 1023 & n); } return d(o, i); }, a.utf8border = function(t, e) { var a; for ((e = e || t.length) > t.length && (e = t.length), a = e - 1; 0 <= a && 128 == (192 & t[a]);) a--; return a < 0 ? e : 0 === a ? e : a + h[t[a]] > e ? a : e; }; }, { "./common": 3 }], 5: [function(t, e, a) { "use strict"; e.exports = function(t, e, a, i) { for (var n = 65535 & t | 0, r = t >>> 16 & 65535 | 0, s = 0; 0 !== a;) { for (a -= s = 2e3 < a ? 2e3 : a; r = r + (n = n + e[i++] | 0) | 0, --s;); n %= 65521, r %= 65521; } return n | r << 16 | 0; }; }, {}], 6: [function(t, e, a) { "use strict"; e.exports = { Z_NO_FLUSH: 0, Z_PARTIAL_FLUSH: 1, Z_SYNC_FLUSH: 2, Z_FULL_FLUSH: 3, Z_FINISH: 4, Z_BLOCK: 5, Z_TREES: 6, Z_OK: 0, Z_STREAM_END: 1, Z_NEED_DICT: 2, Z_ERRNO: -1, Z_STREAM_ERROR: -2, Z_DATA_ERROR: -3, Z_BUF_ERROR: -5, Z_NO_COMPRESSION: 0, Z_BEST_SPEED: 1, Z_BEST_COMPRESSION: 9, Z_DEFAULT_COMPRESSION: -1, Z_FILTERED: 1, Z_HUFFMAN_ONLY: 2, Z_RLE: 3, Z_FIXED: 4, Z_DEFAULT_STRATEGY: 0, Z_BINARY: 0, Z_TEXT: 1, Z_UNKNOWN: 2, Z_DEFLATED: 8 }; }, {}], 7: [function(t, e, a) { "use strict"; var o = function() { for (var t, e = [], a = 0; a < 256; a++) { t = a; for (var i = 0; i < 8; i++) t = 1 & t ? 3988292384 ^ t >>> 1 : t >>> 1; e[a] = t; } return e; }(); e.exports = function(t, e, a, i) { var n = o, r = i + a; t ^= -1; for (var s = i; s < r; s++) t = t >>> 8 ^ n[255 & (t ^ e[s])]; return -1 ^ t; }; }, {}], 8: [function(t, e, a) { "use strict"; var l, _ = t("../utils/common"), h = t("./trees"), u = t("./adler32"), c = t("./crc32"), i = t("./messages"), d = 0, f = 4, b = 0, g = -2, m = -1, w = 4, n = 2, p = 8, v = 9, r = 286, s = 30, o = 19, k = 2 * r + 1, y = 15, x = 3, z = 258, B = z + x + 1, S = 42, E = 113, A = 1, Z = 2, R = 3, C = 4; function N(t, e) { return t.msg = i[e], e; } function O(t) { return (t << 1) - (4 < t ? 9 : 0); } function D(t) { for (var e = t.length; 0 <= --e;) t[e] = 0; } function I(t) { var e = t.state, a = e.pending; a > t.avail_out && (a = t.avail_out), 0 !== a && (_.arraySet(t.output, e.pending_buf, e.pending_out, a, t.next_out), t.next_out += a, e.pending_out += a, t.total_out += a, t.avail_out -= a, e.pending -= a, 0 === e.pending && (e.pending_out = 0)); } function U(t, e) { h._tr_flush_block(t, 0 <= t.block_start ? t.block_start : -1, t.strstart - t.block_start, e), t.block_start = t.strstart, I(t.strm); } function T(t, e) { t.pending_buf[t.pending++] = e; } function F(t, e) { t.pending_buf[t.pending++] = e >>> 8 & 255, t.pending_buf[t.pending++] = 255 & e; } function L(t, e) { var a, i, n = t.max_chain_length, r = t.strstart, s = t.prev_length, o = t.nice_match, l = t.strstart > t.w_size - B ? t.strstart - (t.w_size - B) : 0, h = t.window, d = t.w_mask, f = t.prev, _ = t.strstart + z, u = h[r + s - 1], c = h[r + s]; t.prev_length >= t.good_match && (n >>= 2), o > t.lookahead && (o = t.lookahead); do { if (h[(a = e) + s] === c && h[a + s - 1] === u && h[a] === h[r] && h[++a] === h[r + 1]) { r += 2, a++; do {} while (h[++r] === h[++a] && h[++r] === h[++a] && h[++r] === h[++a] && h[++r] === h[++a] && h[++r] === h[++a] && h[++r] === h[++a] && h[++r] === h[++a] && h[++r] === h[++a] && r < _); if (i = z - (_ - r), r = _ - z, s < i) { if (t.match_start = e, o <= (s = i)) break; u = h[r + s - 1], c = h[r + s]; } } } while ((e = f[e & d]) > l && 0 != --n); return s <= t.lookahead ? s : t.lookahead; } function H(t) { var e, a, i, n, r, s, o, l, h, d, f = t.w_size; do { if (n = t.window_size - t.lookahead - t.strstart, t.strstart >= f + (f - B)) { for (_.arraySet(t.window, t.window, f, f, 0), t.match_start -= f, t.strstart -= f, t.block_start -= f, e = a = t.hash_size; i = t.head[--e], t.head[e] = f <= i ? i - f : 0, --a;); for (e = a = f; i = t.prev[--e], t.prev[e] = f <= i ? i - f : 0, --a;); n += f; } if (0 === t.strm.avail_in) break; if (s = t.strm, o = t.window, l = t.strstart + t.lookahead, h = n, d = void 0, d = s.avail_in, h < d && (d = h), a = 0 === d ? 0 : (s.avail_in -= d, _.arraySet(o, s.input, s.next_in, d, l), 1 === s.state.wrap ? s.adler = u(s.adler, o, d, l) : 2 === s.state.wrap && (s.adler = c(s.adler, o, d, l)), s.next_in += d, s.total_in += d, d), t.lookahead += a, t.lookahead + t.insert >= x) for (r = t.strstart - t.insert, t.ins_h = t.window[r], t.ins_h = (t.ins_h << t.hash_shift ^ t.window[r + 1]) & t.hash_mask; t.insert && (t.ins_h = (t.ins_h << t.hash_shift ^ t.window[r + x - 1]) & t.hash_mask, t.prev[r & t.w_mask] = t.head[t.ins_h], t.head[t.ins_h] = r, r++, t.insert--, !(t.lookahead + t.insert < x));); } while (t.lookahead < B && 0 !== t.strm.avail_in); } function j(t, e) { for (var a, i;;) { if (t.lookahead < B) { if (H(t), t.lookahead < B && e === d) return A; if (0 === t.lookahead) break; } if (a = 0, t.lookahead >= x && (t.ins_h = (t.ins_h << t.hash_shift ^ t.window[t.strstart + x - 1]) & t.hash_mask, a = t.prev[t.strstart & t.w_mask] = t.head[t.ins_h], t.head[t.ins_h] = t.strstart), 0 !== a && t.strstart - a <= t.w_size - B && (t.match_length = L(t, a)), t.match_length >= x) if (i = h._tr_tally(t, t.strstart - t.match_start, t.match_length - x), t.lookahead -= t.match_length, t.match_length <= t.max_lazy_match && t.lookahead >= x) { for (t.match_length--; t.strstart++, t.ins_h = (t.ins_h << t.hash_shift ^ t.window[t.strstart + x - 1]) & t.hash_mask, a = t.prev[t.strstart & t.w_mask] = t.head[t.ins_h], t.head[t.ins_h] = t.strstart, 0 != --t.match_length;); t.strstart++; } else t.strstart += t.match_length, t.match_length = 0, t.ins_h = t.window[t.strstart], t.ins_h = (t.ins_h << t.hash_shift ^ t.window[t.strstart + 1]) & t.hash_mask; else i = h._tr_tally(t, 0, t.window[t.strstart]), t.lookahead--, t.strstart++; if (i && (U(t, !1), 0 === t.strm.avail_out)) return A; } return t.insert = t.strstart < x - 1 ? t.strstart : x - 1, e === f ? (U(t, !0), 0 === t.strm.avail_out ? R : C) : t.last_lit && (U(t, !1), 0 === t.strm.avail_out) ? A : Z; } function K(t, e) { for (var a, i, n;;) { if (t.lookahead < B) { if (H(t), t.lookahead < B && e === d) return A; if (0 === t.lookahead) break; } if (a = 0, t.lookahead >= x && (t.ins_h = (t.ins_h << t.hash_shift ^ t.window[t.strstart + x - 1]) & t.hash_mask, a = t.prev[t.strstart & t.w_mask] = t.head[t.ins_h], t.head[t.ins_h] = t.strstart), t.prev_length = t.match_length, t.prev_match = t.match_start, t.match_length = x - 1, 0 !== a && t.prev_length < t.max_lazy_match && t.strstart - a <= t.w_size - B && (t.match_length = L(t, a), t.match_length <= 5 && (1 === t.strategy || t.match_length === x && 4096 < t.strstart - t.match_start) && (t.match_length = x - 1)), t.prev_length >= x && t.match_length <= t.prev_length) { for (n = t.strstart + t.lookahead - x, i = h._tr_tally(t, t.strstart - 1 - t.prev_match, t.prev_length - x), t.lookahead -= t.prev_length - 1, t.prev_length -= 2; ++t.strstart <= n && (t.ins_h = (t.ins_h << t.hash_shift ^ t.window[t.strstart + x - 1]) & t.hash_mask, a = t.prev[t.strstart & t.w_mask] = t.head[t.ins_h], t.head[t.ins_h] = t.strstart), 0 != --t.prev_length;); if (t.match_available = 0, t.match_length = x - 1, t.strstart++, i && (U(t, !1), 0 === t.strm.avail_out)) return A; } else if (t.match_available) { if ((i = h._tr_tally(t, 0, t.window[t.strstart - 1])) && U(t, !1), t.strstart++, t.lookahead--, 0 === t.strm.avail_out) return A; } else t.match_available = 1, t.strstart++, t.lookahead--; } return t.match_available && (i = h._tr_tally(t, 0, t.window[t.strstart - 1]), t.match_available = 0), t.insert = t.strstart < x - 1 ? t.strstart : x - 1, e === f ? (U(t, !0), 0 === t.strm.avail_out ? R : C) : t.last_lit && (U(t, !1), 0 === t.strm.avail_out) ? A : Z; } function M(t, e, a, i, n) { this.good_length = t, this.max_lazy = e, this.nice_length = a, this.max_chain = i, this.func = n; } function P() { this.strm = null, this.status = 0, this.pending_buf = null, this.pending_buf_size = 0, this.pending_out = 0, this.pending = 0, this.wrap = 0, this.gzhead = null, this.gzindex = 0, this.method = p, this.last_flush = -1, this.w_size = 0, this.w_bits = 0, this.w_mask = 0, this.window = null, this.window_size = 0, this.prev = null, this.head = null, this.ins_h = 0, this.hash_size = 0, this.hash_bits = 0, this.hash_mask = 0, this.hash_shift = 0, this.block_start = 0, this.match_length = 0, this.prev_match = 0, this.match_available = 0, this.strstart = 0, this.match_start = 0, this.lookahead = 0, this.prev_length = 0, this.max_chain_length = 0, this.max_lazy_match = 0, this.level = 0, this.strategy = 0, this.good_match = 0, this.nice_match = 0, this.dyn_ltree = new _.Buf16(2 * k), this.dyn_dtree = new _.Buf16(2 * (2 * s + 1)), this.bl_tree = new _.Buf16(2 * (2 * o + 1)), D(this.dyn_ltree), D(this.dyn_dtree), D(this.bl_tree), this.l_desc = null, this.d_desc = null, this.bl_desc = null, this.bl_count = new _.Buf16(y + 1), this.heap = new _.Buf16(2 * r + 1), D(this.heap), this.heap_len = 0, this.heap_max = 0, this.depth = new _.Buf16(2 * r + 1), D(this.depth), this.l_buf = 0, this.lit_bufsize = 0, this.last_lit = 0, this.d_buf = 0, this.opt_len = 0, this.static_len = 0, this.matches = 0, this.insert = 0, this.bi_buf = 0, this.bi_valid = 0; } function Y(t) { var e; return t && t.state ? (t.total_in = t.total_out = 0, t.data_type = n, (e = t.state).pending = 0, e.pending_out = 0, e.wrap < 0 && (e.wrap = -e.wrap), e.status = e.wrap ? S : E, t.adler = 2 === e.wrap ? 0 : 1, e.last_flush = d, h._tr_init(e), b) : N(t, g); } function q(t) { var e, a = Y(t); return a === b && ((e = t.state).window_size = 2 * e.w_size, D(e.head), e.max_lazy_match = l[e.level].max_lazy, e.good_match = l[e.level].good_length, e.nice_match = l[e.level].nice_length, e.max_chain_length = l[e.level].max_chain, e.strstart = 0, e.block_start = 0, e.lookahead = 0, e.insert = 0, e.match_length = e.prev_length = x - 1, e.match_available = 0, e.ins_h = 0), a; } function G(t, e, a, i, n, r) { if (!t) return g; var s = 1; if (e === m && (e = 6), i < 0 ? (s = 0, i = -i) : 15 < i && (s = 2, i -= 16), n < 1 || v < n || a !== p || i < 8 || 15 < i || e < 0 || 9 < e || r < 0 || w < r) return N(t, g); 8 === i && (i = 9); var o = new P(); return (t.state = o).strm = t, o.wrap = s, o.gzhead = null, o.w_bits = i, o.w_size = 1 << o.w_bits, o.w_mask = o.w_size - 1, o.hash_bits = n + 7, o.hash_size = 1 << o.hash_bits, o.hash_mask = o.hash_size - 1, o.hash_shift = ~~((o.hash_bits + x - 1) / x), o.window = new _.Buf8(2 * o.w_size), o.head = new _.Buf16(o.hash_size), o.prev = new _.Buf16(o.w_size), o.lit_bufsize = 1 << n + 6, o.pending_buf_size = 4 * o.lit_bufsize, o.pending_buf = new _.Buf8(o.pending_buf_size), o.d_buf = 1 * o.lit_bufsize, o.l_buf = 3 * o.lit_bufsize, o.level = e, o.strategy = r, o.method = a, q(t); } l = [ new M(0, 0, 0, 0, function(t, e) { var a = 65535; for (a > t.pending_buf_size - 5 && (a = t.pending_buf_size - 5);;) { if (t.lookahead <= 1) { if (H(t), 0 === t.lookahead && e === d) return A; if (0 === t.lookahead) break; } t.strstart += t.lookahead, t.lookahead = 0; var i = t.block_start + a; if ((0 === t.strstart || t.strstart >= i) && (t.lookahead = t.strstart - i, t.strstart = i, U(t, !1), 0 === t.strm.avail_out)) return A; if (t.strstart - t.block_start >= t.w_size - B && (U(t, !1), 0 === t.strm.avail_out)) return A; } return t.insert = 0, e === f ? (U(t, !0), 0 === t.strm.avail_out ? R : C) : (t.strstart > t.block_start && (U(t, !1), t.strm.avail_out), A); }), new M(4, 4, 8, 4, j), new M(4, 5, 16, 8, j), new M(4, 6, 32, 32, j), new M(4, 4, 16, 16, K), new M(8, 16, 32, 32, K), new M(8, 16, 128, 128, K), new M(8, 32, 128, 256, K), new M(32, 128, 258, 1024, K), new M(32, 258, 258, 4096, K) ], a.deflateInit = function(t, e) { return G(t, e, p, 15, 8, 0); }, a.deflateInit2 = G, a.deflateReset = q, a.deflateResetKeep = Y, a.deflateSetHeader = function(t, e) { return t && t.state ? 2 !== t.state.wrap ? g : (t.state.gzhead = e, b) : g; }, a.deflate = function(t, e) { var a, i, n, r; if (!t || !t.state || 5 < e || e < 0) return t ? N(t, g) : g; if (i = t.state, !t.output || !t.input && 0 !== t.avail_in || 666 === i.status && e !== f) return N(t, 0 === t.avail_out ? -5 : g); if (i.strm = t, a = i.last_flush, i.last_flush = e, i.status === S) if (2 === i.wrap) t.adler = 0, T(i, 31), T(i, 139), T(i, 8), i.gzhead ? (T(i, (i.gzhead.text ? 1 : 0) + (i.gzhead.hcrc ? 2 : 0) + (i.gzhead.extra ? 4 : 0) + (i.gzhead.name ? 8 : 0) + (i.gzhead.comment ? 16 : 0)), T(i, 255 & i.gzhead.time), T(i, i.gzhead.time >> 8 & 255), T(i, i.gzhead.time >> 16 & 255), T(i, i.gzhead.time >> 24 & 255), T(i, 9 === i.level ? 2 : 2 <= i.strategy || i.level < 2 ? 4 : 0), T(i, 255 & i.gzhead.os), i.gzhead.extra && i.gzhead.extra.length && (T(i, 255 & i.gzhead.extra.length), T(i, i.gzhead.extra.length >> 8 & 255)), i.gzhead.hcrc && (t.adler = c(t.adler, i.pending_buf, i.pending, 0)), i.gzindex = 0, i.status = 69) : (T(i, 0), T(i, 0), T(i, 0), T(i, 0), T(i, 0), T(i, 9 === i.level ? 2 : 2 <= i.strategy || i.level < 2 ? 4 : 0), T(i, 3), i.status = E); else { var s = p + (i.w_bits - 8 << 4) << 8; s |= (2 <= i.strategy || i.level < 2 ? 0 : i.level < 6 ? 1 : 6 === i.level ? 2 : 3) << 6, 0 !== i.strstart && (s |= 32), s += 31 - s % 31, i.status = E, F(i, s), 0 !== i.strstart && (F(i, t.adler >>> 16), F(i, 65535 & t.adler)), t.adler = 1; } if (69 === i.status) if (i.gzhead.extra) { for (n = i.pending; i.gzindex < (65535 & i.gzhead.extra.length) && (i.pending !== i.pending_buf_size || (i.gzhead.hcrc && i.pending > n && (t.adler = c(t.adler, i.pending_buf, i.pending - n, n)), I(t), n = i.pending, i.pending !== i.pending_buf_size));) T(i, 255 & i.gzhead.extra[i.gzindex]), i.gzindex++; i.gzhead.hcrc && i.pending > n && (t.adler = c(t.adler, i.pending_buf, i.pending - n, n)), i.gzindex === i.gzhead.extra.length && (i.gzindex = 0, i.status = 73); } else i.status = 73; if (73 === i.status) if (i.gzhead.name) { n = i.pending; do { if (i.pending === i.pending_buf_size && (i.gzhead.hcrc && i.pending > n && (t.adler = c(t.adler, i.pending_buf, i.pending - n, n)), I(t), n = i.pending, i.pending === i.pending_buf_size)) { r = 1; break; } T(i, r = i.gzindex < i.gzhead.name.length ? 255 & i.gzhead.name.charCodeAt(i.gzindex++) : 0); } while (0 !== r); i.gzhead.hcrc && i.pending > n && (t.adler = c(t.adler, i.pending_buf, i.pending - n, n)), 0 === r && (i.gzindex = 0, i.status = 91); } else i.status = 91; if (91 === i.status) if (i.gzhead.comment) { n = i.pending; do { if (i.pending === i.pending_buf_size && (i.gzhead.hcrc && i.pending > n && (t.adler = c(t.adler, i.pending_buf, i.pending - n, n)), I(t), n = i.pending, i.pending === i.pending_buf_size)) { r = 1; break; } T(i, r = i.gzindex < i.gzhead.comment.length ? 255 & i.gzhead.comment.charCodeAt(i.gzindex++) : 0); } while (0 !== r); i.gzhead.hcrc && i.pending > n && (t.adler = c(t.adler, i.pending_buf, i.pending - n, n)), 0 === r && (i.status = 103); } else i.status = 103; if (103 === i.status && (i.gzhead.hcrc ? (i.pending + 2 > i.pending_buf_size && I(t), i.pending + 2 <= i.pending_buf_size && (T(i, 255 & t.adler), T(i, t.adler >> 8 & 255), t.adler = 0, i.status = E)) : i.status = E), 0 !== i.pending) { if (I(t), 0 === t.avail_out) return i.last_flush = -1, b; } else if (0 === t.avail_in && O(e) <= O(a) && e !== f) return N(t, -5); if (666 === i.status && 0 !== t.avail_in) return N(t, -5); if (0 !== t.avail_in || 0 !== i.lookahead || e !== d && 666 !== i.status) { var o = 2 === i.strategy ? function(t, e) { for (var a;;) { if (0 === t.lookahead && (H(t), 0 === t.lookahead)) { if (e === d) return A; break; } if (t.match_length = 0, a = h._tr_tally(t, 0, t.window[t.strstart]), t.lookahead--, t.strstart++, a && (U(t, !1), 0 === t.strm.avail_out)) return A; } return t.insert = 0, e === f ? (U(t, !0), 0 === t.strm.avail_out ? R : C) : t.last_lit && (U(t, !1), 0 === t.strm.avail_out) ? A : Z; }(i, e) : 3 === i.strategy ? function(t, e) { for (var a, i, n, r, s = t.window;;) { if (t.lookahead <= z) { if (H(t), t.lookahead <= z && e === d) return A; if (0 === t.lookahead) break; } if (t.match_length = 0, t.lookahead >= x && 0 < t.strstart && (i = s[n = t.strstart - 1]) === s[++n] && i === s[++n] && i === s[++n]) { r = t.strstart + z; do {} while (i === s[++n] && i === s[++n] && i === s[++n] && i === s[++n] && i === s[++n] && i === s[++n] && i === s[++n] && i === s[++n] && n < r); t.match_length = z - (r - n), t.match_length > t.lookahead && (t.match_length = t.lookahead); } if (t.match_length >= x ? (a = h._tr_tally(t, 1, t.match_length - x), t.lookahead -= t.match_length, t.strstart += t.match_length, t.match_length = 0) : (a = h._tr_tally(t, 0, t.window[t.strstart]), t.lookahead--, t.strstart++), a && (U(t, !1), 0 === t.strm.avail_out)) return A; } return t.insert = 0, e === f ? (U(t, !0), 0 === t.strm.avail_out ? R : C) : t.last_lit && (U(t, !1), 0 === t.strm.avail_out) ? A : Z; }(i, e) : l[i.level].func(i, e); if (o !== R && o !== C || (i.status = 666), o === A || o === R) return 0 === t.avail_out && (i.last_flush = -1), b; if (o === Z && (1 === e ? h._tr_align(i) : 5 !== e && (h._tr_stored_block(i, 0, 0, !1), 3 === e && (D(i.head), 0 === i.lookahead && (i.strstart = 0, i.block_start = 0, i.insert = 0))), I(t), 0 === t.avail_out)) return i.last_flush = -1, b; } return e !== f ? b : i.wrap <= 0 ? 1 : (2 === i.wrap ? (T(i, 255 & t.adler), T(i, t.adler >> 8 & 255), T(i, t.adler >> 16 & 255), T(i, t.adler >> 24 & 255), T(i, 255 & t.total_in), T(i, t.total_in >> 8 & 255), T(i, t.total_in >> 16 & 255), T(i, t.total_in >> 24 & 255)) : (F(i, t.adler >>> 16), F(i, 65535 & t.adler)), I(t), 0 < i.wrap && (i.wrap = -i.wrap), 0 !== i.pending ? b : 1); }, a.deflateEnd = function(t) { var e; return t && t.state ? (e = t.state.status) !== S && 69 !== e && 73 !== e && 91 !== e && 103 !== e && e !== E && 666 !== e ? N(t, g) : (t.state = null, e === E ? N(t, -3) : b) : g; }, a.deflateSetDictionary = function(t, e) { var a, i, n, r, s, o, l, h, d = e.length; if (!t || !t.state) return g; if (2 === (r = (a = t.state).wrap) || 1 === r && a.status !== S || a.lookahead) return g; for (1 === r && (t.adler = u(t.adler, e, d, 0)), a.wrap = 0, d >= a.w_size && (0 === r && (D(a.head), a.strstart = 0, a.block_start = 0, a.insert = 0), h = new _.Buf8(a.w_size), _.arraySet(h, e, d - a.w_size, a.w_size, 0), e = h, d = a.w_size), s = t.avail_in, o = t.next_in, l = t.input, t.avail_in = d, t.next_in = 0, t.input = e, H(a); a.lookahead >= x;) { for (i = a.strstart, n = a.lookahead - (x - 1); a.ins_h = (a.ins_h << a.hash_shift ^ a.window[i + x - 1]) & a.hash_mask, a.prev[i & a.w_mask] = a.head[a.ins_h], a.head[a.ins_h] = i, i++, --n;); a.strstart = i, a.lookahead = x - 1, H(a); } return a.strstart += a.lookahead, a.block_start = a.strstart, a.insert = a.lookahead, a.lookahead = 0, a.match_length = a.prev_length = x - 1, a.match_available = 0, t.next_in = o, t.input = l, t.avail_in = s, a.wrap = r, b; }, a.deflateInfo = "pako deflate (from Nodeca project)"; }, { "../utils/common": 3, "./adler32": 5, "./crc32": 7, "./messages": 13, "./trees": 14 }], 9: [function(t, e, a) { "use strict"; e.exports = function() { this.text = 0, this.time = 0, this.xflags = 0, this.os = 0, this.extra = null, this.extra_len = 0, this.name = "", this.comment = "", this.hcrc = 0, this.done = !1; }; }, {}], 10: [function(t, e, a) { "use strict"; e.exports = function(t, e) { var a, i, n, r, s, o, l, h, d, f, _, u, c, b, g, m, w, p, v, k, y, x, z, B, S; a = t.state, i = t.next_in, B = t.input, n = i + (t.avail_in - 5), r = t.next_out, S = t.output, s = r - (e - t.avail_out), o = r + (t.avail_out - 257), l = a.dmax, h = a.wsize, d = a.whave, f = a.wnext, _ = a.window, u = a.hold, c = a.bits, b = a.lencode, g = a.distcode, m = (1 << a.lenbits) - 1, w = (1 << a.distbits) - 1; t: do { c < 15 && (u += B[i++] << c, c += 8, u += B[i++] << c, c += 8), p = b[u & m]; e: for (;;) { if (u >>>= v = p >>> 24, c -= v, 0 === (v = p >>> 16 & 255)) S[r++] = 65535 & p; else { if (!(16 & v)) { if (0 == (64 & v)) { p = b[(65535 & p) + (u & (1 << v) - 1)]; continue e; } if (32 & v) { a.mode = 12; break t; } t.msg = "invalid literal/length code", a.mode = 30; break t; } k = 65535 & p, (v &= 15) && (c < v && (u += B[i++] << c, c += 8), k += u & (1 << v) - 1, u >>>= v, c -= v), c < 15 && (u += B[i++] << c, c += 8, u += B[i++] << c, c += 8), p = g[u & w]; a: for (;;) { if (u >>>= v = p >>> 24, c -= v, !(16 & (v = p >>> 16 & 255))) { if (0 == (64 & v)) { p = g[(65535 & p) + (u & (1 << v) - 1)]; continue a; } t.msg = "invalid distance code", a.mode = 30; break t; } if (y = 65535 & p, c < (v &= 15) && (u += B[i++] << c, (c += 8) < v && (u += B[i++] << c, c += 8)), l < (y += u & (1 << v) - 1)) { t.msg = "invalid distance too far back", a.mode = 30; break t; } if (u >>>= v, c -= v, (v = r - s) < y) { if (d < (v = y - v) && a.sane) { t.msg = "invalid distance too far back", a.mode = 30; break t; } if (z = _, (x = 0) === f) { if (x += h - v, v < k) { for (k -= v; S[r++] = _[x++], --v;); x = r - y, z = S; } } else if (f < v) { if (x += h + f - v, (v -= f) < k) { for (k -= v; S[r++] = _[x++], --v;); if (x = 0, f < k) { for (k -= v = f; S[r++] = _[x++], --v;); x = r - y, z = S; } } } else if (x += f - v, v < k) { for (k -= v; S[r++] = _[x++], --v;); x = r - y, z = S; } for (; 2 < k;) S[r++] = z[x++], S[r++] = z[x++], S[r++] = z[x++], k -= 3; k && (S[r++] = z[x++], 1 < k && (S[r++] = z[x++])); } else { for (x = r - y; S[r++] = S[x++], S[r++] = S[x++], S[r++] = S[x++], 2 < (k -= 3);); k && (S[r++] = S[x++], 1 < k && (S[r++] = S[x++])); } break; } } break; } } while (i < n && r < o); i -= k = c >> 3, u &= (1 << (c -= k << 3)) - 1, t.next_in = i, t.next_out = r, t.avail_in = i < n ? n - i + 5 : 5 - (i - n), t.avail_out = r < o ? o - r + 257 : 257 - (r - o), a.hold = u, a.bits = c; }; }, {}], 11: [function(t, e, a) { "use strict"; var Z = t("../utils/common"), R = t("./adler32"), C = t("./crc32"), N = t("./inffast"), O = t("./inftrees"), D = 1, I = 2, U = 0, T = -2, F = 1, i = 852, n = 592; function L(t) { return (t >>> 24 & 255) + (t >>> 8 & 65280) + ((65280 & t) << 8) + ((255 & t) << 24); } function r() { this.mode = 0, this.last = !1, this.wrap = 0, this.havedict = !1, this.flags = 0, this.dmax = 0, this.check = 0, this.total = 0, this.head = null, this.wbits = 0, this.wsize = 0, this.whave = 0, this.wnext = 0, this.window = null, this.hold = 0, this.bits = 0, this.length = 0, this.offset = 0, this.extra = 0, this.lencode = null, this.distcode = null, this.lenbits = 0, this.distbits = 0, this.ncode = 0, this.nlen = 0, this.ndist = 0, this.have = 0, this.next = null, this.lens = new Z.Buf16(320), this.work = new Z.Buf16(288), this.lendyn = null, this.distdyn = null, this.sane = 0, this.back = 0, this.was = 0; } function s(t) { var e; return t && t.state ? (e = t.state, t.total_in = t.total_out = e.total = 0, t.msg = "", e.wrap && (t.adler = 1 & e.wrap), e.mode = F, e.last = 0, e.havedict = 0, e.dmax = 32768, e.head = null, e.hold = 0, e.bits = 0, e.lencode = e.lendyn = new Z.Buf32(i), e.distcode = e.distdyn = new Z.Buf32(n), e.sane = 1, e.back = -1, U) : T; } function o(t) { var e; return t && t.state ? ((e = t.state).wsize = 0, e.whave = 0, e.wnext = 0, s(t)) : T; } function l(t, e) { var a, i; return t && t.state ? (i = t.state, e < 0 ? (a = 0, e = -e) : (a = 1 + (e >> 4), e < 48 && (e &= 15)), e && (e < 8 || 15 < e) ? T : (null !== i.window && i.wbits !== e && (i.window = null), i.wrap = a, i.wbits = e, o(t))) : T; } function h(t, e) { var a, i; return t ? (i = new r(), (t.state = i).window = null, (a = l(t, e)) !== U && (t.state = null), a) : T; } var d, f, _ = !0; function H(t) { if (_) { var e; for (d = new Z.Buf32(512), f = new Z.Buf32(32), e = 0; e < 144;) t.lens[e++] = 8; for (; e < 256;) t.lens[e++] = 9; for (; e < 280;) t.lens[e++] = 7; for (; e < 288;) t.lens[e++] = 8; for (O(D, t.lens, 0, 288, d, 0, t.work, { bits: 9 }), e = 0; e < 32;) t.lens[e++] = 5; O(I, t.lens, 0, 32, f, 0, t.work, { bits: 5 }), _ = !1; } t.lencode = d, t.lenbits = 9, t.distcode = f, t.distbits = 5; } function j(t, e, a, i) { var n, r = t.state; return null === r.window && (r.wsize = 1 << r.wbits, r.wnext = 0, r.whave = 0, r.window = new Z.Buf8(r.wsize)), i >= r.wsize ? (Z.arraySet(r.window, e, a - r.wsize, r.wsize, 0), r.wnext = 0, r.whave = r.wsize) : (i < (n = r.wsize - r.wnext) && (n = i), Z.arraySet(r.window, e, a - i, n, r.wnext), (i -= n) ? (Z.arraySet(r.window, e, a - i, i, 0), r.wnext = i, r.whave = r.wsize) : (r.wnext += n, r.wnext === r.wsize && (r.wnext = 0), r.whave < r.wsize && (r.whave += n))), 0; } a.inflateReset = o, a.inflateReset2 = l, a.inflateResetKeep = s, a.inflateInit = function(t) { return h(t, 15); }, a.inflateInit2 = h, a.inflate = function(t, e) { var a, i, n, r, s, o, l, h, d, f, _, u, c, b, g, m, w, p, v, k, y, x, z, B, S = 0, E = new Z.Buf8(4), A = [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ]; if (!t || !t.state || !t.output || !t.input && 0 !== t.avail_in) return T; 12 === (a = t.state).mode && (a.mode = 13), s = t.next_out, n = t.output, l = t.avail_out, r = t.next_in, i = t.input, o = t.avail_in, h = a.hold, d = a.bits, f = o, _ = l, x = U; t: for (;;) switch (a.mode) { case F: if (0 === a.wrap) { a.mode = 13; break; } for (; d < 16;) { if (0 === o) break t; o--, h += i[r++] << d, d += 8; } if (2 & a.wrap && 35615 === h) { E[a.check = 0] = 255 & h, E[1] = h >>> 8 & 255, a.check = C(a.check, E, 2, 0), d = h = 0, a.mode = 2; break; } if (a.flags = 0, a.head && (a.head.done = !1), !(1 & a.wrap) || (((255 & h) << 8) + (h >> 8)) % 31) { t.msg = "incorrect header check", a.mode = 30; break; } if (8 != (15 & h)) { t.msg = "unknown compression method", a.mode = 30; break; } if (d -= 4, y = 8 + (15 & (h >>>= 4)), 0 === a.wbits) a.wbits = y; else if (y > a.wbits) { t.msg = "invalid window size", a.mode = 30; break; } a.dmax = 1 << y, t.adler = a.check = 1, a.mode = 512 & h ? 10 : 12, d = h = 0; break; case 2: for (; d < 16;) { if (0 === o) break t; o--, h += i[r++] << d, d += 8; } if (a.flags = h, 8 != (255 & a.flags)) { t.msg = "unknown compression method", a.mode = 30; break; } if (57344 & a.flags) { t.msg = "unknown header flags set", a.mode = 30; break; } a.head && (a.head.text = h >> 8 & 1), 512 & a.flags && (E[0] = 255 & h, E[1] = h >>> 8 & 255, a.check = C(a.check, E, 2, 0)), d = h = 0, a.mode = 3; case 3: for (; d < 32;) { if (0 === o) break t; o--, h += i[r++] << d, d += 8; } a.head && (a.head.time = h), 512 & a.flags && (E[0] = 255 & h, E[1] = h >>> 8 & 255, E[2] = h >>> 16 & 255, E[3] = h >>> 24 & 255, a.check = C(a.check, E, 4, 0)), d = h = 0, a.mode = 4; case 4: for (; d < 16;) { if (0 === o) break t; o--, h += i[r++] << d, d += 8; } a.head && (a.head.xflags = 255 & h, a.head.os = h >> 8), 512 & a.flags && (E[0] = 255 & h, E[1] = h >>> 8 & 255, a.check = C(a.check, E, 2, 0)), d = h = 0, a.mode = 5; case 5: if (1024 & a.flags) { for (; d < 16;) { if (0 === o) break t; o--, h += i[r++] << d, d += 8; } a.length = h, a.head && (a.head.extra_len = h), 512 & a.flags && (E[0] = 255 & h, E[1] = h >>> 8 & 255, a.check = C(a.check, E, 2, 0)), d = h = 0; } else a.head && (a.head.extra = null); a.mode = 6; case 6: if (1024 & a.flags && (o < (u = a.length) && (u = o), u && (a.head && (y = a.head.extra_len - a.length, a.head.extra || (a.head.extra = new Array(a.head.extra_len)), Z.arraySet(a.head.extra, i, r, u, y)), 512 & a.flags && (a.check = C(a.check, i, u, r)), o -= u, r += u, a.length -= u), a.length)) break t; a.length = 0, a.mode = 7; case 7: if (2048 & a.flags) { if (0 === o) break t; for (u = 0; y = i[r + u++], a.head && y && a.length < 65536 && (a.head.name += String.fromCharCode(y)), y && u < o;); if (512 & a.flags && (a.check = C(a.check, i, u, r)), o -= u, r += u, y) break t; } else a.head && (a.head.name = null); a.length = 0, a.mode = 8; case 8: if (4096 & a.flags) { if (0 === o) break t; for (u = 0; y = i[r + u++], a.head && y && a.length < 65536 && (a.head.comment += String.fromCharCode(y)), y && u < o;); if (512 & a.flags && (a.check = C(a.check, i, u, r)), o -= u, r += u, y) break t; } else a.head && (a.head.comment = null); a.mode = 9; case 9: if (512 & a.flags) { for (; d < 16;) { if (0 === o) break t; o--, h += i[r++] << d, d += 8; } if (h !== (65535 & a.check)) { t.msg = "header crc mismatch", a.mode = 30; break; } d = h = 0; } a.head && (a.head.hcrc = a.flags >> 9 & 1, a.head.done = !0), t.adler = a.check = 0, a.mode = 12; break; case 10: for (; d < 32;) { if (0 === o) break t; o--, h += i[r++] << d, d += 8; } t.adler = a.check = L(h), d = h = 0, a.mode = 11; case 11: if (0 === a.havedict) return t.next_out = s, t.avail_out = l, t.next_in = r, t.avail_in = o, a.hold = h, a.bits = d, 2; t.adler = a.check = 1, a.mode = 12; case 12: if (5 === e || 6 === e) break t; case 13: if (a.last) { h >>>= 7 & d, d -= 7 & d, a.mode = 27; break; } for (; d < 3;) { if (0 === o) break t; o--, h += i[r++] << d, d += 8; } switch (a.last = 1 & h, d -= 1, 3 & (h >>>= 1)) { case 0: a.mode = 14; break; case 1: if (H(a), a.mode = 20, 6 !== e) break; h >>>= 2, d -= 2; break t; case 2: a.mode = 17; break; case 3: t.msg = "invalid block type", a.mode = 30; } h >>>= 2, d -= 2; break; case 14: for (h >>>= 7 & d, d -= 7 & d; d < 32;) { if (0 === o) break t; o--, h += i[r++] << d, d += 8; } if ((65535 & h) != (h >>> 16 ^ 65535)) { t.msg = "invalid stored block lengths", a.mode = 30; break; } if (a.length = 65535 & h, d = h = 0, a.mode = 15, 6 === e) break t; case 15: a.mode = 16; case 16: if (u = a.length) { if (o < u && (u = o), l < u && (u = l), 0 === u) break t; Z.arraySet(n, i, r, u, s), o -= u, r += u, l -= u, s += u, a.length -= u; break; } a.mode = 12; break; case 17: for (; d < 14;) { if (0 === o) break t; o--, h += i[r++] << d, d += 8; } if (a.nlen = 257 + (31 & h), h >>>= 5, d -= 5, a.ndist = 1 + (31 & h), h >>>= 5, d -= 5, a.ncode = 4 + (15 & h), h >>>= 4, d -= 4, 286 < a.nlen || 30 < a.ndist) { t.msg = "too many length or distance symbols", a.mode = 30; break; } a.have = 0, a.mode = 18; case 18: for (; a.have < a.ncode;) { for (; d < 3;) { if (0 === o) break t; o--, h += i[r++] << d, d += 8; } a.lens[A[a.have++]] = 7 & h, h >>>= 3, d -= 3; } for (; a.have < 19;) a.lens[A[a.have++]] = 0; if (a.lencode = a.lendyn, a.lenbits = 7, z = { bits: a.lenbits }, x = O(0, a.lens, 0, 19, a.lencode, 0, a.work, z), a.lenbits = z.bits, x) { t.msg = "invalid code lengths set", a.mode = 30; break; } a.have = 0, a.mode = 19; case 19: for (; a.have < a.nlen + a.ndist;) { for (; m = (S = a.lencode[h & (1 << a.lenbits) - 1]) >>> 16 & 255, w = 65535 & S, !((g = S >>> 24) <= d);) { if (0 === o) break t; o--, h += i[r++] << d, d += 8; } if (w < 16) h >>>= g, d -= g, a.lens[a.have++] = w; else { if (16 === w) { for (B = g + 2; d < B;) { if (0 === o) break t; o--, h += i[r++] << d, d += 8; } if (h >>>= g, d -= g, 0 === a.have) { t.msg = "invalid bit length repeat", a.mode = 30; break; } y = a.lens[a.have - 1], u = 3 + (3 & h), h >>>= 2, d -= 2; } else if (17 === w) { for (B = g + 3; d < B;) { if (0 === o) break t; o--, h += i[r++] << d, d += 8; } d -= g, y = 0, u = 3 + (7 & (h >>>= g)), h >>>= 3, d -= 3; } else { for (B = g + 7; d < B;) { if (0 === o) break t; o--, h += i[r++] << d, d += 8; } d -= g, y = 0, u = 11 + (127 & (h >>>= g)), h >>>= 7, d -= 7; } if (a.have + u > a.nlen + a.ndist) { t.msg = "invalid bit length repeat", a.mode = 30; break; } for (; u--;) a.lens[a.have++] = y; } } if (30 === a.mode) break; if (0 === a.lens[256]) { t.msg = "invalid code -- missing end-of-block", a.mode = 30; break; } if (a.lenbits = 9, z = { bits: a.lenbits }, x = O(D, a.lens, 0, a.nlen, a.lencode, 0, a.work, z), a.lenbits = z.bits, x) { t.msg = "invalid literal/lengths set", a.mode = 30; break; } if (a.distbits = 6, a.distcode = a.distdyn, z = { bits: a.distbits }, x = O(I, a.lens, a.nlen, a.ndist, a.distcode, 0, a.work, z), a.distbits = z.bits, x) { t.msg = "invalid distances set", a.mode = 30; break; } if (a.mode = 20, 6 === e) break t; case 20: a.mode = 21; case 21: if (6 <= o && 258 <= l) { t.next_out = s, t.avail_out = l, t.next_in = r, t.avail_in = o, a.hold = h, a.bits = d, N(t, _), s = t.next_out, n = t.output, l = t.avail_out, r = t.next_in, i = t.input, o = t.avail_in, h = a.hold, d = a.bits, 12 === a.mode && (a.back = -1); break; } for (a.back = 0; m = (S = a.lencode[h & (1 << a.lenbits) - 1]) >>> 16 & 255, w = 65535 & S, !((g = S >>> 24) <= d);) { if (0 === o) break t; o--, h += i[r++] << d, d += 8; } if (m && 0 == (240 & m)) { for (p = g, v = m, k = w; m = (S = a.lencode[k + ((h & (1 << p + v) - 1) >> p)]) >>> 16 & 255, w = 65535 & S, !(p + (g = S >>> 24) <= d);) { if (0 === o) break t; o--, h += i[r++] << d, d += 8; } h >>>= p, d -= p, a.back += p; } if (h >>>= g, d -= g, a.back += g, a.length = w, 0 === m) { a.mode = 26; break; } if (32 & m) { a.back = -1, a.mode = 12; break; } if (64 & m) { t.msg = "invalid literal/length code", a.mode = 30; break; } a.extra = 15 & m, a.mode = 22; case 22: if (a.extra) { for (B = a.extra; d < B;) { if (0 === o) break t; o--, h += i[r++] << d, d += 8; } a.length += h & (1 << a.extra) - 1, h >>>= a.extra, d -= a.extra, a.back += a.extra; } a.was = a.length, a.mode = 23; case 23: for (; m = (S = a.distcode[h & (1 << a.distbits) - 1]) >>> 16 & 255, w = 65535 & S, !((g = S >>> 24) <= d);) { if (0 === o) break t; o--, h += i[r++] << d, d += 8; } if (0 == (240 & m)) { for (p = g, v = m, k = w; m = (S = a.distcode[k + ((h & (1 << p + v) - 1) >> p)]) >>> 16 & 255, w = 65535 & S, !(p + (g = S >>> 24) <= d);) { if (0 === o) break t; o--, h += i[r++] << d, d += 8; } h >>>= p, d -= p, a.back += p; } if (h >>>= g, d -= g, a.back += g, 64 & m) { t.msg = "invalid distance code", a.mode = 30; break; } a.offset = w, a.extra = 15 & m, a.mode = 24; case 24: if (a.extra) { for (B = a.extra; d < B;) { if (0 === o) break t; o--, h += i[r++] << d, d += 8; } a.offset += h & (1 << a.extra) - 1, h >>>= a.extra, d -= a.extra, a.back += a.extra; } if (a.offset > a.dmax) { t.msg = "invalid distance too far back", a.mode = 30; break; } a.mode = 25; case 25: if (0 === l) break t; if (u = _ - l, a.offset > u) { if ((u = a.offset - u) > a.whave && a.sane) { t.msg = "invalid distance too far back", a.mode = 30; break; } u > a.wnext ? (u -= a.wnext, c = a.wsize - u) : c = a.wnext - u, u > a.length && (u = a.length), b = a.window; } else b = n, c = s - a.offset, u = a.length; for (l < u && (u = l), l -= u, a.length -= u; n[s++] = b[c++], --u;); 0 === a.length && (a.mode = 21); break; case 26: if (0 === l) break t; n[s++] = a.length, l--, a.mode = 21; break; case 27: if (a.wrap) { for (; d < 32;) { if (0 === o) break t; o--, h |= i[r++] << d, d += 8; } if (_ -= l, t.total_out += _, a.total += _, _ && (t.adler = a.check = a.flags ? C(a.check, n, _, s - _) : R(a.check, n, _, s - _)), _ = l, (a.flags ? h : L(h)) !== a.check) { t.msg = "incorrect data check", a.mode = 30; break; } d = h = 0; } a.mode = 28; case 28: if (a.wrap && a.flags) { for (; d < 32;) { if (0 === o) break t; o--, h += i[r++] << d, d += 8; } if (h !== (4294967295 & a.total)) { t.msg = "incorrect length check", a.mode = 30; break; } d = h = 0; } a.mode = 29; case 29: x = 1; break t; case 30: x = -3; break t; case 31: return -4; case 32: default: return T; } return t.next_out = s, t.avail_out = l, t.next_in = r, t.avail_in = o, a.hold = h, a.bits = d, (a.wsize || _ !== t.avail_out && a.mode < 30 && (a.mode < 27 || 4 !== e)) && j(t, t.output, t.next_out, _ - t.avail_out) ? (a.mode = 31, -4) : (f -= t.avail_in, _ -= t.avail_out, t.total_in += f, t.total_out += _, a.total += _, a.wrap && _ && (t.adler = a.check = a.flags ? C(a.check, n, _, t.next_out - _) : R(a.check, n, _, t.next_out - _)), t.data_type = a.bits + (a.last ? 64 : 0) + (12 === a.mode ? 128 : 0) + (20 === a.mode || 15 === a.mode ? 256 : 0), (0 === f && 0 === _ || 4 === e) && x === U && (x = -5), x); }, a.inflateEnd = function(t) { if (!t || !t.state) return T; var e = t.state; return e.window && (e.window = null), t.state = null, U; }, a.inflateGetHeader = function(t, e) { var a; return t && t.state ? 0 == (2 & (a = t.state).wrap) ? T : ((a.head = e).done = !1, U) : T; }, a.inflateSetDictionary = function(t, e) { var a, i = e.length; return t && t.state ? 0 !== (a = t.state).wrap && 11 !== a.mode ? T : 11 === a.mode && R(1, e, i, 0) !== a.check ? -3 : j(t, e, i, i) ? (a.mode = 31, -4) : (a.havedict = 1, U) : T; }, a.inflateInfo = "pako inflate (from Nodeca project)"; }, { "../utils/common": 3, "./adler32": 5, "./crc32": 7, "./inffast": 10, "./inftrees": 12 }], 12: [function(t, e, a) { "use strict"; var D = t("../utils/common"), I = [ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 ], U = [ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78 ], T = [ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0 ], F = [ 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 64, 64 ]; e.exports = function(t, e, a, i, n, r, s, o) { var l, h, d, f, _, u, c, b, g, m = o.bits, w = 0, p = 0, v = 0, k = 0, y = 0, x = 0, z = 0, B = 0, S = 0, E = 0, A = null, Z = 0, R = new D.Buf16(16), C = new D.Buf16(16), N = null, O = 0; for (w = 0; w <= 15; w++) R[w] = 0; for (p = 0; p < i; p++) R[e[a + p]]++; for (y = m, k = 15; 1 <= k && 0 === R[k]; k--); if (k < y && (y = k), 0 === k) return n[r++] = 20971520, n[r++] = 20971520, o.bits = 1, 0; for (v = 1; v < k && 0 === R[v]; v++); for (y < v && (y = v), w = B = 1; w <= 15; w++) if (B <<= 1, (B -= R[w]) < 0) return -1; if (0 < B && (0 === t || 1 !== k)) return -1; for (C[1] = 0, w = 1; w < 15; w++) C[w + 1] = C[w] + R[w]; for (p = 0; p < i; p++) 0 !== e[a + p] && (s[C[e[a + p]]++] = p); if (0 === t ? (A = N = s, u = 19) : 1 === t ? (A = I, Z -= 257, N = U, O -= 257, u = 256) : (A = T, N = F, u = -1), w = v, _ = r, z = p = E = 0, d = -1, f = (S = 1 << (x = y)) - 1, 1 === t && 852 < S || 2 === t && 592 < S) return 1; for (;;) { for (c = w - z, s[p] < u ? (b = 0, g = s[p]) : s[p] > u ? (b = N[O + s[p]], g = A[Z + s[p]]) : (b = 96, g = 0), l = 1 << w - z, v = h = 1 << x; n[_ + (E >> z) + (h -= l)] = c << 24 | b << 16 | g | 0, 0 !== h;); for (l = 1 << w - 1; E & l;) l >>= 1; if (0 !== l ? (E &= l - 1, E += l) : E = 0, p++, 0 == --R[w]) { if (w === k) break; w = e[a + s[p]]; } if (y < w && (E & f) !== d) { for (0 === z && (z = y), _ += v, B = 1 << (x = w - z); x + z < k && !((B -= R[x + z]) <= 0);) x++, B <<= 1; if (S += 1 << x, 1 === t && 852 < S || 2 === t && 592 < S) return 1; n[d = E & f] = y << 24 | x << 16 | _ - r | 0; } } return 0 !== E && (n[_ + E] = w - z << 24 | 64 << 16 | 0), o.bits = y, 0; }; }, { "../utils/common": 3 }], 13: [function(t, e, a) { "use strict"; e.exports = { 2: "need dictionary", 1: "stream end", 0: "", "-1": "file error", "-2": "stream error", "-3": "data error", "-4": "insufficient memory", "-5": "buffer error", "-6": "incompatible version" }; }, {}], 14: [function(t, e, a) { "use strict"; var l = t("../utils/common"), o = 0, h = 1; function i(t) { for (var e = t.length; 0 <= --e;) t[e] = 0; } var d = 0, s = 29, f = 256, _ = f + 1 + s, u = 30, c = 19, g = 2 * _ + 1, m = 15, n = 16, b = 7, w = 256, p = 16, v = 17, k = 18, y = [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 ], x = [ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 ], z = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7 ], B = [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ], S = new Array(2 * (_ + 2)); i(S); var E = new Array(2 * u); i(E); var A = new Array(512); i(A); var Z = new Array(256); i(Z); var R = new Array(s); i(R); var C, N, O, D = new Array(u); function I(t, e, a, i, n) { this.static_tree = t, this.extra_bits = e, this.extra_base = a, this.elems = i, this.max_length = n, this.has_stree = t && t.length; } function r(t, e) { this.dyn_tree = t, this.max_code = 0, this.stat_desc = e; } function U(t) { return t < 256 ? A[t] : A[256 + (t >>> 7)]; } function T(t, e) { t.pending_buf[t.pending++] = 255 & e, t.pending_buf[t.pending++] = e >>> 8 & 255; } function F(t, e, a) { t.bi_valid > n - a ? (t.bi_buf |= e << t.bi_valid & 65535, T(t, t.bi_buf), t.bi_buf = e >> n - t.bi_valid, t.bi_valid += a - n) : (t.bi_buf |= e << t.bi_valid & 65535, t.bi_valid += a); } function L(t, e, a) { F(t, a[2 * e], a[2 * e + 1]); } function H(t, e) { for (var a = 0; a |= 1 & t, t >>>= 1, a <<= 1, 0 < --e;); return a >>> 1; } function j(t, e, a) { var i, n, r = new Array(m + 1), s = 0; for (i = 1; i <= m; i++) r[i] = s = s + a[i - 1] << 1; for (n = 0; n <= e; n++) { var o = t[2 * n + 1]; 0 !== o && (t[2 * n] = H(r[o]++, o)); } } function K(t) { var e; for (e = 0; e < _; e++) t.dyn_ltree[2 * e] = 0; for (e = 0; e < u; e++) t.dyn_dtree[2 * e] = 0; for (e = 0; e < c; e++) t.bl_tree[2 * e] = 0; t.dyn_ltree[2 * w] = 1, t.opt_len = t.static_len = 0, t.last_lit = t.matches = 0; } function M(t) { 8 < t.bi_valid ? T(t, t.bi_buf) : 0 < t.bi_valid && (t.pending_buf[t.pending++] = t.bi_buf), t.bi_buf = 0, t.bi_valid = 0; } function P(t, e, a, i) { var n = 2 * e, r = 2 * a; return t[n] < t[r] || t[n] === t[r] && i[e] <= i[a]; } function Y(t, e, a) { for (var i = t.heap[a], n = a << 1; n <= t.heap_len && (n < t.heap_len && P(e, t.heap[n + 1], t.heap[n], t.depth) && n++, !P(e, i, t.heap[n], t.depth));) t.heap[a] = t.heap[n], a = n, n <<= 1; t.heap[a] = i; } function q(t, e, a) { var i, n, r, s, o = 0; if (0 !== t.last_lit) for (; i = t.pending_buf[t.d_buf + 2 * o] << 8 | t.pending_buf[t.d_buf + 2 * o + 1], n = t.pending_buf[t.l_buf + o], o++, 0 === i ? L(t, n, e) : (L(t, (r = Z[n]) + f + 1, e), 0 !== (s = y[r]) && F(t, n -= R[r], s), L(t, r = U(--i), a), 0 !== (s = x[r]) && F(t, i -= D[r], s)), o < t.last_lit;); L(t, w, e); } function G(t, e) { var a, i, n, r = e.dyn_tree, s = e.stat_desc.static_tree, o = e.stat_desc.has_stree, l = e.stat_desc.elems, h = -1; for (t.heap_len = 0, t.heap_max = g, a = 0; a < l; a++) 0 !== r[2 * a] ? (t.heap[++t.heap_len] = h = a, t.depth[a] = 0) : r[2 * a + 1] = 0; for (; t.heap_len < 2;) r[2 * (n = t.heap[++t.heap_len] = h < 2 ? ++h : 0)] = 1, t.depth[n] = 0, t.opt_len--, o && (t.static_len -= s[2 * n + 1]); for (e.max_code = h, a = t.heap_len >> 1; 1 <= a; a--) Y(t, r, a); for (n = l; a = t.heap[1], t.heap[1] = t.heap[t.heap_len--], Y(t, r, 1), i = t.heap[1], t.heap[--t.heap_max] = a, t.heap[--t.heap_max] = i, r[2 * n] = r[2 * a] + r[2 * i], t.depth[n] = (t.depth[a] >= t.depth[i] ? t.depth[a] : t.depth[i]) + 1, r[2 * a + 1] = r[2 * i + 1] = n, t.heap[1] = n++, Y(t, r, 1), 2 <= t.heap_len;); t.heap[--t.heap_max] = t.heap[1], function(t, e) { var a, i, n, r, s, o, l = e.dyn_tree, h = e.max_code, d = e.stat_desc.static_tree, f = e.stat_desc.has_stree, _ = e.stat_desc.extra_bits, u = e.stat_desc.extra_base, c = e.stat_desc.max_length, b = 0; for (r = 0; r <= m; r++) t.bl_count[r] = 0; for (l[2 * t.heap[t.heap_max] + 1] = 0, a = t.heap_max + 1; a < g; a++) c < (r = l[2 * l[2 * (i = t.heap[a]) + 1] + 1] + 1) && (r = c, b++), l[2 * i + 1] = r, h < i || (t.bl_count[r]++, s = 0, u <= i && (s = _[i - u]), o = l[2 * i], t.opt_len += o * (r + s), f && (t.static_len += o * (d[2 * i + 1] + s))); if (0 !== b) { do { for (r = c - 1; 0 === t.bl_count[r];) r--; t.bl_count[r]--, t.bl_count[r + 1] += 2, t.bl_count[c]--, b -= 2; } while (0 < b); for (r = c; 0 !== r; r--) for (i = t.bl_count[r]; 0 !== i;) h < (n = t.heap[--a]) || (l[2 * n + 1] !== r && (t.opt_len += (r - l[2 * n + 1]) * l[2 * n], l[2 * n + 1] = r), i--); } }(t, e), j(r, h, t.bl_count); } function X(t, e, a) { var i, n, r = -1, s = e[1], o = 0, l = 7, h = 4; for (0 === s && (l = 138, h = 3), e[2 * (a + 1) + 1] = 65535, i = 0; i <= a; i++) n = s, s = e[2 * (i + 1) + 1], ++o < l && n === s || (o < h ? t.bl_tree[2 * n] += o : 0 !== n ? (n !== r && t.bl_tree[2 * n]++, t.bl_tree[2 * p]++) : o <= 10 ? t.bl_tree[2 * v]++ : t.bl_tree[2 * k]++, r = n, (o = 0) === s ? (l = 138, h = 3) : n === s ? (l = 6, h = 3) : (l = 7, h = 4)); } function W(t, e, a) { var i, n, r = -1, s = e[1], o = 0, l = 7, h = 4; for (0 === s && (l = 138, h = 3), i = 0; i <= a; i++) if (n = s, s = e[2 * (i + 1) + 1], !(++o < l && n === s)) { if (o < h) for (; L(t, n, t.bl_tree), 0 != --o;); else 0 !== n ? (n !== r && (L(t, n, t.bl_tree), o--), L(t, p, t.bl_tree), F(t, o - 3, 2)) : o <= 10 ? (L(t, v, t.bl_tree), F(t, o - 3, 3)) : (L(t, k, t.bl_tree), F(t, o - 11, 7)); r = n, (o = 0) === s ? (l = 138, h = 3) : n === s ? (l = 6, h = 3) : (l = 7, h = 4); } } i(D); var J = !1; function Q(t, e, a, i) { var n, r, s, o; F(t, (d << 1) + (i ? 1 : 0), 3), r = e, s = a, o = !0, M(n = t), o && (T(n, s), T(n, ~s)), l.arraySet(n.pending_buf, n.window, r, s, n.pending), n.pending += s; } a._tr_init = function(t) { J || (function() { var t, e, a, i, n, r = new Array(m + 1); for (i = a = 0; i < s - 1; i++) for (R[i] = a, t = 0; t < 1 << y[i]; t++) Z[a++] = i; for (Z[a - 1] = i, i = n = 0; i < 16; i++) for (D[i] = n, t = 0; t < 1 << x[i]; t++) A[n++] = i; for (n >>= 7; i < u; i++) for (D[i] = n << 7, t = 0; t < 1 << x[i] - 7; t++) A[256 + n++] = i; for (e = 0; e <= m; e++) r[e] = 0; for (t = 0; t <= 143;) S[2 * t + 1] = 8, t++, r[8]++; for (; t <= 255;) S[2 * t + 1] = 9, t++, r[9]++; for (; t <= 279;) S[2 * t + 1] = 7, t++, r[7]++; for (; t <= 287;) S[2 * t + 1] = 8, t++, r[8]++; for (j(S, _ + 1, r), t = 0; t < u; t++) E[2 * t + 1] = 5, E[2 * t] = H(t, 5); C = new I(S, y, f + 1, _, m), N = new I(E, x, 0, u, m), O = new I(new Array(0), z, 0, c, b); }(), J = !0), t.l_desc = new r(t.dyn_ltree, C), t.d_desc = new r(t.dyn_dtree, N), t.bl_desc = new r(t.bl_tree, O), t.bi_buf = 0, t.bi_valid = 0, K(t); }, a._tr_stored_block = Q, a._tr_flush_block = function(t, e, a, i) { var n, r, s = 0; 0 < t.level ? (2 === t.strm.data_type && (t.strm.data_type = function(t) { var e, a = 4093624447; for (e = 0; e <= 31; e++, a >>>= 1) if (1 & a && 0 !== t.dyn_ltree[2 * e]) return o; if (0 !== t.dyn_ltree[18] || 0 !== t.dyn_ltree[20] || 0 !== t.dyn_ltree[26]) return h; for (e = 32; e < f; e++) if (0 !== t.dyn_ltree[2 * e]) return h; return o; }(t)), G(t, t.l_desc), G(t, t.d_desc), s = function(t) { var e; for (X(t, t.dyn_ltree, t.l_desc.max_code), X(t, t.dyn_dtree, t.d_desc.max_code), G(t, t.bl_desc), e = c - 1; 3 <= e && 0 === t.bl_tree[2 * B[e] + 1]; e--); return t.opt_len += 3 * (e + 1) + 5 + 5 + 4, e; }(t), n = t.opt_len + 3 + 7 >>> 3, (r = t.static_len + 3 + 7 >>> 3) <= n && (n = r)) : n = r = a + 5, a + 4 <= n && -1 !== e ? Q(t, e, a, i) : 4 === t.strategy || r === n ? (F(t, 2 + (i ? 1 : 0), 3), q(t, S, E)) : (F(t, 4 + (i ? 1 : 0), 3), function(t, e, a, i) { var n; for (F(t, e - 257, 5), F(t, a - 1, 5), F(t, i - 4, 4), n = 0; n < i; n++) F(t, t.bl_tree[2 * B[n] + 1], 3); W(t, t.dyn_ltree, e - 1), W(t, t.dyn_dtree, a - 1); }(t, t.l_desc.max_code + 1, t.d_desc.max_code + 1, s + 1), q(t, t.dyn_ltree, t.dyn_dtree)), K(t), i && M(t); }, a._tr_tally = function(t, e, a) { return t.pending_buf[t.d_buf + 2 * t.last_lit] = e >>> 8 & 255, t.pending_buf[t.d_buf + 2 * t.last_lit + 1] = 255 & e, t.pending_buf[t.l_buf + t.last_lit] = 255 & a, t.last_lit++, 0 === e ? t.dyn_ltree[2 * a]++ : (t.matches++, e--, t.dyn_ltree[2 * (Z[a] + f + 1)]++, t.dyn_dtree[2 * U(e)]++), t.last_lit === t.lit_bufsize - 1; }, a._tr_align = function(t) { var e; F(t, 2, 3), L(t, w, S), 16 === (e = t).bi_valid ? (T(e, e.bi_buf), e.bi_buf = 0, e.bi_valid = 0) : 8 <= e.bi_valid && (e.pending_buf[e.pending++] = 255 & e.bi_buf, e.bi_buf >>= 8, e.bi_valid -= 8); }; }, { "../utils/common": 3 }], 15: [function(t, e, a) { "use strict"; e.exports = function() { this.input = null, this.next_in = 0, this.avail_in = 0, this.total_in = 0, this.output = null, this.next_out = 0, this.avail_out = 0, this.total_out = 0, this.msg = "", this.state = null, this.data_type = 2, this.adler = 0; }; }, {}], "/": [function(t, e, a) { "use strict"; var i = {}; (0, t("./lib/utils/common").assign)(i, t("./lib/deflate"), t("./lib/inflate"), t("./lib/zlib/constants")), e.exports = i; }, { "./lib/deflate": 1, "./lib/inflate": 2, "./lib/utils/common": 3, "./lib/zlib/constants": 6 }] }, {}, [])("/"); }); })); //#endregion //#region ../libs_drpy/crypto-js.js var require_crypto_js$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => { ; (function(root, factory) { if (typeof exports === "object") { module.exports = exports = factory(); } else if (typeof define === "function" && define.amd) { define([], factory); } else { globalThis.CryptoJS = factory(); } })(exports, function() { /** * CryptoJS core components. */ var CryptoJS = CryptoJS || function(Math, undefined) { var crypto; if (typeof window !== "undefined" && window.crypto) { crypto = window.crypto; } if (typeof self !== "undefined" && self.crypto) { crypto = self.crypto; } if (typeof globalThis !== "undefined" && globalThis.crypto) { crypto = globalThis.crypto; } if (!crypto && typeof window !== "undefined" && window.msCrypto) { crypto = window.msCrypto; } if (!crypto && typeof global !== "undefined" && global.crypto) { crypto = global.crypto; } if (!crypto && typeof __require === "function") { try { crypto = __require("crypto"); } catch (err) {} } var cryptoSecureRandomInt = function() { if (crypto) { if (typeof crypto.getRandomValues === "function") { try { return crypto.getRandomValues(new Uint32Array(1))[0]; } catch (err) {} } if (typeof crypto.randomBytes === "function") { try { return crypto.randomBytes(4).readInt32LE(); } catch (err) {} } } throw new Error("Native crypto module could not be used to get secure random number."); }; var create = Object.create || function() { function F() {} return function(obj) { var subtype; F.prototype = obj; subtype = new F(); F.prototype = null; return subtype; }; }(); /** * CryptoJS namespace. */ var C = {}; /** * Library namespace. */ var C_lib = C.lib = {}; /** * Base object for prototypal inheritance. */ var Base = C_lib.Base = function() { return { extend: function(overrides) { var subtype = create(this); if (overrides) { subtype.mixIn(overrides); } if (!subtype.hasOwnProperty("init") || this.init === subtype.init) { subtype.init = function() { subtype.$super.init.apply(this, arguments); }; } subtype.init.prototype = subtype; subtype.$super = this; return subtype; }, create: function() { var instance = this.extend(); instance.init.apply(instance, arguments); return instance; }, init: function() {}, mixIn: function(properties) { for (var propertyName in properties) { if (properties.hasOwnProperty(propertyName)) { this[propertyName] = properties[propertyName]; } } if (properties.hasOwnProperty("toString")) { this.toString = properties.toString; } }, clone: function() { return this.init.prototype.extend(this); } }; }(); /** * An array of 32-bit words. * * @property {Array} words The array of 32-bit words. * @property {number} sigBytes The number of significant bytes in this word array. */ var WordArray = C_lib.WordArray = Base.extend({ init: function(words, sigBytes) { words = this.words = words || []; if (sigBytes != undefined) { this.sigBytes = sigBytes; } else { this.sigBytes = words.length * 4; } }, toString: function(encoder) { return (encoder || Hex).stringify(this); }, concat: function(wordArray) { var thisWords = this.words; var thatWords = wordArray.words; var thisSigBytes = this.sigBytes; var thatSigBytes = wordArray.sigBytes; this.clamp(); if (thisSigBytes % 4) { for (var i = 0; i < thatSigBytes; i++) { var thatByte = thatWords[i >>> 2] >>> 24 - i % 4 * 8 & 255; thisWords[thisSigBytes + i >>> 2] |= thatByte << 24 - (thisSigBytes + i) % 4 * 8; } } else { for (var j = 0; j < thatSigBytes; j += 4) { thisWords[thisSigBytes + j >>> 2] = thatWords[j >>> 2]; } } this.sigBytes += thatSigBytes; return this; }, clamp: function() { var words = this.words; var sigBytes = this.sigBytes; words[sigBytes >>> 2] &= 4294967295 << 32 - sigBytes % 4 * 8; words.length = Math.ceil(sigBytes / 4); }, clone: function() { var clone = Base.clone.call(this); clone.words = this.words.slice(0); return clone; }, random: function(nBytes) { var words = []; for (var i = 0; i < nBytes; i += 4) { words.push(cryptoSecureRandomInt()); } return new WordArray.init(words, nBytes); } }); /** * Encoder namespace. */ var C_enc = C.enc = {}; /** * Hex encoding strategy. */ var Hex = C_enc.Hex = { stringify: function(wordArray) { var words = wordArray.words; var sigBytes = wordArray.sigBytes; var hexChars = []; for (var i = 0; i < sigBytes; i++) { var bite = words[i >>> 2] >>> 24 - i % 4 * 8 & 255; hexChars.push((bite >>> 4).toString(16)); hexChars.push((bite & 15).toString(16)); } return hexChars.join(""); }, parse: function(hexStr) { var hexStrLength = hexStr.length; var words = []; for (var i = 0; i < hexStrLength; i += 2) { words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << 24 - i % 8 * 4; } return new WordArray.init(words, hexStrLength / 2); } }; /** * Latin1 encoding strategy. */ var Latin1 = C_enc.Latin1 = { stringify: function(wordArray) { var words = wordArray.words; var sigBytes = wordArray.sigBytes; var latin1Chars = []; for (var i = 0; i < sigBytes; i++) { var bite = words[i >>> 2] >>> 24 - i % 4 * 8 & 255; latin1Chars.push(String.fromCharCode(bite)); } return latin1Chars.join(""); }, parse: function(latin1Str) { var latin1StrLength = latin1Str.length; var words = []; for (var i = 0; i < latin1StrLength; i++) { words[i >>> 2] |= (latin1Str.charCodeAt(i) & 255) << 24 - i % 4 * 8; } return new WordArray.init(words, latin1StrLength); } }; /** * UTF-8 encoding strategy. */ var Utf8 = C_enc.Utf8 = { stringify: function(wordArray) { try { return decodeURIComponent(escape(Latin1.stringify(wordArray))); } catch (e) { throw new Error("Malformed UTF-8 data"); } }, parse: function(utf8Str) { return Latin1.parse(unescape(encodeURIComponent(utf8Str))); } }; /** * Abstract buffered block algorithm template. * * The property blockSize must be implemented in a concrete subtype. * * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0 */ var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({ reset: function() { this._data = new WordArray.init(); this._nDataBytes = 0; }, _append: function(data) { if (typeof data == "string") { data = Utf8.parse(data); } this._data.concat(data); this._nDataBytes += data.sigBytes; }, _process: function(doFlush) { var processedWords; var data = this._data; var dataWords = data.words; var dataSigBytes = data.sigBytes; var blockSize = this.blockSize; var blockSizeBytes = blockSize * 4; var nBlocksReady = dataSigBytes / blockSizeBytes; if (doFlush) { nBlocksReady = Math.ceil(nBlocksReady); } else { nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0); } var nWordsReady = nBlocksReady * blockSize; var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes); if (nWordsReady) { for (var offset = 0; offset < nWordsReady; offset += blockSize) { this._doProcessBlock(dataWords, offset); } processedWords = dataWords.splice(0, nWordsReady); data.sigBytes -= nBytesReady; } return new WordArray.init(processedWords, nBytesReady); }, clone: function() { var clone = Base.clone.call(this); clone._data = this._data.clone(); return clone; }, _minBufferSize: 0 }); /** * Abstract hasher template. * * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits) */ var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({ cfg: Base.extend(), init: function(cfg) { this.cfg = this.cfg.extend(cfg); this.reset(); }, reset: function() { BufferedBlockAlgorithm.reset.call(this); this._doReset(); }, update: function(messageUpdate) { this._append(messageUpdate); this._process(); return this; }, finalize: function(messageUpdate) { if (messageUpdate) { this._append(messageUpdate); } var hash = this._doFinalize(); return hash; }, blockSize: 512 / 32, _createHelper: function(hasher) { return function(message, cfg) { return new hasher.init(cfg).finalize(message); }; }, _createHmacHelper: function(hasher) { return function(message, key) { return new C_algo.HMAC.init(hasher, key).finalize(message); }; } }); /** * Algorithm namespace. */ var C_algo = C.algo = {}; return C; }(Math); (function(undefined) { var C = CryptoJS; var C_lib = C.lib; var Base = C_lib.Base; var X32WordArray = C_lib.WordArray; /** * x64 namespace. */ var C_x64 = C.x64 = {}; /** * A 64-bit word. */ var X64Word = C_x64.Word = Base.extend({ init: function(high, low) { this.high = high; this.low = low; } }); /** * An array of 64-bit words. * * @property {Array} words The array of CryptoJS.x64.Word objects. * @property {number} sigBytes The number of significant bytes in this word array. */ var X64WordArray = C_x64.WordArray = Base.extend({ init: function(words, sigBytes) { words = this.words = words || []; if (sigBytes != undefined) { this.sigBytes = sigBytes; } else { this.sigBytes = words.length * 8; } }, toX32: function() { var x64Words = this.words; var x64WordsLength = x64Words.length; var x32Words = []; for (var i = 0; i < x64WordsLength; i++) { var x64Word = x64Words[i]; x32Words.push(x64Word.high); x32Words.push(x64Word.low); } return X32WordArray.create(x32Words, this.sigBytes); }, clone: function() { var clone = Base.clone.call(this); var words = clone.words = this.words.slice(0); var wordsLength = words.length; for (var i = 0; i < wordsLength; i++) { words[i] = words[i].clone(); } return clone; } }); })(); (function() { if (typeof ArrayBuffer != "function") { return; } var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var superInit = WordArray.init; var subInit = WordArray.init = function(typedArray) { if (typedArray instanceof ArrayBuffer) { typedArray = new Uint8Array(typedArray); } if (typedArray instanceof Int8Array || typeof Uint8ClampedArray !== "undefined" && typedArray instanceof Uint8ClampedArray || typedArray instanceof Int16Array || typedArray instanceof Uint16Array || typedArray instanceof Int32Array || typedArray instanceof Uint32Array || typedArray instanceof Float32Array || typedArray instanceof Float64Array) { typedArray = new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength); } if (typedArray instanceof Uint8Array) { var typedArrayByteLength = typedArray.byteLength; var words = []; for (var i = 0; i < typedArrayByteLength; i++) { words[i >>> 2] |= typedArray[i] << 24 - i % 4 * 8; } superInit.call(this, words, typedArrayByteLength); } else { superInit.apply(this, arguments); } }; subInit.prototype = WordArray; })(); (function() { var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var C_enc = C.enc; /** * UTF-16 BE encoding strategy. */ var Utf16BE = C_enc.Utf16 = C_enc.Utf16BE = { stringify: function(wordArray) { var words = wordArray.words; var sigBytes = wordArray.sigBytes; var utf16Chars = []; for (var i = 0; i < sigBytes; i += 2) { var codePoint = words[i >>> 2] >>> 16 - i % 4 * 8 & 65535; utf16Chars.push(String.fromCharCode(codePoint)); } return utf16Chars.join(""); }, parse: function(utf16Str) { var utf16StrLength = utf16Str.length; var words = []; for (var i = 0; i < utf16StrLength; i++) { words[i >>> 1] |= utf16Str.charCodeAt(i) << 16 - i % 2 * 16; } return WordArray.create(words, utf16StrLength * 2); } }; /** * UTF-16 LE encoding strategy. */ C_enc.Utf16LE = { stringify: function(wordArray) { var words = wordArray.words; var sigBytes = wordArray.sigBytes; var utf16Chars = []; for (var i = 0; i < sigBytes; i += 2) { var codePoint = swapEndian(words[i >>> 2] >>> 16 - i % 4 * 8 & 65535); utf16Chars.push(String.fromCharCode(codePoint)); } return utf16Chars.join(""); }, parse: function(utf16Str) { var utf16StrLength = utf16Str.length; var words = []; for (var i = 0; i < utf16StrLength; i++) { words[i >>> 1] |= swapEndian(utf16Str.charCodeAt(i) << 16 - i % 2 * 16); } return WordArray.create(words, utf16StrLength * 2); } }; function swapEndian(word) { return word << 8 & 4278255360 | word >>> 8 & 16711935; } })(); (function() { var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var C_enc = C.enc; /** * Base64 encoding strategy. */ var Base64 = C_enc.Base64 = { stringify: function(wordArray) { var words = wordArray.words; var sigBytes = wordArray.sigBytes; var map = this._map; wordArray.clamp(); var base64Chars = []; for (var i = 0; i < sigBytes; i += 3) { var byte1 = words[i >>> 2] >>> 24 - i % 4 * 8 & 255; var byte2 = words[i + 1 >>> 2] >>> 24 - (i + 1) % 4 * 8 & 255; var byte3 = words[i + 2 >>> 2] >>> 24 - (i + 2) % 4 * 8 & 255; var triplet = byte1 << 16 | byte2 << 8 | byte3; for (var j = 0; j < 4 && i + j * .75 < sigBytes; j++) { base64Chars.push(map.charAt(triplet >>> 6 * (3 - j) & 63)); } } var paddingChar = map.charAt(64); if (paddingChar) { while (base64Chars.length % 4) { base64Chars.push(paddingChar); } } return base64Chars.join(""); }, parse: function(base64Str) { var base64StrLength = base64Str.length; var map = this._map; var reverseMap = this._reverseMap; if (!reverseMap) { reverseMap = this._reverseMap = []; for (var j = 0; j < map.length; j++) { reverseMap[map.charCodeAt(j)] = j; } } var paddingChar = map.charAt(64); if (paddingChar) { var paddingIndex = base64Str.indexOf(paddingChar); if (paddingIndex !== -1) { base64StrLength = paddingIndex; } } return parseLoop(base64Str, base64StrLength, reverseMap); }, _map: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" }; function parseLoop(base64Str, base64StrLength, reverseMap) { var words = []; var nBytes = 0; for (var i = 0; i < base64StrLength; i++) { if (i % 4) { var bits1 = reverseMap[base64Str.charCodeAt(i - 1)] << i % 4 * 2; var bits2 = reverseMap[base64Str.charCodeAt(i)] >>> 6 - i % 4 * 2; var bitsCombined = bits1 | bits2; words[nBytes >>> 2] |= bitsCombined << 24 - nBytes % 4 * 8; nBytes++; } } return WordArray.create(words, nBytes); } })(); (function() { var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var C_enc = C.enc; /** * Base64url encoding strategy. */ var Base64url = C_enc.Base64url = { stringify: function(wordArray, urlSafe = true) { var words = wordArray.words; var sigBytes = wordArray.sigBytes; var map = urlSafe ? this._safe_map : this._map; wordArray.clamp(); var base64Chars = []; for (var i = 0; i < sigBytes; i += 3) { var byte1 = words[i >>> 2] >>> 24 - i % 4 * 8 & 255; var byte2 = words[i + 1 >>> 2] >>> 24 - (i + 1) % 4 * 8 & 255; var byte3 = words[i + 2 >>> 2] >>> 24 - (i + 2) % 4 * 8 & 255; var triplet = byte1 << 16 | byte2 << 8 | byte3; for (var j = 0; j < 4 && i + j * .75 < sigBytes; j++) { base64Chars.push(map.charAt(triplet >>> 6 * (3 - j) & 63)); } } var paddingChar = map.charAt(64); if (paddingChar) { while (base64Chars.length % 4) { base64Chars.push(paddingChar); } } return base64Chars.join(""); }, parse: function(base64Str, urlSafe = true) { var base64StrLength = base64Str.length; var map = urlSafe ? this._safe_map : this._map; var reverseMap = this._reverseMap; if (!reverseMap) { reverseMap = this._reverseMap = []; for (var j = 0; j < map.length; j++) { reverseMap[map.charCodeAt(j)] = j; } } var paddingChar = map.charAt(64); if (paddingChar) { var paddingIndex = base64Str.indexOf(paddingChar); if (paddingIndex !== -1) { base64StrLength = paddingIndex; } } return parseLoop(base64Str, base64StrLength, reverseMap); }, _map: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", _safe_map: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_" }; function parseLoop(base64Str, base64StrLength, reverseMap) { var words = []; var nBytes = 0; for (var i = 0; i < base64StrLength; i++) { if (i % 4) { var bits1 = reverseMap[base64Str.charCodeAt(i - 1)] << i % 4 * 2; var bits2 = reverseMap[base64Str.charCodeAt(i)] >>> 6 - i % 4 * 2; var bitsCombined = bits1 | bits2; words[nBytes >>> 2] |= bitsCombined << 24 - nBytes % 4 * 8; nBytes++; } } return WordArray.create(words, nBytes); } })(); (function(Math) { var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var Hasher = C_lib.Hasher; var C_algo = C.algo; var T = []; (function() { for (var i = 0; i < 64; i++) { T[i] = Math.abs(Math.sin(i + 1)) * 4294967296 | 0; } })(); /** * MD5 hash algorithm. */ var MD5 = C_algo.MD5 = Hasher.extend({ _doReset: function() { this._hash = new WordArray.init([ 1732584193, 4023233417, 2562383102, 271733878 ]); }, _doProcessBlock: function(M, offset) { for (var i = 0; i < 16; i++) { var offset_i = offset + i; var M_offset_i = M[offset_i]; M[offset_i] = (M_offset_i << 8 | M_offset_i >>> 24) & 16711935 | (M_offset_i << 24 | M_offset_i >>> 8) & 4278255360; } var H = this._hash.words; var M_offset_0 = M[offset + 0]; var M_offset_1 = M[offset + 1]; var M_offset_2 = M[offset + 2]; var M_offset_3 = M[offset + 3]; var M_offset_4 = M[offset + 4]; var M_offset_5 = M[offset + 5]; var M_offset_6 = M[offset + 6]; var M_offset_7 = M[offset + 7]; var M_offset_8 = M[offset + 8]; var M_offset_9 = M[offset + 9]; var M_offset_10 = M[offset + 10]; var M_offset_11 = M[offset + 11]; var M_offset_12 = M[offset + 12]; var M_offset_13 = M[offset + 13]; var M_offset_14 = M[offset + 14]; var M_offset_15 = M[offset + 15]; var a = H[0]; var b = H[1]; var c = H[2]; var d = H[3]; a = FF(a, b, c, d, M_offset_0, 7, T[0]); d = FF(d, a, b, c, M_offset_1, 12, T[1]); c = FF(c, d, a, b, M_offset_2, 17, T[2]); b = FF(b, c, d, a, M_offset_3, 22, T[3]); a = FF(a, b, c, d, M_offset_4, 7, T[4]); d = FF(d, a, b, c, M_offset_5, 12, T[5]); c = FF(c, d, a, b, M_offset_6, 17, T[6]); b = FF(b, c, d, a, M_offset_7, 22, T[7]); a = FF(a, b, c, d, M_offset_8, 7, T[8]); d = FF(d, a, b, c, M_offset_9, 12, T[9]); c = FF(c, d, a, b, M_offset_10, 17, T[10]); b = FF(b, c, d, a, M_offset_11, 22, T[11]); a = FF(a, b, c, d, M_offset_12, 7, T[12]); d = FF(d, a, b, c, M_offset_13, 12, T[13]); c = FF(c, d, a, b, M_offset_14, 17, T[14]); b = FF(b, c, d, a, M_offset_15, 22, T[15]); a = GG(a, b, c, d, M_offset_1, 5, T[16]); d = GG(d, a, b, c, M_offset_6, 9, T[17]); c = GG(c, d, a, b, M_offset_11, 14, T[18]); b = GG(b, c, d, a, M_offset_0, 20, T[19]); a = GG(a, b, c, d, M_offset_5, 5, T[20]); d = GG(d, a, b, c, M_offset_10, 9, T[21]); c = GG(c, d, a, b, M_offset_15, 14, T[22]); b = GG(b, c, d, a, M_offset_4, 20, T[23]); a = GG(a, b, c, d, M_offset_9, 5, T[24]); d = GG(d, a, b, c, M_offset_14, 9, T[25]); c = GG(c, d, a, b, M_offset_3, 14, T[26]); b = GG(b, c, d, a, M_offset_8, 20, T[27]); a = GG(a, b, c, d, M_offset_13, 5, T[28]); d = GG(d, a, b, c, M_offset_2, 9, T[29]); c = GG(c, d, a, b, M_offset_7, 14, T[30]); b = GG(b, c, d, a, M_offset_12, 20, T[31]); a = HH(a, b, c, d, M_offset_5, 4, T[32]); d = HH(d, a, b, c, M_offset_8, 11, T[33]); c = HH(c, d, a, b, M_offset_11, 16, T[34]); b = HH(b, c, d, a, M_offset_14, 23, T[35]); a = HH(a, b, c, d, M_offset_1, 4, T[36]); d = HH(d, a, b, c, M_offset_4, 11, T[37]); c = HH(c, d, a, b, M_offset_7, 16, T[38]); b = HH(b, c, d, a, M_offset_10, 23, T[39]); a = HH(a, b, c, d, M_offset_13, 4, T[40]); d = HH(d, a, b, c, M_offset_0, 11, T[41]); c = HH(c, d, a, b, M_offset_3, 16, T[42]); b = HH(b, c, d, a, M_offset_6, 23, T[43]); a = HH(a, b, c, d, M_offset_9, 4, T[44]); d = HH(d, a, b, c, M_offset_12, 11, T[45]); c = HH(c, d, a, b, M_offset_15, 16, T[46]); b = HH(b, c, d, a, M_offset_2, 23, T[47]); a = II(a, b, c, d, M_offset_0, 6, T[48]); d = II(d, a, b, c, M_offset_7, 10, T[49]); c = II(c, d, a, b, M_offset_14, 15, T[50]); b = II(b, c, d, a, M_offset_5, 21, T[51]); a = II(a, b, c, d, M_offset_12, 6, T[52]); d = II(d, a, b, c, M_offset_3, 10, T[53]); c = II(c, d, a, b, M_offset_10, 15, T[54]); b = II(b, c, d, a, M_offset_1, 21, T[55]); a = II(a, b, c, d, M_offset_8, 6, T[56]); d = II(d, a, b, c, M_offset_15, 10, T[57]); c = II(c, d, a, b, M_offset_6, 15, T[58]); b = II(b, c, d, a, M_offset_13, 21, T[59]); a = II(a, b, c, d, M_offset_4, 6, T[60]); d = II(d, a, b, c, M_offset_11, 10, T[61]); c = II(c, d, a, b, M_offset_2, 15, T[62]); b = II(b, c, d, a, M_offset_9, 21, T[63]); H[0] = H[0] + a | 0; H[1] = H[1] + b | 0; H[2] = H[2] + c | 0; H[3] = H[3] + d | 0; }, _doFinalize: function() { var data = this._data; var dataWords = data.words; var nBitsTotal = this._nDataBytes * 8; var nBitsLeft = data.sigBytes * 8; dataWords[nBitsLeft >>> 5] |= 128 << 24 - nBitsLeft % 32; var nBitsTotalH = Math.floor(nBitsTotal / 4294967296); var nBitsTotalL = nBitsTotal; dataWords[(nBitsLeft + 64 >>> 9 << 4) + 15] = (nBitsTotalH << 8 | nBitsTotalH >>> 24) & 16711935 | (nBitsTotalH << 24 | nBitsTotalH >>> 8) & 4278255360; dataWords[(nBitsLeft + 64 >>> 9 << 4) + 14] = (nBitsTotalL << 8 | nBitsTotalL >>> 24) & 16711935 | (nBitsTotalL << 24 | nBitsTotalL >>> 8) & 4278255360; data.sigBytes = (dataWords.length + 1) * 4; this._process(); var hash = this._hash; var H = hash.words; for (var i = 0; i < 4; i++) { var H_i = H[i]; H[i] = (H_i << 8 | H_i >>> 24) & 16711935 | (H_i << 24 | H_i >>> 8) & 4278255360; } return hash; }, clone: function() { var clone = Hasher.clone.call(this); clone._hash = this._hash.clone(); return clone; } }); function FF(a, b, c, d, x, s, t) { var n = a + (b & c | ~b & d) + x + t; return (n << s | n >>> 32 - s) + b; } function GG(a, b, c, d, x, s, t) { var n = a + (b & d | c & ~d) + x + t; return (n << s | n >>> 32 - s) + b; } function HH(a, b, c, d, x, s, t) { var n = a + (b ^ c ^ d) + x + t; return (n << s | n >>> 32 - s) + b; } function II(a, b, c, d, x, s, t) { var n = a + (c ^ (b | ~d)) + x + t; return (n << s | n >>> 32 - s) + b; } /** * Shortcut function to the hasher's object interface. * * @param {WordArray|string} message The message to hash. * * @return {WordArray} The hash. * * @static * * @example * * var hash = CryptoJS.MD5('message'); * var hash = CryptoJS.MD5(wordArray); */ C.MD5 = Hasher._createHelper(MD5); /** * Shortcut function to the HMAC's object interface. * * @param {WordArray|string} message The message to hash. * @param {WordArray|string} key The secret key. * * @return {WordArray} The HMAC. * * @static * * @example * * var hmac = CryptoJS.HmacMD5(message, key); */ C.HmacMD5 = Hasher._createHmacHelper(MD5); })(Math); (function() { var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var Hasher = C_lib.Hasher; var C_algo = C.algo; var W = []; /** * SHA-1 hash algorithm. */ var SHA1 = C_algo.SHA1 = Hasher.extend({ _doReset: function() { this._hash = new WordArray.init([ 1732584193, 4023233417, 2562383102, 271733878, 3285377520 ]); }, _doProcessBlock: function(M, offset) { var H = this._hash.words; var a = H[0]; var b = H[1]; var c = H[2]; var d = H[3]; var e = H[4]; for (var i = 0; i < 80; i++) { if (i < 16) { W[i] = M[offset + i] | 0; } else { var n = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]; W[i] = n << 1 | n >>> 31; } var t = (a << 5 | a >>> 27) + e + W[i]; if (i < 20) { t += (b & c | ~b & d) + 1518500249; } else if (i < 40) { t += (b ^ c ^ d) + 1859775393; } else if (i < 60) { t += (b & c | b & d | c & d) - 1894007588; } else { t += (b ^ c ^ d) - 899497514; } e = d; d = c; c = b << 30 | b >>> 2; b = a; a = t; } H[0] = H[0] + a | 0; H[1] = H[1] + b | 0; H[2] = H[2] + c | 0; H[3] = H[3] + d | 0; H[4] = H[4] + e | 0; }, _doFinalize: function() { var data = this._data; var dataWords = data.words; var nBitsTotal = this._nDataBytes * 8; var nBitsLeft = data.sigBytes * 8; dataWords[nBitsLeft >>> 5] |= 128 << 24 - nBitsLeft % 32; dataWords[(nBitsLeft + 64 >>> 9 << 4) + 14] = Math.floor(nBitsTotal / 4294967296); dataWords[(nBitsLeft + 64 >>> 9 << 4) + 15] = nBitsTotal; data.sigBytes = dataWords.length * 4; this._process(); return this._hash; }, clone: function() { var clone = Hasher.clone.call(this); clone._hash = this._hash.clone(); return clone; } }); /** * Shortcut function to the hasher's object interface. * * @param {WordArray|string} message The message to hash. * * @return {WordArray} The hash. * * @static * * @example * * var hash = CryptoJS.SHA1('message'); * var hash = CryptoJS.SHA1(wordArray); */ C.SHA1 = Hasher._createHelper(SHA1); /** * Shortcut function to the HMAC's object interface. * * @param {WordArray|string} message The message to hash. * @param {WordArray|string} key The secret key. * * @return {WordArray} The HMAC. * * @static * * @example * * var hmac = CryptoJS.HmacSHA1(message, key); */ C.HmacSHA1 = Hasher._createHmacHelper(SHA1); })(); (function(Math) { var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var Hasher = C_lib.Hasher; var C_algo = C.algo; var H = []; var K = []; (function() { function isPrime(n) { var sqrtN = Math.sqrt(n); for (var factor = 2; factor <= sqrtN; factor++) { if (!(n % factor)) { return false; } } return true; } function getFractionalBits(n) { return (n - (n | 0)) * 4294967296 | 0; } var n = 2; var nPrime = 0; while (nPrime < 64) { if (isPrime(n)) { if (nPrime < 8) { H[nPrime] = getFractionalBits(Math.pow(n, 1 / 2)); } K[nPrime] = getFractionalBits(Math.pow(n, 1 / 3)); nPrime++; } n++; } })(); var W = []; /** * SHA-256 hash algorithm. */ var SHA256 = C_algo.SHA256 = Hasher.extend({ _doReset: function() { this._hash = new WordArray.init(H.slice(0)); }, _doProcessBlock: function(M, offset) { var H = this._hash.words; var a = H[0]; var b = H[1]; var c = H[2]; var d = H[3]; var e = H[4]; var f = H[5]; var g = H[6]; var h = H[7]; for (var i = 0; i < 64; i++) { if (i < 16) { W[i] = M[offset + i] | 0; } else { var gamma0x = W[i - 15]; var gamma0 = (gamma0x << 25 | gamma0x >>> 7) ^ (gamma0x << 14 | gamma0x >>> 18) ^ gamma0x >>> 3; var gamma1x = W[i - 2]; var gamma1 = (gamma1x << 15 | gamma1x >>> 17) ^ (gamma1x << 13 | gamma1x >>> 19) ^ gamma1x >>> 10; W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16]; } var ch = e & f ^ ~e & g; var maj = a & b ^ a & c ^ b & c; var sigma0 = (a << 30 | a >>> 2) ^ (a << 19 | a >>> 13) ^ (a << 10 | a >>> 22); var sigma1 = (e << 26 | e >>> 6) ^ (e << 21 | e >>> 11) ^ (e << 7 | e >>> 25); var t1 = h + sigma1 + ch + K[i] + W[i]; var t2 = sigma0 + maj; h = g; g = f; f = e; e = d + t1 | 0; d = c; c = b; b = a; a = t1 + t2 | 0; } H[0] = H[0] + a | 0; H[1] = H[1] + b | 0; H[2] = H[2] + c | 0; H[3] = H[3] + d | 0; H[4] = H[4] + e | 0; H[5] = H[5] + f | 0; H[6] = H[6] + g | 0; H[7] = H[7] + h | 0; }, _doFinalize: function() { var data = this._data; var dataWords = data.words; var nBitsTotal = this._nDataBytes * 8; var nBitsLeft = data.sigBytes * 8; dataWords[nBitsLeft >>> 5] |= 128 << 24 - nBitsLeft % 32; dataWords[(nBitsLeft + 64 >>> 9 << 4) + 14] = Math.floor(nBitsTotal / 4294967296); dataWords[(nBitsLeft + 64 >>> 9 << 4) + 15] = nBitsTotal; data.sigBytes = dataWords.length * 4; this._process(); return this._hash; }, clone: function() { var clone = Hasher.clone.call(this); clone._hash = this._hash.clone(); return clone; } }); /** * Shortcut function to the hasher's object interface. * * @param {WordArray|string} message The message to hash. * * @return {WordArray} The hash. * * @static * * @example * * var hash = CryptoJS.SHA256('message'); * var hash = CryptoJS.SHA256(wordArray); */ C.SHA256 = Hasher._createHelper(SHA256); /** * Shortcut function to the HMAC's object interface. * * @param {WordArray|string} message The message to hash. * @param {WordArray|string} key The secret key. * * @return {WordArray} The HMAC. * * @static * * @example * * var hmac = CryptoJS.HmacSHA256(message, key); */ C.HmacSHA256 = Hasher._createHmacHelper(SHA256); })(Math); (function() { var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var C_algo = C.algo; var SHA256 = C_algo.SHA256; /** * SHA-224 hash algorithm. */ var SHA224 = C_algo.SHA224 = SHA256.extend({ _doReset: function() { this._hash = new WordArray.init([ 3238371032, 914150663, 812702999, 4144912697, 4290775857, 1750603025, 1694076839, 3204075428 ]); }, _doFinalize: function() { var hash = SHA256._doFinalize.call(this); hash.sigBytes -= 4; return hash; } }); /** * Shortcut function to the hasher's object interface. * * @param {WordArray|string} message The message to hash. * * @return {WordArray} The hash. * * @static * * @example * * var hash = CryptoJS.SHA224('message'); * var hash = CryptoJS.SHA224(wordArray); */ C.SHA224 = SHA256._createHelper(SHA224); /** * Shortcut function to the HMAC's object interface. * * @param {WordArray|string} message The message to hash. * @param {WordArray|string} key The secret key. * * @return {WordArray} The HMAC. * * @static * * @example * * var hmac = CryptoJS.HmacSHA224(message, key); */ C.HmacSHA224 = SHA256._createHmacHelper(SHA224); })(); (function() { var C = CryptoJS; var C_lib = C.lib; var Hasher = C_lib.Hasher; var C_x64 = C.x64; var X64Word = C_x64.Word; var X64WordArray = C_x64.WordArray; var C_algo = C.algo; function X64Word_create() { return X64Word.create.apply(X64Word, arguments); } var K = [ X64Word_create(1116352408, 3609767458), X64Word_create(1899447441, 602891725), X64Word_create(3049323471, 3964484399), X64Word_create(3921009573, 2173295548), X64Word_create(961987163, 4081628472), X64Word_create(1508970993, 3053834265), X64Word_create(2453635748, 2937671579), X64Word_create(2870763221, 3664609560), X64Word_create(3624381080, 2734883394), X64Word_create(310598401, 1164996542), X64Word_create(607225278, 1323610764), X64Word_create(1426881987, 3590304994), X64Word_create(1925078388, 4068182383), X64Word_create(2162078206, 991336113), X64Word_create(2614888103, 633803317), X64Word_create(3248222580, 3479774868), X64Word_create(3835390401, 2666613458), X64Word_create(4022224774, 944711139), X64Word_create(264347078, 2341262773), X64Word_create(604807628, 2007800933), X64Word_create(770255983, 1495990901), X64Word_create(1249150122, 1856431235), X64Word_create(1555081692, 3175218132), X64Word_create(1996064986, 2198950837), X64Word_create(2554220882, 3999719339), X64Word_create(2821834349, 766784016), X64Word_create(2952996808, 2566594879), X64Word_create(3210313671, 3203337956), X64Word_create(3336571891, 1034457026), X64Word_create(3584528711, 2466948901), X64Word_create(113926993, 3758326383), X64Word_create(338241895, 168717936), X64Word_create(666307205, 1188179964), X64Word_create(773529912, 1546045734), X64Word_create(1294757372, 1522805485), X64Word_create(1396182291, 2643833823), X64Word_create(1695183700, 2343527390), X64Word_create(1986661051, 1014477480), X64Word_create(2177026350, 1206759142), X64Word_create(2456956037, 344077627), X64Word_create(2730485921, 1290863460), X64Word_create(2820302411, 3158454273), X64Word_create(3259730800, 3505952657), X64Word_create(3345764771, 106217008), X64Word_create(3516065817, 3606008344), X64Word_create(3600352804, 1432725776), X64Word_create(4094571909, 1467031594), X64Word_create(275423344, 851169720), X64Word_create(430227734, 3100823752), X64Word_create(506948616, 1363258195), X64Word_create(659060556, 3750685593), X64Word_create(883997877, 3785050280), X64Word_create(958139571, 3318307427), X64Word_create(1322822218, 3812723403), X64Word_create(1537002063, 2003034995), X64Word_create(1747873779, 3602036899), X64Word_create(1955562222, 1575990012), X64Word_create(2024104815, 1125592928), X64Word_create(2227730452, 2716904306), X64Word_create(2361852424, 442776044), X64Word_create(2428436474, 593698344), X64Word_create(2756734187, 3733110249), X64Word_create(3204031479, 2999351573), X64Word_create(3329325298, 3815920427), X64Word_create(3391569614, 3928383900), X64Word_create(3515267271, 566280711), X64Word_create(3940187606, 3454069534), X64Word_create(4118630271, 4000239992), X64Word_create(116418474, 1914138554), X64Word_create(174292421, 2731055270), X64Word_create(289380356, 3203993006), X64Word_create(460393269, 320620315), X64Word_create(685471733, 587496836), X64Word_create(852142971, 1086792851), X64Word_create(1017036298, 365543100), X64Word_create(1126000580, 2618297676), X64Word_create(1288033470, 3409855158), X64Word_create(1501505948, 4234509866), X64Word_create(1607167915, 987167468), X64Word_create(1816402316, 1246189591) ]; var W = []; (function() { for (var i = 0; i < 80; i++) { W[i] = X64Word_create(); } })(); /** * SHA-512 hash algorithm. */ var SHA512 = C_algo.SHA512 = Hasher.extend({ _doReset: function() { this._hash = new X64WordArray.init([ new X64Word.init(1779033703, 4089235720), new X64Word.init(3144134277, 2227873595), new X64Word.init(1013904242, 4271175723), new X64Word.init(2773480762, 1595750129), new X64Word.init(1359893119, 2917565137), new X64Word.init(2600822924, 725511199), new X64Word.init(528734635, 4215389547), new X64Word.init(1541459225, 327033209) ]); }, _doProcessBlock: function(M, offset) { var H = this._hash.words; var H0 = H[0]; var H1 = H[1]; var H2 = H[2]; var H3 = H[3]; var H4 = H[4]; var H5 = H[5]; var H6 = H[6]; var H7 = H[7]; var H0h = H0.high; var H0l = H0.low; var H1h = H1.high; var H1l = H1.low; var H2h = H2.high; var H2l = H2.low; var H3h = H3.high; var H3l = H3.low; var H4h = H4.high; var H4l = H4.low; var H5h = H5.high; var H5l = H5.low; var H6h = H6.high; var H6l = H6.low; var H7h = H7.high; var H7l = H7.low; var ah = H0h; var al = H0l; var bh = H1h; var bl = H1l; var ch = H2h; var cl = H2l; var dh = H3h; var dl = H3l; var eh = H4h; var el = H4l; var fh = H5h; var fl = H5l; var gh = H6h; var gl = H6l; var hh = H7h; var hl = H7l; for (var i = 0; i < 80; i++) { var Wil; var Wih; var Wi = W[i]; if (i < 16) { Wih = Wi.high = M[offset + i * 2] | 0; Wil = Wi.low = M[offset + i * 2 + 1] | 0; } else { var gamma0x = W[i - 15]; var gamma0xh = gamma0x.high; var gamma0xl = gamma0x.low; var gamma0h = (gamma0xh >>> 1 | gamma0xl << 31) ^ (gamma0xh >>> 8 | gamma0xl << 24) ^ gamma0xh >>> 7; var gamma0l = (gamma0xl >>> 1 | gamma0xh << 31) ^ (gamma0xl >>> 8 | gamma0xh << 24) ^ (gamma0xl >>> 7 | gamma0xh << 25); var gamma1x = W[i - 2]; var gamma1xh = gamma1x.high; var gamma1xl = gamma1x.low; var gamma1h = (gamma1xh >>> 19 | gamma1xl << 13) ^ (gamma1xh << 3 | gamma1xl >>> 29) ^ gamma1xh >>> 6; var gamma1l = (gamma1xl >>> 19 | gamma1xh << 13) ^ (gamma1xl << 3 | gamma1xh >>> 29) ^ (gamma1xl >>> 6 | gamma1xh << 26); var Wi7 = W[i - 7]; var Wi7h = Wi7.high; var Wi7l = Wi7.low; var Wi16 = W[i - 16]; var Wi16h = Wi16.high; var Wi16l = Wi16.low; Wil = gamma0l + Wi7l; Wih = gamma0h + Wi7h + (Wil >>> 0 < gamma0l >>> 0 ? 1 : 0); Wil = Wil + gamma1l; Wih = Wih + gamma1h + (Wil >>> 0 < gamma1l >>> 0 ? 1 : 0); Wil = Wil + Wi16l; Wih = Wih + Wi16h + (Wil >>> 0 < Wi16l >>> 0 ? 1 : 0); Wi.high = Wih; Wi.low = Wil; } var chh = eh & fh ^ ~eh & gh; var chl = el & fl ^ ~el & gl; var majh = ah & bh ^ ah & ch ^ bh & ch; var majl = al & bl ^ al & cl ^ bl & cl; var sigma0h = (ah >>> 28 | al << 4) ^ (ah << 30 | al >>> 2) ^ (ah << 25 | al >>> 7); var sigma0l = (al >>> 28 | ah << 4) ^ (al << 30 | ah >>> 2) ^ (al << 25 | ah >>> 7); var sigma1h = (eh >>> 14 | el << 18) ^ (eh >>> 18 | el << 14) ^ (eh << 23 | el >>> 9); var sigma1l = (el >>> 14 | eh << 18) ^ (el >>> 18 | eh << 14) ^ (el << 23 | eh >>> 9); var Ki = K[i]; var Kih = Ki.high; var Kil = Ki.low; var t1l = hl + sigma1l; var t1h = hh + sigma1h + (t1l >>> 0 < hl >>> 0 ? 1 : 0); var t1l = t1l + chl; var t1h = t1h + chh + (t1l >>> 0 < chl >>> 0 ? 1 : 0); var t1l = t1l + Kil; var t1h = t1h + Kih + (t1l >>> 0 < Kil >>> 0 ? 1 : 0); var t1l = t1l + Wil; var t1h = t1h + Wih + (t1l >>> 0 < Wil >>> 0 ? 1 : 0); var t2l = sigma0l + majl; var t2h = sigma0h + majh + (t2l >>> 0 < sigma0l >>> 0 ? 1 : 0); hh = gh; hl = gl; gh = fh; gl = fl; fh = eh; fl = el; el = dl + t1l | 0; eh = dh + t1h + (el >>> 0 < dl >>> 0 ? 1 : 0) | 0; dh = ch; dl = cl; ch = bh; cl = bl; bh = ah; bl = al; al = t1l + t2l | 0; ah = t1h + t2h + (al >>> 0 < t1l >>> 0 ? 1 : 0) | 0; } H0l = H0.low = H0l + al; H0.high = H0h + ah + (H0l >>> 0 < al >>> 0 ? 1 : 0); H1l = H1.low = H1l + bl; H1.high = H1h + bh + (H1l >>> 0 < bl >>> 0 ? 1 : 0); H2l = H2.low = H2l + cl; H2.high = H2h + ch + (H2l >>> 0 < cl >>> 0 ? 1 : 0); H3l = H3.low = H3l + dl; H3.high = H3h + dh + (H3l >>> 0 < dl >>> 0 ? 1 : 0); H4l = H4.low = H4l + el; H4.high = H4h + eh + (H4l >>> 0 < el >>> 0 ? 1 : 0); H5l = H5.low = H5l + fl; H5.high = H5h + fh + (H5l >>> 0 < fl >>> 0 ? 1 : 0); H6l = H6.low = H6l + gl; H6.high = H6h + gh + (H6l >>> 0 < gl >>> 0 ? 1 : 0); H7l = H7.low = H7l + hl; H7.high = H7h + hh + (H7l >>> 0 < hl >>> 0 ? 1 : 0); }, _doFinalize: function() { var data = this._data; var dataWords = data.words; var nBitsTotal = this._nDataBytes * 8; var nBitsLeft = data.sigBytes * 8; dataWords[nBitsLeft >>> 5] |= 128 << 24 - nBitsLeft % 32; dataWords[(nBitsLeft + 128 >>> 10 << 5) + 30] = Math.floor(nBitsTotal / 4294967296); dataWords[(nBitsLeft + 128 >>> 10 << 5) + 31] = nBitsTotal; data.sigBytes = dataWords.length * 4; this._process(); var hash = this._hash.toX32(); return hash; }, clone: function() { var clone = Hasher.clone.call(this); clone._hash = this._hash.clone(); return clone; }, blockSize: 1024 / 32 }); /** * Shortcut function to the hasher's object interface. * * @param {WordArray|string} message The message to hash. * * @return {WordArray} The hash. * * @static * * @example * * var hash = CryptoJS.SHA512('message'); * var hash = CryptoJS.SHA512(wordArray); */ C.SHA512 = Hasher._createHelper(SHA512); /** * Shortcut function to the HMAC's object interface. * * @param {WordArray|string} message The message to hash. * @param {WordArray|string} key The secret key. * * @return {WordArray} The HMAC. * * @static * * @example * * var hmac = CryptoJS.HmacSHA512(message, key); */ C.HmacSHA512 = Hasher._createHmacHelper(SHA512); })(); (function() { var C = CryptoJS; var C_x64 = C.x64; var X64Word = C_x64.Word; var X64WordArray = C_x64.WordArray; var C_algo = C.algo; var SHA512 = C_algo.SHA512; /** * SHA-384 hash algorithm. */ var SHA384 = C_algo.SHA384 = SHA512.extend({ _doReset: function() { this._hash = new X64WordArray.init([ new X64Word.init(3418070365, 3238371032), new X64Word.init(1654270250, 914150663), new X64Word.init(2438529370, 812702999), new X64Word.init(355462360, 4144912697), new X64Word.init(1731405415, 4290775857), new X64Word.init(2394180231, 1750603025), new X64Word.init(3675008525, 1694076839), new X64Word.init(1203062813, 3204075428) ]); }, _doFinalize: function() { var hash = SHA512._doFinalize.call(this); hash.sigBytes -= 16; return hash; } }); /** * Shortcut function to the hasher's object interface. * * @param {WordArray|string} message The message to hash. * * @return {WordArray} The hash. * * @static * * @example * * var hash = CryptoJS.SHA384('message'); * var hash = CryptoJS.SHA384(wordArray); */ C.SHA384 = SHA512._createHelper(SHA384); /** * Shortcut function to the HMAC's object interface. * * @param {WordArray|string} message The message to hash. * @param {WordArray|string} key The secret key. * * @return {WordArray} The HMAC. * * @static * * @example * * var hmac = CryptoJS.HmacSHA384(message, key); */ C.HmacSHA384 = SHA512._createHmacHelper(SHA384); })(); (function(Math) { var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var Hasher = C_lib.Hasher; var C_x64 = C.x64; var X64Word = C_x64.Word; var C_algo = C.algo; var RHO_OFFSETS = []; var PI_INDEXES = []; var ROUND_CONSTANTS = []; (function() { var x = 1, y = 0; for (var t = 0; t < 24; t++) { RHO_OFFSETS[x + 5 * y] = (t + 1) * (t + 2) / 2 % 64; var newX = y % 5; var newY = (2 * x + 3 * y) % 5; x = newX; y = newY; } for (var x = 0; x < 5; x++) { for (var y = 0; y < 5; y++) { PI_INDEXES[x + 5 * y] = y + (2 * x + 3 * y) % 5 * 5; } } var LFSR = 1; for (var i = 0; i < 24; i++) { var roundConstantMsw = 0; var roundConstantLsw = 0; for (var j = 0; j < 7; j++) { if (LFSR & 1) { var bitPosition = (1 << j) - 1; if (bitPosition < 32) { roundConstantLsw ^= 1 << bitPosition; } else { roundConstantMsw ^= 1 << bitPosition - 32; } } if (LFSR & 128) { LFSR = LFSR << 1 ^ 113; } else { LFSR <<= 1; } } ROUND_CONSTANTS[i] = X64Word.create(roundConstantMsw, roundConstantLsw); } })(); var T = []; (function() { for (var i = 0; i < 25; i++) { T[i] = X64Word.create(); } })(); /** * SHA-3 hash algorithm. */ var SHA3 = C_algo.SHA3 = Hasher.extend({ cfg: Hasher.cfg.extend({ outputLength: 512 }), _doReset: function() { var state = this._state = []; for (var i = 0; i < 25; i++) { state[i] = new X64Word.init(); } this.blockSize = (1600 - 2 * this.cfg.outputLength) / 32; }, _doProcessBlock: function(M, offset) { var state = this._state; var nBlockSizeLanes = this.blockSize / 2; for (var i = 0; i < nBlockSizeLanes; i++) { var M2i = M[offset + 2 * i]; var M2i1 = M[offset + 2 * i + 1]; M2i = (M2i << 8 | M2i >>> 24) & 16711935 | (M2i << 24 | M2i >>> 8) & 4278255360; M2i1 = (M2i1 << 8 | M2i1 >>> 24) & 16711935 | (M2i1 << 24 | M2i1 >>> 8) & 4278255360; var lane = state[i]; lane.high ^= M2i1; lane.low ^= M2i; } for (var round = 0; round < 24; round++) { for (var x = 0; x < 5; x++) { var tMsw = 0, tLsw = 0; for (var y = 0; y < 5; y++) { var lane = state[x + 5 * y]; tMsw ^= lane.high; tLsw ^= lane.low; } var Tx = T[x]; Tx.high = tMsw; Tx.low = tLsw; } for (var x = 0; x < 5; x++) { var Tx4 = T[(x + 4) % 5]; var Tx1 = T[(x + 1) % 5]; var Tx1Msw = Tx1.high; var Tx1Lsw = Tx1.low; var tMsw = Tx4.high ^ (Tx1Msw << 1 | Tx1Lsw >>> 31); var tLsw = Tx4.low ^ (Tx1Lsw << 1 | Tx1Msw >>> 31); for (var y = 0; y < 5; y++) { var lane = state[x + 5 * y]; lane.high ^= tMsw; lane.low ^= tLsw; } } for (var laneIndex = 1; laneIndex < 25; laneIndex++) { var tMsw; var tLsw; var lane = state[laneIndex]; var laneMsw = lane.high; var laneLsw = lane.low; var rhoOffset = RHO_OFFSETS[laneIndex]; if (rhoOffset < 32) { tMsw = laneMsw << rhoOffset | laneLsw >>> 32 - rhoOffset; tLsw = laneLsw << rhoOffset | laneMsw >>> 32 - rhoOffset; } else { tMsw = laneLsw << rhoOffset - 32 | laneMsw >>> 64 - rhoOffset; tLsw = laneMsw << rhoOffset - 32 | laneLsw >>> 64 - rhoOffset; } var TPiLane = T[PI_INDEXES[laneIndex]]; TPiLane.high = tMsw; TPiLane.low = tLsw; } var T0 = T[0]; var state0 = state[0]; T0.high = state0.high; T0.low = state0.low; for (var x = 0; x < 5; x++) { for (var y = 0; y < 5; y++) { var laneIndex = x + 5 * y; var lane = state[laneIndex]; var TLane = T[laneIndex]; var Tx1Lane = T[(x + 1) % 5 + 5 * y]; var Tx2Lane = T[(x + 2) % 5 + 5 * y]; lane.high = TLane.high ^ ~Tx1Lane.high & Tx2Lane.high; lane.low = TLane.low ^ ~Tx1Lane.low & Tx2Lane.low; } } var lane = state[0]; var roundConstant = ROUND_CONSTANTS[round]; lane.high ^= roundConstant.high; lane.low ^= roundConstant.low; } }, _doFinalize: function() { var data = this._data; var dataWords = data.words; var nBitsTotal = this._nDataBytes * 8; var nBitsLeft = data.sigBytes * 8; var blockSizeBits = this.blockSize * 32; dataWords[nBitsLeft >>> 5] |= 1 << 24 - nBitsLeft % 32; dataWords[(Math.ceil((nBitsLeft + 1) / blockSizeBits) * blockSizeBits >>> 5) - 1] |= 128; data.sigBytes = dataWords.length * 4; this._process(); var state = this._state; var outputLengthBytes = this.cfg.outputLength / 8; var outputLengthLanes = outputLengthBytes / 8; var hashWords = []; for (var i = 0; i < outputLengthLanes; i++) { var lane = state[i]; var laneMsw = lane.high; var laneLsw = lane.low; laneMsw = (laneMsw << 8 | laneMsw >>> 24) & 16711935 | (laneMsw << 24 | laneMsw >>> 8) & 4278255360; laneLsw = (laneLsw << 8 | laneLsw >>> 24) & 16711935 | (laneLsw << 24 | laneLsw >>> 8) & 4278255360; hashWords.push(laneLsw); hashWords.push(laneMsw); } return new WordArray.init(hashWords, outputLengthBytes); }, clone: function() { var clone = Hasher.clone.call(this); var state = clone._state = this._state.slice(0); for (var i = 0; i < 25; i++) { state[i] = state[i].clone(); } return clone; } }); /** * Shortcut function to the hasher's object interface. * * @param {WordArray|string} message The message to hash. * * @return {WordArray} The hash. * * @static * * @example * * var hash = CryptoJS.SHA3('message'); * var hash = CryptoJS.SHA3(wordArray); */ C.SHA3 = Hasher._createHelper(SHA3); /** * Shortcut function to the HMAC's object interface. * * @param {WordArray|string} message The message to hash. * @param {WordArray|string} key The secret key. * * @return {WordArray} The HMAC. * * @static * * @example * * var hmac = CryptoJS.HmacSHA3(message, key); */ C.HmacSHA3 = Hasher._createHmacHelper(SHA3); })(Math); /** @preserve (c) 2012 by Cédric Mesnil. 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. 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. */ (function(Math) { var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var Hasher = C_lib.Hasher; var C_algo = C.algo; var _zl = WordArray.create([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 ]); var _zr = WordArray.create([ 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 ]); var _sl = WordArray.create([ 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 ]); var _sr = WordArray.create([ 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 ]); var _hl = WordArray.create([ 0, 1518500249, 1859775393, 2400959708, 2840853838 ]); var _hr = WordArray.create([ 1352829926, 1548603684, 1836072691, 2053994217, 0 ]); /** * RIPEMD160 hash algorithm. */ var RIPEMD160 = C_algo.RIPEMD160 = Hasher.extend({ _doReset: function() { this._hash = WordArray.create([ 1732584193, 4023233417, 2562383102, 271733878, 3285377520 ]); }, _doProcessBlock: function(M, offset) { for (var i = 0; i < 16; i++) { var offset_i = offset + i; var M_offset_i = M[offset_i]; M[offset_i] = (M_offset_i << 8 | M_offset_i >>> 24) & 16711935 | (M_offset_i << 24 | M_offset_i >>> 8) & 4278255360; } var H = this._hash.words; var hl = _hl.words; var hr = _hr.words; var zl = _zl.words; var zr = _zr.words; var sl = _sl.words; var sr = _sr.words; var al, bl, cl, dl, el; var ar, br, cr, dr, er; ar = al = H[0]; br = bl = H[1]; cr = cl = H[2]; dr = dl = H[3]; er = el = H[4]; var t; for (var i = 0; i < 80; i += 1) { t = al + M[offset + zl[i]] | 0; if (i < 16) { t += f1(bl, cl, dl) + hl[0]; } else if (i < 32) { t += f2(bl, cl, dl) + hl[1]; } else if (i < 48) { t += f3(bl, cl, dl) + hl[2]; } else if (i < 64) { t += f4(bl, cl, dl) + hl[3]; } else { t += f5(bl, cl, dl) + hl[4]; } t = t | 0; t = rotl(t, sl[i]); t = t + el | 0; al = el; el = dl; dl = rotl(cl, 10); cl = bl; bl = t; t = ar + M[offset + zr[i]] | 0; if (i < 16) { t += f5(br, cr, dr) + hr[0]; } else if (i < 32) { t += f4(br, cr, dr) + hr[1]; } else if (i < 48) { t += f3(br, cr, dr) + hr[2]; } else if (i < 64) { t += f2(br, cr, dr) + hr[3]; } else { t += f1(br, cr, dr) + hr[4]; } t = t | 0; t = rotl(t, sr[i]); t = t + er | 0; ar = er; er = dr; dr = rotl(cr, 10); cr = br; br = t; } t = H[1] + cl + dr | 0; H[1] = H[2] + dl + er | 0; H[2] = H[3] + el + ar | 0; H[3] = H[4] + al + br | 0; H[4] = H[0] + bl + cr | 0; H[0] = t; }, _doFinalize: function() { var data = this._data; var dataWords = data.words; var nBitsTotal = this._nDataBytes * 8; var nBitsLeft = data.sigBytes * 8; dataWords[nBitsLeft >>> 5] |= 128 << 24 - nBitsLeft % 32; dataWords[(nBitsLeft + 64 >>> 9 << 4) + 14] = (nBitsTotal << 8 | nBitsTotal >>> 24) & 16711935 | (nBitsTotal << 24 | nBitsTotal >>> 8) & 4278255360; data.sigBytes = (dataWords.length + 1) * 4; this._process(); var hash = this._hash; var H = hash.words; for (var i = 0; i < 5; i++) { var H_i = H[i]; H[i] = (H_i << 8 | H_i >>> 24) & 16711935 | (H_i << 24 | H_i >>> 8) & 4278255360; } return hash; }, clone: function() { var clone = Hasher.clone.call(this); clone._hash = this._hash.clone(); return clone; } }); function f1(x, y, z) { return x ^ y ^ z; } function f2(x, y, z) { return x & y | ~x & z; } function f3(x, y, z) { return (x | ~y) ^ z; } function f4(x, y, z) { return x & z | y & ~z; } function f5(x, y, z) { return x ^ (y | ~z); } function rotl(x, n) { return x << n | x >>> 32 - n; } /** * Shortcut function to the hasher's object interface. * * @param {WordArray|string} message The message to hash. * * @return {WordArray} The hash. * * @static * * @example * * var hash = CryptoJS.RIPEMD160('message'); * var hash = CryptoJS.RIPEMD160(wordArray); */ C.RIPEMD160 = Hasher._createHelper(RIPEMD160); /** * Shortcut function to the HMAC's object interface. * * @param {WordArray|string} message The message to hash. * @param {WordArray|string} key The secret key. * * @return {WordArray} The HMAC. * * @static * * @example * * var hmac = CryptoJS.HmacRIPEMD160(message, key); */ C.HmacRIPEMD160 = Hasher._createHmacHelper(RIPEMD160); })(Math); (function() { var C = CryptoJS; var C_lib = C.lib; var Base = C_lib.Base; var C_enc = C.enc; var Utf8 = C_enc.Utf8; var C_algo = C.algo; /** * HMAC algorithm. */ var HMAC = C_algo.HMAC = Base.extend({ init: function(hasher, key) { hasher = this._hasher = new hasher.init(); if (typeof key == "string") { key = Utf8.parse(key); } var hasherBlockSize = hasher.blockSize; var hasherBlockSizeBytes = hasherBlockSize * 4; if (key.sigBytes > hasherBlockSizeBytes) { key = hasher.finalize(key); } key.clamp(); var oKey = this._oKey = key.clone(); var iKey = this._iKey = key.clone(); var oKeyWords = oKey.words; var iKeyWords = iKey.words; for (var i = 0; i < hasherBlockSize; i++) { oKeyWords[i] ^= 1549556828; iKeyWords[i] ^= 909522486; } oKey.sigBytes = iKey.sigBytes = hasherBlockSizeBytes; this.reset(); }, reset: function() { var hasher = this._hasher; hasher.reset(); hasher.update(this._iKey); }, update: function(messageUpdate) { this._hasher.update(messageUpdate); return this; }, finalize: function(messageUpdate) { var hasher = this._hasher; var innerHash = hasher.finalize(messageUpdate); hasher.reset(); var hmac = hasher.finalize(this._oKey.clone().concat(innerHash)); return hmac; } }); })(); (function() { var C = CryptoJS; var C_lib = C.lib; var Base = C_lib.Base; var WordArray = C_lib.WordArray; var C_algo = C.algo; var SHA1 = C_algo.SHA1; var HMAC = C_algo.HMAC; /** * Password-Based Key Derivation Function 2 algorithm. */ var PBKDF2 = C_algo.PBKDF2 = Base.extend({ cfg: Base.extend({ keySize: 128 / 32, hasher: SHA1, iterations: 1 }), init: function(cfg) { this.cfg = this.cfg.extend(cfg); }, compute: function(password, salt) { var cfg = this.cfg; var hmac = HMAC.create(cfg.hasher, password); var derivedKey = WordArray.create(); var blockIndex = WordArray.create([1]); var derivedKeyWords = derivedKey.words; var blockIndexWords = blockIndex.words; var keySize = cfg.keySize; var iterations = cfg.iterations; while (derivedKeyWords.length < keySize) { var block = hmac.update(salt).finalize(blockIndex); hmac.reset(); var blockWords = block.words; var blockWordsLength = blockWords.length; var intermediate = block; for (var i = 1; i < iterations; i++) { intermediate = hmac.finalize(intermediate); hmac.reset(); var intermediateWords = intermediate.words; for (var j = 0; j < blockWordsLength; j++) { blockWords[j] ^= intermediateWords[j]; } } derivedKey.concat(block); blockIndexWords[0]++; } derivedKey.sigBytes = keySize * 4; return derivedKey; } }); /** * Computes the Password-Based Key Derivation Function 2. * * @param {WordArray|string} password The password. * @param {WordArray|string} salt A salt. * @param {Object} cfg (Optional) The configuration options to use for this computation. * * @return {WordArray} The derived key. * * @static * * @example * * var key = CryptoJS.PBKDF2(password, salt); * var key = CryptoJS.PBKDF2(password, salt, { keySize: 8 }); * var key = CryptoJS.PBKDF2(password, salt, { keySize: 8, iterations: 1000 }); */ C.PBKDF2 = function(password, salt, cfg) { return PBKDF2.create(cfg).compute(password, salt); }; })(); (function() { var C = CryptoJS; var C_lib = C.lib; var Base = C_lib.Base; var WordArray = C_lib.WordArray; var C_algo = C.algo; var MD5 = C_algo.MD5; /** * This key derivation function is meant to conform with EVP_BytesToKey. * www.openssl.org/docs/crypto/EVP_BytesToKey.html */ var EvpKDF = C_algo.EvpKDF = Base.extend({ cfg: Base.extend({ keySize: 128 / 32, hasher: MD5, iterations: 1 }), init: function(cfg) { this.cfg = this.cfg.extend(cfg); }, compute: function(password, salt) { var block; var cfg = this.cfg; var hasher = cfg.hasher.create(); var derivedKey = WordArray.create(); var derivedKeyWords = derivedKey.words; var keySize = cfg.keySize; var iterations = cfg.iterations; while (derivedKeyWords.length < keySize) { if (block) { hasher.update(block); } block = hasher.update(password).finalize(salt); hasher.reset(); for (var i = 1; i < iterations; i++) { block = hasher.finalize(block); hasher.reset(); } derivedKey.concat(block); } derivedKey.sigBytes = keySize * 4; return derivedKey; } }); /** * Derives a key from a password. * * @param {WordArray|string} password The password. * @param {WordArray|string} salt A salt. * @param {Object} cfg (Optional) The configuration options to use for this computation. * * @return {WordArray} The derived key. * * @static * * @example * * var key = CryptoJS.EvpKDF(password, salt); * var key = CryptoJS.EvpKDF(password, salt, { keySize: 8 }); * var key = CryptoJS.EvpKDF(password, salt, { keySize: 8, iterations: 1000 }); */ C.EvpKDF = function(password, salt, cfg) { return EvpKDF.create(cfg).compute(password, salt); }; })(); /** * Cipher core components. */ CryptoJS.lib.Cipher || function(undefined) { var C = CryptoJS; var C_lib = C.lib; var Base = C_lib.Base; var WordArray = C_lib.WordArray; var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm; var C_enc = C.enc; var Utf8 = C_enc.Utf8; var Base64 = C_enc.Base64; var C_algo = C.algo; var EvpKDF = C_algo.EvpKDF; /** * Abstract base cipher template. * * @property {number} keySize This cipher's key size. Default: 4 (128 bits) * @property {number} ivSize This cipher's IV size. Default: 4 (128 bits) * @property {number} _ENC_XFORM_MODE A constant representing encryption mode. * @property {number} _DEC_XFORM_MODE A constant representing decryption mode. */ var Cipher = C_lib.Cipher = BufferedBlockAlgorithm.extend({ cfg: Base.extend(), createEncryptor: function(key, cfg) { return this.create(this._ENC_XFORM_MODE, key, cfg); }, createDecryptor: function(key, cfg) { return this.create(this._DEC_XFORM_MODE, key, cfg); }, init: function(xformMode, key, cfg) { this.cfg = this.cfg.extend(cfg); this._xformMode = xformMode; this._key = key; this.reset(); }, reset: function() { BufferedBlockAlgorithm.reset.call(this); this._doReset(); }, process: function(dataUpdate) { this._append(dataUpdate); return this._process(); }, finalize: function(dataUpdate) { if (dataUpdate) { this._append(dataUpdate); } var finalProcessedData = this._doFinalize(); return finalProcessedData; }, keySize: 128 / 32, ivSize: 128 / 32, _ENC_XFORM_MODE: 1, _DEC_XFORM_MODE: 2, _createHelper: function() { function selectCipherStrategy(key) { if (typeof key == "string") { return PasswordBasedCipher; } else { return SerializableCipher; } } return function(cipher) { return { encrypt: function(message, key, cfg) { return selectCipherStrategy(key).encrypt(cipher, message, key, cfg); }, decrypt: function(ciphertext, key, cfg) { return selectCipherStrategy(key).decrypt(cipher, ciphertext, key, cfg); } }; }; }() }); /** * Abstract base stream cipher template. * * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 1 (32 bits) */ var StreamCipher = C_lib.StreamCipher = Cipher.extend({ _doFinalize: function() { var finalProcessedBlocks = this._process(!!"flush"); return finalProcessedBlocks; }, blockSize: 1 }); /** * Mode namespace. */ var C_mode = C.mode = {}; /** * Abstract base block cipher mode template. */ var BlockCipherMode = C_lib.BlockCipherMode = Base.extend({ createEncryptor: function(cipher, iv) { return this.Encryptor.create(cipher, iv); }, createDecryptor: function(cipher, iv) { return this.Decryptor.create(cipher, iv); }, init: function(cipher, iv) { this._cipher = cipher; this._iv = iv; } }); /** * Cipher Block Chaining mode. */ var CBC = C_mode.CBC = function() { /** * Abstract base CBC mode. */ var CBC = BlockCipherMode.extend(); /** * CBC encryptor. */ CBC.Encryptor = CBC.extend({ processBlock: function(words, offset) { var cipher = this._cipher; var blockSize = cipher.blockSize; xorBlock.call(this, words, offset, blockSize); cipher.encryptBlock(words, offset); this._prevBlock = words.slice(offset, offset + blockSize); } }); /** * CBC decryptor. */ CBC.Decryptor = CBC.extend({ processBlock: function(words, offset) { var cipher = this._cipher; var blockSize = cipher.blockSize; var thisBlock = words.slice(offset, offset + blockSize); cipher.decryptBlock(words, offset); xorBlock.call(this, words, offset, blockSize); this._prevBlock = thisBlock; } }); function xorBlock(words, offset, blockSize) { var block; var iv = this._iv; if (iv) { block = iv; this._iv = undefined; } else { block = this._prevBlock; } for (var i = 0; i < blockSize; i++) { words[offset + i] ^= block[i]; } } return CBC; }(); /** * Padding namespace. */ var C_pad = C.pad = {}; /** * PKCS #5/7 padding strategy. */ var Pkcs7 = C_pad.Pkcs7 = { pad: function(data, blockSize) { var blockSizeBytes = blockSize * 4; var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes; var paddingWord = nPaddingBytes << 24 | nPaddingBytes << 16 | nPaddingBytes << 8 | nPaddingBytes; var paddingWords = []; for (var i = 0; i < nPaddingBytes; i += 4) { paddingWords.push(paddingWord); } var padding = WordArray.create(paddingWords, nPaddingBytes); data.concat(padding); }, unpad: function(data) { var nPaddingBytes = data.words[data.sigBytes - 1 >>> 2] & 255; data.sigBytes -= nPaddingBytes; } }; /** * Abstract base block cipher template. * * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 4 (128 bits) */ var BlockCipher = C_lib.BlockCipher = Cipher.extend({ cfg: Cipher.cfg.extend({ mode: CBC, padding: Pkcs7 }), reset: function() { var modeCreator; Cipher.reset.call(this); var cfg = this.cfg; var iv = cfg.iv; var mode = cfg.mode; if (this._xformMode == this._ENC_XFORM_MODE) { modeCreator = mode.createEncryptor; } else { modeCreator = mode.createDecryptor; this._minBufferSize = 1; } if (this._mode && this._mode.__creator == modeCreator) { this._mode.init(this, iv && iv.words); } else { this._mode = modeCreator.call(mode, this, iv && iv.words); this._mode.__creator = modeCreator; } }, _doProcessBlock: function(words, offset) { this._mode.processBlock(words, offset); }, _doFinalize: function() { var finalProcessedBlocks; var padding = this.cfg.padding; if (this._xformMode == this._ENC_XFORM_MODE) { padding.pad(this._data, this.blockSize); finalProcessedBlocks = this._process(!!"flush"); } else { finalProcessedBlocks = this._process(!!"flush"); padding.unpad(finalProcessedBlocks); } return finalProcessedBlocks; }, blockSize: 128 / 32 }); /** * A collection of cipher parameters. * * @property {WordArray} ciphertext The raw ciphertext. * @property {WordArray} key The key to this ciphertext. * @property {WordArray} iv The IV used in the ciphering operation. * @property {WordArray} salt The salt used with a key derivation function. * @property {Cipher} algorithm The cipher algorithm. * @property {Mode} mode The block mode used in the ciphering operation. * @property {Padding} padding The padding scheme used in the ciphering operation. * @property {number} blockSize The block size of the cipher. * @property {Format} formatter The default formatting strategy to convert this cipher params object to a string. */ var CipherParams = C_lib.CipherParams = Base.extend({ init: function(cipherParams) { this.mixIn(cipherParams); }, toString: function(formatter) { return (formatter || this.formatter).stringify(this); } }); /** * Format namespace. */ var C_format = C.format = {}; /** * OpenSSL formatting strategy. */ var OpenSSLFormatter = C_format.OpenSSL = { stringify: function(cipherParams) { var wordArray; var ciphertext = cipherParams.ciphertext; var salt = cipherParams.salt; if (salt) { wordArray = WordArray.create([1398893684, 1701076831]).concat(salt).concat(ciphertext); } else { wordArray = ciphertext; } return wordArray.toString(Base64); }, parse: function(openSSLStr) { var salt; var ciphertext = Base64.parse(openSSLStr); var ciphertextWords = ciphertext.words; if (ciphertextWords[0] == 1398893684 && ciphertextWords[1] == 1701076831) { salt = WordArray.create(ciphertextWords.slice(2, 4)); ciphertextWords.splice(0, 4); ciphertext.sigBytes -= 16; } return CipherParams.create({ ciphertext, salt }); } }; /** * A cipher wrapper that returns ciphertext as a serializable cipher params object. */ var SerializableCipher = C_lib.SerializableCipher = Base.extend({ cfg: Base.extend({ format: OpenSSLFormatter }), encrypt: function(cipher, message, key, cfg) { cfg = this.cfg.extend(cfg); var encryptor = cipher.createEncryptor(key, cfg); var ciphertext = encryptor.finalize(message); var cipherCfg = encryptor.cfg; return CipherParams.create({ ciphertext, key, iv: cipherCfg.iv, algorithm: cipher, mode: cipherCfg.mode, padding: cipherCfg.padding, blockSize: cipher.blockSize, formatter: cfg.format }); }, decrypt: function(cipher, ciphertext, key, cfg) { cfg = this.cfg.extend(cfg); ciphertext = this._parse(ciphertext, cfg.format); var plaintext = cipher.createDecryptor(key, cfg).finalize(ciphertext.ciphertext); return plaintext; }, _parse: function(ciphertext, format) { if (typeof ciphertext == "string") { return format.parse(ciphertext, this); } else { return ciphertext; } } }); /** * Key derivation function namespace. */ var C_kdf = C.kdf = {}; /** * OpenSSL key derivation function. */ var OpenSSLKdf = C_kdf.OpenSSL = { execute: function(password, keySize, ivSize, salt) { if (!salt) { salt = WordArray.random(64 / 8); } var key = EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt); var iv = WordArray.create(key.words.slice(keySize), ivSize * 4); key.sigBytes = keySize * 4; return CipherParams.create({ key, iv, salt }); } }; /** * A serializable cipher wrapper that derives the key from a password, * and returns ciphertext as a serializable cipher params object. */ var PasswordBasedCipher = C_lib.PasswordBasedCipher = SerializableCipher.extend({ cfg: SerializableCipher.cfg.extend({ kdf: OpenSSLKdf }), encrypt: function(cipher, message, password, cfg) { cfg = this.cfg.extend(cfg); var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize); cfg.iv = derivedParams.iv; var ciphertext = SerializableCipher.encrypt.call(this, cipher, message, derivedParams.key, cfg); ciphertext.mixIn(derivedParams); return ciphertext; }, decrypt: function(cipher, ciphertext, password, cfg) { cfg = this.cfg.extend(cfg); ciphertext = this._parse(ciphertext, cfg.format); var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, ciphertext.salt); cfg.iv = derivedParams.iv; var plaintext = SerializableCipher.decrypt.call(this, cipher, ciphertext, derivedParams.key, cfg); return plaintext; } }); }(); /** * Cipher Feedback block mode. */ CryptoJS.mode.CFB = function() { var CFB = CryptoJS.lib.BlockCipherMode.extend(); CFB.Encryptor = CFB.extend({ processBlock: function(words, offset) { var cipher = this._cipher; var blockSize = cipher.blockSize; generateKeystreamAndEncrypt.call(this, words, offset, blockSize, cipher); this._prevBlock = words.slice(offset, offset + blockSize); } }); CFB.Decryptor = CFB.extend({ processBlock: function(words, offset) { var cipher = this._cipher; var blockSize = cipher.blockSize; var thisBlock = words.slice(offset, offset + blockSize); generateKeystreamAndEncrypt.call(this, words, offset, blockSize, cipher); this._prevBlock = thisBlock; } }); function generateKeystreamAndEncrypt(words, offset, blockSize, cipher) { var keystream; var iv = this._iv; if (iv) { keystream = iv.slice(0); this._iv = undefined; } else { keystream = this._prevBlock; } cipher.encryptBlock(keystream, 0); for (var i = 0; i < blockSize; i++) { words[offset + i] ^= keystream[i]; } } return CFB; }(); /** * Counter block mode. */ CryptoJS.mode.CTR = function() { var CTR = CryptoJS.lib.BlockCipherMode.extend(); var Encryptor = CTR.Encryptor = CTR.extend({ processBlock: function(words, offset) { var cipher = this._cipher; var blockSize = cipher.blockSize; var iv = this._iv; var counter = this._counter; if (iv) { counter = this._counter = iv.slice(0); this._iv = undefined; } var keystream = counter.slice(0); cipher.encryptBlock(keystream, 0); counter[blockSize - 1] = counter[blockSize - 1] + 1 | 0; for (var i = 0; i < blockSize; i++) { words[offset + i] ^= keystream[i]; } } }); CTR.Decryptor = Encryptor; return CTR; }(); /** @preserve * Counter block mode compatible with Dr Brian Gladman fileenc.c * derived from CryptoJS.mode.CTR * Jan Hruby jhruby.web@gmail.com */ CryptoJS.mode.CTRGladman = function() { var CTRGladman = CryptoJS.lib.BlockCipherMode.extend(); function incWord(word) { if ((word >> 24 & 255) === 255) { var b1 = word >> 16 & 255; var b2 = word >> 8 & 255; var b3 = word & 255; if (b1 === 255) { b1 = 0; if (b2 === 255) { b2 = 0; if (b3 === 255) { b3 = 0; } else { ++b3; } } else { ++b2; } } else { ++b1; } word = 0; word += b1 << 16; word += b2 << 8; word += b3; } else { word += 1 << 24; } return word; } function incCounter(counter) { if ((counter[0] = incWord(counter[0])) === 0) { counter[1] = incWord(counter[1]); } return counter; } var Encryptor = CTRGladman.Encryptor = CTRGladman.extend({ processBlock: function(words, offset) { var cipher = this._cipher; var blockSize = cipher.blockSize; var iv = this._iv; var counter = this._counter; if (iv) { counter = this._counter = iv.slice(0); this._iv = undefined; } incCounter(counter); var keystream = counter.slice(0); cipher.encryptBlock(keystream, 0); for (var i = 0; i < blockSize; i++) { words[offset + i] ^= keystream[i]; } } }); CTRGladman.Decryptor = Encryptor; return CTRGladman; }(); /** * Output Feedback block mode. */ CryptoJS.mode.OFB = function() { var OFB = CryptoJS.lib.BlockCipherMode.extend(); var Encryptor = OFB.Encryptor = OFB.extend({ processBlock: function(words, offset) { var cipher = this._cipher; var blockSize = cipher.blockSize; var iv = this._iv; var keystream = this._keystream; if (iv) { keystream = this._keystream = iv.slice(0); this._iv = undefined; } cipher.encryptBlock(keystream, 0); for (var i = 0; i < blockSize; i++) { words[offset + i] ^= keystream[i]; } } }); OFB.Decryptor = Encryptor; return OFB; }(); /** * Electronic Codebook block mode. */ CryptoJS.mode.ECB = function() { var ECB = CryptoJS.lib.BlockCipherMode.extend(); ECB.Encryptor = ECB.extend({ processBlock: function(words, offset) { this._cipher.encryptBlock(words, offset); } }); ECB.Decryptor = ECB.extend({ processBlock: function(words, offset) { this._cipher.decryptBlock(words, offset); } }); return ECB; }(); /** * ANSI X.923 padding strategy. */ CryptoJS.pad.AnsiX923 = { pad: function(data, blockSize) { var dataSigBytes = data.sigBytes; var blockSizeBytes = blockSize * 4; var nPaddingBytes = blockSizeBytes - dataSigBytes % blockSizeBytes; var lastBytePos = dataSigBytes + nPaddingBytes - 1; data.clamp(); data.words[lastBytePos >>> 2] |= nPaddingBytes << 24 - lastBytePos % 4 * 8; data.sigBytes += nPaddingBytes; }, unpad: function(data) { var nPaddingBytes = data.words[data.sigBytes - 1 >>> 2] & 255; data.sigBytes -= nPaddingBytes; } }; /** * ISO 10126 padding strategy. */ CryptoJS.pad.Iso10126 = { pad: function(data, blockSize) { var blockSizeBytes = blockSize * 4; var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes; data.concat(CryptoJS.lib.WordArray.random(nPaddingBytes - 1)).concat(CryptoJS.lib.WordArray.create([nPaddingBytes << 24], 1)); }, unpad: function(data) { var nPaddingBytes = data.words[data.sigBytes - 1 >>> 2] & 255; data.sigBytes -= nPaddingBytes; } }; /** * ISO/IEC 9797-1 Padding Method 2. */ CryptoJS.pad.Iso97971 = { pad: function(data, blockSize) { data.concat(CryptoJS.lib.WordArray.create([2147483648], 1)); CryptoJS.pad.ZeroPadding.pad(data, blockSize); }, unpad: function(data) { CryptoJS.pad.ZeroPadding.unpad(data); data.sigBytes--; } }; /** * Zero padding strategy. */ CryptoJS.pad.ZeroPadding = { pad: function(data, blockSize) { var blockSizeBytes = blockSize * 4; data.clamp(); data.sigBytes += blockSizeBytes - (data.sigBytes % blockSizeBytes || blockSizeBytes); }, unpad: function(data) { var dataWords = data.words; var i = data.sigBytes - 1; for (var i = data.sigBytes - 1; i >= 0; i--) { if (dataWords[i >>> 2] >>> 24 - i % 4 * 8 & 255) { data.sigBytes = i + 1; break; } } } }; /** * A noop padding strategy. */ CryptoJS.pad.NoPadding = { pad: function() {}, unpad: function() {} }; (function(undefined) { var C = CryptoJS; var C_lib = C.lib; var CipherParams = C_lib.CipherParams; var C_enc = C.enc; var Hex = C_enc.Hex; var C_format = C.format; var HexFormatter = C_format.Hex = { stringify: function(cipherParams) { return cipherParams.ciphertext.toString(Hex); }, parse: function(input) { var ciphertext = Hex.parse(input); return CipherParams.create({ ciphertext }); } }; })(); (function() { var C = CryptoJS; var C_lib = C.lib; var BlockCipher = C_lib.BlockCipher; var C_algo = C.algo; var SBOX = []; var INV_SBOX = []; var SUB_MIX_0 = []; var SUB_MIX_1 = []; var SUB_MIX_2 = []; var SUB_MIX_3 = []; var INV_SUB_MIX_0 = []; var INV_SUB_MIX_1 = []; var INV_SUB_MIX_2 = []; var INV_SUB_MIX_3 = []; (function() { var d = []; for (var i = 0; i < 256; i++) { if (i < 128) { d[i] = i << 1; } else { d[i] = i << 1 ^ 283; } } var x = 0; var xi = 0; for (var i = 0; i < 256; i++) { var sx = xi ^ xi << 1 ^ xi << 2 ^ xi << 3 ^ xi << 4; sx = sx >>> 8 ^ sx & 255 ^ 99; SBOX[x] = sx; INV_SBOX[sx] = x; var x2 = d[x]; var x4 = d[x2]; var x8 = d[x4]; var t = d[sx] * 257 ^ sx * 16843008; SUB_MIX_0[x] = t << 24 | t >>> 8; SUB_MIX_1[x] = t << 16 | t >>> 16; SUB_MIX_2[x] = t << 8 | t >>> 24; SUB_MIX_3[x] = t; var t = x8 * 16843009 ^ x4 * 65537 ^ x2 * 257 ^ x * 16843008; INV_SUB_MIX_0[sx] = t << 24 | t >>> 8; INV_SUB_MIX_1[sx] = t << 16 | t >>> 16; INV_SUB_MIX_2[sx] = t << 8 | t >>> 24; INV_SUB_MIX_3[sx] = t; if (!x) { x = xi = 1; } else { x = x2 ^ d[d[d[x8 ^ x2]]]; xi ^= d[d[xi]]; } } })(); var RCON = [ 0, 1, 2, 4, 8, 16, 32, 64, 128, 27, 54 ]; /** * AES block cipher algorithm. */ var AES = C_algo.AES = BlockCipher.extend({ _doReset: function() { var t; if (this._nRounds && this._keyPriorReset === this._key) { return; } var key = this._keyPriorReset = this._key; var keyWords = key.words; var keySize = key.sigBytes / 4; var nRounds = this._nRounds = keySize + 6; var ksRows = (nRounds + 1) * 4; var keySchedule = this._keySchedule = []; for (var ksRow = 0; ksRow < ksRows; ksRow++) { if (ksRow < keySize) { keySchedule[ksRow] = keyWords[ksRow]; } else { t = keySchedule[ksRow - 1]; if (!(ksRow % keySize)) { t = t << 8 | t >>> 24; t = SBOX[t >>> 24] << 24 | SBOX[t >>> 16 & 255] << 16 | SBOX[t >>> 8 & 255] << 8 | SBOX[t & 255]; t ^= RCON[ksRow / keySize | 0] << 24; } else if (keySize > 6 && ksRow % keySize == 4) { t = SBOX[t >>> 24] << 24 | SBOX[t >>> 16 & 255] << 16 | SBOX[t >>> 8 & 255] << 8 | SBOX[t & 255]; } keySchedule[ksRow] = keySchedule[ksRow - keySize] ^ t; } } var invKeySchedule = this._invKeySchedule = []; for (var invKsRow = 0; invKsRow < ksRows; invKsRow++) { var ksRow = ksRows - invKsRow; if (invKsRow % 4) { var t = keySchedule[ksRow]; } else { var t = keySchedule[ksRow - 4]; } if (invKsRow < 4 || ksRow <= 4) { invKeySchedule[invKsRow] = t; } else { invKeySchedule[invKsRow] = INV_SUB_MIX_0[SBOX[t >>> 24]] ^ INV_SUB_MIX_1[SBOX[t >>> 16 & 255]] ^ INV_SUB_MIX_2[SBOX[t >>> 8 & 255]] ^ INV_SUB_MIX_3[SBOX[t & 255]]; } } }, encryptBlock: function(M, offset) { this._doCryptBlock(M, offset, this._keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX); }, decryptBlock: function(M, offset) { var t = M[offset + 1]; M[offset + 1] = M[offset + 3]; M[offset + 3] = t; this._doCryptBlock(M, offset, this._invKeySchedule, INV_SUB_MIX_0, INV_SUB_MIX_1, INV_SUB_MIX_2, INV_SUB_MIX_3, INV_SBOX); var t = M[offset + 1]; M[offset + 1] = M[offset + 3]; M[offset + 3] = t; }, _doCryptBlock: function(M, offset, keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX) { var nRounds = this._nRounds; var s0 = M[offset] ^ keySchedule[0]; var s1 = M[offset + 1] ^ keySchedule[1]; var s2 = M[offset + 2] ^ keySchedule[2]; var s3 = M[offset + 3] ^ keySchedule[3]; var ksRow = 4; for (var round = 1; round < nRounds; round++) { var t0 = SUB_MIX_0[s0 >>> 24] ^ SUB_MIX_1[s1 >>> 16 & 255] ^ SUB_MIX_2[s2 >>> 8 & 255] ^ SUB_MIX_3[s3 & 255] ^ keySchedule[ksRow++]; var t1 = SUB_MIX_0[s1 >>> 24] ^ SUB_MIX_1[s2 >>> 16 & 255] ^ SUB_MIX_2[s3 >>> 8 & 255] ^ SUB_MIX_3[s0 & 255] ^ keySchedule[ksRow++]; var t2 = SUB_MIX_0[s2 >>> 24] ^ SUB_MIX_1[s3 >>> 16 & 255] ^ SUB_MIX_2[s0 >>> 8 & 255] ^ SUB_MIX_3[s1 & 255] ^ keySchedule[ksRow++]; var t3 = SUB_MIX_0[s3 >>> 24] ^ SUB_MIX_1[s0 >>> 16 & 255] ^ SUB_MIX_2[s1 >>> 8 & 255] ^ SUB_MIX_3[s2 & 255] ^ keySchedule[ksRow++]; s0 = t0; s1 = t1; s2 = t2; s3 = t3; } var t0 = (SBOX[s0 >>> 24] << 24 | SBOX[s1 >>> 16 & 255] << 16 | SBOX[s2 >>> 8 & 255] << 8 | SBOX[s3 & 255]) ^ keySchedule[ksRow++]; var t1 = (SBOX[s1 >>> 24] << 24 | SBOX[s2 >>> 16 & 255] << 16 | SBOX[s3 >>> 8 & 255] << 8 | SBOX[s0 & 255]) ^ keySchedule[ksRow++]; var t2 = (SBOX[s2 >>> 24] << 24 | SBOX[s3 >>> 16 & 255] << 16 | SBOX[s0 >>> 8 & 255] << 8 | SBOX[s1 & 255]) ^ keySchedule[ksRow++]; var t3 = (SBOX[s3 >>> 24] << 24 | SBOX[s0 >>> 16 & 255] << 16 | SBOX[s1 >>> 8 & 255] << 8 | SBOX[s2 & 255]) ^ keySchedule[ksRow++]; M[offset] = t0; M[offset + 1] = t1; M[offset + 2] = t2; M[offset + 3] = t3; }, keySize: 256 / 32 }); /** * Shortcut functions to the cipher's object interface. * * @example * * var ciphertext = CryptoJS.AES.encrypt(message, key, cfg); * var plaintext = CryptoJS.AES.decrypt(ciphertext, key, cfg); */ C.AES = BlockCipher._createHelper(AES); })(); (function() { var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var BlockCipher = C_lib.BlockCipher; var C_algo = C.algo; var PC1 = [ 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 ]; var PC2 = [ 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32 ]; var BIT_SHIFTS = [ 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 ]; var SBOX_P = [ { 0: 8421888, 268435456: 32768, 536870912: 8421378, 805306368: 2, 1073741824: 512, 1342177280: 8421890, 1610612736: 8389122, 1879048192: 8388608, 2147483648: 514, 2415919104: 8389120, 2684354560: 33280, 2952790016: 8421376, 3221225472: 32770, 3489660928: 8388610, 3758096384: 0, 4026531840: 33282, 134217728: 0, 402653184: 8421890, 671088640: 33282, 939524096: 32768, 1207959552: 8421888, 1476395008: 512, 1744830464: 8421378, 2013265920: 2, 2281701376: 8389120, 2550136832: 33280, 2818572288: 8421376, 3087007744: 8389122, 3355443200: 8388610, 3623878656: 32770, 3892314112: 514, 4160749568: 8388608, 1: 32768, 268435457: 2, 536870913: 8421888, 805306369: 8388608, 1073741825: 8421378, 1342177281: 33280, 1610612737: 512, 1879048193: 8389122, 2147483649: 8421890, 2415919105: 8421376, 2684354561: 8388610, 2952790017: 33282, 3221225473: 514, 3489660929: 8389120, 3758096385: 32770, 4026531841: 0, 134217729: 8421890, 402653185: 8421376, 671088641: 8388608, 939524097: 512, 1207959553: 32768, 1476395009: 8388610, 1744830465: 2, 2013265921: 33282, 2281701377: 32770, 2550136833: 8389122, 2818572289: 514, 3087007745: 8421888, 3355443201: 8389120, 3623878657: 0, 3892314113: 33280, 4160749569: 8421378 }, { 0: 1074282512, 16777216: 16384, 33554432: 524288, 50331648: 1074266128, 67108864: 1073741840, 83886080: 1074282496, 100663296: 1073758208, 117440512: 16, 134217728: 540672, 150994944: 1073758224, 167772160: 1073741824, 184549376: 540688, 201326592: 524304, 218103808: 0, 234881024: 16400, 251658240: 1074266112, 8388608: 1073758208, 25165824: 540688, 41943040: 16, 58720256: 1073758224, 75497472: 1074282512, 92274688: 1073741824, 109051904: 524288, 125829120: 1074266128, 142606336: 524304, 159383552: 0, 176160768: 16384, 192937984: 1074266112, 209715200: 1073741840, 226492416: 540672, 243269632: 1074282496, 260046848: 16400, 268435456: 0, 285212672: 1074266128, 301989888: 1073758224, 318767104: 1074282496, 335544320: 1074266112, 352321536: 16, 369098752: 540688, 385875968: 16384, 402653184: 16400, 419430400: 524288, 436207616: 524304, 452984832: 1073741840, 469762048: 540672, 486539264: 1073758208, 503316480: 1073741824, 520093696: 1074282512, 276824064: 540688, 293601280: 524288, 310378496: 1074266112, 327155712: 16384, 343932928: 1073758208, 360710144: 1074282512, 377487360: 16, 394264576: 1073741824, 411041792: 1074282496, 427819008: 1073741840, 444596224: 1073758224, 461373440: 524304, 478150656: 0, 494927872: 16400, 511705088: 1074266128, 528482304: 540672 }, { 0: 260, 1048576: 0, 2097152: 67109120, 3145728: 65796, 4194304: 65540, 5242880: 67108868, 6291456: 67174660, 7340032: 67174400, 8388608: 67108864, 9437184: 67174656, 10485760: 65792, 11534336: 67174404, 12582912: 67109124, 13631488: 65536, 14680064: 4, 15728640: 256, 524288: 67174656, 1572864: 67174404, 2621440: 0, 3670016: 67109120, 4718592: 67108868, 5767168: 65536, 6815744: 65540, 7864320: 260, 8912896: 4, 9961472: 256, 11010048: 67174400, 12058624: 65796, 13107200: 65792, 14155776: 67109124, 15204352: 67174660, 16252928: 67108864, 16777216: 67174656, 17825792: 65540, 18874368: 65536, 19922944: 67109120, 20971520: 256, 22020096: 67174660, 23068672: 67108868, 24117248: 0, 25165824: 67109124, 26214400: 67108864, 27262976: 4, 28311552: 65792, 29360128: 67174400, 30408704: 260, 31457280: 65796, 32505856: 67174404, 17301504: 67108864, 18350080: 260, 19398656: 67174656, 20447232: 0, 21495808: 65540, 22544384: 67109120, 23592960: 256, 24641536: 67174404, 25690112: 65536, 26738688: 67174660, 27787264: 65796, 28835840: 67108868, 29884416: 67109124, 30932992: 67174400, 31981568: 4, 33030144: 65792 }, { 0: 2151682048, 65536: 2147487808, 131072: 4198464, 196608: 2151677952, 262144: 0, 327680: 4198400, 393216: 2147483712, 458752: 4194368, 524288: 2147483648, 589824: 4194304, 655360: 64, 720896: 2147487744, 786432: 2151678016, 851968: 4160, 917504: 4096, 983040: 2151682112, 32768: 2147487808, 98304: 64, 163840: 2151678016, 229376: 2147487744, 294912: 4198400, 360448: 2151682112, 425984: 0, 491520: 2151677952, 557056: 4096, 622592: 2151682048, 688128: 4194304, 753664: 4160, 819200: 2147483648, 884736: 4194368, 950272: 4198464, 1015808: 2147483712, 1048576: 4194368, 1114112: 4198400, 1179648: 2147483712, 1245184: 0, 1310720: 4160, 1376256: 2151678016, 1441792: 2151682048, 1507328: 2147487808, 1572864: 2151682112, 1638400: 2147483648, 1703936: 2151677952, 1769472: 4198464, 1835008: 2147487744, 1900544: 4194304, 1966080: 64, 2031616: 4096, 1081344: 2151677952, 1146880: 2151682112, 1212416: 0, 1277952: 4198400, 1343488: 4194368, 1409024: 2147483648, 1474560: 2147487808, 1540096: 64, 1605632: 2147483712, 1671168: 4096, 1736704: 2147487744, 1802240: 2151678016, 1867776: 4160, 1933312: 2151682048, 1998848: 4194304, 2064384: 4198464 }, { 0: 128, 4096: 17039360, 8192: 262144, 12288: 536870912, 16384: 537133184, 20480: 16777344, 24576: 553648256, 28672: 262272, 32768: 16777216, 36864: 537133056, 40960: 536871040, 45056: 553910400, 49152: 553910272, 53248: 0, 57344: 17039488, 61440: 553648128, 2048: 17039488, 6144: 553648256, 10240: 128, 14336: 17039360, 18432: 262144, 22528: 537133184, 26624: 553910272, 30720: 536870912, 34816: 537133056, 38912: 0, 43008: 553910400, 47104: 16777344, 51200: 536871040, 55296: 553648128, 59392: 16777216, 63488: 262272, 65536: 262144, 69632: 128, 73728: 536870912, 77824: 553648256, 81920: 16777344, 86016: 553910272, 90112: 537133184, 94208: 16777216, 98304: 553910400, 102400: 553648128, 106496: 17039360, 110592: 537133056, 114688: 262272, 118784: 536871040, 122880: 0, 126976: 17039488, 67584: 553648256, 71680: 16777216, 75776: 17039360, 79872: 537133184, 83968: 536870912, 88064: 17039488, 92160: 128, 96256: 553910272, 100352: 262272, 104448: 553910400, 108544: 0, 112640: 553648128, 116736: 16777344, 120832: 262144, 124928: 537133056, 129024: 536871040 }, { 0: 268435464, 256: 8192, 512: 270532608, 768: 270540808, 1024: 268443648, 1280: 2097152, 1536: 2097160, 1792: 268435456, 2048: 0, 2304: 268443656, 2560: 2105344, 2816: 8, 3072: 270532616, 3328: 2105352, 3584: 8200, 3840: 270540800, 128: 270532608, 384: 270540808, 640: 8, 896: 2097152, 1152: 2105352, 1408: 268435464, 1664: 268443648, 1920: 8200, 2176: 2097160, 2432: 8192, 2688: 268443656, 2944: 270532616, 3200: 0, 3456: 270540800, 3712: 2105344, 3968: 268435456, 4096: 268443648, 4352: 270532616, 4608: 270540808, 4864: 8200, 5120: 2097152, 5376: 268435456, 5632: 268435464, 5888: 2105344, 6144: 2105352, 6400: 0, 6656: 8, 6912: 270532608, 7168: 8192, 7424: 268443656, 7680: 270540800, 7936: 2097160, 4224: 8, 4480: 2105344, 4736: 2097152, 4992: 268435464, 5248: 268443648, 5504: 8200, 5760: 270540808, 6016: 270532608, 6272: 270540800, 6528: 270532616, 6784: 8192, 7040: 2105352, 7296: 2097160, 7552: 0, 7808: 268435456, 8064: 268443656 }, { 0: 1048576, 16: 33555457, 32: 1024, 48: 1049601, 64: 34604033, 80: 0, 96: 1, 112: 34603009, 128: 33555456, 144: 1048577, 160: 33554433, 176: 34604032, 192: 34603008, 208: 1025, 224: 1049600, 240: 33554432, 8: 34603009, 24: 0, 40: 33555457, 56: 34604032, 72: 1048576, 88: 33554433, 104: 33554432, 120: 1025, 136: 1049601, 152: 33555456, 168: 34603008, 184: 1048577, 200: 1024, 216: 34604033, 232: 1, 248: 1049600, 256: 33554432, 272: 1048576, 288: 33555457, 304: 34603009, 320: 1048577, 336: 33555456, 352: 34604032, 368: 1049601, 384: 1025, 400: 34604033, 416: 1049600, 432: 1, 448: 0, 464: 34603008, 480: 33554433, 496: 1024, 264: 1049600, 280: 33555457, 296: 34603009, 312: 1, 328: 33554432, 344: 1048576, 360: 1025, 376: 34604032, 392: 33554433, 408: 34603008, 424: 0, 440: 34604033, 456: 1049601, 472: 1024, 488: 33555456, 504: 1048577 }, { 0: 134219808, 1: 131072, 2: 134217728, 3: 32, 4: 131104, 5: 134350880, 6: 134350848, 7: 2048, 8: 134348800, 9: 134219776, 10: 133120, 11: 134348832, 12: 2080, 13: 0, 14: 134217760, 15: 133152, 2147483648: 2048, 2147483649: 134350880, 2147483650: 134219808, 2147483651: 134217728, 2147483652: 134348800, 2147483653: 133120, 2147483654: 133152, 2147483655: 32, 2147483656: 134217760, 2147483657: 2080, 2147483658: 131104, 2147483659: 134350848, 2147483660: 0, 2147483661: 134348832, 2147483662: 134219776, 2147483663: 131072, 16: 133152, 17: 134350848, 18: 32, 19: 2048, 20: 134219776, 21: 134217760, 22: 134348832, 23: 131072, 24: 0, 25: 131104, 26: 134348800, 27: 134219808, 28: 134350880, 29: 133120, 30: 2080, 31: 134217728, 2147483664: 131072, 2147483665: 2048, 2147483666: 134348832, 2147483667: 133152, 2147483668: 32, 2147483669: 134348800, 2147483670: 134217728, 2147483671: 134219808, 2147483672: 134350880, 2147483673: 134217760, 2147483674: 134219776, 2147483675: 0, 2147483676: 133120, 2147483677: 2080, 2147483678: 131104, 2147483679: 134350848 } ]; var SBOX_MASK = [ 4160749569, 528482304, 33030144, 2064384, 129024, 8064, 504, 2147483679 ]; /** * DES block cipher algorithm. */ var DES = C_algo.DES = BlockCipher.extend({ _doReset: function() { var key = this._key; var keyWords = key.words; var keyBits = []; for (var i = 0; i < 56; i++) { var keyBitPos = PC1[i] - 1; keyBits[i] = keyWords[keyBitPos >>> 5] >>> 31 - keyBitPos % 32 & 1; } var subKeys = this._subKeys = []; for (var nSubKey = 0; nSubKey < 16; nSubKey++) { var subKey = subKeys[nSubKey] = []; var bitShift = BIT_SHIFTS[nSubKey]; for (var i = 0; i < 24; i++) { subKey[i / 6 | 0] |= keyBits[(PC2[i] - 1 + bitShift) % 28] << 31 - i % 6; subKey[4 + (i / 6 | 0)] |= keyBits[28 + (PC2[i + 24] - 1 + bitShift) % 28] << 31 - i % 6; } subKey[0] = subKey[0] << 1 | subKey[0] >>> 31; for (var i = 1; i < 7; i++) { subKey[i] = subKey[i] >>> (i - 1) * 4 + 3; } subKey[7] = subKey[7] << 5 | subKey[7] >>> 27; } var invSubKeys = this._invSubKeys = []; for (var i = 0; i < 16; i++) { invSubKeys[i] = subKeys[15 - i]; } }, encryptBlock: function(M, offset) { this._doCryptBlock(M, offset, this._subKeys); }, decryptBlock: function(M, offset) { this._doCryptBlock(M, offset, this._invSubKeys); }, _doCryptBlock: function(M, offset, subKeys) { this._lBlock = M[offset]; this._rBlock = M[offset + 1]; exchangeLR.call(this, 4, 252645135); exchangeLR.call(this, 16, 65535); exchangeRL.call(this, 2, 858993459); exchangeRL.call(this, 8, 16711935); exchangeLR.call(this, 1, 1431655765); for (var round = 0; round < 16; round++) { var subKey = subKeys[round]; var lBlock = this._lBlock; var rBlock = this._rBlock; var f = 0; for (var i = 0; i < 8; i++) { f |= SBOX_P[i][((rBlock ^ subKey[i]) & SBOX_MASK[i]) >>> 0]; } this._lBlock = rBlock; this._rBlock = lBlock ^ f; } var t = this._lBlock; this._lBlock = this._rBlock; this._rBlock = t; exchangeLR.call(this, 1, 1431655765); exchangeRL.call(this, 8, 16711935); exchangeRL.call(this, 2, 858993459); exchangeLR.call(this, 16, 65535); exchangeLR.call(this, 4, 252645135); M[offset] = this._lBlock; M[offset + 1] = this._rBlock; }, keySize: 64 / 32, ivSize: 64 / 32, blockSize: 64 / 32 }); function exchangeLR(offset, mask) { var t = (this._lBlock >>> offset ^ this._rBlock) & mask; this._rBlock ^= t; this._lBlock ^= t << offset; } function exchangeRL(offset, mask) { var t = (this._rBlock >>> offset ^ this._lBlock) & mask; this._lBlock ^= t; this._rBlock ^= t << offset; } /** * Shortcut functions to the cipher's object interface. * * @example * * var ciphertext = CryptoJS.DES.encrypt(message, key, cfg); * var plaintext = CryptoJS.DES.decrypt(ciphertext, key, cfg); */ C.DES = BlockCipher._createHelper(DES); /** * Triple-DES block cipher algorithm. */ var TripleDES = C_algo.TripleDES = BlockCipher.extend({ _doReset: function() { var key = this._key; var keyWords = key.words; if (keyWords.length !== 2 && keyWords.length !== 4 && keyWords.length < 6) { throw new Error("Invalid key length - 3DES requires the key length to be 64, 128, 192 or >192."); } var key1 = keyWords.slice(0, 2); var key2 = keyWords.length < 4 ? keyWords.slice(0, 2) : keyWords.slice(2, 4); var key3 = keyWords.length < 6 ? keyWords.slice(0, 2) : keyWords.slice(4, 6); this._des1 = DES.createEncryptor(WordArray.create(key1)); this._des2 = DES.createEncryptor(WordArray.create(key2)); this._des3 = DES.createEncryptor(WordArray.create(key3)); }, encryptBlock: function(M, offset) { this._des1.encryptBlock(M, offset); this._des2.decryptBlock(M, offset); this._des3.encryptBlock(M, offset); }, decryptBlock: function(M, offset) { this._des3.decryptBlock(M, offset); this._des2.encryptBlock(M, offset); this._des1.decryptBlock(M, offset); }, keySize: 192 / 32, ivSize: 64 / 32, blockSize: 64 / 32 }); /** * Shortcut functions to the cipher's object interface. * * @example * * var ciphertext = CryptoJS.TripleDES.encrypt(message, key, cfg); * var plaintext = CryptoJS.TripleDES.decrypt(ciphertext, key, cfg); */ C.TripleDES = BlockCipher._createHelper(TripleDES); })(); (function() { var C = CryptoJS; var C_lib = C.lib; var StreamCipher = C_lib.StreamCipher; var C_algo = C.algo; /** * RC4 stream cipher algorithm. */ var RC4 = C_algo.RC4 = StreamCipher.extend({ _doReset: function() { var key = this._key; var keyWords = key.words; var keySigBytes = key.sigBytes; var S = this._S = []; for (var i = 0; i < 256; i++) { S[i] = i; } for (var i = 0, j = 0; i < 256; i++) { var keyByteIndex = i % keySigBytes; var keyByte = keyWords[keyByteIndex >>> 2] >>> 24 - keyByteIndex % 4 * 8 & 255; j = (j + S[i] + keyByte) % 256; var t = S[i]; S[i] = S[j]; S[j] = t; } this._i = this._j = 0; }, _doProcessBlock: function(M, offset) { M[offset] ^= generateKeystreamWord.call(this); }, keySize: 256 / 32, ivSize: 0 }); function generateKeystreamWord() { var S = this._S; var i = this._i; var j = this._j; var keystreamWord = 0; for (var n = 0; n < 4; n++) { i = (i + 1) % 256; j = (j + S[i]) % 256; var t = S[i]; S[i] = S[j]; S[j] = t; keystreamWord |= S[(S[i] + S[j]) % 256] << 24 - n * 8; } this._i = i; this._j = j; return keystreamWord; } /** * Shortcut functions to the cipher's object interface. * * @example * * var ciphertext = CryptoJS.RC4.encrypt(message, key, cfg); * var plaintext = CryptoJS.RC4.decrypt(ciphertext, key, cfg); */ C.RC4 = StreamCipher._createHelper(RC4); /** * Modified RC4 stream cipher algorithm. */ var RC4Drop = C_algo.RC4Drop = RC4.extend({ cfg: RC4.cfg.extend({ drop: 192 }), _doReset: function() { RC4._doReset.call(this); for (var i = this.cfg.drop; i > 0; i--) { generateKeystreamWord.call(this); } } }); /** * Shortcut functions to the cipher's object interface. * * @example * * var ciphertext = CryptoJS.RC4Drop.encrypt(message, key, cfg); * var plaintext = CryptoJS.RC4Drop.decrypt(ciphertext, key, cfg); */ C.RC4Drop = StreamCipher._createHelper(RC4Drop); })(); (function() { var C = CryptoJS; var C_lib = C.lib; var StreamCipher = C_lib.StreamCipher; var C_algo = C.algo; var S = []; var C_ = []; var G = []; /** * Rabbit stream cipher algorithm */ var Rabbit = C_algo.Rabbit = StreamCipher.extend({ _doReset: function() { var K = this._key.words; var iv = this.cfg.iv; for (var i = 0; i < 4; i++) { K[i] = (K[i] << 8 | K[i] >>> 24) & 16711935 | (K[i] << 24 | K[i] >>> 8) & 4278255360; } var X = this._X = [ K[0], K[3] << 16 | K[2] >>> 16, K[1], K[0] << 16 | K[3] >>> 16, K[2], K[1] << 16 | K[0] >>> 16, K[3], K[2] << 16 | K[1] >>> 16 ]; var C = this._C = [ K[2] << 16 | K[2] >>> 16, K[0] & 4294901760 | K[1] & 65535, K[3] << 16 | K[3] >>> 16, K[1] & 4294901760 | K[2] & 65535, K[0] << 16 | K[0] >>> 16, K[2] & 4294901760 | K[3] & 65535, K[1] << 16 | K[1] >>> 16, K[3] & 4294901760 | K[0] & 65535 ]; this._b = 0; for (var i = 0; i < 4; i++) { nextState.call(this); } for (var i = 0; i < 8; i++) { C[i] ^= X[i + 4 & 7]; } if (iv) { var IV = iv.words; var IV_0 = IV[0]; var IV_1 = IV[1]; var i0 = (IV_0 << 8 | IV_0 >>> 24) & 16711935 | (IV_0 << 24 | IV_0 >>> 8) & 4278255360; var i2 = (IV_1 << 8 | IV_1 >>> 24) & 16711935 | (IV_1 << 24 | IV_1 >>> 8) & 4278255360; var i1 = i0 >>> 16 | i2 & 4294901760; var i3 = i2 << 16 | i0 & 65535; C[0] ^= i0; C[1] ^= i1; C[2] ^= i2; C[3] ^= i3; C[4] ^= i0; C[5] ^= i1; C[6] ^= i2; C[7] ^= i3; for (var i = 0; i < 4; i++) { nextState.call(this); } } }, _doProcessBlock: function(M, offset) { var X = this._X; nextState.call(this); S[0] = X[0] ^ X[5] >>> 16 ^ X[3] << 16; S[1] = X[2] ^ X[7] >>> 16 ^ X[5] << 16; S[2] = X[4] ^ X[1] >>> 16 ^ X[7] << 16; S[3] = X[6] ^ X[3] >>> 16 ^ X[1] << 16; for (var i = 0; i < 4; i++) { S[i] = (S[i] << 8 | S[i] >>> 24) & 16711935 | (S[i] << 24 | S[i] >>> 8) & 4278255360; M[offset + i] ^= S[i]; } }, blockSize: 128 / 32, ivSize: 64 / 32 }); function nextState() { var X = this._X; var C = this._C; for (var i = 0; i < 8; i++) { C_[i] = C[i]; } C[0] = C[0] + 1295307597 + this._b | 0; C[1] = C[1] + 3545052371 + (C[0] >>> 0 < C_[0] >>> 0 ? 1 : 0) | 0; C[2] = C[2] + 886263092 + (C[1] >>> 0 < C_[1] >>> 0 ? 1 : 0) | 0; C[3] = C[3] + 1295307597 + (C[2] >>> 0 < C_[2] >>> 0 ? 1 : 0) | 0; C[4] = C[4] + 3545052371 + (C[3] >>> 0 < C_[3] >>> 0 ? 1 : 0) | 0; C[5] = C[5] + 886263092 + (C[4] >>> 0 < C_[4] >>> 0 ? 1 : 0) | 0; C[6] = C[6] + 1295307597 + (C[5] >>> 0 < C_[5] >>> 0 ? 1 : 0) | 0; C[7] = C[7] + 3545052371 + (C[6] >>> 0 < C_[6] >>> 0 ? 1 : 0) | 0; this._b = C[7] >>> 0 < C_[7] >>> 0 ? 1 : 0; for (var i = 0; i < 8; i++) { var gx = X[i] + C[i]; var ga = gx & 65535; var gb = gx >>> 16; var gh = ((ga * ga >>> 17) + ga * gb >>> 15) + gb * gb; var gl = ((gx & 4294901760) * gx | 0) + ((gx & 65535) * gx | 0); G[i] = gh ^ gl; } X[0] = G[0] + (G[7] << 16 | G[7] >>> 16) + (G[6] << 16 | G[6] >>> 16) | 0; X[1] = G[1] + (G[0] << 8 | G[0] >>> 24) + G[7] | 0; X[2] = G[2] + (G[1] << 16 | G[1] >>> 16) + (G[0] << 16 | G[0] >>> 16) | 0; X[3] = G[3] + (G[2] << 8 | G[2] >>> 24) + G[1] | 0; X[4] = G[4] + (G[3] << 16 | G[3] >>> 16) + (G[2] << 16 | G[2] >>> 16) | 0; X[5] = G[5] + (G[4] << 8 | G[4] >>> 24) + G[3] | 0; X[6] = G[6] + (G[5] << 16 | G[5] >>> 16) + (G[4] << 16 | G[4] >>> 16) | 0; X[7] = G[7] + (G[6] << 8 | G[6] >>> 24) + G[5] | 0; } /** * Shortcut functions to the cipher's object interface. * * @example * * var ciphertext = CryptoJS.Rabbit.encrypt(message, key, cfg); * var plaintext = CryptoJS.Rabbit.decrypt(ciphertext, key, cfg); */ C.Rabbit = StreamCipher._createHelper(Rabbit); })(); (function() { var C = CryptoJS; var C_lib = C.lib; var StreamCipher = C_lib.StreamCipher; var C_algo = C.algo; var S = []; var C_ = []; var G = []; /** * Rabbit stream cipher algorithm. * * This is a legacy version that neglected to convert the key to little-endian. * This error doesn't affect the cipher's security, * but it does affect its compatibility with other implementations. */ var RabbitLegacy = C_algo.RabbitLegacy = StreamCipher.extend({ _doReset: function() { var K = this._key.words; var iv = this.cfg.iv; var X = this._X = [ K[0], K[3] << 16 | K[2] >>> 16, K[1], K[0] << 16 | K[3] >>> 16, K[2], K[1] << 16 | K[0] >>> 16, K[3], K[2] << 16 | K[1] >>> 16 ]; var C = this._C = [ K[2] << 16 | K[2] >>> 16, K[0] & 4294901760 | K[1] & 65535, K[3] << 16 | K[3] >>> 16, K[1] & 4294901760 | K[2] & 65535, K[0] << 16 | K[0] >>> 16, K[2] & 4294901760 | K[3] & 65535, K[1] << 16 | K[1] >>> 16, K[3] & 4294901760 | K[0] & 65535 ]; this._b = 0; for (var i = 0; i < 4; i++) { nextState.call(this); } for (var i = 0; i < 8; i++) { C[i] ^= X[i + 4 & 7]; } if (iv) { var IV = iv.words; var IV_0 = IV[0]; var IV_1 = IV[1]; var i0 = (IV_0 << 8 | IV_0 >>> 24) & 16711935 | (IV_0 << 24 | IV_0 >>> 8) & 4278255360; var i2 = (IV_1 << 8 | IV_1 >>> 24) & 16711935 | (IV_1 << 24 | IV_1 >>> 8) & 4278255360; var i1 = i0 >>> 16 | i2 & 4294901760; var i3 = i2 << 16 | i0 & 65535; C[0] ^= i0; C[1] ^= i1; C[2] ^= i2; C[3] ^= i3; C[4] ^= i0; C[5] ^= i1; C[6] ^= i2; C[7] ^= i3; for (var i = 0; i < 4; i++) { nextState.call(this); } } }, _doProcessBlock: function(M, offset) { var X = this._X; nextState.call(this); S[0] = X[0] ^ X[5] >>> 16 ^ X[3] << 16; S[1] = X[2] ^ X[7] >>> 16 ^ X[5] << 16; S[2] = X[4] ^ X[1] >>> 16 ^ X[7] << 16; S[3] = X[6] ^ X[3] >>> 16 ^ X[1] << 16; for (var i = 0; i < 4; i++) { S[i] = (S[i] << 8 | S[i] >>> 24) & 16711935 | (S[i] << 24 | S[i] >>> 8) & 4278255360; M[offset + i] ^= S[i]; } }, blockSize: 128 / 32, ivSize: 64 / 32 }); function nextState() { var X = this._X; var C = this._C; for (var i = 0; i < 8; i++) { C_[i] = C[i]; } C[0] = C[0] + 1295307597 + this._b | 0; C[1] = C[1] + 3545052371 + (C[0] >>> 0 < C_[0] >>> 0 ? 1 : 0) | 0; C[2] = C[2] + 886263092 + (C[1] >>> 0 < C_[1] >>> 0 ? 1 : 0) | 0; C[3] = C[3] + 1295307597 + (C[2] >>> 0 < C_[2] >>> 0 ? 1 : 0) | 0; C[4] = C[4] + 3545052371 + (C[3] >>> 0 < C_[3] >>> 0 ? 1 : 0) | 0; C[5] = C[5] + 886263092 + (C[4] >>> 0 < C_[4] >>> 0 ? 1 : 0) | 0; C[6] = C[6] + 1295307597 + (C[5] >>> 0 < C_[5] >>> 0 ? 1 : 0) | 0; C[7] = C[7] + 3545052371 + (C[6] >>> 0 < C_[6] >>> 0 ? 1 : 0) | 0; this._b = C[7] >>> 0 < C_[7] >>> 0 ? 1 : 0; for (var i = 0; i < 8; i++) { var gx = X[i] + C[i]; var ga = gx & 65535; var gb = gx >>> 16; var gh = ((ga * ga >>> 17) + ga * gb >>> 15) + gb * gb; var gl = ((gx & 4294901760) * gx | 0) + ((gx & 65535) * gx | 0); G[i] = gh ^ gl; } X[0] = G[0] + (G[7] << 16 | G[7] >>> 16) + (G[6] << 16 | G[6] >>> 16) | 0; X[1] = G[1] + (G[0] << 8 | G[0] >>> 24) + G[7] | 0; X[2] = G[2] + (G[1] << 16 | G[1] >>> 16) + (G[0] << 16 | G[0] >>> 16) | 0; X[3] = G[3] + (G[2] << 8 | G[2] >>> 24) + G[1] | 0; X[4] = G[4] + (G[3] << 16 | G[3] >>> 16) + (G[2] << 16 | G[2] >>> 16) | 0; X[5] = G[5] + (G[4] << 8 | G[4] >>> 24) + G[3] | 0; X[6] = G[6] + (G[5] << 16 | G[5] >>> 16) + (G[4] << 16 | G[4] >>> 16) | 0; X[7] = G[7] + (G[6] << 8 | G[6] >>> 24) + G[5] | 0; } /** * Shortcut functions to the cipher's object interface. * * @example * * var ciphertext = CryptoJS.RabbitLegacy.encrypt(message, key, cfg); * var plaintext = CryptoJS.RabbitLegacy.decrypt(ciphertext, key, cfg); */ C.RabbitLegacy = StreamCipher._createHelper(RabbitLegacy); })(); return CryptoJS; }); })); //#endregion //#region ../utils/random-http-ua.js var require_random_http_ua = /* @__PURE__ */ __commonJSMin(((exports, module) => { function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === "function") { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function(key) { _defineProperty(target, key, source[key]); }); } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } /** * 随机生成http的user-agent * NPM NAME : random-http-ua * vervison : v1.0.1 * Github : https://github.com/seasidesun/random-http-ua * Author : seasidesun * Email : seasidetank@gmail.com */ (function() { /** * 根据所给概率返回此次随机是否落在概率区间 * @param {Number} rate 概率 0-10 * @return {Boolean} 是否概率落在区间 */ var rMP = function rMP(rate) { var seed = parseInt(Math.random().toString().slice(2, 4)); return seed < rate; }; /** * 根据所给概率返回此次随机是否有值 * @param {String} data 概率^有效值 * @return {String} 有效值 */ var rMPR = function rMPR(data) { data = data.split("^"); if (!data[1]) return data[0]; return rMP(data[0]) ? data[1] : ""; }; /** * 随机输出数组内的元素 * @param {Array || String} list 供随机的数据 * @return {String} 随机出的数据 */ var rML = function rML(list) { if (!Array.isArray(list)) list = [list]; var listNoRate = []; var listWithRate = []; list.forEach(function(data) { if (data.indexOf("^") !== -1) listWithRate.push(data); else listNoRate.push(data); }); if (listWithRate.length) { var rateResult = null; for (var n = 0; n < listWithRate.length; n++) { var curRandomValue = rMPR(listWithRate[n]); if (curRandomValue) { rateResult = curRandomValue; break; } } if (rateResult) return rateResult; } if (!listNoRate.length) listNoRate = listWithRate; var seed = parseInt(Math.random().toString().slice(-3).split("").reverse().join("")); var index = seed % listNoRate.length; return listNoRate[index].replace(/^[0-9]{1,3}\^/, ""); }; /** * 随机26字母 * @param {Number} num 字母的长度 * @return {String} 随机出的字母 */ var rMW = function rMW() { var num = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; var ret = ""; for (var n = 0; n < num; n++) { ret += rML([ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" ]); } return ret; }; /** * 随机输出区间内的一个数字 * @param {Number || String} from 最小值 * @param {Number || String} to 最大值 * @return {String} 随机出的数字 */ var rMR = function rMR(from, to) { from = parseInt(from); to = parseInt(to); if (isNaN(from)) return ""; if (isNaN(to)) to = 0; if (from === to) return from; var base = Math.min(from, to); var range = Math.abs(from - to) + 1; var randomRange = range.toString().length + 1; var seed = parseInt(Math.random().toString().slice(-randomRange).split("").reverse().join("")); var jump = seed % range; return base + jump; }; /** * 将数组里的元素拼成一个字符串,['', ';']过滤掉 * @param {Array || String} list * @return {String} ua的一部分 */ var cL = function cL(list) { if (!Array.isArray(list)) list = [list]; return list.filter(function(item) { return ["", ";"].indexOf(item) === -1; }).join(" "); }; /** * 供随机的数据 * device: 设备类型 mobile || pc * * pcOs: pc端操作系统 * mobileOs: 移动端操作系统 * * windowsVer: windows系统版本 * windowsBit: windows系统Bit位 * windowsApp: windows系统下的浏览器应用 eg.ie、chrome * * macosVer: macos系统版本 * macosApp: macos系统下的浏览器应用 eg.safari、chrome * * iosVer: ios版本 * iosApp: ios浏览器应用 * * androidVer: 安卓版本 * androidBrand: 安卓机型 eg.samsung、huawei、mi * androidApp: 安卓浏览器应用 eg.uc、wechat * * UA中的部分字符串随机: * engineVer: ua中浏览引擎版本 * versionVer: ua中浏览引擎版本加号版本 * chromeVer: ua中chrome版本 * safariVer: ua中safari版本 * mobileVer: ua中Mobile版本 * networwVer: ua中网络类型 * netVer: ua中'.net'版本,重要是ie中使用到 * ieVer: ie版本 * tridentVer: trident版本,主要ie中使用到 * qbVer: qq浏览器版本 * qbcoreVer: qq浏览器core版本 * edgeVer: egde浏览器版本 * firefoxVer: firefox浏览器版本 * * 只有customMap中的字段支持自定义 */ var customDefault = { "device": ["mobile", "pc"], "pcOs": ["windows", "macos"], "mobileOs": ["android", "ios"], "windowsApp": [ "ie", "edge", "qb", "chrome", "firfox", "360" ], "macosApp": [ "safari", "chrome", "firfox" ], "iosApp": [ "safari", "qb", "wechat" ], "androidBrand": [ "huawei", "mi", "vivo", "oppo", "samsung" ], "androidApp": [ "wechat", "uc", "baidu", "qb", "native" ] }; var rD = { "device": function device() { return rML(customDefault["device"]); }, "pcOs": function pcOs() { return rML(customDefault["pcOs"]); }, "mobileOs": function mobileOs() { return rML(customDefault["mobileOs"]); }, "windowsVer": function windowsVer() { return rML([ "5.1", "6.1", "10.0" ]); }, "windowsBit": function windowsBit() { return rML(["WOW64", "Win64; x64"]); }, "windowsApp": function windowsApp() { return rML(customDefault["windowsApp"]); }, "macosVer": function macosVer() { return rML([ "10_13_1", "10_13_2", "10_13_3", "10_13_4", "10_13_5", "10_13_6", "10_14_1", "10_14_2", "10_14_3" ]); }, "macosApp": function macosApp() { return rML(customDefault["macosApp"]); }, "iosVer": function iosVer() { return rML([ `10_${rMR(1, 2)}`, `11_${rMR(1, 4)}_${rMR(1, 4)}`, `12_${rMR(1, 2)}_${rMR(1, 4)}` ]); }, "iosApp": function iosApp() { return rML(customDefault["iosApp"]); }, "androidVer": function androidVer() { return `${rMR(7, 9)}.${rMR(0, 5)}${rMPR(`80^.${rMR(0, 5)}`)}`; }, "androidBrand": function androidBrand() { return rML(customDefault["androidBrand"]); }, "androidApp": function androidApp() { return rML(customDefault["androidApp"]); }, "engineVer": function engineVer() { return `${rMR(412, 605)}.${rMR(1, 10)}${rMPR(`80^.${rMR(1, 60)}`)}`; }, "versionVer": function versionVer() { return `${rMR(4, 12)}.${rMR(0, 5)}`; }, "chromeVer": function chromeVer() { return `${rMR(50, 73)}.0.${rMR(2500, 3500)}.${rMR(1, 100)}`; }, "safariVer": function safariVer() { return `${rMR(537, 605)}.${rMR(1, 36)}${rMPR(`80^.${rMR(1, 20)}`)}`; }, "mobileVer": function mobileVer() { return `${rMR(11, 14)}${rMW()}${rMR(1, 60)}${rMR(1, 60)}${rMPR(`80^${rMW()}`)}`; }, "networwVer": function networwVer() { return rML([ "5^3G", "4G", "WIFI" ]); }, "netVer": function netVer() { return `${rMR(2, 4)}.${rMR(0, 5)}${rMPR(`80^.${rMR(30729, 50727)}`)}`; }, "ieVer": function ieVer() { return rML([ "8.0", "9.0", "10.0" ]); }, "tridentVer": function tridentVer() { return rML([ "4.0", "5.0", "6.0" ]); }, "qbVer": function qbVer() { return `${rMR(8, 10)}.${rMR(0, 5)}.${rMR(2500, 3200)}.${rML([ "100", "200", "300", "400" ])}`; }, "qbcoreVer": function qbcoreVer() { return `${rMR(1, 3)}.${rMR(50, 75)}.${rMR(500, 3500)}.${rML([ "100", "200", "300", "400" ])}`; }, "edgeVer": function edgeVer() { return `${rMR(11, 17)}.${rMR(11e3, 17e3)}`; }, "firefoxVer": function firefoxVer() { return `${rMR(55, 65)}.${rMR(0, 10)}`; } }; var osHandlerOfpc = { "windows": function windows() { return `Windows NT ${rD.windowsVer()}; ${rD.windowsBit()}`; }, "windows-ie": function windowsIe() { return cL([ `compatible; MSIE ${rD.ieVer()};`, `Windows NT ${rD.windowsVer()};`, `${rMPR(`50^${rD.windowsBit()}`)};`, `Trident/${rD.tridentVer()};`, `${rMPR(`50^SLCC2`)};`, `${rMPR(`50^${`.NET CLR ${rD.netVer()}`}`)};`, `${rMPR(`50^Tablet PC 2.0`)};` ]); }, "macos": function macos() { return `Macintosh; Intel Mac OS X ${rD.macosVer()}`; }, "macos-firefox": function macosFirefox() { return `Macintosh; Intel Mac OS X ${rD.macosVer()} rv:${rMR(60, 65)}.0`; }, "ios": function ios() { return `iPhone; CPU iPhone OS ${rD.iosVer()} like Mac OS X`; }, "android": function android() { return `Linux; Android ${rD.androidVer()}; wv`; }, "android-huawei": function androidHuawei() { var tag = `${rML([`95^${rMW(3)}`, "EDISON"])}-${rML(["AL", "UL"])}${rMR(0, 2)}${rMR(0, 2)}`; return `Linux; Android ${rD.androidVer()}; ${tag} Build/HUAWEI${tag}; wv`; }, "android-mi": function androidMi() { var miVerList = [ "4LTE", "5", "5X", "5C", "5s", "5s Plus", "6", "6X", "8", "8 UD", "8 SE", "8 Lite", "9", "MAX", "MAX 2", "MAX 3", "PAD", "PAD 4", "NOTE", "NOTE LTE" ]; var miVer = rML([`MI ${rML(miVerList)}`, `MIX ${rML([ "2", "2s", "3" ])}`]); var suf1 = `Build/${rML([ "OPM1", "PKQ1", "OPR1" ])}.${rMR(17e4, 180729)}.${rMR(17e4, 180729)}`; var suf2 = `Build/${rMW(3)}${rMR(10, 30)}${rMW(1)}`; var suf = rML([`${suf1}`, `${suf2}`]); return `Linux; Android ${rD.androidVer()}; ${miVer} ${suf}; wv`; }, "android-oppo": function androidOppo() { var oppoVerList = [ "r9 plustm a", "A57t", "R9m", "R9t", "A79t", "R11t", "A57", "A37m", "R11", "A59s", "R9sk", "A73t", "A83", "R9 Plustm A", "R9s", "R9tm", "R11s", "A77", "A79k", "R11st", "A77t", "A33", "A53", "A59m", "R11 Plus", "R9s Plus", "A83t", "R9", "A59t", "R9skt", "A37t", "A53m", "A73", "R7sm", "R7s", "R9st", "r7s", "r9", "a37m", "r9m", "R11 Plusk", "r9 plusm a" ]; var tag = `OPPO ${rML(oppoVerList)} Build/${rMW(3)}${rMR(10, 30)}${rMW(1)}`; return `Linux; Android ${rD.androidVer()}; ${tag}; wv`; }, "android-vivo": function androidVivo() { var vivoVerList = [ "X21i A", "X9Plus", "Y66L", "Y66", "X20", "V3Max A", "X7", "NEX A", "Y31", "X9i", "Y85A", "Y75A", "X9s", "Xplay6", "Y83A", "X7Plus", "X9s Plus", "X9s L", "X9", "X9L", "X6Plus D", "Y71", "X21UD A", "Y51A", "X6Plus L", "Y71A", "X20A", "Y66i A", "X6A", "X21", "X9Plus L", "Y53L", "V3M A", "X6D", "X21A", "V3", "Y66i", "X6S A", "Z1", "X3V", "Y67L", "X20Plus A", "Xplay5A", "Z1i", "NEX S" ]; var tag = `vivo ${rML(vivoVerList)} Build/${rML([ "OPM1", "PKQ1", "OPR1" ])}.${rMR(17e3, 180128)}.0${rMR(1, 99)}`; return `Linux; Android ${rD.androidVer()}; ${tag}; wv`; }, "android-samsung": function androidSamsung() { var samsungVerList = [ "G9550", "C7000", "G9500", "C5000", "G9600", "N9500", "G9200", "G9508", "G6100", "G9287", "N9600", "C7010", "G9350", "G9280", "N9006", "G9300", "J3109", "C9000", "G935F", "N950N", "G9650", "A500FU", "C5010", "J5008", "A5000", "G955F", "A9100", "E7009", "G8508S", "W2018", "J3110", "G955U", "G5700", "A7100", "A7000", "G9608", "G8850", "G8750", "A600N", "A8000", "J7008", "G950U", "N9508", "G5108Q", "N9108V", "G9008V", "N920I", "G610F", "A6050", "W2016", "C9008", "G9750", "G3606", "A5108", "J5108", "P585Y", "G928V", "T331C", "N9005", "N960F", "G7105", "N9200", "G1600", "J250F", "N9008V", "G8870" ]; var tag = `SM-${rML(samsungVerList)} Build/${rMW(`${rMR(1, 3)}`)}${rMR(0, 99)}${rMW(1)}`; return `Linux; Android ${rD.androidVer()}; ${tag}; wv`; } }; var appSufHandlerOfpc = { "windows": function windows() { return ``; }, "windows-qb": function windowsQb() { return `QBCore/${rD.qbVer()} QQBrowser/${rD.qbcoreVer()}`; }, "windows-edge": function windowsEdge() { return `edge/${rD.edgeVer()}`; }, "windows-360": function windows360() { return `QIHU 360SE`; }, "windows-firefox": function windowsFirefox() { return `Gecko/20${rMR(13, 17)}${rMR(1, 12)}${rMR(1, 30)} Firefox/${rD.firefoxVer()}`; }, "macos": function macos() { return ``; }, "macos-firefox": function macosFirefox() { return `Gecko/20${rMR(13, 17)}${rMR(1, 12)}${rMR(1, 30)} Firefox/${rD.firefoxVer()}`; }, "ios": function ios() { return `Safari/${rD.safariVer()}`; }, "ios-qb": function iosQb() { return `MQQBrowser/${rMR(8, 10)}.${rMR(0, 5)}.${rMR(1, 5)} Safari/${rD.safariVer()} MttCustomUA/${rMR(1, 3)} QBWebViewType/${rMR(2, 5)} WKType/`; }, "ios-wechat": function iosWechat() { return `MicroMessenger/${rMR(5, 7)}.${rMR(0, 3)}.${rMR(1, 5)}(0x${rMR(15e6, 23e6)}) NetType/${rD.networwVer()} Language/zh_CN`; }, "android-native": function androidNative() { return `Mobile Safari/${rD.safariVer()}`; }, "android-wechat": function androidWechat() { return `Mobile Safari/${rD.safariVer()} MicroMessenger/${rMR(5, 7)}.${rMR(0, 3)}.${rMR(1, 5)}(0x${rMR(15e6, 23e6)}) NetType/${rD.networwVer()} Language/zh_CN`; }, "android-baidu": function androidBaidu() { return `Mobile Safari/${rD.safariVer()}${rML(["2^ ", ` T7/${rMR(6, 9)}.${rMR(1, 9)} `])}baidubrowser/${rMR(1, 9)}.${rMR(10, 19)}.${rMR(10, 19)}.0 (Baidu; P1 ${rMR(1, 9)}.${rMR(0, 9)}.${rMR(0, 9)})`; }, "android-uc": function androidUc() { return `UCBrowser/${rMR(10, 12)}.${rMR(0, 5)}.${rMR(0, 9)}.${rMR(100, 983)} Mobile Safari/${rD.safariVer()}`; }, "android-qb": function androidQb() { return `MQQBrowser/${rMR(6, 8)}.${rMR(1, 9)} TBS/0${rMR(41e3, 45e3)} Mobile Safari/${rD.safariVer()}`; } }; var genOneUaOfpc = function genOneUaOfpc(opts) { var foundation = "Mozilla/5.0"; var tag = `${opts.os}-${opts.app}`; var osHandler = osHandlerOfpc[`${tag}`] || osHandlerOfpc[`${opts.os}`]; var osInfo = osHandler(); var engine = `AppleWebKit/${rD.engineVer()} (KHTML\, like Gecko)`; var version = `Version/${rD.versionVer()}`; var chrome = `Chrome/${rD.chromeVer()}`; var safari = `Safari/${rD.safariVer()}`; var prefix = rML([`50^${version}`, `${chrome}`]); var suffix = cL([`${prefix}`, `${safari}`]); var ua = ""; switch (tag) { case "windows-ie": ua = `${foundation} (${osInfo})`; break; case "windows-": ua = `${foundation} (${osInfo}) ${engine} ${suffix}`; break; case "macos-": ua = `${foundation} (${osInfo}) ${engine} ${suffix}`; break; default: var appSuf = appSufHandlerOfpc[`${tag}`] || appSufHandlerOfpc[`${opts.os}`]; ua = cL([ `${foundation}`, `(${osInfo})`, `${engine}`, `${suffix}`, `${appSuf()}` ]); break; } return ua; }; /** * 生成一个mobile user-agent * @param {Object} opts * @return {String} ua */ var genOneUaOfmobile = function genOneUaOfmobile(opts) { var foundation = "Mozilla/5.0"; var osInfo = ""; if (opts.os === "ios") { var _tag = `${opts.os}-${opts.app}`; var osHandler = osHandlerOfpc[`${_tag}`] || osHandlerOfpc[`${opts.os}`]; osInfo = osHandler(); } else { var deviceTag = `${opts.os}-${opts.brand}`; var _osHandler = osHandlerOfpc[`${deviceTag}`] || osHandlerOfpc[`${opts.os}`]; osInfo = _osHandler(); } var engine = `AppleWebKit/${rD.engineVer()} (KHTML\, like Gecko)`; var prefix = ""; var version = `Version/${rD.versionVer()}`; if (opts.os === "ios") { var mobile = `Mobile/${rD.mobileVer()}`; prefix = rML([`50^${version}`, `${mobile}`]); } else { var chrome = `Chrome/${rD.chromeVer()}`; prefix = rML([`50^${version}`, `${chrome}`]); } var ua = ""; var tag = `${opts.os}-${opts.app}`; var appSuf = appSufHandlerOfpc[`${tag}`] || appSufHandlerOfpc[`${opts.os}`]; switch (tag) { case "ios-": ua = `${foundation} (${osInfo}) ${engine} ${prefix} ${appSuf()}`; break; default: ua = `${foundation} (${osInfo}) ${engine} ${prefix} ${appSuf()}`; break; } return ua; }; /** * 生成一个ua * @param {Object} opts 浏览器系统环境 * @return {String} ua */ var genOneUa = function genOneUa(opts) { switch (opts.device) { case "pc": return genOneUaOfpc(opts); case "mobile": return genOneUaOfmobile(opts); default: break; } }; /** * 随机生成一个浏览器的系统环境 * @return {Object} 浏览器系统环境 * device: pc | mobile * os: windows | macos | andriod | ios * app: safari | wechat | chrome | qb * brand: huawei | mi | oppo | vivo | samsung */ var genUaType = function genUaType() { var device = rD.device(); var os = rD[`${device}Os`](); var app = rD[`${os}App`](); var brand = `${device}${os}` === "mobileandroid" ? rD.androidBrand() : ""; return { device, os, app, brand }; }; /** * 随机生成浏览器的ua * @param {String | Number} ua的数量 * @param {Object} ua的类型 * @return {String | Array} 浏览器ua * customMap 为可自定义的ua参数 */ var customMap = [ "device", "pcOs", "mobileOs", "windowsApp", "macosApp", "iosApp", "androidBrand", "androidApp" ]; var generateUa = function generateUa() { var num = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; var opt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; num = parseInt(num); if (isNaN(num) || num < 1) num = 1; var config = _objectSpread({}, customDefault, opt); customMap.forEach(function(key) { rD[key] = function() { return rML(config[key]); }; }); var ret = []; for (var n = 0; n < num; n++) { ret.push(genOneUa(genUaType())); } return ret[1] ? ret : ret[0]; }; var randomUa = { generateUa }; if (typeof exports === "object") { module.exports = randomUa; } else if (typeof define === "function") { define(function() { return randomUa; }); } else { globalThis.randomUa = randomUa; } })(); })); //#endregion //#region ../libs_drpy/jinja.js var require_jinja = /* @__PURE__ */ __commonJSMin(((exports, module) => { /*! * Jinja Templating for JavaScript v0.1.8 * https://github.com/sstur/jinja-js * * This is a slimmed-down Jinja2 implementation [http://jinja.pocoo.org/] * * In the interest of simplicity, it deviates from Jinja2 as follows: * - Line statements, cycle, super, macro tags and block nesting are not implemented * - auto escapes html by default (the filter is "html" not "e") * - Only "html" and "safe" filters are built in * - Filters are not valid in expressions; `foo|length > 1` is not valid * - Expression Tests (`if num is odd`) not implemented (`is` translates to `==` and `isnot` to `!=`) * * Notes: * - if property is not found, but method '_get' exists, it will be called with the property name (and cached) * - `{% for n in obj %}` iterates the object's keys; get the value with `{% for n in obj %}{{ obj[n] }}{% endfor %}` * - subscript notation `a[0]` takes literals or simple variables but not `a[item.key]` * - `.2` is not a valid number literal; use `0.2` * */ (function(global, factory) { typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.jinja = {})); })(exports, (function(jinja) { "use strict"; var STRINGS = /'(\\.|[^'])*'|"(\\.|[^"'"])*"/g; var IDENTS_AND_NUMS = /([$_a-z][$\w]*)|([+-]?\d+(\.\d+)?)/g; var NUMBER = /^[+-]?\d+(\.\d+)?$/; var NON_PRIMITIVES = /\[[@#~](,[@#~])*\]|\[\]|\{([@i]:[@#~])(,[@i]:[@#~])*\}|\{\}/g; var IDENTIFIERS = /[$_a-z][$\w]*/gi; var VARIABLES = /i(\.i|\[[@#i]\])*/g; var ACCESSOR = /(\.i|\[[@#i]\])/g; var OPERATORS = /(===?|!==?|>=?|<=?|&&|\|\||[+\-\*\/%])/g; var EOPS = /(^|[^$\w])(and|or|not|is|isnot)([^$\w]|$)/g; var LEADING_SPACE = /^\s+/; var TRAILING_SPACE = /\s+$/; var START_TOKEN = /\{\{\{|\{\{|\{%|\{#/; var TAGS = { "{{{": /^('(\\.|[^'])*'|"(\\.|[^"'"])*"|.)+?\}\}\}/, "{{": /^('(\\.|[^'])*'|"(\\.|[^"'"])*"|.)+?\}\}/, "{%": /^('(\\.|[^'])*'|"(\\.|[^"'"])*"|.)+?%\}/, "{#": /^('(\\.|[^'])*'|"(\\.|[^"'"])*"|.)+?#\}/ }; var delimeters = { "{%": "directive", "{{": "output", "{#": "comment" }; var operators = { and: "&&", or: "||", not: "!", is: "==", isnot: "!=" }; var constants = { "true": true, "false": false, "null": null }; function Parser() { this.nest = []; this.compiled = []; this.childBlocks = 0; this.parentBlocks = 0; this.isSilent = false; } Parser.prototype.push = function(line) { if (!this.isSilent) { this.compiled.push(line); } }; Parser.prototype.parse = function(src) { this.tokenize(src); return this.compiled; }; Parser.prototype.tokenize = function(src) { var lastEnd = 0, parser = this, trimLeading = false; matchAll(src, START_TOKEN, function(open, index, src) { var match = src.slice(index + open.length).match(TAGS[open]); match = match ? match[0] : ""; var simplified = match.replace(STRINGS, "@"); if (!match || ~simplified.indexOf(open)) { return index + 1; } var inner = match.slice(0, 0 - open.length); if (inner.charAt(0) === "-") var wsCollapseLeft = true; if (inner.slice(-1) === "-") var wsCollapseRight = true; inner = inner.replace(/^-|-$/g, "").trim(); if (parser.rawMode && open + inner !== "{%endraw") { return index + 1; } var text = src.slice(lastEnd, index); lastEnd = index + open.length + match.length; if (trimLeading) text = trimLeft(text); if (wsCollapseLeft) text = trimRight(text); if (wsCollapseRight) trimLeading = true; if (open === "{{{") { open = "{{"; inner += "|safe"; } parser.textHandler(text); parser.tokenHandler(open, inner); }); var text = src.slice(lastEnd); if (trimLeading) text = trimLeft(text); this.textHandler(text); }; Parser.prototype.textHandler = function(text) { this.push("write(" + JSON.stringify(text) + ");"); }; Parser.prototype.tokenHandler = function(open, inner) { var type = delimeters[open]; if (type === "directive") { this.compileTag(inner); } else if (type === "output") { var extracted = this.extractEnt(inner, STRINGS, "@"); extracted.src = extracted.src.replace(/\|\|/g, "~").split("|"); extracted.src = extracted.src.map(function(part) { return part.split("~").join("||"); }); var parts = this.injectEnt(extracted, "@"); if (parts.length > 1) { var filters = parts.slice(1).map(this.parseFilter.bind(this)); this.push("filter(" + this.parseExpr(parts[0]) + "," + filters.join(",") + ");"); } else { this.push("filter(" + this.parseExpr(parts[0]) + ");"); } } }; Parser.prototype.compileTag = function(str) { var directive = str.split(" ")[0]; var handler = tagHandlers[directive]; if (!handler) { throw new Error("Invalid tag: " + str); } handler.call(this, str.slice(directive.length).trim()); }; Parser.prototype.parseFilter = function(src) { src = src.trim(); var match = src.match(/[:(]/); var i = match ? match.index : -1; if (i < 0) return JSON.stringify([src]); var name = src.slice(0, i); var args = src.charAt(i) === ":" ? src.slice(i + 1) : src.slice(i + 1, -1); args = this.parseExpr(args, { terms: true }); return "[" + JSON.stringify(name) + "," + args + "]"; }; Parser.prototype.extractEnt = function(src, regex, placeholder) { var subs = [], isFunc = typeof placeholder == "function"; src = src.replace(regex, function(str) { var replacement = isFunc ? placeholder(str) : placeholder; if (replacement) { subs.push(str); return replacement; } return str; }); return { src, subs }; }; Parser.prototype.injectEnt = function(extracted, placeholder) { var src = extracted.src, subs = extracted.subs, isArr = Array.isArray(src); var arr = isArr ? src : [src]; var re = new RegExp("[" + placeholder + "]", "g"), i = 0; arr.forEach(function(src, index) { arr[index] = src.replace(re, function() { return subs[i++]; }); }); return isArr ? arr : arr[0]; }; Parser.prototype.replaceComplex = function(s) { var parsed = this.extractEnt(s, /i(\.i|\[[@#i]\])+/g, "v"); parsed.src = parsed.src.replace(NON_PRIMITIVES, "~"); return this.injectEnt(parsed, "v"); }; Parser.prototype.parseExpr = function(src, opts) { opts = opts || {}; var parsed1 = this.extractEnt(src, STRINGS, "@"); parsed1.src = parsed1.src.replace(EOPS, function(s, before, op, after) { return op in operators ? before + operators[op] + after : s; }); var parsed2 = this.extractEnt(parsed1.src, IDENTS_AND_NUMS, function(s) { return s in constants || NUMBER.test(s) ? "#" : null; }); var parsed3 = this.extractEnt(parsed2.src, IDENTIFIERS, "i"); parsed3.src = parsed3.src.replace(/\s+/g, ""); var simplified = parsed3.src; while (simplified !== (simplified = this.replaceComplex(simplified))); while (simplified !== (simplified = simplified.replace(/i(\.i|\[[@#i]\])+/, "v"))); simplified = simplified.replace(/[iv]\[v?\]/g, "x"); simplified = simplified.replace(/[@#~v]/g, "i"); simplified = simplified.replace(OPERATORS, "%"); simplified = simplified.replace(/!+[i]/g, "i"); var terms = opts.terms ? simplified.split(",") : [simplified]; terms.forEach(function(term) { while (term !== (term = term.replace(/\(i(%i)*\)/g, "i"))); if (!term.match(/^i(%i)*/)) { throw new Error("Invalid expression: " + src + " " + term); } }); parsed3.src = parsed3.src.replace(VARIABLES, this.parseVar.bind(this)); parsed2.src = this.injectEnt(parsed3, "i"); parsed1.src = this.injectEnt(parsed2, "#"); return this.injectEnt(parsed1, "@"); }; Parser.prototype.parseVar = function(src) { var args = Array.prototype.slice.call(arguments); var str = args.pop(), index = args.pop(); if (src === "i" && str.charAt(index + 1) === ":") { return "\"i\""; } var parts = ["\"i\""]; src.replace(ACCESSOR, function(part) { if (part === ".i") { parts.push("\"i\""); } else if (part === "[i]") { parts.push("get(\"i\")"); } else { parts.push(part.slice(1, -1)); } }); return "get(" + parts.join(",") + ")"; }; Parser.prototype.escName = function(str) { return str.replace(/\W/g, function(s) { return "$" + s.charCodeAt(0).toString(16); }); }; Parser.prototype.parseQuoted = function(str) { if (str.charAt(0) === "'") { str = str.slice(1, -1).replace(/\\.|"/, function(s) { if (s === "\\'") return "'"; return s.charAt(0) === "\\" ? s : "\\" + s; }); str = "\"" + str + "\""; } return JSON.parse(str); }; var tagHandlers = { "if": function(expr) { this.push("if (" + this.parseExpr(expr) + ") {"); this.nest.unshift("if"); }, "else": function() { if (this.nest[0] === "for") { this.push("}, function() {"); } else { this.push("} else {"); } }, "elseif": function(expr) { this.push("} else if (" + this.parseExpr(expr) + ") {"); }, "endif": function() { this.nest.shift(); this.push("}"); }, "for": function(str) { var i = str.indexOf(" in "); var name = str.slice(0, i).trim(); var expr = str.slice(i + 4).trim(); this.push("each(" + this.parseExpr(expr) + "," + JSON.stringify(name) + ",function() {"); this.nest.unshift("for"); }, "endfor": function() { this.nest.shift(); this.push("});"); }, "raw": function() { this.rawMode = true; }, "endraw": function() { this.rawMode = false; }, "set": function(stmt) { var i = stmt.indexOf("="); var name = stmt.slice(0, i).trim(); var expr = stmt.slice(i + 1).trim(); this.push("set(" + JSON.stringify(name) + "," + this.parseExpr(expr) + ");"); }, "block": function(name) { if (this.isParent) { ++this.parentBlocks; var blockName = "block_" + (this.escName(name) || this.parentBlocks); this.push("block(typeof " + blockName + " == \"function\" ? " + blockName + " : function() {"); } else if (this.hasParent) { this.isSilent = false; ++this.childBlocks; blockName = "block_" + (this.escName(name) || this.childBlocks); this.push("function " + blockName + "() {"); } this.nest.unshift("block"); }, "endblock": function() { this.nest.shift(); if (this.isParent) { this.push("});"); } else if (this.hasParent) { this.push("}"); this.isSilent = true; } }, "extends": function(name) { name = this.parseQuoted(name); var parentSrc = this.readTemplateFile(name); this.isParent = true; this.tokenize(parentSrc); this.isParent = false; this.hasParent = true; this.isSilent = true; }, "include": function(name) { name = this.parseQuoted(name); var incSrc = this.readTemplateFile(name); this.isInclude = true; this.tokenize(incSrc); this.isInclude = false; } }; tagHandlers.assign = tagHandlers.set; tagHandlers.elif = tagHandlers.elseif; var getRuntime = function runtime(data, opts) { var defaults = { autoEscape: "toJson" }; var _toString = Object.prototype.toString; var _hasOwnProperty = Object.prototype.hasOwnProperty; var getKeys = Object.keys || function(obj) { var keys = []; for (var n in obj) if (_hasOwnProperty.call(obj, n)) keys.push(n); return keys; }; var isArray = Array.isArray || function(obj) { return _toString.call(obj) === "[object Array]"; }; var create = Object.create || function(obj) { function F() {} F.prototype = obj; return new F(); }; var toString = function(val) { if (val == null) return ""; return typeof val.toString == "function" ? val.toString() : _toString.call(val); }; var extend = function(dest, src) { var keys = getKeys(src); for (var i = 0, len = keys.length; i < len; i++) { var key = keys[i]; dest[key] = src[key]; } return dest; }; var get = function() { var val, n = arguments[0], c = stack.length; while (c--) { val = stack[c][n]; if (typeof val != "undefined") break; } for (var i = 1, len = arguments.length; i < len; i++) { if (val == null) continue; n = arguments[i]; val = _hasOwnProperty.call(val, n) ? val[n] : typeof val._get == "function" ? val[n] = val._get(n) : null; } return val == null ? "" : val; }; var set = function(n, val) { stack[stack.length - 1][n] = val; }; var push = function(ctx) { stack.push(ctx || {}); }; var pop = function() { stack.pop(); }; var write = function(str) { output.push(str); }; var filter = function(val) { for (var i = 1, len = arguments.length; i < len; i++) { var arr = arguments[i], name = arr[0], filter = filters[name]; if (filter) { arr[0] = val; val = filter.apply(data, arr); } else { throw new Error("Invalid filter: " + name); } } if (opts.autoEscape && name !== opts.autoEscape && name !== "safe") { val = filters[opts.autoEscape].call(data, val); } output.push(val); }; var each = function(obj, loopvar, fn1, fn2) { if (obj == null) return; var arr = isArray(obj) ? obj : getKeys(obj), len = arr.length; var ctx = { loop: { length: len, first: arr[0], last: arr[len - 1] } }; push(ctx); for (var i = 0; i < len; i++) { extend(ctx.loop, { index: i + 1, index0: i }); fn1(ctx[loopvar] = arr[i]); } if (len === 0 && fn2) fn2(); pop(); }; var block = function(fn) { push(); fn(); pop(); }; var render = function() { return output.join(""); }; data = data || {}; opts = extend(defaults, opts || {}); var filters = extend({ html: function(val) { return toString(val).split("&").join("&").split("<").join("<").split(">").join(">").split("\"").join("""); }, safe: function(val) { return val; }, toJson: function(val) { if (typeof val === "object") { return JSON.stringify(val); } return toString(val); } }, opts.filters || {}); var stack = [create(data || {})], output = []; return { get, set, push, pop, write, filter, each, block, render }; }; var runtime; jinja.compile = function(markup, opts) { opts = opts || {}; var parser = new Parser(); parser.readTemplateFile = this.readTemplateFile; var code = []; code.push("function render($) {"); code.push("var get = $.get, set = $.set, push = $.push, pop = $.pop, write = $.write, filter = $.filter, each = $.each, block = $.block;"); code.push.apply(code, parser.parse(markup)); code.push("return $.render();"); code.push("}"); code = code.join("\n"); if (opts.runtime === false) { var fn = new Function("data", "options", "return (" + code + ")(runtime(data, options))"); } else { runtime = runtime || (runtime = getRuntime.toString()); fn = new Function("data", "options", "return (" + code + ")((" + runtime + ")(data, options))"); } return { render: fn }; }; jinja.render = function(markup, data, opts) { var tmpl = jinja.compile(markup); return tmpl.render(data, opts); }; jinja.templateFiles = []; jinja.readTemplateFile = function(name) { var templateFiles = this.templateFiles || []; var templateFile = templateFiles[name]; if (templateFile == null) { throw new Error("Template file not found: " + name); } return templateFile; }; /*! * Helpers */ function trimLeft(str) { return str.replace(LEADING_SPACE, ""); } function trimRight(str) { return str.replace(TRAILING_SPACE, ""); } function matchAll(str, reg, fn) { reg = new RegExp(reg.source, "g" + (reg.ignoreCase ? "i" : "") + (reg.multiline ? "m" : "")); var match; while (match = reg.exec(str)) { var result = fn(match[0], match.index, str); if (typeof result == "number") { reg.lastIndex = result; } } } })); })); //#endregion //#region shim.js var import_pako_min = /* @__PURE__ */ __toESM(require_pako_min(), 1); var import_crypto_js$1 = /* @__PURE__ */ __toESM(require_crypto_js$1(), 1); var import_random_http_ua = /* @__PURE__ */ __toESM(require_random_http_ua(), 1); var import_jinja = /* @__PURE__ */ __toESM(require_jinja(), 1); global.pako = import_pako_min.default; global.CryptoJS = import_crypto_js$1.default; global.randomUa = import_random_http_ua.default; global.jinja = import_jinja.render ? import_jinja : import_jinja.default || import_jinja; //#endregion //#region ../utils/api_helper.js /** * API辅助工具模块 * 提供文件监听、引擎选择等API相关的辅助功能 * 支持热重载和多种引擎类型的动态选择 */ let jsonWatcher = null; let debounceTimers = new Map(); /** * 启动JSON文件监听器 * 在开发环境下监听JSON文件变化,自动清除模块缓存实现热重载 * @param {Object} ENGINES - 引擎对象集合 * @param {string} jsonDir - 要监听的JSON文件目录路径 */ function startJsonWatcher(ENGINES, jsonDir) { if (process.env.NODE_ENV !== "development") return; try { jsonWatcher = watch(jsonDir, { recursive: true }, (eventType, filename) => { if (filename && filename.endsWith(".json")) { if (debounceTimers.has(filename)) { clearTimeout(debounceTimers.get(filename)); } const timer = setTimeout(() => { console.log(`[HotReload] ${filename} changed, clearing cache...`); ENGINES.drpyS.clearAllCache(); debounceTimers.delete(filename); }, 100); debounceTimers.set(filename, timer); } }); } catch (error) { console.error("start json file listening failed with error:", error); } } /** * 根据适配器类型获取对应的API引擎 * 支持多种引擎类型:py(hipy)、cat(catvod)、xbpq、默认(drpyS) * @param {Object} engines - 所有可用的引擎对象 * @param {string} moduleName - 模块名称 * @param {Object} query - 查询参数对象 * @param {Object} options - 配置选项,包含各种目录路径 * @returns {Object} 包含引擎、目录、扩展名和模块路径的对象 */ function getApiEngine(engines, moduleName, query, options) { const adapt = query.do; let apiEngine; let moduleDir; let _ext; switch (adapt) { case "py": apiEngine = engines.hipy; moduleDir = options.pyDir; _ext = ".py"; break; case "php": apiEngine = engines.php; moduleDir = options.phpDir; _ext = ".php"; break; case "cat": apiEngine = engines.catvod; moduleDir = options.catDir; _ext = ".js"; break; case "xbpq": apiEngine = engines.xbpq; moduleDir = options.xbpqDir; _ext = ".json"; break; default: apiEngine = engines.drpyS; moduleDir = options.jsDir; _ext = ".js"; } const modulePath = path.join(moduleDir, `${moduleName}${_ext}`); return { apiEngine, moduleDir, _ext, modulePath }; } //#endregion //#region ../node_modules/xmlhttprequest/lib/XMLHttpRequest.js var require_XMLHttpRequest = /* @__PURE__ */ __commonJSMin(((exports) => { /** * Wrapper for built-in http.js to emulate the browser XMLHttpRequest object. * * This can be used with JS designed for browsers to improve reuse of code and * allow the use of existing libraries. * * Usage: include("XMLHttpRequest.js") and use XMLHttpRequest per W3C specs. * * @author Dan DeFelippi * @contributor David Ellis * @license MIT */ var Url = __require("url"); var spawn = __require("child_process").spawn; var fs$6 = __require("fs"); exports.XMLHttpRequest = function() { "use strict"; /** * Private variables */ var self = this; var http = __require("http"); var https = __require("https"); var request; var response; var settings = {}; var disableHeaderCheck = false; var defaultHeaders = { "User-Agent": "node-XMLHttpRequest", "Accept": "*/*" }; var headers = {}; var headersCase = {}; var forbiddenRequestHeaders = [ "accept-charset", "accept-encoding", "access-control-request-headers", "access-control-request-method", "connection", "content-length", "content-transfer-encoding", "cookie", "cookie2", "date", "expect", "host", "keep-alive", "origin", "referer", "te", "trailer", "transfer-encoding", "upgrade", "via" ]; var forbiddenRequestMethods = [ "TRACE", "TRACK", "CONNECT" ]; var sendFlag = false; var errorFlag = false; var listeners = {}; /** * Constants */ this.UNSENT = 0; this.OPENED = 1; this.HEADERS_RECEIVED = 2; this.LOADING = 3; this.DONE = 4; /** * Public vars */ this.readyState = this.UNSENT; this.onreadystatechange = null; this.responseText = ""; this.responseXML = ""; this.status = null; this.statusText = null; this.withCredentials = false; /** * Private methods */ /** * Check if the specified header is allowed. * * @param string header Header to validate * @return boolean False if not allowed, otherwise true */ var isAllowedHttpHeader = function(header) { return disableHeaderCheck || header && forbiddenRequestHeaders.indexOf(header.toLowerCase()) === -1; }; /** * Check if the specified method is allowed. * * @param string method Request method to validate * @return boolean False if not allowed, otherwise true */ var isAllowedHttpMethod = function(method) { return method && forbiddenRequestMethods.indexOf(method) === -1; }; /** * Public methods */ /** * Open the connection. Currently supports local server requests. * * @param string method Connection method (eg GET, POST) * @param string url URL for the connection. * @param boolean async Asynchronous connection. Default is true. * @param string user Username for basic authentication (optional) * @param string password Password for basic authentication (optional) */ this.open = function(method, url, async, user, password) { this.abort(); errorFlag = false; if (!isAllowedHttpMethod(method)) { throw new Error("SecurityError: Request method not allowed"); } settings = { "method": method, "url": url.toString(), "async": typeof async !== "boolean" ? true : async, "user": user || null, "password": password || null }; setState(this.OPENED); }; /** * Disables or enables isAllowedHttpHeader() check the request. Enabled by default. * This does not conform to the W3C spec. * * @param boolean state Enable or disable header checking. */ this.setDisableHeaderCheck = function(state) { disableHeaderCheck = state; }; /** * Sets a header for the request or appends the value if one is already set. * * @param string header Header name * @param string value Header value */ this.setRequestHeader = function(header, value) { if (this.readyState !== this.OPENED) { throw new Error("INVALID_STATE_ERR: setRequestHeader can only be called when state is OPEN"); } if (!isAllowedHttpHeader(header)) { console.warn("Refused to set unsafe header \"" + header + "\""); return; } if (sendFlag) { throw new Error("INVALID_STATE_ERR: send flag is true"); } header = headersCase[header.toLowerCase()] || header; headersCase[header.toLowerCase()] = header; headers[header] = headers[header] ? headers[header] + ", " + value : value; }; /** * Gets a header from the server response. * * @param string header Name of header to get. * @return string Text of the header or null if it doesn't exist. */ this.getResponseHeader = function(header) { if (typeof header === "string" && this.readyState > this.OPENED && response && response.headers && response.headers[header.toLowerCase()] && !errorFlag) { return response.headers[header.toLowerCase()]; } return null; }; /** * Gets all the response headers. * * @return string A string with all response headers separated by CR+LF */ this.getAllResponseHeaders = function() { if (this.readyState < this.HEADERS_RECEIVED || errorFlag) { return ""; } var result = ""; for (var i in response.headers) { if (i !== "set-cookie" && i !== "set-cookie2") { result += i + ": " + response.headers[i] + "\r\n"; } } return result.substr(0, result.length - 2); }; /** * Gets a request header * * @param string name Name of header to get * @return string Returns the request header or empty string if not set */ this.getRequestHeader = function(name) { if (typeof name === "string" && headersCase[name.toLowerCase()]) { return headers[headersCase[name.toLowerCase()]]; } return ""; }; /** * Sends the request to the server. * * @param string data Optional data to send as request body. */ this.send = function(data) { if (this.readyState !== this.OPENED) { throw new Error("INVALID_STATE_ERR: connection must be opened before send() is called"); } if (sendFlag) { throw new Error("INVALID_STATE_ERR: send has already been called"); } var ssl = false, local = false; var url = Url.parse(settings.url); var host; switch (url.protocol) { case "https:": ssl = true; case "http:": host = url.hostname; break; case "file:": local = true; break; case undefined: case null: case "": host = "localhost"; break; default: throw new Error("Protocol not supported."); } if (local) { if (settings.method !== "GET") { throw new Error("XMLHttpRequest: Only GET method is supported"); } if (settings.async) { fs$6.readFile(url.pathname, "utf8", function(error, data) { if (error) { self.handleError(error); } else { self.status = 200; self.responseText = data; setState(self.DONE); } }); } else { try { this.responseText = fs$6.readFileSync(url.pathname, "utf8"); this.status = 200; setState(self.DONE); } catch (e) { this.handleError(e); } } return; } var port = url.port || (ssl ? 443 : 80); var uri = url.pathname + (url.search ? url.search : ""); for (var name in defaultHeaders) { if (!headersCase[name.toLowerCase()]) { headers[name] = defaultHeaders[name]; } } headers.Host = host; if (!(ssl && port === 443 || port === 80)) { headers.Host += ":" + url.port; } if (settings.user) { if (typeof settings.password === "undefined") { settings.password = ""; } var authBuf = new Buffer(settings.user + ":" + settings.password); headers.Authorization = "Basic " + authBuf.toString("base64"); } if (settings.method === "GET" || settings.method === "HEAD") { data = null; } else if (data) { headers["Content-Length"] = Buffer.isBuffer(data) ? data.length : Buffer.byteLength(data); if (!headers["Content-Type"]) { headers["Content-Type"] = "text/plain;charset=UTF-8"; } } else if (settings.method === "POST") { headers["Content-Length"] = 0; } var options = { host, port, path: uri, method: settings.method, headers, agent: false, withCredentials: self.withCredentials }; errorFlag = false; if (settings.async) { var doRequest = ssl ? https.request : http.request; sendFlag = true; self.dispatchEvent("readystatechange"); var responseHandler = function responseHandler(resp) { response = resp; if (response.statusCode === 301 || response.statusCode === 302 || response.statusCode === 303 || response.statusCode === 307) { settings.url = response.headers.location; var url = Url.parse(settings.url); host = url.hostname; var newOptions = { hostname: url.hostname, port: url.port, path: url.path, method: response.statusCode === 303 ? "GET" : settings.method, headers, withCredentials: self.withCredentials }; request = doRequest(newOptions, responseHandler).on("error", errorHandler); request.end(); return; } response.setEncoding("utf8"); setState(self.HEADERS_RECEIVED); self.status = response.statusCode; response.on("data", function(chunk) { if (chunk) { self.responseText += chunk; } if (sendFlag) { setState(self.LOADING); } }); response.on("end", function() { if (sendFlag) { setState(self.DONE); sendFlag = false; } }); response.on("error", function(error) { self.handleError(error); }); }; var errorHandler = function errorHandler(error) { self.handleError(error); }; request = doRequest(options, responseHandler).on("error", errorHandler); if (data) { request.write(data); } request.end(); self.dispatchEvent("loadstart"); } else { var contentFile = ".node-xmlhttprequest-content-" + process.pid; var syncFile = ".node-xmlhttprequest-sync-" + process.pid; fs$6.writeFileSync(syncFile, "", "utf8"); var execString = "var http = require('http'), https = require('https'), fs = require('fs');" + "var doRequest = http" + (ssl ? "s" : "") + ".request;" + "var options = " + JSON.stringify(options) + ";" + "var responseText = '';" + "var req = doRequest(options, function(response) {" + "response.setEncoding('utf8');" + "response.on('data', function(chunk) {" + " responseText += chunk;" + "});" + "response.on('end', function() {" + "fs.writeFileSync('" + contentFile + "', JSON.stringify({err: null, data: {statusCode: response.statusCode, headers: response.headers, text: responseText}}), 'utf8');" + "fs.unlinkSync('" + syncFile + "');" + "});" + "response.on('error', function(error) {" + "fs.writeFileSync('" + contentFile + "', JSON.stringify({err: error}), 'utf8');" + "fs.unlinkSync('" + syncFile + "');" + "});" + "}).on('error', function(error) {" + "fs.writeFileSync('" + contentFile + "', JSON.stringify({err: error}), 'utf8');" + "fs.unlinkSync('" + syncFile + "');" + "});" + (data ? "req.write('" + JSON.stringify(data).slice(1, -1).replace(/'/g, "\\'") + "');" : "") + "req.end();"; var syncProc = spawn(process.argv[0], ["-e", execString]); while (fs$6.existsSync(syncFile)) {} var resp = JSON.parse(fs$6.readFileSync(contentFile, "utf8")); syncProc.stdin.end(); fs$6.unlinkSync(contentFile); if (resp.err) { self.handleError(resp.err); } else { response = resp.data; self.status = resp.data.statusCode; self.responseText = resp.data.text; setState(self.DONE); } } }; /** * Called when an error is encountered to deal with it. */ this.handleError = function(error) { this.status = 0; this.statusText = error; this.responseText = error.stack; errorFlag = true; setState(this.DONE); this.dispatchEvent("error"); }; /** * Aborts a request. */ this.abort = function() { if (request) { request.abort(); request = null; } headers = defaultHeaders; this.status = 0; this.responseText = ""; this.responseXML = ""; errorFlag = true; if (this.readyState !== this.UNSENT && (this.readyState !== this.OPENED || sendFlag) && this.readyState !== this.DONE) { sendFlag = false; setState(this.DONE); } this.readyState = this.UNSENT; this.dispatchEvent("abort"); }; /** * Adds an event listener. Preferred method of binding to events. */ this.addEventListener = function(event, callback) { if (!(event in listeners)) { listeners[event] = []; } listeners[event].push(callback); }; /** * Remove an event callback that has already been bound. * Only works on the matching funciton, cannot be a copy. */ this.removeEventListener = function(event, callback) { if (event in listeners) { listeners[event] = listeners[event].filter(function(ev) { return ev !== callback; }); } }; /** * Dispatch any events, including both "on" methods and events attached using addEventListener. */ this.dispatchEvent = function(event) { if (typeof self["on" + event] === "function") { self["on" + event](); } if (event in listeners) { for (var i = 0, len = listeners[event].length; i < len; i++) { listeners[event][i].call(self); } } }; /** * Changes readyState and calls onreadystatechange. * * @param int state New state */ var setState = function(state) { if (state == self.LOADING || self.readyState !== state) { self.readyState = state; if (settings.async || self.readyState < self.OPENED || self.readyState === self.DONE) { self.dispatchEvent("readystatechange"); } if (self.readyState === self.DONE && !errorFlag) { self.dispatchEvent("load"); self.dispatchEvent("loadend"); } } }; }; })); //#endregion //#region ../node_modules/ws/lib/constants.js var require_constants$7 = /* @__PURE__ */ __commonJSMin(((exports, module) => { const BINARY_TYPES = [ "nodebuffer", "arraybuffer", "fragments" ]; const hasBlob = typeof Blob !== "undefined"; if (hasBlob) BINARY_TYPES.push("blob"); module.exports = { BINARY_TYPES, EMPTY_BUFFER: Buffer.alloc(0), GUID: "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", hasBlob, kForOnEventAttribute: Symbol("kIsForOnEventAttribute"), kListener: Symbol("kListener"), kStatusCode: Symbol("status-code"), kWebSocket: Symbol("websocket"), NOOP: () => {} }; })); //#endregion //#region ../node_modules/ws/lib/buffer-util.js var require_buffer_util = /* @__PURE__ */ __commonJSMin(((exports, module) => { const { EMPTY_BUFFER } = require_constants$7(); const FastBuffer = Buffer[Symbol.species]; /** * Merges an array of buffers into a new buffer. * * @param {Buffer[]} list The array of buffers to concat * @param {Number} totalLength The total length of buffers in the list * @return {Buffer} The resulting buffer * @public */ function concat(list, totalLength) { if (list.length === 0) return EMPTY_BUFFER; if (list.length === 1) return list[0]; const target = Buffer.allocUnsafe(totalLength); let offset = 0; for (let i = 0; i < list.length; i++) { const buf = list[i]; target.set(buf, offset); offset += buf.length; } if (offset < totalLength) { return new FastBuffer(target.buffer, target.byteOffset, offset); } return target; } /** * Masks a buffer using the given mask. * * @param {Buffer} source The buffer to mask * @param {Buffer} mask The mask to use * @param {Buffer} output The buffer where to store the result * @param {Number} offset The offset at which to start writing * @param {Number} length The number of bytes to mask. * @public */ function _mask(source, mask, output, offset, length) { for (let i = 0; i < length; i++) { output[offset + i] = source[i] ^ mask[i & 3]; } } /** * Unmasks a buffer using the given mask. * * @param {Buffer} buffer The buffer to unmask * @param {Buffer} mask The mask to use * @public */ function _unmask(buffer, mask) { for (let i = 0; i < buffer.length; i++) { buffer[i] ^= mask[i & 3]; } } /** * Converts a buffer to an `ArrayBuffer`. * * @param {Buffer} buf The buffer to convert * @return {ArrayBuffer} Converted buffer * @public */ function toArrayBuffer(buf) { if (buf.length === buf.buffer.byteLength) { return buf.buffer; } return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.length); } /** * Converts `data` to a `Buffer`. * * @param {*} data The data to convert * @return {Buffer} The buffer * @throws {TypeError} * @public */ function toBuffer(data) { toBuffer.readOnly = true; if (Buffer.isBuffer(data)) return data; let buf; if (data instanceof ArrayBuffer) { buf = new FastBuffer(data); } else if (ArrayBuffer.isView(data)) { buf = new FastBuffer(data.buffer, data.byteOffset, data.byteLength); } else { buf = Buffer.from(data); toBuffer.readOnly = false; } return buf; } module.exports = { concat, mask: _mask, toArrayBuffer, toBuffer, unmask: _unmask }; /* istanbul ignore else */ if (!process.env.WS_NO_BUFFER_UTIL) { try { const bufferUtil = __require("bufferutil"); module.exports.mask = function(source, mask, output, offset, length) { if (length < 48) _mask(source, mask, output, offset, length); else bufferUtil.mask(source, mask, output, offset, length); }; module.exports.unmask = function(buffer, mask) { if (buffer.length < 32) _unmask(buffer, mask); else bufferUtil.unmask(buffer, mask); }; } catch (e) {} } })); //#endregion //#region ../node_modules/ws/lib/limiter.js var require_limiter = /* @__PURE__ */ __commonJSMin(((exports, module) => { const kDone = Symbol("kDone"); const kRun = Symbol("kRun"); /** * A very simple job queue with adjustable concurrency. Adapted from * https://github.com/STRML/async-limiter */ var Limiter = class { /** * Creates a new `Limiter`. * * @param {Number} [concurrency=Infinity] The maximum number of jobs allowed * to run concurrently */ constructor(concurrency) { this[kDone] = () => { this.pending--; this[kRun](); }; this.concurrency = concurrency || Infinity; this.jobs = []; this.pending = 0; } /** * Adds a job to the queue. * * @param {Function} job The job to run * @public */ add(job) { this.jobs.push(job); this[kRun](); } /** * Removes a job from the queue and runs it if possible. * * @private */ [kRun]() { if (this.pending === this.concurrency) return; if (this.jobs.length) { const job = this.jobs.shift(); this.pending++; job(this[kDone]); } } }; module.exports = Limiter; })); //#endregion //#region ../node_modules/ws/lib/permessage-deflate.js var require_permessage_deflate$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => { const zlib$3 = __require("zlib"); const bufferUtil = require_buffer_util(); const Limiter = require_limiter(); const { kStatusCode } = require_constants$7(); const FastBuffer = Buffer[Symbol.species]; const TRAILER = Buffer.from([ 0, 0, 255, 255 ]); const kPerMessageDeflate = Symbol("permessage-deflate"); const kTotalLength = Symbol("total-length"); const kCallback = Symbol("callback"); const kBuffers = Symbol("buffers"); const kError = Symbol("error"); let zlibLimiter; /** * permessage-deflate implementation. */ var PerMessageDeflate = class { /** * Creates a PerMessageDeflate instance. * * @param {Object} [options] Configuration options * @param {(Boolean|Number)} [options.clientMaxWindowBits] Advertise support * for, or request, a custom client window size * @param {Boolean} [options.clientNoContextTakeover=false] Advertise/ * acknowledge disabling of client context takeover * @param {Number} [options.concurrencyLimit=10] The number of concurrent * calls to zlib * @param {(Boolean|Number)} [options.serverMaxWindowBits] Request/confirm the * use of a custom server window size * @param {Boolean} [options.serverNoContextTakeover=false] Request/accept * disabling of server context takeover * @param {Number} [options.threshold=1024] Size (in bytes) below which * messages should not be compressed if context takeover is disabled * @param {Object} [options.zlibDeflateOptions] Options to pass to zlib on * deflate * @param {Object} [options.zlibInflateOptions] Options to pass to zlib on * inflate * @param {Boolean} [isServer=false] Create the instance in either server or * client mode * @param {Number} [maxPayload=0] The maximum allowed message length */ constructor(options, isServer, maxPayload) { this._maxPayload = maxPayload | 0; this._options = options || {}; this._threshold = this._options.threshold !== undefined ? this._options.threshold : 1024; this._isServer = !!isServer; this._deflate = null; this._inflate = null; this.params = null; if (!zlibLimiter) { const concurrency = this._options.concurrencyLimit !== undefined ? this._options.concurrencyLimit : 10; zlibLimiter = new Limiter(concurrency); } } /** * @type {String} */ static get extensionName() { return "permessage-deflate"; } /** * Create an extension negotiation offer. * * @return {Object} Extension parameters * @public */ offer() { const params = {}; if (this._options.serverNoContextTakeover) { params.server_no_context_takeover = true; } if (this._options.clientNoContextTakeover) { params.client_no_context_takeover = true; } if (this._options.serverMaxWindowBits) { params.server_max_window_bits = this._options.serverMaxWindowBits; } if (this._options.clientMaxWindowBits) { params.client_max_window_bits = this._options.clientMaxWindowBits; } else if (this._options.clientMaxWindowBits == null) { params.client_max_window_bits = true; } return params; } /** * Accept an extension negotiation offer/response. * * @param {Array} configurations The extension negotiation offers/reponse * @return {Object} Accepted configuration * @public */ accept(configurations) { configurations = this.normalizeParams(configurations); this.params = this._isServer ? this.acceptAsServer(configurations) : this.acceptAsClient(configurations); return this.params; } /** * Releases all resources used by the extension. * * @public */ cleanup() { if (this._inflate) { this._inflate.close(); this._inflate = null; } if (this._deflate) { const callback = this._deflate[kCallback]; this._deflate.close(); this._deflate = null; if (callback) { callback(new Error("The deflate stream was closed while data was being processed")); } } } /** * Accept an extension negotiation offer. * * @param {Array} offers The extension negotiation offers * @return {Object} Accepted configuration * @private */ acceptAsServer(offers) { const opts = this._options; const accepted = offers.find((params) => { if (opts.serverNoContextTakeover === false && params.server_no_context_takeover || params.server_max_window_bits && (opts.serverMaxWindowBits === false || typeof opts.serverMaxWindowBits === "number" && opts.serverMaxWindowBits > params.server_max_window_bits) || typeof opts.clientMaxWindowBits === "number" && !params.client_max_window_bits) { return false; } return true; }); if (!accepted) { throw new Error("None of the extension offers can be accepted"); } if (opts.serverNoContextTakeover) { accepted.server_no_context_takeover = true; } if (opts.clientNoContextTakeover) { accepted.client_no_context_takeover = true; } if (typeof opts.serverMaxWindowBits === "number") { accepted.server_max_window_bits = opts.serverMaxWindowBits; } if (typeof opts.clientMaxWindowBits === "number") { accepted.client_max_window_bits = opts.clientMaxWindowBits; } else if (accepted.client_max_window_bits === true || opts.clientMaxWindowBits === false) { delete accepted.client_max_window_bits; } return accepted; } /** * Accept the extension negotiation response. * * @param {Array} response The extension negotiation response * @return {Object} Accepted configuration * @private */ acceptAsClient(response) { const params = response[0]; if (this._options.clientNoContextTakeover === false && params.client_no_context_takeover) { throw new Error("Unexpected parameter \"client_no_context_takeover\""); } if (!params.client_max_window_bits) { if (typeof this._options.clientMaxWindowBits === "number") { params.client_max_window_bits = this._options.clientMaxWindowBits; } } else if (this._options.clientMaxWindowBits === false || typeof this._options.clientMaxWindowBits === "number" && params.client_max_window_bits > this._options.clientMaxWindowBits) { throw new Error("Unexpected or invalid parameter \"client_max_window_bits\""); } return params; } /** * Normalize parameters. * * @param {Array} configurations The extension negotiation offers/reponse * @return {Array} The offers/response with normalized parameters * @private */ normalizeParams(configurations) { configurations.forEach((params) => { Object.keys(params).forEach((key) => { let value = params[key]; if (value.length > 1) { throw new Error(`Parameter "${key}" must have only a single value`); } value = value[0]; if (key === "client_max_window_bits") { if (value !== true) { const num = +value; if (!Number.isInteger(num) || num < 8 || num > 15) { throw new TypeError(`Invalid value for parameter "${key}": ${value}`); } value = num; } else if (!this._isServer) { throw new TypeError(`Invalid value for parameter "${key}": ${value}`); } } else if (key === "server_max_window_bits") { const num = +value; if (!Number.isInteger(num) || num < 8 || num > 15) { throw new TypeError(`Invalid value for parameter "${key}": ${value}`); } value = num; } else if (key === "client_no_context_takeover" || key === "server_no_context_takeover") { if (value !== true) { throw new TypeError(`Invalid value for parameter "${key}": ${value}`); } } else { throw new Error(`Unknown parameter "${key}"`); } params[key] = value; }); }); return configurations; } /** * Decompress data. Concurrency limited. * * @param {Buffer} data Compressed data * @param {Boolean} fin Specifies whether or not this is the last fragment * @param {Function} callback Callback * @public */ decompress(data, fin, callback) { zlibLimiter.add((done) => { this._decompress(data, fin, (err, result) => { done(); callback(err, result); }); }); } /** * Compress data. Concurrency limited. * * @param {(Buffer|String)} data Data to compress * @param {Boolean} fin Specifies whether or not this is the last fragment * @param {Function} callback Callback * @public */ compress(data, fin, callback) { zlibLimiter.add((done) => { this._compress(data, fin, (err, result) => { done(); callback(err, result); }); }); } /** * Decompress data. * * @param {Buffer} data Compressed data * @param {Boolean} fin Specifies whether or not this is the last fragment * @param {Function} callback Callback * @private */ _decompress(data, fin, callback) { const endpoint = this._isServer ? "client" : "server"; if (!this._inflate) { const key = `${endpoint}_max_window_bits`; const windowBits = typeof this.params[key] !== "number" ? zlib$3.Z_DEFAULT_WINDOWBITS : this.params[key]; this._inflate = zlib$3.createInflateRaw({ ...this._options.zlibInflateOptions, windowBits }); this._inflate[kPerMessageDeflate] = this; this._inflate[kTotalLength] = 0; this._inflate[kBuffers] = []; this._inflate.on("error", inflateOnError); this._inflate.on("data", inflateOnData); } this._inflate[kCallback] = callback; this._inflate.write(data); if (fin) this._inflate.write(TRAILER); this._inflate.flush(() => { const err = this._inflate[kError]; if (err) { this._inflate.close(); this._inflate = null; callback(err); return; } const data = bufferUtil.concat(this._inflate[kBuffers], this._inflate[kTotalLength]); if (this._inflate._readableState.endEmitted) { this._inflate.close(); this._inflate = null; } else { this._inflate[kTotalLength] = 0; this._inflate[kBuffers] = []; if (fin && this.params[`${endpoint}_no_context_takeover`]) { this._inflate.reset(); } } callback(null, data); }); } /** * Compress data. * * @param {(Buffer|String)} data Data to compress * @param {Boolean} fin Specifies whether or not this is the last fragment * @param {Function} callback Callback * @private */ _compress(data, fin, callback) { const endpoint = this._isServer ? "server" : "client"; if (!this._deflate) { const key = `${endpoint}_max_window_bits`; const windowBits = typeof this.params[key] !== "number" ? zlib$3.Z_DEFAULT_WINDOWBITS : this.params[key]; this._deflate = zlib$3.createDeflateRaw({ ...this._options.zlibDeflateOptions, windowBits }); this._deflate[kTotalLength] = 0; this._deflate[kBuffers] = []; this._deflate.on("data", deflateOnData); } this._deflate[kCallback] = callback; this._deflate.write(data); this._deflate.flush(zlib$3.Z_SYNC_FLUSH, () => { if (!this._deflate) { return; } let data = bufferUtil.concat(this._deflate[kBuffers], this._deflate[kTotalLength]); if (fin) { data = new FastBuffer(data.buffer, data.byteOffset, data.length - 4); } this._deflate[kCallback] = null; this._deflate[kTotalLength] = 0; this._deflate[kBuffers] = []; if (fin && this.params[`${endpoint}_no_context_takeover`]) { this._deflate.reset(); } callback(null, data); }); } }; module.exports = PerMessageDeflate; /** * The listener of the `zlib.DeflateRaw` stream `'data'` event. * * @param {Buffer} chunk A chunk of data * @private */ function deflateOnData(chunk) { this[kBuffers].push(chunk); this[kTotalLength] += chunk.length; } /** * The listener of the `zlib.InflateRaw` stream `'data'` event. * * @param {Buffer} chunk A chunk of data * @private */ function inflateOnData(chunk) { this[kTotalLength] += chunk.length; if (this[kPerMessageDeflate]._maxPayload < 1 || this[kTotalLength] <= this[kPerMessageDeflate]._maxPayload) { this[kBuffers].push(chunk); return; } this[kError] = new RangeError("Max payload size exceeded"); this[kError].code = "WS_ERR_UNSUPPORTED_MESSAGE_LENGTH"; this[kError][kStatusCode] = 1009; this.removeListener("data", inflateOnData); this.reset(); } /** * The listener of the `zlib.InflateRaw` stream `'error'` event. * * @param {Error} err The emitted error * @private */ function inflateOnError(err) { this[kPerMessageDeflate]._inflate = null; if (this[kError]) { this[kCallback](this[kError]); return; } err[kStatusCode] = 1007; this[kCallback](err); } })); //#endregion //#region ../node_modules/ws/lib/validation.js var require_validation$2 = /* @__PURE__ */ __commonJSMin(((exports, module) => { const { isUtf8: isUtf8$1 } = __require("buffer"); const { hasBlob } = require_constants$7(); const tokenChars = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0 ]; /** * Checks if a status code is allowed in a close frame. * * @param {Number} code The status code * @return {Boolean} `true` if the status code is valid, else `false` * @public */ function isValidStatusCode(code) { return code >= 1e3 && code <= 1014 && code !== 1004 && code !== 1005 && code !== 1006 || code >= 3e3 && code <= 4999; } /** * Checks if a given buffer contains only correct UTF-8. * Ported from https://www.cl.cam.ac.uk/%7Emgk25/ucs/utf8_check.c by * Markus Kuhn. * * @param {Buffer} buf The buffer to check * @return {Boolean} `true` if `buf` contains only correct UTF-8, else `false` * @public */ function _isValidUTF8(buf) { const len = buf.length; let i = 0; while (i < len) { if ((buf[i] & 128) === 0) { i++; } else if ((buf[i] & 224) === 192) { if (i + 1 === len || (buf[i + 1] & 192) !== 128 || (buf[i] & 254) === 192) { return false; } i += 2; } else if ((buf[i] & 240) === 224) { if (i + 2 >= len || (buf[i + 1] & 192) !== 128 || (buf[i + 2] & 192) !== 128 || buf[i] === 224 && (buf[i + 1] & 224) === 128 || buf[i] === 237 && (buf[i + 1] & 224) === 160) { return false; } i += 3; } else if ((buf[i] & 248) === 240) { if (i + 3 >= len || (buf[i + 1] & 192) !== 128 || (buf[i + 2] & 192) !== 128 || (buf[i + 3] & 192) !== 128 || buf[i] === 240 && (buf[i + 1] & 240) === 128 || buf[i] === 244 && buf[i + 1] > 143 || buf[i] > 244) { return false; } i += 4; } else { return false; } } return true; } /** * Determines whether a value is a `Blob`. * * @param {*} value The value to be tested * @return {Boolean} `true` if `value` is a `Blob`, else `false` * @private */ function isBlob(value) { return hasBlob && typeof value === "object" && typeof value.arrayBuffer === "function" && typeof value.type === "string" && typeof value.stream === "function" && (value[Symbol.toStringTag] === "Blob" || value[Symbol.toStringTag] === "File"); } module.exports = { isBlob, isValidStatusCode, isValidUTF8: _isValidUTF8, tokenChars }; if (isUtf8$1) { module.exports.isValidUTF8 = function(buf) { return buf.length < 24 ? _isValidUTF8(buf) : isUtf8$1(buf); }; } else if (!process.env.WS_NO_UTF_8_VALIDATE) { try { const isValidUTF8 = __require("utf-8-validate"); module.exports.isValidUTF8 = function(buf) { return buf.length < 32 ? _isValidUTF8(buf) : isValidUTF8(buf); }; } catch (e) {} } })); //#endregion //#region ../node_modules/ws/lib/receiver.js var require_receiver$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => { const { Writable: Writable$7 } = __require("stream"); const PerMessageDeflate = require_permessage_deflate$1(); const { BINARY_TYPES, EMPTY_BUFFER, kStatusCode, kWebSocket } = require_constants$7(); const { concat, toArrayBuffer, unmask } = require_buffer_util(); const { isValidStatusCode, isValidUTF8 } = require_validation$2(); const FastBuffer = Buffer[Symbol.species]; const GET_INFO = 0; const GET_PAYLOAD_LENGTH_16 = 1; const GET_PAYLOAD_LENGTH_64 = 2; const GET_MASK = 3; const GET_DATA = 4; const INFLATING = 5; const DEFER_EVENT = 6; /** * HyBi Receiver implementation. * * @extends Writable */ var Receiver = class extends Writable$7 { /** * Creates a Receiver instance. * * @param {Object} [options] Options object * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted * multiple times in the same tick * @param {String} [options.binaryType=nodebuffer] The type for binary data * @param {Object} [options.extensions] An object containing the negotiated * extensions * @param {Boolean} [options.isServer=false] Specifies whether to operate in * client or server mode * @param {Number} [options.maxPayload=0] The maximum allowed message length * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or * not to skip UTF-8 validation for text and close messages */ constructor(options = {}) { super(); this._allowSynchronousEvents = options.allowSynchronousEvents !== undefined ? options.allowSynchronousEvents : true; this._binaryType = options.binaryType || BINARY_TYPES[0]; this._extensions = options.extensions || {}; this._isServer = !!options.isServer; this._maxPayload = options.maxPayload | 0; this._skipUTF8Validation = !!options.skipUTF8Validation; this[kWebSocket] = undefined; this._bufferedBytes = 0; this._buffers = []; this._compressed = false; this._payloadLength = 0; this._mask = undefined; this._fragmented = 0; this._masked = false; this._fin = false; this._opcode = 0; this._totalPayloadLength = 0; this._messageLength = 0; this._fragments = []; this._errored = false; this._loop = false; this._state = GET_INFO; } /** * Implements `Writable.prototype._write()`. * * @param {Buffer} chunk The chunk of data to write * @param {String} encoding The character encoding of `chunk` * @param {Function} cb Callback * @private */ _write(chunk, encoding, cb) { if (this._opcode === 8 && this._state == GET_INFO) return cb(); this._bufferedBytes += chunk.length; this._buffers.push(chunk); this.startLoop(cb); } /** * Consumes `n` bytes from the buffered data. * * @param {Number} n The number of bytes to consume * @return {Buffer} The consumed bytes * @private */ consume(n) { this._bufferedBytes -= n; if (n === this._buffers[0].length) return this._buffers.shift(); if (n < this._buffers[0].length) { const buf = this._buffers[0]; this._buffers[0] = new FastBuffer(buf.buffer, buf.byteOffset + n, buf.length - n); return new FastBuffer(buf.buffer, buf.byteOffset, n); } const dst = Buffer.allocUnsafe(n); do { const buf = this._buffers[0]; const offset = dst.length - n; if (n >= buf.length) { dst.set(this._buffers.shift(), offset); } else { dst.set(new Uint8Array(buf.buffer, buf.byteOffset, n), offset); this._buffers[0] = new FastBuffer(buf.buffer, buf.byteOffset + n, buf.length - n); } n -= buf.length; } while (n > 0); return dst; } /** * Starts the parsing loop. * * @param {Function} cb Callback * @private */ startLoop(cb) { this._loop = true; do { switch (this._state) { case GET_INFO: this.getInfo(cb); break; case GET_PAYLOAD_LENGTH_16: this.getPayloadLength16(cb); break; case GET_PAYLOAD_LENGTH_64: this.getPayloadLength64(cb); break; case GET_MASK: this.getMask(); break; case GET_DATA: this.getData(cb); break; case INFLATING: case DEFER_EVENT: this._loop = false; return; } } while (this._loop); if (!this._errored) cb(); } /** * Reads the first two bytes of a frame. * * @param {Function} cb Callback * @private */ getInfo(cb) { if (this._bufferedBytes < 2) { this._loop = false; return; } const buf = this.consume(2); if ((buf[0] & 48) !== 0) { const error = this.createError(RangeError, "RSV2 and RSV3 must be clear", true, 1002, "WS_ERR_UNEXPECTED_RSV_2_3"); cb(error); return; } const compressed = (buf[0] & 64) === 64; if (compressed && !this._extensions[PerMessageDeflate.extensionName]) { const error = this.createError(RangeError, "RSV1 must be clear", true, 1002, "WS_ERR_UNEXPECTED_RSV_1"); cb(error); return; } this._fin = (buf[0] & 128) === 128; this._opcode = buf[0] & 15; this._payloadLength = buf[1] & 127; if (this._opcode === 0) { if (compressed) { const error = this.createError(RangeError, "RSV1 must be clear", true, 1002, "WS_ERR_UNEXPECTED_RSV_1"); cb(error); return; } if (!this._fragmented) { const error = this.createError(RangeError, "invalid opcode 0", true, 1002, "WS_ERR_INVALID_OPCODE"); cb(error); return; } this._opcode = this._fragmented; } else if (this._opcode === 1 || this._opcode === 2) { if (this._fragmented) { const error = this.createError(RangeError, `invalid opcode ${this._opcode}`, true, 1002, "WS_ERR_INVALID_OPCODE"); cb(error); return; } this._compressed = compressed; } else if (this._opcode > 7 && this._opcode < 11) { if (!this._fin) { const error = this.createError(RangeError, "FIN must be set", true, 1002, "WS_ERR_EXPECTED_FIN"); cb(error); return; } if (compressed) { const error = this.createError(RangeError, "RSV1 must be clear", true, 1002, "WS_ERR_UNEXPECTED_RSV_1"); cb(error); return; } if (this._payloadLength > 125 || this._opcode === 8 && this._payloadLength === 1) { const error = this.createError(RangeError, `invalid payload length ${this._payloadLength}`, true, 1002, "WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH"); cb(error); return; } } else { const error = this.createError(RangeError, `invalid opcode ${this._opcode}`, true, 1002, "WS_ERR_INVALID_OPCODE"); cb(error); return; } if (!this._fin && !this._fragmented) this._fragmented = this._opcode; this._masked = (buf[1] & 128) === 128; if (this._isServer) { if (!this._masked) { const error = this.createError(RangeError, "MASK must be set", true, 1002, "WS_ERR_EXPECTED_MASK"); cb(error); return; } } else if (this._masked) { const error = this.createError(RangeError, "MASK must be clear", true, 1002, "WS_ERR_UNEXPECTED_MASK"); cb(error); return; } if (this._payloadLength === 126) this._state = GET_PAYLOAD_LENGTH_16; else if (this._payloadLength === 127) this._state = GET_PAYLOAD_LENGTH_64; else this.haveLength(cb); } /** * Gets extended payload length (7+16). * * @param {Function} cb Callback * @private */ getPayloadLength16(cb) { if (this._bufferedBytes < 2) { this._loop = false; return; } this._payloadLength = this.consume(2).readUInt16BE(0); this.haveLength(cb); } /** * Gets extended payload length (7+64). * * @param {Function} cb Callback * @private */ getPayloadLength64(cb) { if (this._bufferedBytes < 8) { this._loop = false; return; } const buf = this.consume(8); const num = buf.readUInt32BE(0); if (num > Math.pow(2, 53 - 32) - 1) { const error = this.createError(RangeError, "Unsupported WebSocket frame: payload length > 2^53 - 1", false, 1009, "WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH"); cb(error); return; } this._payloadLength = num * Math.pow(2, 32) + buf.readUInt32BE(4); this.haveLength(cb); } /** * Payload length has been read. * * @param {Function} cb Callback * @private */ haveLength(cb) { if (this._payloadLength && this._opcode < 8) { this._totalPayloadLength += this._payloadLength; if (this._totalPayloadLength > this._maxPayload && this._maxPayload > 0) { const error = this.createError(RangeError, "Max payload size exceeded", false, 1009, "WS_ERR_UNSUPPORTED_MESSAGE_LENGTH"); cb(error); return; } } if (this._masked) this._state = GET_MASK; else this._state = GET_DATA; } /** * Reads mask bytes. * * @private */ getMask() { if (this._bufferedBytes < 4) { this._loop = false; return; } this._mask = this.consume(4); this._state = GET_DATA; } /** * Reads data bytes. * * @param {Function} cb Callback * @private */ getData(cb) { let data = EMPTY_BUFFER; if (this._payloadLength) { if (this._bufferedBytes < this._payloadLength) { this._loop = false; return; } data = this.consume(this._payloadLength); if (this._masked && (this._mask[0] | this._mask[1] | this._mask[2] | this._mask[3]) !== 0) { unmask(data, this._mask); } } if (this._opcode > 7) { this.controlMessage(data, cb); return; } if (this._compressed) { this._state = INFLATING; this.decompress(data, cb); return; } if (data.length) { this._messageLength = this._totalPayloadLength; this._fragments.push(data); } this.dataMessage(cb); } /** * Decompresses data. * * @param {Buffer} data Compressed data * @param {Function} cb Callback * @private */ decompress(data, cb) { const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName]; perMessageDeflate.decompress(data, this._fin, (err, buf) => { if (err) return cb(err); if (buf.length) { this._messageLength += buf.length; if (this._messageLength > this._maxPayload && this._maxPayload > 0) { const error = this.createError(RangeError, "Max payload size exceeded", false, 1009, "WS_ERR_UNSUPPORTED_MESSAGE_LENGTH"); cb(error); return; } this._fragments.push(buf); } this.dataMessage(cb); if (this._state === GET_INFO) this.startLoop(cb); }); } /** * Handles a data message. * * @param {Function} cb Callback * @private */ dataMessage(cb) { if (!this._fin) { this._state = GET_INFO; return; } const messageLength = this._messageLength; const fragments = this._fragments; this._totalPayloadLength = 0; this._messageLength = 0; this._fragmented = 0; this._fragments = []; if (this._opcode === 2) { let data; if (this._binaryType === "nodebuffer") { data = concat(fragments, messageLength); } else if (this._binaryType === "arraybuffer") { data = toArrayBuffer(concat(fragments, messageLength)); } else if (this._binaryType === "blob") { data = new Blob(fragments); } else { data = fragments; } if (this._allowSynchronousEvents) { this.emit("message", data, true); this._state = GET_INFO; } else { this._state = DEFER_EVENT; setImmediate(() => { this.emit("message", data, true); this._state = GET_INFO; this.startLoop(cb); }); } } else { const buf = concat(fragments, messageLength); if (!this._skipUTF8Validation && !isValidUTF8(buf)) { const error = this.createError(Error, "invalid UTF-8 sequence", true, 1007, "WS_ERR_INVALID_UTF8"); cb(error); return; } if (this._state === INFLATING || this._allowSynchronousEvents) { this.emit("message", buf, false); this._state = GET_INFO; } else { this._state = DEFER_EVENT; setImmediate(() => { this.emit("message", buf, false); this._state = GET_INFO; this.startLoop(cb); }); } } } /** * Handles a control message. * * @param {Buffer} data Data to handle * @return {(Error|RangeError|undefined)} A possible error * @private */ controlMessage(data, cb) { if (this._opcode === 8) { if (data.length === 0) { this._loop = false; this.emit("conclude", 1005, EMPTY_BUFFER); this.end(); } else { const code = data.readUInt16BE(0); if (!isValidStatusCode(code)) { const error = this.createError(RangeError, `invalid status code ${code}`, true, 1002, "WS_ERR_INVALID_CLOSE_CODE"); cb(error); return; } const buf = new FastBuffer(data.buffer, data.byteOffset + 2, data.length - 2); if (!this._skipUTF8Validation && !isValidUTF8(buf)) { const error = this.createError(Error, "invalid UTF-8 sequence", true, 1007, "WS_ERR_INVALID_UTF8"); cb(error); return; } this._loop = false; this.emit("conclude", code, buf); this.end(); } this._state = GET_INFO; return; } if (this._allowSynchronousEvents) { this.emit(this._opcode === 9 ? "ping" : "pong", data); this._state = GET_INFO; } else { this._state = DEFER_EVENT; setImmediate(() => { this.emit(this._opcode === 9 ? "ping" : "pong", data); this._state = GET_INFO; this.startLoop(cb); }); } } /** * Builds an error object. * * @param {function(new:Error|RangeError)} ErrorCtor The error constructor * @param {String} message The error message * @param {Boolean} prefix Specifies whether or not to add a default prefix to * `message` * @param {Number} statusCode The status code * @param {String} errorCode The exposed error code * @return {(Error|RangeError)} The error * @private */ createError(ErrorCtor, message, prefix, statusCode, errorCode) { this._loop = false; this._errored = true; const err = new ErrorCtor(prefix ? `Invalid WebSocket frame: ${message}` : message); Error.captureStackTrace(err, this.createError); err.code = errorCode; err[kStatusCode] = statusCode; return err; } }; module.exports = Receiver; })); //#endregion //#region ../node_modules/ws/lib/sender.js var require_sender$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => { const { Duplex: Duplex$4 } = __require("stream"); const { randomFillSync: randomFillSync$1 } = __require("crypto"); const PerMessageDeflate = require_permessage_deflate$1(); const { EMPTY_BUFFER, kWebSocket, NOOP } = require_constants$7(); const { isBlob, isValidStatusCode } = require_validation$2(); const { mask: applyMask, toBuffer } = require_buffer_util(); const kByteLength = Symbol("kByteLength"); const maskBuffer = Buffer.alloc(4); const RANDOM_POOL_SIZE = 8 * 1024; let randomPool; let randomPoolPointer = RANDOM_POOL_SIZE; const DEFAULT = 0; const DEFLATING = 1; const GET_BLOB_DATA = 2; /** * HyBi Sender implementation. */ var Sender = class Sender { /** * Creates a Sender instance. * * @param {Duplex} socket The connection socket * @param {Object} [extensions] An object containing the negotiated extensions * @param {Function} [generateMask] The function used to generate the masking * key */ constructor(socket, extensions, generateMask) { this._extensions = extensions || {}; if (generateMask) { this._generateMask = generateMask; this._maskBuffer = Buffer.alloc(4); } this._socket = socket; this._firstFragment = true; this._compress = false; this._bufferedBytes = 0; this._queue = []; this._state = DEFAULT; this.onerror = NOOP; this[kWebSocket] = undefined; } /** * Frames a piece of data according to the HyBi WebSocket protocol. * * @param {(Buffer|String)} data The data to frame * @param {Object} options Options object * @param {Boolean} [options.fin=false] Specifies whether or not to set the * FIN bit * @param {Function} [options.generateMask] The function used to generate the * masking key * @param {Boolean} [options.mask=false] Specifies whether or not to mask * `data` * @param {Buffer} [options.maskBuffer] The buffer used to store the masking * key * @param {Number} options.opcode The opcode * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be * modified * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the * RSV1 bit * @return {(Buffer|String)[]} The framed data * @public */ static frame(data, options) { let mask; let merge = false; let offset = 2; let skipMasking = false; if (options.mask) { mask = options.maskBuffer || maskBuffer; if (options.generateMask) { options.generateMask(mask); } else { if (randomPoolPointer === RANDOM_POOL_SIZE) { /* istanbul ignore else */ if (randomPool === undefined) { randomPool = Buffer.alloc(RANDOM_POOL_SIZE); } randomFillSync$1(randomPool, 0, RANDOM_POOL_SIZE); randomPoolPointer = 0; } mask[0] = randomPool[randomPoolPointer++]; mask[1] = randomPool[randomPoolPointer++]; mask[2] = randomPool[randomPoolPointer++]; mask[3] = randomPool[randomPoolPointer++]; } skipMasking = (mask[0] | mask[1] | mask[2] | mask[3]) === 0; offset = 6; } let dataLength; if (typeof data === "string") { if ((!options.mask || skipMasking) && options[kByteLength] !== undefined) { dataLength = options[kByteLength]; } else { data = Buffer.from(data); dataLength = data.length; } } else { dataLength = data.length; merge = options.mask && options.readOnly && !skipMasking; } let payloadLength = dataLength; if (dataLength >= 65536) { offset += 8; payloadLength = 127; } else if (dataLength > 125) { offset += 2; payloadLength = 126; } const target = Buffer.allocUnsafe(merge ? dataLength + offset : offset); target[0] = options.fin ? options.opcode | 128 : options.opcode; if (options.rsv1) target[0] |= 64; target[1] = payloadLength; if (payloadLength === 126) { target.writeUInt16BE(dataLength, 2); } else if (payloadLength === 127) { target[2] = target[3] = 0; target.writeUIntBE(dataLength, 4, 6); } if (!options.mask) return [target, data]; target[1] |= 128; target[offset - 4] = mask[0]; target[offset - 3] = mask[1]; target[offset - 2] = mask[2]; target[offset - 1] = mask[3]; if (skipMasking) return [target, data]; if (merge) { applyMask(data, mask, target, offset, dataLength); return [target]; } applyMask(data, mask, data, 0, dataLength); return [target, data]; } /** * Sends a close message to the other peer. * * @param {Number} [code] The status code component of the body * @param {(String|Buffer)} [data] The message component of the body * @param {Boolean} [mask=false] Specifies whether or not to mask the message * @param {Function} [cb] Callback * @public */ close(code, data, mask, cb) { let buf; if (code === undefined) { buf = EMPTY_BUFFER; } else if (typeof code !== "number" || !isValidStatusCode(code)) { throw new TypeError("First argument must be a valid error code number"); } else if (data === undefined || !data.length) { buf = Buffer.allocUnsafe(2); buf.writeUInt16BE(code, 0); } else { const length = Buffer.byteLength(data); if (length > 123) { throw new RangeError("The message must not be greater than 123 bytes"); } buf = Buffer.allocUnsafe(2 + length); buf.writeUInt16BE(code, 0); if (typeof data === "string") { buf.write(data, 2); } else { buf.set(data, 2); } } const options = { [kByteLength]: buf.length, fin: true, generateMask: this._generateMask, mask, maskBuffer: this._maskBuffer, opcode: 8, readOnly: false, rsv1: false }; if (this._state !== DEFAULT) { this.enqueue([ this.dispatch, buf, false, options, cb ]); } else { this.sendFrame(Sender.frame(buf, options), cb); } } /** * Sends a ping message to the other peer. * * @param {*} data The message to send * @param {Boolean} [mask=false] Specifies whether or not to mask `data` * @param {Function} [cb] Callback * @public */ ping(data, mask, cb) { let byteLength; let readOnly; if (typeof data === "string") { byteLength = Buffer.byteLength(data); readOnly = false; } else if (isBlob(data)) { byteLength = data.size; readOnly = false; } else { data = toBuffer(data); byteLength = data.length; readOnly = toBuffer.readOnly; } if (byteLength > 125) { throw new RangeError("The data size must not be greater than 125 bytes"); } const options = { [kByteLength]: byteLength, fin: true, generateMask: this._generateMask, mask, maskBuffer: this._maskBuffer, opcode: 9, readOnly, rsv1: false }; if (isBlob(data)) { if (this._state !== DEFAULT) { this.enqueue([ this.getBlobData, data, false, options, cb ]); } else { this.getBlobData(data, false, options, cb); } } else if (this._state !== DEFAULT) { this.enqueue([ this.dispatch, data, false, options, cb ]); } else { this.sendFrame(Sender.frame(data, options), cb); } } /** * Sends a pong message to the other peer. * * @param {*} data The message to send * @param {Boolean} [mask=false] Specifies whether or not to mask `data` * @param {Function} [cb] Callback * @public */ pong(data, mask, cb) { let byteLength; let readOnly; if (typeof data === "string") { byteLength = Buffer.byteLength(data); readOnly = false; } else if (isBlob(data)) { byteLength = data.size; readOnly = false; } else { data = toBuffer(data); byteLength = data.length; readOnly = toBuffer.readOnly; } if (byteLength > 125) { throw new RangeError("The data size must not be greater than 125 bytes"); } const options = { [kByteLength]: byteLength, fin: true, generateMask: this._generateMask, mask, maskBuffer: this._maskBuffer, opcode: 10, readOnly, rsv1: false }; if (isBlob(data)) { if (this._state !== DEFAULT) { this.enqueue([ this.getBlobData, data, false, options, cb ]); } else { this.getBlobData(data, false, options, cb); } } else if (this._state !== DEFAULT) { this.enqueue([ this.dispatch, data, false, options, cb ]); } else { this.sendFrame(Sender.frame(data, options), cb); } } /** * Sends a data message to the other peer. * * @param {*} data The message to send * @param {Object} options Options object * @param {Boolean} [options.binary=false] Specifies whether `data` is binary * or text * @param {Boolean} [options.compress=false] Specifies whether or not to * compress `data` * @param {Boolean} [options.fin=false] Specifies whether the fragment is the * last one * @param {Boolean} [options.mask=false] Specifies whether or not to mask * `data` * @param {Function} [cb] Callback * @public */ send(data, options, cb) { const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName]; let opcode = options.binary ? 2 : 1; let rsv1 = options.compress; let byteLength; let readOnly; if (typeof data === "string") { byteLength = Buffer.byteLength(data); readOnly = false; } else if (isBlob(data)) { byteLength = data.size; readOnly = false; } else { data = toBuffer(data); byteLength = data.length; readOnly = toBuffer.readOnly; } if (this._firstFragment) { this._firstFragment = false; if (rsv1 && perMessageDeflate && perMessageDeflate.params[perMessageDeflate._isServer ? "server_no_context_takeover" : "client_no_context_takeover"]) { rsv1 = byteLength >= perMessageDeflate._threshold; } this._compress = rsv1; } else { rsv1 = false; opcode = 0; } if (options.fin) this._firstFragment = true; const opts = { [kByteLength]: byteLength, fin: options.fin, generateMask: this._generateMask, mask: options.mask, maskBuffer: this._maskBuffer, opcode, readOnly, rsv1 }; if (isBlob(data)) { if (this._state !== DEFAULT) { this.enqueue([ this.getBlobData, data, this._compress, opts, cb ]); } else { this.getBlobData(data, this._compress, opts, cb); } } else if (this._state !== DEFAULT) { this.enqueue([ this.dispatch, data, this._compress, opts, cb ]); } else { this.dispatch(data, this._compress, opts, cb); } } /** * Gets the contents of a blob as binary data. * * @param {Blob} blob The blob * @param {Boolean} [compress=false] Specifies whether or not to compress * the data * @param {Object} options Options object * @param {Boolean} [options.fin=false] Specifies whether or not to set the * FIN bit * @param {Function} [options.generateMask] The function used to generate the * masking key * @param {Boolean} [options.mask=false] Specifies whether or not to mask * `data` * @param {Buffer} [options.maskBuffer] The buffer used to store the masking * key * @param {Number} options.opcode The opcode * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be * modified * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the * RSV1 bit * @param {Function} [cb] Callback * @private */ getBlobData(blob, compress, options, cb) { this._bufferedBytes += options[kByteLength]; this._state = GET_BLOB_DATA; blob.arrayBuffer().then((arrayBuffer) => { if (this._socket.destroyed) { const err = new Error("The socket was closed while the blob was being read"); process.nextTick(callCallbacks, this, err, cb); return; } this._bufferedBytes -= options[kByteLength]; const data = toBuffer(arrayBuffer); if (!compress) { this._state = DEFAULT; this.sendFrame(Sender.frame(data, options), cb); this.dequeue(); } else { this.dispatch(data, compress, options, cb); } }).catch((err) => { process.nextTick(onError, this, err, cb); }); } /** * Dispatches a message. * * @param {(Buffer|String)} data The message to send * @param {Boolean} [compress=false] Specifies whether or not to compress * `data` * @param {Object} options Options object * @param {Boolean} [options.fin=false] Specifies whether or not to set the * FIN bit * @param {Function} [options.generateMask] The function used to generate the * masking key * @param {Boolean} [options.mask=false] Specifies whether or not to mask * `data` * @param {Buffer} [options.maskBuffer] The buffer used to store the masking * key * @param {Number} options.opcode The opcode * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be * modified * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the * RSV1 bit * @param {Function} [cb] Callback * @private */ dispatch(data, compress, options, cb) { if (!compress) { this.sendFrame(Sender.frame(data, options), cb); return; } const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName]; this._bufferedBytes += options[kByteLength]; this._state = DEFLATING; perMessageDeflate.compress(data, options.fin, (_, buf) => { if (this._socket.destroyed) { const err = new Error("The socket was closed while data was being compressed"); callCallbacks(this, err, cb); return; } this._bufferedBytes -= options[kByteLength]; this._state = DEFAULT; options.readOnly = false; this.sendFrame(Sender.frame(buf, options), cb); this.dequeue(); }); } /** * Executes queued send operations. * * @private */ dequeue() { while (this._state === DEFAULT && this._queue.length) { const params = this._queue.shift(); this._bufferedBytes -= params[3][kByteLength]; Reflect.apply(params[0], this, params.slice(1)); } } /** * Enqueues a send operation. * * @param {Array} params Send operation parameters. * @private */ enqueue(params) { this._bufferedBytes += params[3][kByteLength]; this._queue.push(params); } /** * Sends a frame. * * @param {(Buffer | String)[]} list The frame to send * @param {Function} [cb] Callback * @private */ sendFrame(list, cb) { if (list.length === 2) { this._socket.cork(); this._socket.write(list[0]); this._socket.write(list[1], cb); this._socket.uncork(); } else { this._socket.write(list[0], cb); } } }; module.exports = Sender; /** * Calls queued callbacks with an error. * * @param {Sender} sender The `Sender` instance * @param {Error} err The error to call the callbacks with * @param {Function} [cb] The first callback * @private */ function callCallbacks(sender, err, cb) { if (typeof cb === "function") cb(err); for (let i = 0; i < sender._queue.length; i++) { const params = sender._queue[i]; const callback = params[params.length - 1]; if (typeof callback === "function") callback(err); } } /** * Handles a `Sender` error. * * @param {Sender} sender The `Sender` instance * @param {Error} err The error * @param {Function} [cb] The first pending callback * @private */ function onError(sender, err, cb) { callCallbacks(sender, err, cb); sender.onerror(err); } })); //#endregion //#region ../node_modules/ws/lib/event-target.js var require_event_target = /* @__PURE__ */ __commonJSMin(((exports, module) => { const { kForOnEventAttribute, kListener } = require_constants$7(); const kCode = Symbol("kCode"); const kData = Symbol("kData"); const kError = Symbol("kError"); const kMessage = Symbol("kMessage"); const kReason = Symbol("kReason"); const kTarget = Symbol("kTarget"); const kType = Symbol("kType"); const kWasClean = Symbol("kWasClean"); /** * Class representing an event. */ var Event = class { /** * Create a new `Event`. * * @param {String} type The name of the event * @throws {TypeError} If the `type` argument is not specified */ constructor(type) { this[kTarget] = null; this[kType] = type; } /** * @type {*} */ get target() { return this[kTarget]; } /** * @type {String} */ get type() { return this[kType]; } }; Object.defineProperty(Event.prototype, "target", { enumerable: true }); Object.defineProperty(Event.prototype, "type", { enumerable: true }); /** * Class representing a close event. * * @extends Event */ var CloseEvent = class extends Event { /** * Create a new `CloseEvent`. * * @param {String} type The name of the event * @param {Object} [options] A dictionary object that allows for setting * attributes via object members of the same name * @param {Number} [options.code=0] The status code explaining why the * connection was closed * @param {String} [options.reason=''] A human-readable string explaining why * the connection was closed * @param {Boolean} [options.wasClean=false] Indicates whether or not the * connection was cleanly closed */ constructor(type, options = {}) { super(type); this[kCode] = options.code === undefined ? 0 : options.code; this[kReason] = options.reason === undefined ? "" : options.reason; this[kWasClean] = options.wasClean === undefined ? false : options.wasClean; } /** * @type {Number} */ get code() { return this[kCode]; } /** * @type {String} */ get reason() { return this[kReason]; } /** * @type {Boolean} */ get wasClean() { return this[kWasClean]; } }; Object.defineProperty(CloseEvent.prototype, "code", { enumerable: true }); Object.defineProperty(CloseEvent.prototype, "reason", { enumerable: true }); Object.defineProperty(CloseEvent.prototype, "wasClean", { enumerable: true }); /** * Class representing an error event. * * @extends Event */ var ErrorEvent = class extends Event { /** * Create a new `ErrorEvent`. * * @param {String} type The name of the event * @param {Object} [options] A dictionary object that allows for setting * attributes via object members of the same name * @param {*} [options.error=null] The error that generated this event * @param {String} [options.message=''] The error message */ constructor(type, options = {}) { super(type); this[kError] = options.error === undefined ? null : options.error; this[kMessage] = options.message === undefined ? "" : options.message; } /** * @type {*} */ get error() { return this[kError]; } /** * @type {String} */ get message() { return this[kMessage]; } }; Object.defineProperty(ErrorEvent.prototype, "error", { enumerable: true }); Object.defineProperty(ErrorEvent.prototype, "message", { enumerable: true }); /** * Class representing a message event. * * @extends Event */ var MessageEvent = class extends Event { /** * Create a new `MessageEvent`. * * @param {String} type The name of the event * @param {Object} [options] A dictionary object that allows for setting * attributes via object members of the same name * @param {*} [options.data=null] The message content */ constructor(type, options = {}) { super(type); this[kData] = options.data === undefined ? null : options.data; } /** * @type {*} */ get data() { return this[kData]; } }; Object.defineProperty(MessageEvent.prototype, "data", { enumerable: true }); /** * This provides methods for emulating the `EventTarget` interface. It's not * meant to be used directly. * * @mixin */ const EventTarget = { addEventListener(type, handler, options = {}) { for (const listener of this.listeners(type)) { if (!options[kForOnEventAttribute] && listener[kListener] === handler && !listener[kForOnEventAttribute]) { return; } } let wrapper; if (type === "message") { wrapper = function onMessage(data, isBinary) { const event = new MessageEvent("message", { data: isBinary ? data : data.toString() }); event[kTarget] = this; callListener(handler, this, event); }; } else if (type === "close") { wrapper = function onClose(code, message) { const event = new CloseEvent("close", { code, reason: message.toString(), wasClean: this._closeFrameReceived && this._closeFrameSent }); event[kTarget] = this; callListener(handler, this, event); }; } else if (type === "error") { wrapper = function onError(error) { const event = new ErrorEvent("error", { error, message: error.message }); event[kTarget] = this; callListener(handler, this, event); }; } else if (type === "open") { wrapper = function onOpen() { const event = new Event("open"); event[kTarget] = this; callListener(handler, this, event); }; } else { return; } wrapper[kForOnEventAttribute] = !!options[kForOnEventAttribute]; wrapper[kListener] = handler; if (options.once) { this.once(type, wrapper); } else { this.on(type, wrapper); } }, removeEventListener(type, handler) { for (const listener of this.listeners(type)) { if (listener[kListener] === handler && !listener[kForOnEventAttribute]) { this.removeListener(type, listener); break; } } } }; module.exports = { CloseEvent, ErrorEvent, Event, EventTarget, MessageEvent }; /** * Call an event listener * * @param {(Function|Object)} listener The listener to call * @param {*} thisArg The value to use as `this`` when calling the listener * @param {Event} event The event to pass to the listener * @private */ function callListener(listener, thisArg, event) { if (typeof listener === "object" && listener.handleEvent) { listener.handleEvent.call(listener, event); } else { listener.call(thisArg, event); } } })); //#endregion //#region ../node_modules/ws/lib/extension.js var require_extension = /* @__PURE__ */ __commonJSMin(((exports, module) => { const { tokenChars } = require_validation$2(); /** * Adds an offer to the map of extension offers or a parameter to the map of * parameters. * * @param {Object} dest The map of extension offers or parameters * @param {String} name The extension or parameter name * @param {(Object|Boolean|String)} elem The extension parameters or the * parameter value * @private */ function push(dest, name, elem) { if (dest[name] === undefined) dest[name] = [elem]; else dest[name].push(elem); } /** * Parses the `Sec-WebSocket-Extensions` header into an object. * * @param {String} header The field value of the header * @return {Object} The parsed object * @public */ function parse(header) { const offers = Object.create(null); let params = Object.create(null); let mustUnescape = false; let isEscaping = false; let inQuotes = false; let extensionName; let paramName; let start = -1; let code = -1; let end = -1; let i = 0; for (; i < header.length; i++) { code = header.charCodeAt(i); if (extensionName === undefined) { if (end === -1 && tokenChars[code] === 1) { if (start === -1) start = i; } else if (i !== 0 && (code === 32 || code === 9)) { if (end === -1 && start !== -1) end = i; } else if (code === 59 || code === 44) { if (start === -1) { throw new SyntaxError(`Unexpected character at index ${i}`); } if (end === -1) end = i; const name = header.slice(start, end); if (code === 44) { push(offers, name, params); params = Object.create(null); } else { extensionName = name; } start = end = -1; } else { throw new SyntaxError(`Unexpected character at index ${i}`); } } else if (paramName === undefined) { if (end === -1 && tokenChars[code] === 1) { if (start === -1) start = i; } else if (code === 32 || code === 9) { if (end === -1 && start !== -1) end = i; } else if (code === 59 || code === 44) { if (start === -1) { throw new SyntaxError(`Unexpected character at index ${i}`); } if (end === -1) end = i; push(params, header.slice(start, end), true); if (code === 44) { push(offers, extensionName, params); params = Object.create(null); extensionName = undefined; } start = end = -1; } else if (code === 61 && start !== -1 && end === -1) { paramName = header.slice(start, i); start = end = -1; } else { throw new SyntaxError(`Unexpected character at index ${i}`); } } else { if (isEscaping) { if (tokenChars[code] !== 1) { throw new SyntaxError(`Unexpected character at index ${i}`); } if (start === -1) start = i; else if (!mustUnescape) mustUnescape = true; isEscaping = false; } else if (inQuotes) { if (tokenChars[code] === 1) { if (start === -1) start = i; } else if (code === 34 && start !== -1) { inQuotes = false; end = i; } else if (code === 92) { isEscaping = true; } else { throw new SyntaxError(`Unexpected character at index ${i}`); } } else if (code === 34 && header.charCodeAt(i - 1) === 61) { inQuotes = true; } else if (end === -1 && tokenChars[code] === 1) { if (start === -1) start = i; } else if (start !== -1 && (code === 32 || code === 9)) { if (end === -1) end = i; } else if (code === 59 || code === 44) { if (start === -1) { throw new SyntaxError(`Unexpected character at index ${i}`); } if (end === -1) end = i; let value = header.slice(start, end); if (mustUnescape) { value = value.replace(/\\/g, ""); mustUnescape = false; } push(params, paramName, value); if (code === 44) { push(offers, extensionName, params); params = Object.create(null); extensionName = undefined; } paramName = undefined; start = end = -1; } else { throw new SyntaxError(`Unexpected character at index ${i}`); } } } if (start === -1 || inQuotes || code === 32 || code === 9) { throw new SyntaxError("Unexpected end of input"); } if (end === -1) end = i; const token = header.slice(start, end); if (extensionName === undefined) { push(offers, token, params); } else { if (paramName === undefined) { push(params, token, true); } else if (mustUnescape) { push(params, paramName, token.replace(/\\/g, "")); } else { push(params, paramName, token); } push(offers, extensionName, params); } return offers; } /** * Builds the `Sec-WebSocket-Extensions` header field value. * * @param {Object} extensions The map of extensions and parameters to format * @return {String} A string representing the given object * @public */ function format(extensions) { return Object.keys(extensions).map((extension) => { let configurations = extensions[extension]; if (!Array.isArray(configurations)) configurations = [configurations]; return configurations.map((params) => { return [extension].concat(Object.keys(params).map((k) => { let values = params[k]; if (!Array.isArray(values)) values = [values]; return values.map((v) => v === true ? k : `${k}=${v}`).join("; "); })).join("; "); }).join(", "); }).join(", "); } module.exports = { format, parse }; })); //#endregion //#region ../node_modules/ws/lib/websocket.js var require_websocket$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => { const EventEmitter$10 = __require("events"); const https$6 = __require("https"); const http$12 = __require("http"); const net$6 = __require("net"); const tls$2 = __require("tls"); const { randomBytes, createHash: createHash$2 } = __require("crypto"); const { Duplex: Duplex$3, Readable: Readable$9 } = __require("stream"); const { URL: URL$2 } = __require("url"); const PerMessageDeflate = require_permessage_deflate$1(); const Receiver = require_receiver$1(); const Sender = require_sender$1(); const { isBlob } = require_validation$2(); const { BINARY_TYPES, EMPTY_BUFFER, GUID, kForOnEventAttribute, kListener, kStatusCode, kWebSocket, NOOP } = require_constants$7(); const { EventTarget: { addEventListener, removeEventListener } } = require_event_target(); const { format, parse } = require_extension(); const { toBuffer } = require_buffer_util(); const closeTimeout = 30 * 1e3; const kAborted = Symbol("kAborted"); const protocolVersions = [8, 13]; const readyStates = [ "CONNECTING", "OPEN", "CLOSING", "CLOSED" ]; const subprotocolRegex = /^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/; /** * Class representing a WebSocket. * * @extends EventEmitter */ var WebSocket = class WebSocket extends EventEmitter$10 { /** * Create a new `WebSocket`. * * @param {(String|URL)} address The URL to which to connect * @param {(String|String[])} [protocols] The subprotocols * @param {Object} [options] Connection options */ constructor(address, protocols, options) { super(); this._binaryType = BINARY_TYPES[0]; this._closeCode = 1006; this._closeFrameReceived = false; this._closeFrameSent = false; this._closeMessage = EMPTY_BUFFER; this._closeTimer = null; this._errorEmitted = false; this._extensions = {}; this._paused = false; this._protocol = ""; this._readyState = WebSocket.CONNECTING; this._receiver = null; this._sender = null; this._socket = null; if (address !== null) { this._bufferedAmount = 0; this._isServer = false; this._redirects = 0; if (protocols === undefined) { protocols = []; } else if (!Array.isArray(protocols)) { if (typeof protocols === "object" && protocols !== null) { options = protocols; protocols = []; } else { protocols = [protocols]; } } initAsClient(this, address, protocols, options); } else { this._autoPong = options.autoPong; this._isServer = true; } } /** * For historical reasons, the custom "nodebuffer" type is used by the default * instead of "blob". * * @type {String} */ get binaryType() { return this._binaryType; } set binaryType(type) { if (!BINARY_TYPES.includes(type)) return; this._binaryType = type; if (this._receiver) this._receiver._binaryType = type; } /** * @type {Number} */ get bufferedAmount() { if (!this._socket) return this._bufferedAmount; return this._socket._writableState.length + this._sender._bufferedBytes; } /** * @type {String} */ get extensions() { return Object.keys(this._extensions).join(); } /** * @type {Boolean} */ get isPaused() { return this._paused; } /** * @type {Function} */ /* istanbul ignore next */ get onclose() { return null; } /** * @type {Function} */ /* istanbul ignore next */ get onerror() { return null; } /** * @type {Function} */ /* istanbul ignore next */ get onopen() { return null; } /** * @type {Function} */ /* istanbul ignore next */ get onmessage() { return null; } /** * @type {String} */ get protocol() { return this._protocol; } /** * @type {Number} */ get readyState() { return this._readyState; } /** * @type {String} */ get url() { return this._url; } /** * Set up the socket and the internal resources. * * @param {Duplex} socket The network socket between the server and client * @param {Buffer} head The first packet of the upgraded stream * @param {Object} options Options object * @param {Boolean} [options.allowSynchronousEvents=false] Specifies whether * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted * multiple times in the same tick * @param {Function} [options.generateMask] The function used to generate the * masking key * @param {Number} [options.maxPayload=0] The maximum allowed message size * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or * not to skip UTF-8 validation for text and close messages * @private */ setSocket(socket, head, options) { const receiver = new Receiver({ allowSynchronousEvents: options.allowSynchronousEvents, binaryType: this.binaryType, extensions: this._extensions, isServer: this._isServer, maxPayload: options.maxPayload, skipUTF8Validation: options.skipUTF8Validation }); const sender = new Sender(socket, this._extensions, options.generateMask); this._receiver = receiver; this._sender = sender; this._socket = socket; receiver[kWebSocket] = this; sender[kWebSocket] = this; socket[kWebSocket] = this; receiver.on("conclude", receiverOnConclude); receiver.on("drain", receiverOnDrain); receiver.on("error", receiverOnError); receiver.on("message", receiverOnMessage); receiver.on("ping", receiverOnPing); receiver.on("pong", receiverOnPong); sender.onerror = senderOnError; if (socket.setTimeout) socket.setTimeout(0); if (socket.setNoDelay) socket.setNoDelay(); if (head.length > 0) socket.unshift(head); socket.on("close", socketOnClose); socket.on("data", socketOnData); socket.on("end", socketOnEnd); socket.on("error", socketOnError); this._readyState = WebSocket.OPEN; this.emit("open"); } /** * Emit the `'close'` event. * * @private */ emitClose() { if (!this._socket) { this._readyState = WebSocket.CLOSED; this.emit("close", this._closeCode, this._closeMessage); return; } if (this._extensions[PerMessageDeflate.extensionName]) { this._extensions[PerMessageDeflate.extensionName].cleanup(); } this._receiver.removeAllListeners(); this._readyState = WebSocket.CLOSED; this.emit("close", this._closeCode, this._closeMessage); } /** * Start a closing handshake. * * +----------+ +-----------+ +----------+ * - - -|ws.close()|-->|close frame|-->|ws.close()|- - - * | +----------+ +-----------+ +----------+ | * +----------+ +-----------+ | * CLOSING |ws.close()|<--|close frame|<--+-----+ CLOSING * +----------+ +-----------+ | * | | | +---+ | * +------------------------+-->|fin| - - - - * | +---+ | +---+ * - - - - -|fin|<---------------------+ * +---+ * * @param {Number} [code] Status code explaining why the connection is closing * @param {(String|Buffer)} [data] The reason why the connection is * closing * @public */ close(code, data) { if (this.readyState === WebSocket.CLOSED) return; if (this.readyState === WebSocket.CONNECTING) { const msg = "WebSocket was closed before the connection was established"; abortHandshake(this, this._req, msg); return; } if (this.readyState === WebSocket.CLOSING) { if (this._closeFrameSent && (this._closeFrameReceived || this._receiver._writableState.errorEmitted)) { this._socket.end(); } return; } this._readyState = WebSocket.CLOSING; this._sender.close(code, data, !this._isServer, (err) => { if (err) return; this._closeFrameSent = true; if (this._closeFrameReceived || this._receiver._writableState.errorEmitted) { this._socket.end(); } }); setCloseTimer(this); } /** * Pause the socket. * * @public */ pause() { if (this.readyState === WebSocket.CONNECTING || this.readyState === WebSocket.CLOSED) { return; } this._paused = true; this._socket.pause(); } /** * Send a ping. * * @param {*} [data] The data to send * @param {Boolean} [mask] Indicates whether or not to mask `data` * @param {Function} [cb] Callback which is executed when the ping is sent * @public */ ping(data, mask, cb) { if (this.readyState === WebSocket.CONNECTING) { throw new Error("WebSocket is not open: readyState 0 (CONNECTING)"); } if (typeof data === "function") { cb = data; data = mask = undefined; } else if (typeof mask === "function") { cb = mask; mask = undefined; } if (typeof data === "number") data = data.toString(); if (this.readyState !== WebSocket.OPEN) { sendAfterClose(this, data, cb); return; } if (mask === undefined) mask = !this._isServer; this._sender.ping(data || EMPTY_BUFFER, mask, cb); } /** * Send a pong. * * @param {*} [data] The data to send * @param {Boolean} [mask] Indicates whether or not to mask `data` * @param {Function} [cb] Callback which is executed when the pong is sent * @public */ pong(data, mask, cb) { if (this.readyState === WebSocket.CONNECTING) { throw new Error("WebSocket is not open: readyState 0 (CONNECTING)"); } if (typeof data === "function") { cb = data; data = mask = undefined; } else if (typeof mask === "function") { cb = mask; mask = undefined; } if (typeof data === "number") data = data.toString(); if (this.readyState !== WebSocket.OPEN) { sendAfterClose(this, data, cb); return; } if (mask === undefined) mask = !this._isServer; this._sender.pong(data || EMPTY_BUFFER, mask, cb); } /** * Resume the socket. * * @public */ resume() { if (this.readyState === WebSocket.CONNECTING || this.readyState === WebSocket.CLOSED) { return; } this._paused = false; if (!this._receiver._writableState.needDrain) this._socket.resume(); } /** * Send a data message. * * @param {*} data The message to send * @param {Object} [options] Options object * @param {Boolean} [options.binary] Specifies whether `data` is binary or * text * @param {Boolean} [options.compress] Specifies whether or not to compress * `data` * @param {Boolean} [options.fin=true] Specifies whether the fragment is the * last one * @param {Boolean} [options.mask] Specifies whether or not to mask `data` * @param {Function} [cb] Callback which is executed when data is written out * @public */ send(data, options, cb) { if (this.readyState === WebSocket.CONNECTING) { throw new Error("WebSocket is not open: readyState 0 (CONNECTING)"); } if (typeof options === "function") { cb = options; options = {}; } if (typeof data === "number") data = data.toString(); if (this.readyState !== WebSocket.OPEN) { sendAfterClose(this, data, cb); return; } const opts = { binary: typeof data !== "string", mask: !this._isServer, compress: true, fin: true, ...options }; if (!this._extensions[PerMessageDeflate.extensionName]) { opts.compress = false; } this._sender.send(data || EMPTY_BUFFER, opts, cb); } /** * Forcibly close the connection. * * @public */ terminate() { if (this.readyState === WebSocket.CLOSED) return; if (this.readyState === WebSocket.CONNECTING) { const msg = "WebSocket was closed before the connection was established"; abortHandshake(this, this._req, msg); return; } if (this._socket) { this._readyState = WebSocket.CLOSING; this._socket.destroy(); } } }; /** * @constant {Number} CONNECTING * @memberof WebSocket */ Object.defineProperty(WebSocket, "CONNECTING", { enumerable: true, value: readyStates.indexOf("CONNECTING") }); /** * @constant {Number} CONNECTING * @memberof WebSocket.prototype */ Object.defineProperty(WebSocket.prototype, "CONNECTING", { enumerable: true, value: readyStates.indexOf("CONNECTING") }); /** * @constant {Number} OPEN * @memberof WebSocket */ Object.defineProperty(WebSocket, "OPEN", { enumerable: true, value: readyStates.indexOf("OPEN") }); /** * @constant {Number} OPEN * @memberof WebSocket.prototype */ Object.defineProperty(WebSocket.prototype, "OPEN", { enumerable: true, value: readyStates.indexOf("OPEN") }); /** * @constant {Number} CLOSING * @memberof WebSocket */ Object.defineProperty(WebSocket, "CLOSING", { enumerable: true, value: readyStates.indexOf("CLOSING") }); /** * @constant {Number} CLOSING * @memberof WebSocket.prototype */ Object.defineProperty(WebSocket.prototype, "CLOSING", { enumerable: true, value: readyStates.indexOf("CLOSING") }); /** * @constant {Number} CLOSED * @memberof WebSocket */ Object.defineProperty(WebSocket, "CLOSED", { enumerable: true, value: readyStates.indexOf("CLOSED") }); /** * @constant {Number} CLOSED * @memberof WebSocket.prototype */ Object.defineProperty(WebSocket.prototype, "CLOSED", { enumerable: true, value: readyStates.indexOf("CLOSED") }); [ "binaryType", "bufferedAmount", "extensions", "isPaused", "protocol", "readyState", "url" ].forEach((property) => { Object.defineProperty(WebSocket.prototype, property, { enumerable: true }); }); [ "open", "error", "close", "message" ].forEach((method) => { Object.defineProperty(WebSocket.prototype, `on${method}`, { enumerable: true, get() { for (const listener of this.listeners(method)) { if (listener[kForOnEventAttribute]) return listener[kListener]; } return null; }, set(handler) { for (const listener of this.listeners(method)) { if (listener[kForOnEventAttribute]) { this.removeListener(method, listener); break; } } if (typeof handler !== "function") return; this.addEventListener(method, handler, { [kForOnEventAttribute]: true }); } }); }); WebSocket.prototype.addEventListener = addEventListener; WebSocket.prototype.removeEventListener = removeEventListener; module.exports = WebSocket; /** * Initialize a WebSocket client. * * @param {WebSocket} websocket The client to initialize * @param {(String|URL)} address The URL to which to connect * @param {Array} protocols The subprotocols * @param {Object} [options] Connection options * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether any * of the `'message'`, `'ping'`, and `'pong'` events can be emitted multiple * times in the same tick * @param {Boolean} [options.autoPong=true] Specifies whether or not to * automatically send a pong in response to a ping * @param {Function} [options.finishRequest] A function which can be used to * customize the headers of each http request before it is sent * @param {Boolean} [options.followRedirects=false] Whether or not to follow * redirects * @param {Function} [options.generateMask] The function used to generate the * masking key * @param {Number} [options.handshakeTimeout] Timeout in milliseconds for the * handshake request * @param {Number} [options.maxPayload=104857600] The maximum allowed message * size * @param {Number} [options.maxRedirects=10] The maximum number of redirects * allowed * @param {String} [options.origin] Value of the `Origin` or * `Sec-WebSocket-Origin` header * @param {(Boolean|Object)} [options.perMessageDeflate=true] Enable/disable * permessage-deflate * @param {Number} [options.protocolVersion=13] Value of the * `Sec-WebSocket-Version` header * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or * not to skip UTF-8 validation for text and close messages * @private */ function initAsClient(websocket, address, protocols, options) { const opts = { allowSynchronousEvents: true, autoPong: true, protocolVersion: protocolVersions[1], maxPayload: 100 * 1024 * 1024, skipUTF8Validation: false, perMessageDeflate: true, followRedirects: false, maxRedirects: 10, ...options, socketPath: undefined, hostname: undefined, protocol: undefined, timeout: undefined, method: "GET", host: undefined, path: undefined, port: undefined }; websocket._autoPong = opts.autoPong; if (!protocolVersions.includes(opts.protocolVersion)) { throw new RangeError(`Unsupported protocol version: ${opts.protocolVersion} ` + `(supported versions: ${protocolVersions.join(", ")})`); } let parsedUrl; if (address instanceof URL$2) { parsedUrl = address; } else { try { parsedUrl = new URL$2(address); } catch (e) { throw new SyntaxError(`Invalid URL: ${address}`); } } if (parsedUrl.protocol === "http:") { parsedUrl.protocol = "ws:"; } else if (parsedUrl.protocol === "https:") { parsedUrl.protocol = "wss:"; } websocket._url = parsedUrl.href; const isSecure = parsedUrl.protocol === "wss:"; const isIpcUrl = parsedUrl.protocol === "ws+unix:"; let invalidUrlMessage; if (parsedUrl.protocol !== "ws:" && !isSecure && !isIpcUrl) { invalidUrlMessage = "The URL's protocol must be one of \"ws:\", \"wss:\", " + "\"http:\", \"https:\", or \"ws+unix:\""; } else if (isIpcUrl && !parsedUrl.pathname) { invalidUrlMessage = "The URL's pathname is empty"; } else if (parsedUrl.hash) { invalidUrlMessage = "The URL contains a fragment identifier"; } if (invalidUrlMessage) { const err = new SyntaxError(invalidUrlMessage); if (websocket._redirects === 0) { throw err; } else { emitErrorAndClose(websocket, err); return; } } const defaultPort = isSecure ? 443 : 80; const key = randomBytes(16).toString("base64"); const request = isSecure ? https$6.request : http$12.request; const protocolSet = new Set(); let perMessageDeflate; opts.createConnection = opts.createConnection || (isSecure ? tlsConnect : netConnect); opts.defaultPort = opts.defaultPort || defaultPort; opts.port = parsedUrl.port || defaultPort; opts.host = parsedUrl.hostname.startsWith("[") ? parsedUrl.hostname.slice(1, -1) : parsedUrl.hostname; opts.headers = { ...opts.headers, "Sec-WebSocket-Version": opts.protocolVersion, "Sec-WebSocket-Key": key, Connection: "Upgrade", Upgrade: "websocket" }; opts.path = parsedUrl.pathname + parsedUrl.search; opts.timeout = opts.handshakeTimeout; if (opts.perMessageDeflate) { perMessageDeflate = new PerMessageDeflate(opts.perMessageDeflate !== true ? opts.perMessageDeflate : {}, false, opts.maxPayload); opts.headers["Sec-WebSocket-Extensions"] = format({ [PerMessageDeflate.extensionName]: perMessageDeflate.offer() }); } if (protocols.length) { for (const protocol of protocols) { if (typeof protocol !== "string" || !subprotocolRegex.test(protocol) || protocolSet.has(protocol)) { throw new SyntaxError("An invalid or duplicated subprotocol was specified"); } protocolSet.add(protocol); } opts.headers["Sec-WebSocket-Protocol"] = protocols.join(","); } if (opts.origin) { if (opts.protocolVersion < 13) { opts.headers["Sec-WebSocket-Origin"] = opts.origin; } else { opts.headers.Origin = opts.origin; } } if (parsedUrl.username || parsedUrl.password) { opts.auth = `${parsedUrl.username}:${parsedUrl.password}`; } if (isIpcUrl) { const parts = opts.path.split(":"); opts.socketPath = parts[0]; opts.path = parts[1]; } let req; if (opts.followRedirects) { if (websocket._redirects === 0) { websocket._originalIpc = isIpcUrl; websocket._originalSecure = isSecure; websocket._originalHostOrSocketPath = isIpcUrl ? opts.socketPath : parsedUrl.host; const headers = options && options.headers; options = { ...options, headers: {} }; if (headers) { for (const [key, value] of Object.entries(headers)) { options.headers[key.toLowerCase()] = value; } } } else if (websocket.listenerCount("redirect") === 0) { const isSameHost = isIpcUrl ? websocket._originalIpc ? opts.socketPath === websocket._originalHostOrSocketPath : false : websocket._originalIpc ? false : parsedUrl.host === websocket._originalHostOrSocketPath; if (!isSameHost || websocket._originalSecure && !isSecure) { delete opts.headers.authorization; delete opts.headers.cookie; if (!isSameHost) delete opts.headers.host; opts.auth = undefined; } } if (opts.auth && !options.headers.authorization) { options.headers.authorization = "Basic " + Buffer.from(opts.auth).toString("base64"); } req = websocket._req = request(opts); if (websocket._redirects) { websocket.emit("redirect", websocket.url, req); } } else { req = websocket._req = request(opts); } if (opts.timeout) { req.on("timeout", () => { abortHandshake(websocket, req, "Opening handshake has timed out"); }); } req.on("error", (err) => { if (req === null || req[kAborted]) return; req = websocket._req = null; emitErrorAndClose(websocket, err); }); req.on("response", (res) => { const location = res.headers.location; const statusCode = res.statusCode; if (location && opts.followRedirects && statusCode >= 300 && statusCode < 400) { if (++websocket._redirects > opts.maxRedirects) { abortHandshake(websocket, req, "Maximum redirects exceeded"); return; } req.abort(); let addr; try { addr = new URL$2(location, address); } catch (e) { const err = new SyntaxError(`Invalid URL: ${location}`); emitErrorAndClose(websocket, err); return; } initAsClient(websocket, addr, protocols, options); } else if (!websocket.emit("unexpected-response", req, res)) { abortHandshake(websocket, req, `Unexpected server response: ${res.statusCode}`); } }); req.on("upgrade", (res, socket, head) => { websocket.emit("upgrade", res); if (websocket.readyState !== WebSocket.CONNECTING) return; req = websocket._req = null; const upgrade = res.headers.upgrade; if (upgrade === undefined || upgrade.toLowerCase() !== "websocket") { abortHandshake(websocket, socket, "Invalid Upgrade header"); return; } const digest = createHash$2("sha1").update(key + GUID).digest("base64"); if (res.headers["sec-websocket-accept"] !== digest) { abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header"); return; } const serverProt = res.headers["sec-websocket-protocol"]; let protError; if (serverProt !== undefined) { if (!protocolSet.size) { protError = "Server sent a subprotocol but none was requested"; } else if (!protocolSet.has(serverProt)) { protError = "Server sent an invalid subprotocol"; } } else if (protocolSet.size) { protError = "Server sent no subprotocol"; } if (protError) { abortHandshake(websocket, socket, protError); return; } if (serverProt) websocket._protocol = serverProt; const secWebSocketExtensions = res.headers["sec-websocket-extensions"]; if (secWebSocketExtensions !== undefined) { if (!perMessageDeflate) { const message = "Server sent a Sec-WebSocket-Extensions header but no extension " + "was requested"; abortHandshake(websocket, socket, message); return; } let extensions; try { extensions = parse(secWebSocketExtensions); } catch (err) { const message = "Invalid Sec-WebSocket-Extensions header"; abortHandshake(websocket, socket, message); return; } const extensionNames = Object.keys(extensions); if (extensionNames.length !== 1 || extensionNames[0] !== PerMessageDeflate.extensionName) { const message = "Server indicated an extension that was not requested"; abortHandshake(websocket, socket, message); return; } try { perMessageDeflate.accept(extensions[PerMessageDeflate.extensionName]); } catch (err) { const message = "Invalid Sec-WebSocket-Extensions header"; abortHandshake(websocket, socket, message); return; } websocket._extensions[PerMessageDeflate.extensionName] = perMessageDeflate; } websocket.setSocket(socket, head, { allowSynchronousEvents: opts.allowSynchronousEvents, generateMask: opts.generateMask, maxPayload: opts.maxPayload, skipUTF8Validation: opts.skipUTF8Validation }); }); if (opts.finishRequest) { opts.finishRequest(req, websocket); } else { req.end(); } } /** * Emit the `'error'` and `'close'` events. * * @param {WebSocket} websocket The WebSocket instance * @param {Error} The error to emit * @private */ function emitErrorAndClose(websocket, err) { websocket._readyState = WebSocket.CLOSING; websocket._errorEmitted = true; websocket.emit("error", err); websocket.emitClose(); } /** * Create a `net.Socket` and initiate a connection. * * @param {Object} options Connection options * @return {net.Socket} The newly created socket used to start the connection * @private */ function netConnect(options) { options.path = options.socketPath; return net$6.connect(options); } /** * Create a `tls.TLSSocket` and initiate a connection. * * @param {Object} options Connection options * @return {tls.TLSSocket} The newly created socket used to start the connection * @private */ function tlsConnect(options) { options.path = undefined; if (!options.servername && options.servername !== "") { options.servername = net$6.isIP(options.host) ? "" : options.host; } return tls$2.connect(options); } /** * Abort the handshake and emit an error. * * @param {WebSocket} websocket The WebSocket instance * @param {(http.ClientRequest|net.Socket|tls.Socket)} stream The request to * abort or the socket to destroy * @param {String} message The error message * @private */ function abortHandshake(websocket, stream, message) { websocket._readyState = WebSocket.CLOSING; const err = new Error(message); Error.captureStackTrace(err, abortHandshake); if (stream.setHeader) { stream[kAborted] = true; stream.abort(); if (stream.socket && !stream.socket.destroyed) { stream.socket.destroy(); } process.nextTick(emitErrorAndClose, websocket, err); } else { stream.destroy(err); stream.once("error", websocket.emit.bind(websocket, "error")); stream.once("close", websocket.emitClose.bind(websocket)); } } /** * Handle cases where the `ping()`, `pong()`, or `send()` methods are called * when the `readyState` attribute is `CLOSING` or `CLOSED`. * * @param {WebSocket} websocket The WebSocket instance * @param {*} [data] The data to send * @param {Function} [cb] Callback * @private */ function sendAfterClose(websocket, data, cb) { if (data) { const length = isBlob(data) ? data.size : toBuffer(data).length; if (websocket._socket) websocket._sender._bufferedBytes += length; else websocket._bufferedAmount += length; } if (cb) { const err = new Error(`WebSocket is not open: readyState ${websocket.readyState} ` + `(${readyStates[websocket.readyState]})`); process.nextTick(cb, err); } } /** * The listener of the `Receiver` `'conclude'` event. * * @param {Number} code The status code * @param {Buffer} reason The reason for closing * @private */ function receiverOnConclude(code, reason) { const websocket = this[kWebSocket]; websocket._closeFrameReceived = true; websocket._closeMessage = reason; websocket._closeCode = code; if (websocket._socket[kWebSocket] === undefined) return; websocket._socket.removeListener("data", socketOnData); process.nextTick(resume, websocket._socket); if (code === 1005) websocket.close(); else websocket.close(code, reason); } /** * The listener of the `Receiver` `'drain'` event. * * @private */ function receiverOnDrain() { const websocket = this[kWebSocket]; if (!websocket.isPaused) websocket._socket.resume(); } /** * The listener of the `Receiver` `'error'` event. * * @param {(RangeError|Error)} err The emitted error * @private */ function receiverOnError(err) { const websocket = this[kWebSocket]; if (websocket._socket[kWebSocket] !== undefined) { websocket._socket.removeListener("data", socketOnData); process.nextTick(resume, websocket._socket); websocket.close(err[kStatusCode]); } if (!websocket._errorEmitted) { websocket._errorEmitted = true; websocket.emit("error", err); } } /** * The listener of the `Receiver` `'finish'` event. * * @private */ function receiverOnFinish() { this[kWebSocket].emitClose(); } /** * The listener of the `Receiver` `'message'` event. * * @param {Buffer|ArrayBuffer|Buffer[])} data The message * @param {Boolean} isBinary Specifies whether the message is binary or not * @private */ function receiverOnMessage(data, isBinary) { this[kWebSocket].emit("message", data, isBinary); } /** * The listener of the `Receiver` `'ping'` event. * * @param {Buffer} data The data included in the ping frame * @private */ function receiverOnPing(data) { const websocket = this[kWebSocket]; if (websocket._autoPong) websocket.pong(data, !this._isServer, NOOP); websocket.emit("ping", data); } /** * The listener of the `Receiver` `'pong'` event. * * @param {Buffer} data The data included in the pong frame * @private */ function receiverOnPong(data) { this[kWebSocket].emit("pong", data); } /** * Resume a readable stream * * @param {Readable} stream The readable stream * @private */ function resume(stream) { stream.resume(); } /** * The `Sender` error event handler. * * @param {Error} The error * @private */ function senderOnError(err) { const websocket = this[kWebSocket]; if (websocket.readyState === WebSocket.CLOSED) return; if (websocket.readyState === WebSocket.OPEN) { websocket._readyState = WebSocket.CLOSING; setCloseTimer(websocket); } this._socket.end(); if (!websocket._errorEmitted) { websocket._errorEmitted = true; websocket.emit("error", err); } } /** * Set a timer to destroy the underlying raw socket of a WebSocket. * * @param {WebSocket} websocket The WebSocket instance * @private */ function setCloseTimer(websocket) { websocket._closeTimer = setTimeout(websocket._socket.destroy.bind(websocket._socket), closeTimeout); } /** * The listener of the socket `'close'` event. * * @private */ function socketOnClose() { const websocket = this[kWebSocket]; this.removeListener("close", socketOnClose); this.removeListener("data", socketOnData); this.removeListener("end", socketOnEnd); websocket._readyState = WebSocket.CLOSING; let chunk; if (!this._readableState.endEmitted && !websocket._closeFrameReceived && !websocket._receiver._writableState.errorEmitted && (chunk = websocket._socket.read()) !== null) { websocket._receiver.write(chunk); } websocket._receiver.end(); this[kWebSocket] = undefined; clearTimeout(websocket._closeTimer); if (websocket._receiver._writableState.finished || websocket._receiver._writableState.errorEmitted) { websocket.emitClose(); } else { websocket._receiver.on("error", receiverOnFinish); websocket._receiver.on("finish", receiverOnFinish); } } /** * The listener of the socket `'data'` event. * * @param {Buffer} chunk A chunk of data * @private */ function socketOnData(chunk) { if (!this[kWebSocket]._receiver.write(chunk)) { this.pause(); } } /** * The listener of the socket `'end'` event. * * @private */ function socketOnEnd() { const websocket = this[kWebSocket]; websocket._readyState = WebSocket.CLOSING; websocket._receiver.end(); this.end(); } /** * The listener of the socket `'error'` event. * * @private */ function socketOnError() { const websocket = this[kWebSocket]; this.removeListener("error", socketOnError); this.on("error", NOOP); if (websocket) { websocket._readyState = WebSocket.CLOSING; this.destroy(); } } })); //#endregion //#region ../node_modules/ws/lib/stream.js var require_stream = /* @__PURE__ */ __commonJSMin(((exports, module) => { const WebSocket = require_websocket$1(); const { Duplex: Duplex$2 } = __require("stream"); /** * Emits the `'close'` event on a stream. * * @param {Duplex} stream The stream. * @private */ function emitClose(stream) { stream.emit("close"); } /** * The listener of the `'end'` event. * * @private */ function duplexOnEnd() { if (!this.destroyed && this._writableState.finished) { this.destroy(); } } /** * The listener of the `'error'` event. * * @param {Error} err The error * @private */ function duplexOnError(err) { this.removeListener("error", duplexOnError); this.destroy(); if (this.listenerCount("error") === 0) { this.emit("error", err); } } /** * Wraps a `WebSocket` in a duplex stream. * * @param {WebSocket} ws The `WebSocket` to wrap * @param {Object} [options] The options for the `Duplex` constructor * @return {Duplex} The duplex stream * @public */ function createWebSocketStream(ws, options) { let terminateOnDestroy = true; const duplex = new Duplex$2({ ...options, autoDestroy: false, emitClose: false, objectMode: false, writableObjectMode: false }); ws.on("message", function message(msg, isBinary) { const data = !isBinary && duplex._readableState.objectMode ? msg.toString() : msg; if (!duplex.push(data)) ws.pause(); }); ws.once("error", function error(err) { if (duplex.destroyed) return; terminateOnDestroy = false; duplex.destroy(err); }); ws.once("close", function close() { if (duplex.destroyed) return; duplex.push(null); }); duplex._destroy = function(err, callback) { if (ws.readyState === ws.CLOSED) { callback(err); process.nextTick(emitClose, duplex); return; } let called = false; ws.once("error", function error(err) { called = true; callback(err); }); ws.once("close", function close() { if (!called) callback(err); process.nextTick(emitClose, duplex); }); if (terminateOnDestroy) ws.terminate(); }; duplex._final = function(callback) { if (ws.readyState === ws.CONNECTING) { ws.once("open", function open() { duplex._final(callback); }); return; } if (ws._socket === null) return; if (ws._socket._writableState.finished) { callback(); if (duplex._readableState.endEmitted) duplex.destroy(); } else { ws._socket.once("finish", function finish() { callback(); }); ws.close(); } }; duplex._read = function() { if (ws.isPaused) ws.resume(); }; duplex._write = function(chunk, encoding, callback) { if (ws.readyState === ws.CONNECTING) { ws.once("open", function open() { duplex._write(chunk, encoding, callback); }); return; } ws.send(chunk, callback); }; duplex.on("end", duplexOnEnd); duplex.on("error", duplexOnError); return duplex; } module.exports = createWebSocketStream; })); //#endregion //#region ../node_modules/ws/lib/subprotocol.js var require_subprotocol = /* @__PURE__ */ __commonJSMin(((exports, module) => { const { tokenChars } = require_validation$2(); /** * Parses the `Sec-WebSocket-Protocol` header into a set of subprotocol names. * * @param {String} header The field value of the header * @return {Set} The subprotocol names * @public */ function parse(header) { const protocols = new Set(); let start = -1; let end = -1; let i = 0; for (i; i < header.length; i++) { const code = header.charCodeAt(i); if (end === -1 && tokenChars[code] === 1) { if (start === -1) start = i; } else if (i !== 0 && (code === 32 || code === 9)) { if (end === -1 && start !== -1) end = i; } else if (code === 44) { if (start === -1) { throw new SyntaxError(`Unexpected character at index ${i}`); } if (end === -1) end = i; const protocol = header.slice(start, end); if (protocols.has(protocol)) { throw new SyntaxError(`The "${protocol}" subprotocol is duplicated`); } protocols.add(protocol); start = end = -1; } else { throw new SyntaxError(`Unexpected character at index ${i}`); } } if (start === -1 || end !== -1) { throw new SyntaxError("Unexpected end of input"); } const protocol = header.slice(start, i); if (protocols.has(protocol)) { throw new SyntaxError(`The "${protocol}" subprotocol is duplicated`); } protocols.add(protocol); return protocols; } module.exports = { parse }; })); //#endregion //#region ../node_modules/ws/lib/websocket-server.js var require_websocket_server = /* @__PURE__ */ __commonJSMin(((exports, module) => { const EventEmitter$9 = __require("events"); const http$11 = __require("http"); const { Duplex: Duplex$1 } = __require("stream"); const { createHash: createHash$1 } = __require("crypto"); const extension = require_extension(); const PerMessageDeflate = require_permessage_deflate$1(); const subprotocol = require_subprotocol(); const WebSocket = require_websocket$1(); const { GUID, kWebSocket } = require_constants$7(); const keyRegex = /^[+/0-9A-Za-z]{22}==$/; const RUNNING = 0; const CLOSING = 1; const CLOSED = 2; /** * Class representing a WebSocket server. * * @extends EventEmitter */ var WebSocketServer = class extends EventEmitter$9 { /** * Create a `WebSocketServer` instance. * * @param {Object} options Configuration options * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted * multiple times in the same tick * @param {Boolean} [options.autoPong=true] Specifies whether or not to * automatically send a pong in response to a ping * @param {Number} [options.backlog=511] The maximum length of the queue of * pending connections * @param {Boolean} [options.clientTracking=true] Specifies whether or not to * track clients * @param {Function} [options.handleProtocols] A hook to handle protocols * @param {String} [options.host] The hostname where to bind the server * @param {Number} [options.maxPayload=104857600] The maximum allowed message * size * @param {Boolean} [options.noServer=false] Enable no server mode * @param {String} [options.path] Accept only connections matching this path * @param {(Boolean|Object)} [options.perMessageDeflate=false] Enable/disable * permessage-deflate * @param {Number} [options.port] The port where to bind the server * @param {(http.Server|https.Server)} [options.server] A pre-created HTTP/S * server to use * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or * not to skip UTF-8 validation for text and close messages * @param {Function} [options.verifyClient] A hook to reject connections * @param {Function} [options.WebSocket=WebSocket] Specifies the `WebSocket` * class to use. It must be the `WebSocket` class or class that extends it * @param {Function} [callback] A listener for the `listening` event */ constructor(options, callback) { super(); options = { allowSynchronousEvents: true, autoPong: true, maxPayload: 100 * 1024 * 1024, skipUTF8Validation: false, perMessageDeflate: false, handleProtocols: null, clientTracking: true, verifyClient: null, noServer: false, backlog: null, server: null, host: null, path: null, port: null, WebSocket, ...options }; if (options.port == null && !options.server && !options.noServer || options.port != null && (options.server || options.noServer) || options.server && options.noServer) { throw new TypeError("One and only one of the \"port\", \"server\", or \"noServer\" options " + "must be specified"); } if (options.port != null) { this._server = http$11.createServer((req, res) => { const body = http$11.STATUS_CODES[426]; res.writeHead(426, { "Content-Length": body.length, "Content-Type": "text/plain" }); res.end(body); }); this._server.listen(options.port, options.host, options.backlog, callback); } else if (options.server) { this._server = options.server; } if (this._server) { const emitConnection = this.emit.bind(this, "connection"); this._removeListeners = addListeners(this._server, { listening: this.emit.bind(this, "listening"), error: this.emit.bind(this, "error"), upgrade: (req, socket, head) => { this.handleUpgrade(req, socket, head, emitConnection); } }); } if (options.perMessageDeflate === true) options.perMessageDeflate = {}; if (options.clientTracking) { this.clients = new Set(); this._shouldEmitClose = false; } this.options = options; this._state = RUNNING; } /** * Returns the bound address, the address family name, and port of the server * as reported by the operating system if listening on an IP socket. * If the server is listening on a pipe or UNIX domain socket, the name is * returned as a string. * * @return {(Object|String|null)} The address of the server * @public */ address() { if (this.options.noServer) { throw new Error("The server is operating in \"noServer\" mode"); } if (!this._server) return null; return this._server.address(); } /** * Stop the server from accepting new connections and emit the `'close'` event * when all existing connections are closed. * * @param {Function} [cb] A one-time listener for the `'close'` event * @public */ close(cb) { if (this._state === CLOSED) { if (cb) { this.once("close", () => { cb(new Error("The server is not running")); }); } process.nextTick(emitClose, this); return; } if (cb) this.once("close", cb); if (this._state === CLOSING) return; this._state = CLOSING; if (this.options.noServer || this.options.server) { if (this._server) { this._removeListeners(); this._removeListeners = this._server = null; } if (this.clients) { if (!this.clients.size) { process.nextTick(emitClose, this); } else { this._shouldEmitClose = true; } } else { process.nextTick(emitClose, this); } } else { const server = this._server; this._removeListeners(); this._removeListeners = this._server = null; server.close(() => { emitClose(this); }); } } /** * See if a given request should be handled by this server instance. * * @param {http.IncomingMessage} req Request object to inspect * @return {Boolean} `true` if the request is valid, else `false` * @public */ shouldHandle(req) { if (this.options.path) { const index = req.url.indexOf("?"); const pathname = index !== -1 ? req.url.slice(0, index) : req.url; if (pathname !== this.options.path) return false; } return true; } /** * Handle a HTTP Upgrade request. * * @param {http.IncomingMessage} req The request object * @param {Duplex} socket The network socket between the server and client * @param {Buffer} head The first packet of the upgraded stream * @param {Function} cb Callback * @public */ handleUpgrade(req, socket, head, cb) { socket.on("error", socketOnError); const key = req.headers["sec-websocket-key"]; const upgrade = req.headers.upgrade; const version = +req.headers["sec-websocket-version"]; if (req.method !== "GET") { const message = "Invalid HTTP method"; abortHandshakeOrEmitwsClientError(this, req, socket, 405, message); return; } if (upgrade === undefined || upgrade.toLowerCase() !== "websocket") { const message = "Invalid Upgrade header"; abortHandshakeOrEmitwsClientError(this, req, socket, 400, message); return; } if (key === undefined || !keyRegex.test(key)) { const message = "Missing or invalid Sec-WebSocket-Key header"; abortHandshakeOrEmitwsClientError(this, req, socket, 400, message); return; } if (version !== 13 && version !== 8) { const message = "Missing or invalid Sec-WebSocket-Version header"; abortHandshakeOrEmitwsClientError(this, req, socket, 400, message, { "Sec-WebSocket-Version": "13, 8" }); return; } if (!this.shouldHandle(req)) { abortHandshake(socket, 400); return; } const secWebSocketProtocol = req.headers["sec-websocket-protocol"]; let protocols = new Set(); if (secWebSocketProtocol !== undefined) { try { protocols = subprotocol.parse(secWebSocketProtocol); } catch (err) { const message = "Invalid Sec-WebSocket-Protocol header"; abortHandshakeOrEmitwsClientError(this, req, socket, 400, message); return; } } const secWebSocketExtensions = req.headers["sec-websocket-extensions"]; const extensions = {}; if (this.options.perMessageDeflate && secWebSocketExtensions !== undefined) { const perMessageDeflate = new PerMessageDeflate(this.options.perMessageDeflate, true, this.options.maxPayload); try { const offers = extension.parse(secWebSocketExtensions); if (offers[PerMessageDeflate.extensionName]) { perMessageDeflate.accept(offers[PerMessageDeflate.extensionName]); extensions[PerMessageDeflate.extensionName] = perMessageDeflate; } } catch (err) { const message = "Invalid or unacceptable Sec-WebSocket-Extensions header"; abortHandshakeOrEmitwsClientError(this, req, socket, 400, message); return; } } if (this.options.verifyClient) { const info = { origin: req.headers[`${version === 8 ? "sec-websocket-origin" : "origin"}`], secure: !!(req.socket.authorized || req.socket.encrypted), req }; if (this.options.verifyClient.length === 2) { this.options.verifyClient(info, (verified, code, message, headers) => { if (!verified) { return abortHandshake(socket, code || 401, message, headers); } this.completeUpgrade(extensions, key, protocols, req, socket, head, cb); }); return; } if (!this.options.verifyClient(info)) return abortHandshake(socket, 401); } this.completeUpgrade(extensions, key, protocols, req, socket, head, cb); } /** * Upgrade the connection to WebSocket. * * @param {Object} extensions The accepted extensions * @param {String} key The value of the `Sec-WebSocket-Key` header * @param {Set} protocols The subprotocols * @param {http.IncomingMessage} req The request object * @param {Duplex} socket The network socket between the server and client * @param {Buffer} head The first packet of the upgraded stream * @param {Function} cb Callback * @throws {Error} If called more than once with the same socket * @private */ completeUpgrade(extensions, key, protocols, req, socket, head, cb) { if (!socket.readable || !socket.writable) return socket.destroy(); if (socket[kWebSocket]) { throw new Error("server.handleUpgrade() was called more than once with the same " + "socket, possibly due to a misconfiguration"); } if (this._state > RUNNING) return abortHandshake(socket, 503); const digest = createHash$1("sha1").update(key + GUID).digest("base64"); const headers = [ "HTTP/1.1 101 Switching Protocols", "Upgrade: websocket", "Connection: Upgrade", `Sec-WebSocket-Accept: ${digest}` ]; const ws = new this.options.WebSocket(null, undefined, this.options); if (protocols.size) { const protocol = this.options.handleProtocols ? this.options.handleProtocols(protocols, req) : protocols.values().next().value; if (protocol) { headers.push(`Sec-WebSocket-Protocol: ${protocol}`); ws._protocol = protocol; } } if (extensions[PerMessageDeflate.extensionName]) { const params = extensions[PerMessageDeflate.extensionName].params; const value = extension.format({ [PerMessageDeflate.extensionName]: [params] }); headers.push(`Sec-WebSocket-Extensions: ${value}`); ws._extensions = extensions; } this.emit("headers", headers, req); socket.write(headers.concat("\r\n").join("\r\n")); socket.removeListener("error", socketOnError); ws.setSocket(socket, head, { allowSynchronousEvents: this.options.allowSynchronousEvents, maxPayload: this.options.maxPayload, skipUTF8Validation: this.options.skipUTF8Validation }); if (this.clients) { this.clients.add(ws); ws.on("close", () => { this.clients.delete(ws); if (this._shouldEmitClose && !this.clients.size) { process.nextTick(emitClose, this); } }); } cb(ws, req); } }; module.exports = WebSocketServer; /** * Add event listeners on an `EventEmitter` using a map of * pairs. * * @param {EventEmitter} server The event emitter * @param {Object.} map The listeners to add * @return {Function} A function that will remove the added listeners when * called * @private */ function addListeners(server, map) { for (const event of Object.keys(map)) server.on(event, map[event]); return function removeListeners() { for (const event of Object.keys(map)) { server.removeListener(event, map[event]); } }; } /** * Emit a `'close'` event on an `EventEmitter`. * * @param {EventEmitter} server The event emitter * @private */ function emitClose(server) { server._state = CLOSED; server.emit("close"); } /** * Handle socket errors. * * @private */ function socketOnError() { this.destroy(); } /** * Close the connection when preconditions are not fulfilled. * * @param {Duplex} socket The socket of the upgrade request * @param {Number} code The HTTP response status code * @param {String} [message] The HTTP response body * @param {Object} [headers] Additional HTTP response headers * @private */ function abortHandshake(socket, code, message, headers) { message = message || http$11.STATUS_CODES[code]; headers = { Connection: "close", "Content-Type": "text/html", "Content-Length": Buffer.byteLength(message), ...headers }; socket.once("finish", socket.destroy); socket.end(`HTTP/1.1 ${code} ${http$11.STATUS_CODES[code]}\r\n` + Object.keys(headers).map((h) => `${h}: ${headers[h]}`).join("\r\n") + "\r\n\r\n" + message); } /** * Emit a `'wsClientError'` event on a `WebSocketServer` if there is at least * one listener for it, otherwise call `abortHandshake()`. * * @param {WebSocketServer} server The WebSocket server * @param {http.IncomingMessage} req The request object * @param {Duplex} socket The socket of the upgrade request * @param {Number} code The HTTP response status code * @param {String} message The HTTP response body * @param {Object} [headers] The HTTP response headers * @private */ function abortHandshakeOrEmitwsClientError(server, req, socket, code, message, headers) { if (server.listenerCount("wsClientError")) { const err = new Error(message); Error.captureStackTrace(err, abortHandshakeOrEmitwsClientError); server.emit("wsClientError", err, socket, req); } else { abortHandshake(socket, code, message, headers); } } })); //#endregion //#region ../node_modules/ws/wrapper.mjs var import_XMLHttpRequest = require_XMLHttpRequest(); var import_stream = /* @__PURE__ */ __toESM(require_stream(), 1); var import_receiver = /* @__PURE__ */ __toESM(require_receiver$1(), 1); var import_sender = /* @__PURE__ */ __toESM(require_sender$1(), 1); var import_websocket = /* @__PURE__ */ __toESM(require_websocket$1(), 1); var import_websocket_server = /* @__PURE__ */ __toESM(require_websocket_server(), 1); var wrapper_default = import_websocket.default; //#endregion //#region ../node_modules/bignumber.js/bignumber.mjs var bignumber_exports = /* @__PURE__ */ __exportAll({ BigNumber: () => BigNumber, default: () => BigNumber }); function clone$2(configObject) { var div, convertBase, parseNumeric, P = BigNumber.prototype = { constructor: BigNumber, toString: null, valueOf: null }, ONE = new BigNumber(1), DECIMAL_PLACES = 20, ROUNDING_MODE = 4, TO_EXP_NEG = -7, TO_EXP_POS = 21, MIN_EXP = -1e7, MAX_EXP = 1e7, CRYPTO = false, MODULO_MODE = 1, POW_PRECISION = 0, FORMAT = { prefix: "", groupSize: 3, secondaryGroupSize: 0, groupSeparator: ",", decimalSeparator: ".", fractionGroupSize: 0, fractionGroupSeparator: "\xA0", suffix: "" }, ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz", alphabetHasNormalDecimalDigits = true; function BigNumber(v, b) { var alphabet, c, caseChanged, e, i, isNum, len, str, x = this; if (!(x instanceof BigNumber)) return new BigNumber(v, b); if (b == null) { if (v && v._isBigNumber === true) { x.s = v.s; if (!v.c || v.e > MAX_EXP) { x.c = x.e = null; } else if (v.e < MIN_EXP) { x.c = [x.e = 0]; } else { x.e = v.e; x.c = v.c.slice(); } return; } if ((isNum = typeof v == "number") && v * 0 == 0) { x.s = 1 / v < 0 ? (v = -v, -1) : 1; if (v === ~~v) { for (e = 0, i = v; i >= 10; i /= 10, e++); if (e > MAX_EXP) { x.c = x.e = null; } else { x.e = e; x.c = [v]; } return; } str = String(v); } else { if (!isNumeric.test(str = String(v))) return parseNumeric(x, str, isNum); x.s = str.charCodeAt(0) == 45 ? (str = str.slice(1), -1) : 1; } if ((e = str.indexOf(".")) > -1) str = str.replace(".", ""); if ((i = str.search(/e/i)) > 0) { if (e < 0) e = i; e += +str.slice(i + 1); str = str.substring(0, i); } else if (e < 0) { e = str.length; } } else { intCheck(b, 2, ALPHABET.length, "Base"); if (b == 10 && alphabetHasNormalDecimalDigits) { x = new BigNumber(v); return round(x, DECIMAL_PLACES + x.e + 1, ROUNDING_MODE); } str = String(v); if (isNum = typeof v == "number") { if (v * 0 != 0) return parseNumeric(x, str, isNum, b); x.s = 1 / v < 0 ? (str = str.slice(1), -1) : 1; if (BigNumber.DEBUG && str.replace(/^0\.0*|\./, "").length > 15) { throw Error(tooManyDigits + v); } } else { x.s = str.charCodeAt(0) === 45 ? (str = str.slice(1), -1) : 1; } alphabet = ALPHABET.slice(0, b); e = i = 0; for (len = str.length; i < len; i++) { if (alphabet.indexOf(c = str.charAt(i)) < 0) { if (c == ".") { if (i > e) { e = len; continue; } } else if (!caseChanged) { if (str == str.toUpperCase() && (str = str.toLowerCase()) || str == str.toLowerCase() && (str = str.toUpperCase())) { caseChanged = true; i = -1; e = 0; continue; } } return parseNumeric(x, String(v), isNum, b); } } isNum = false; str = convertBase(str, b, 10, x.s); if ((e = str.indexOf(".")) > -1) str = str.replace(".", ""); else e = str.length; } for (i = 0; str.charCodeAt(i) === 48; i++); for (len = str.length; str.charCodeAt(--len) === 48;); if (str = str.slice(i, ++len)) { len -= i; if (isNum && BigNumber.DEBUG && len > 15 && (v > MAX_SAFE_INTEGER || v !== mathfloor(v))) { throw Error(tooManyDigits + x.s * v); } if ((e = e - i - 1) > MAX_EXP) { x.c = x.e = null; } else if (e < MIN_EXP) { x.c = [x.e = 0]; } else { x.e = e; x.c = []; i = (e + 1) % LOG_BASE; if (e < 0) i += LOG_BASE; if (i < len) { if (i) x.c.push(+str.slice(0, i)); for (len -= LOG_BASE; i < len;) { x.c.push(+str.slice(i, i += LOG_BASE)); } i = LOG_BASE - (str = str.slice(i)).length; } else { i -= len; } for (; i--; str += "0"); x.c.push(+str); } } else { x.c = [x.e = 0]; } } BigNumber.clone = clone$2; BigNumber.ROUND_UP = 0; BigNumber.ROUND_DOWN = 1; BigNumber.ROUND_CEIL = 2; BigNumber.ROUND_FLOOR = 3; BigNumber.ROUND_HALF_UP = 4; BigNumber.ROUND_HALF_DOWN = 5; BigNumber.ROUND_HALF_EVEN = 6; BigNumber.ROUND_HALF_CEIL = 7; BigNumber.ROUND_HALF_FLOOR = 8; BigNumber.EUCLID = 9; BigNumber.config = BigNumber.set = function(obj) { var p, v; if (obj != null) { if (typeof obj == "object") { if (obj.hasOwnProperty(p = "DECIMAL_PLACES")) { v = obj[p]; intCheck(v, 0, MAX, p); DECIMAL_PLACES = v; } if (obj.hasOwnProperty(p = "ROUNDING_MODE")) { v = obj[p]; intCheck(v, 0, 8, p); ROUNDING_MODE = v; } if (obj.hasOwnProperty(p = "EXPONENTIAL_AT")) { v = obj[p]; if (v && v.pop) { intCheck(v[0], -MAX, 0, p); intCheck(v[1], 0, MAX, p); TO_EXP_NEG = v[0]; TO_EXP_POS = v[1]; } else { intCheck(v, -MAX, MAX, p); TO_EXP_NEG = -(TO_EXP_POS = v < 0 ? -v : v); } } if (obj.hasOwnProperty(p = "RANGE")) { v = obj[p]; if (v && v.pop) { intCheck(v[0], -MAX, -1, p); intCheck(v[1], 1, MAX, p); MIN_EXP = v[0]; MAX_EXP = v[1]; } else { intCheck(v, -MAX, MAX, p); if (v) { MIN_EXP = -(MAX_EXP = v < 0 ? -v : v); } else { throw Error(bignumberError + p + " cannot be zero: " + v); } } } if (obj.hasOwnProperty(p = "CRYPTO")) { v = obj[p]; if (v === !!v) { if (v) { if (typeof crypto != "undefined" && crypto && (crypto.getRandomValues || crypto.randomBytes)) { CRYPTO = v; } else { CRYPTO = !v; throw Error(bignumberError + "crypto unavailable"); } } else { CRYPTO = v; } } else { throw Error(bignumberError + p + " not true or false: " + v); } } if (obj.hasOwnProperty(p = "MODULO_MODE")) { v = obj[p]; intCheck(v, 0, 9, p); MODULO_MODE = v; } if (obj.hasOwnProperty(p = "POW_PRECISION")) { v = obj[p]; intCheck(v, 0, MAX, p); POW_PRECISION = v; } if (obj.hasOwnProperty(p = "FORMAT")) { v = obj[p]; if (typeof v == "object") FORMAT = v; else throw Error(bignumberError + p + " not an object: " + v); } if (obj.hasOwnProperty(p = "ALPHABET")) { v = obj[p]; if (typeof v == "string" && !/^.?$|[+\-.\s]|(.).*\1/.test(v)) { alphabetHasNormalDecimalDigits = v.slice(0, 10) == "0123456789"; ALPHABET = v; } else { throw Error(bignumberError + p + " invalid: " + v); } } } else { throw Error(bignumberError + "Object expected: " + obj); } } return { DECIMAL_PLACES, ROUNDING_MODE, EXPONENTIAL_AT: [TO_EXP_NEG, TO_EXP_POS], RANGE: [MIN_EXP, MAX_EXP], CRYPTO, MODULO_MODE, POW_PRECISION, FORMAT, ALPHABET }; }; BigNumber.isBigNumber = function(v) { if (!v || v._isBigNumber !== true) return false; if (!BigNumber.DEBUG) return true; var i, n, c = v.c, e = v.e, s = v.s; out: if ({}.toString.call(c) == "[object Array]") { if ((s === 1 || s === -1) && e >= -MAX && e <= MAX && e === mathfloor(e)) { if (c[0] === 0) { if (e === 0 && c.length === 1) return true; break out; } i = (e + 1) % LOG_BASE; if (i < 1) i += LOG_BASE; if (String(c[0]).length == i) { for (i = 0; i < c.length; i++) { n = c[i]; if (n < 0 || n >= BASE || n !== mathfloor(n)) break out; } if (n !== 0) return true; } } } else if (c === null && e === null && (s === null || s === 1 || s === -1)) { return true; } throw Error(bignumberError + "Invalid BigNumber: " + v); }; BigNumber.maximum = BigNumber.max = function() { return maxOrMin(arguments, -1); }; BigNumber.minimum = BigNumber.min = function() { return maxOrMin(arguments, 1); }; BigNumber.random = (function() { var pow2_53 = 9007199254740992; var random53bitInt = Math.random() * pow2_53 & 2097151 ? function() { return mathfloor(Math.random() * pow2_53); } : function() { return (Math.random() * 1073741824 | 0) * 8388608 + (Math.random() * 8388608 | 0); }; return function(dp) { var a, b, e, k, v, i = 0, c = [], rand = new BigNumber(ONE); if (dp == null) dp = DECIMAL_PLACES; else intCheck(dp, 0, MAX); k = mathceil(dp / LOG_BASE); if (CRYPTO) { if (crypto.getRandomValues) { a = crypto.getRandomValues(new Uint32Array(k *= 2)); for (; i < k;) { v = a[i] * 131072 + (a[i + 1] >>> 11); if (v >= 9e15) { b = crypto.getRandomValues(new Uint32Array(2)); a[i] = b[0]; a[i + 1] = b[1]; } else { c.push(v % 0x5af3107a4000); i += 2; } } i = k / 2; } else if (crypto.randomBytes) { a = crypto.randomBytes(k *= 7); for (; i < k;) { v = (a[i] & 31) * 281474976710656 + a[i + 1] * 1099511627776 + a[i + 2] * 4294967296 + a[i + 3] * 16777216 + (a[i + 4] << 16) + (a[i + 5] << 8) + a[i + 6]; if (v >= 9e15) { crypto.randomBytes(7).copy(a, i); } else { c.push(v % 0x5af3107a4000); i += 7; } } i = k / 7; } else { CRYPTO = false; throw Error(bignumberError + "crypto unavailable"); } } if (!CRYPTO) { for (; i < k;) { v = random53bitInt(); if (v < 9e15) c[i++] = v % 0x5af3107a4000; } } k = c[--i]; dp %= LOG_BASE; if (k && dp) { v = POWS_TEN[LOG_BASE - dp]; c[i] = mathfloor(k / v) * v; } for (; c[i] === 0; c.pop(), i--); if (i < 0) { c = [e = 0]; } else { for (e = -1; c[0] === 0; c.splice(0, 1), e -= LOG_BASE); for (i = 1, v = c[0]; v >= 10; v /= 10, i++); if (i < LOG_BASE) e -= LOG_BASE - i; } rand.e = e; rand.c = c; return rand; }; })(); BigNumber.sum = function() { var i = 1, args = arguments, sum = new BigNumber(args[0]); for (; i < args.length;) sum = sum.plus(args[i++]); return sum; }; convertBase = (function() { var decimal = "0123456789"; function toBaseOut(str, baseIn, baseOut, alphabet) { var j, arr = [0], arrL, i = 0, len = str.length; for (; i < len;) { for (arrL = arr.length; arrL--; arr[arrL] *= baseIn); arr[0] += alphabet.indexOf(str.charAt(i++)); for (j = 0; j < arr.length; j++) { if (arr[j] > baseOut - 1) { if (arr[j + 1] == null) arr[j + 1] = 0; arr[j + 1] += arr[j] / baseOut | 0; arr[j] %= baseOut; } } } return arr.reverse(); } return function(str, baseIn, baseOut, sign, callerIsToString) { var alphabet, d, e, k, r, x, xc, y, i = str.indexOf("."), dp = DECIMAL_PLACES, rm = ROUNDING_MODE; if (i >= 0) { k = POW_PRECISION; POW_PRECISION = 0; str = str.replace(".", ""); y = new BigNumber(baseIn); x = y.pow(str.length - i); POW_PRECISION = k; y.c = toBaseOut(toFixedPoint(coeffToString(x.c), x.e, "0"), 10, baseOut, decimal); y.e = y.c.length; } xc = toBaseOut(str, baseIn, baseOut, callerIsToString ? (alphabet = ALPHABET, decimal) : (alphabet = decimal, ALPHABET)); e = k = xc.length; for (; xc[--k] == 0; xc.pop()); if (!xc[0]) return alphabet.charAt(0); if (i < 0) { --e; } else { x.c = xc; x.e = e; x.s = sign; x = div(x, y, dp, rm, baseOut); xc = x.c; r = x.r; e = x.e; } d = e + dp + 1; i = xc[d]; k = baseOut / 2; r = r || d < 0 || xc[d + 1] != null; r = rm < 4 ? (i != null || r) && (rm == 0 || rm == (x.s < 0 ? 3 : 2)) : i > k || i == k && (rm == 4 || r || rm == 6 && xc[d - 1] & 1 || rm == (x.s < 0 ? 8 : 7)); if (d < 1 || !xc[0]) { str = r ? toFixedPoint(alphabet.charAt(1), -dp, alphabet.charAt(0)) : alphabet.charAt(0); } else { xc.length = d; if (r) { for (--baseOut; ++xc[--d] > baseOut;) { xc[d] = 0; if (!d) { ++e; xc = [1].concat(xc); } } } for (k = xc.length; !xc[--k];); for (i = 0, str = ""; i <= k; str += alphabet.charAt(xc[i++])); str = toFixedPoint(str, e, alphabet.charAt(0)); } return str; }; })(); div = (function() { function multiply(x, k, base) { var m, temp, xlo, xhi, carry = 0, i = x.length, klo = k % SQRT_BASE, khi = k / SQRT_BASE | 0; for (x = x.slice(); i--;) { xlo = x[i] % SQRT_BASE; xhi = x[i] / SQRT_BASE | 0; m = khi * xlo + xhi * klo; temp = klo * xlo + m % SQRT_BASE * SQRT_BASE + carry; carry = (temp / base | 0) + (m / SQRT_BASE | 0) + khi * xhi; x[i] = temp % base; } if (carry) x = [carry].concat(x); return x; } function compare(a, b, aL, bL) { var i, cmp; if (aL != bL) { cmp = aL > bL ? 1 : -1; } else { for (i = cmp = 0; i < aL; i++) { if (a[i] != b[i]) { cmp = a[i] > b[i] ? 1 : -1; break; } } } return cmp; } function subtract(a, b, aL, base) { var i = 0; for (; aL--;) { a[aL] -= i; i = a[aL] < b[aL] ? 1 : 0; a[aL] = i * base + a[aL] - b[aL]; } for (; !a[0] && a.length > 1; a.splice(0, 1)); } return function(x, y, dp, rm, base) { var cmp, e, i, more, n, prod, prodL, q, qc, rem, remL, rem0, xi, xL, yc0, yL, yz, s = x.s == y.s ? 1 : -1, xc = x.c, yc = y.c; if (!xc || !xc[0] || !yc || !yc[0]) { return new BigNumber(!x.s || !y.s || (xc ? yc && xc[0] == yc[0] : !yc) ? NaN : xc && xc[0] == 0 || !yc ? s * 0 : s / 0); } q = new BigNumber(s); qc = q.c = []; e = x.e - y.e; s = dp + e + 1; if (!base) { base = BASE; e = bitFloor(x.e / LOG_BASE) - bitFloor(y.e / LOG_BASE); s = s / LOG_BASE | 0; } for (i = 0; yc[i] == (xc[i] || 0); i++); if (yc[i] > (xc[i] || 0)) e--; if (s < 0) { qc.push(1); more = true; } else { xL = xc.length; yL = yc.length; i = 0; s += 2; n = mathfloor(base / (yc[0] + 1)); if (n > 1) { yc = multiply(yc, n, base); xc = multiply(xc, n, base); yL = yc.length; xL = xc.length; } xi = yL; rem = xc.slice(0, yL); remL = rem.length; for (; remL < yL; rem[remL++] = 0); yz = yc.slice(); yz = [0].concat(yz); yc0 = yc[0]; if (yc[1] >= base / 2) yc0++; do { n = 0; cmp = compare(yc, rem, yL, remL); if (cmp < 0) { rem0 = rem[0]; if (yL != remL) rem0 = rem0 * base + (rem[1] || 0); n = mathfloor(rem0 / yc0); if (n > 1) { if (n >= base) n = base - 1; prod = multiply(yc, n, base); prodL = prod.length; remL = rem.length; while (compare(prod, rem, prodL, remL) == 1) { n--; subtract(prod, yL < prodL ? yz : yc, prodL, base); prodL = prod.length; cmp = 1; } } else { if (n == 0) { cmp = n = 1; } prod = yc.slice(); prodL = prod.length; } if (prodL < remL) prod = [0].concat(prod); subtract(rem, prod, remL, base); remL = rem.length; if (cmp == -1) { while (compare(yc, rem, yL, remL) < 1) { n++; subtract(rem, yL < remL ? yz : yc, remL, base); remL = rem.length; } } } else if (cmp === 0) { n++; rem = [0]; } qc[i++] = n; if (rem[0]) { rem[remL++] = xc[xi] || 0; } else { rem = [xc[xi]]; remL = 1; } } while ((xi++ < xL || rem[0] != null) && s--); more = rem[0] != null; if (!qc[0]) qc.splice(0, 1); } if (base == BASE) { for (i = 1, s = qc[0]; s >= 10; s /= 10, i++); round(q, dp + (q.e = i + e * LOG_BASE - 1) + 1, rm, more); } else { q.e = e; q.r = +more; } return q; }; })(); function format(n, i, rm, id) { var c0, e, ne, len, str; if (rm == null) rm = ROUNDING_MODE; else intCheck(rm, 0, 8); if (!n.c) return n.toString(); c0 = n.c[0]; ne = n.e; if (i == null) { str = coeffToString(n.c); str = id == 1 || id == 2 && (ne <= TO_EXP_NEG || ne >= TO_EXP_POS) ? toExponential(str, ne) : toFixedPoint(str, ne, "0"); } else { n = round(new BigNumber(n), i, rm); e = n.e; str = coeffToString(n.c); len = str.length; if (id == 1 || id == 2 && (i <= e || e <= TO_EXP_NEG)) { for (; len < i; str += "0", len++); str = toExponential(str, e); } else { i -= ne + (id === 2 && e > ne); str = toFixedPoint(str, e, "0"); if (e + 1 > len) { if (--i > 0) for (str += "."; i--; str += "0"); } else { i += e - len; if (i > 0) { if (e + 1 == len) str += "."; for (; i--; str += "0"); } } } } return n.s < 0 && c0 ? "-" + str : str; } function maxOrMin(args, n) { var k, y, i = 1, x = new BigNumber(args[0]); for (; i < args.length; i++) { y = new BigNumber(args[i]); if (!y.s || (k = compare(x, y)) === n || k === 0 && x.s === n) { x = y; } } return x; } function normalise(n, c, e) { var i = 1, j = c.length; for (; !c[--j]; c.pop()); for (j = c[0]; j >= 10; j /= 10, i++); if ((e = i + e * LOG_BASE - 1) > MAX_EXP) { n.c = n.e = null; } else if (e < MIN_EXP) { n.c = [n.e = 0]; } else { n.e = e; n.c = c; } return n; } parseNumeric = (function() { var basePrefix = /^(-?)0([xbo])(?=\w[\w.]*$)/i, dotAfter = /^([^.]+)\.$/, dotBefore = /^\.([^.]+)$/, isInfinityOrNaN = /^-?(Infinity|NaN)$/, whitespaceOrPlus = /^\s*\+(?=[\w.])|^\s+|\s+$/g; return function(x, str, isNum, b) { var base, s = isNum ? str : str.replace(whitespaceOrPlus, ""); if (isInfinityOrNaN.test(s)) { x.s = isNaN(s) ? null : s < 0 ? -1 : 1; } else { if (!isNum) { s = s.replace(basePrefix, function(m, p1, p2) { base = (p2 = p2.toLowerCase()) == "x" ? 16 : p2 == "b" ? 2 : 8; return !b || b == base ? p1 : m; }); if (b) { base = b; s = s.replace(dotAfter, "$1").replace(dotBefore, "0.$1"); } if (str != s) return new BigNumber(s, base); } if (BigNumber.DEBUG) { throw Error(bignumberError + "Not a" + (b ? " base " + b : "") + " number: " + str); } x.s = null; } x.c = x.e = null; }; })(); function round(x, sd, rm, r) { var d, i, j, k, n, ni, rd, xc = x.c, pows10 = POWS_TEN; if (xc) { out: { for (d = 1, k = xc[0]; k >= 10; k /= 10, d++); i = sd - d; if (i < 0) { i += LOG_BASE; j = sd; n = xc[ni = 0]; rd = mathfloor(n / pows10[d - j - 1] % 10); } else { ni = mathceil((i + 1) / LOG_BASE); if (ni >= xc.length) { if (r) { for (; xc.length <= ni; xc.push(0)); n = rd = 0; d = 1; i %= LOG_BASE; j = i - LOG_BASE + 1; } else { break out; } } else { n = k = xc[ni]; for (d = 1; k >= 10; k /= 10, d++); i %= LOG_BASE; j = i - LOG_BASE + d; rd = j < 0 ? 0 : mathfloor(n / pows10[d - j - 1] % 10); } } r = r || sd < 0 || xc[ni + 1] != null || (j < 0 ? n : n % pows10[d - j - 1]); r = rm < 4 ? (rd || r) && (rm == 0 || rm == (x.s < 0 ? 3 : 2)) : rd > 5 || rd == 5 && (rm == 4 || r || rm == 6 && (i > 0 ? j > 0 ? n / pows10[d - j] : 0 : xc[ni - 1]) % 10 & 1 || rm == (x.s < 0 ? 8 : 7)); if (sd < 1 || !xc[0]) { xc.length = 0; if (r) { sd -= x.e + 1; xc[0] = pows10[(LOG_BASE - sd % LOG_BASE) % LOG_BASE]; x.e = -sd || 0; } else { xc[0] = x.e = 0; } return x; } if (i == 0) { xc.length = ni; k = 1; ni--; } else { xc.length = ni + 1; k = pows10[LOG_BASE - i]; xc[ni] = j > 0 ? mathfloor(n / pows10[d - j] % pows10[j]) * k : 0; } if (r) { for (;;) { if (ni == 0) { for (i = 1, j = xc[0]; j >= 10; j /= 10, i++); j = xc[0] += k; for (k = 1; j >= 10; j /= 10, k++); if (i != k) { x.e++; if (xc[0] == BASE) xc[0] = 1; } break; } else { xc[ni] += k; if (xc[ni] != BASE) break; xc[ni--] = 0; k = 1; } } } for (i = xc.length; xc[--i] === 0; xc.pop()); } if (x.e > MAX_EXP) { x.c = x.e = null; } else if (x.e < MIN_EXP) { x.c = [x.e = 0]; } } return x; } function valueOf(n) { var str, e = n.e; if (e === null) return n.toString(); str = coeffToString(n.c); str = e <= TO_EXP_NEG || e >= TO_EXP_POS ? toExponential(str, e) : toFixedPoint(str, e, "0"); return n.s < 0 ? "-" + str : str; } P.absoluteValue = P.abs = function() { var x = new BigNumber(this); if (x.s < 0) x.s = 1; return x; }; P.comparedTo = function(y, b) { return compare(this, new BigNumber(y, b)); }; P.decimalPlaces = P.dp = function(dp, rm) { var c, n, v, x = this; if (dp != null) { intCheck(dp, 0, MAX); if (rm == null) rm = ROUNDING_MODE; else intCheck(rm, 0, 8); return round(new BigNumber(x), dp + x.e + 1, rm); } if (!(c = x.c)) return null; n = ((v = c.length - 1) - bitFloor(this.e / LOG_BASE)) * LOG_BASE; if (v = c[v]) for (; v % 10 == 0; v /= 10, n--); if (n < 0) n = 0; return n; }; P.dividedBy = P.div = function(y, b) { return div(this, new BigNumber(y, b), DECIMAL_PLACES, ROUNDING_MODE); }; P.dividedToIntegerBy = P.idiv = function(y, b) { return div(this, new BigNumber(y, b), 0, 1); }; P.exponentiatedBy = P.pow = function(n, m) { var half, isModExp, i, k, more, nIsBig, nIsNeg, nIsOdd, y, x = this; n = new BigNumber(n); if (n.c && !n.isInteger()) { throw Error(bignumberError + "Exponent not an integer: " + valueOf(n)); } if (m != null) m = new BigNumber(m); nIsBig = n.e > 14; if (!x.c || !x.c[0] || x.c[0] == 1 && !x.e && x.c.length == 1 || !n.c || !n.c[0]) { y = new BigNumber(Math.pow(+valueOf(x), nIsBig ? n.s * (2 - isOdd(n)) : +valueOf(n))); return m ? y.mod(m) : y; } nIsNeg = n.s < 0; if (m) { if (m.c ? !m.c[0] : !m.s) return new BigNumber(NaN); isModExp = !nIsNeg && x.isInteger() && m.isInteger(); if (isModExp) x = x.mod(m); } else if (n.e > 9 && (x.e > 0 || x.e < -1 || (x.e == 0 ? x.c[0] > 1 || nIsBig && x.c[1] >= 24e7 : x.c[0] < 8e13 || nIsBig && x.c[0] <= 9999975e7))) { k = x.s < 0 && isOdd(n) ? -0 : 0; if (x.e > -1) k = 1 / k; return new BigNumber(nIsNeg ? 1 / k : k); } else if (POW_PRECISION) { k = mathceil(POW_PRECISION / LOG_BASE + 2); } if (nIsBig) { half = new BigNumber(.5); if (nIsNeg) n.s = 1; nIsOdd = isOdd(n); } else { i = Math.abs(+valueOf(n)); nIsOdd = i % 2; } y = new BigNumber(ONE); for (;;) { if (nIsOdd) { y = y.times(x); if (!y.c) break; if (k) { if (y.c.length > k) y.c.length = k; } else if (isModExp) { y = y.mod(m); } } if (i) { i = mathfloor(i / 2); if (i === 0) break; nIsOdd = i % 2; } else { n = n.times(half); round(n, n.e + 1, 1); if (n.e > 14) { nIsOdd = isOdd(n); } else { i = +valueOf(n); if (i === 0) break; nIsOdd = i % 2; } } x = x.times(x); if (k) { if (x.c && x.c.length > k) x.c.length = k; } else if (isModExp) { x = x.mod(m); } } if (isModExp) return y; if (nIsNeg) y = ONE.div(y); return m ? y.mod(m) : k ? round(y, POW_PRECISION, ROUNDING_MODE, more) : y; }; P.integerValue = function(rm) { var n = new BigNumber(this); if (rm == null) rm = ROUNDING_MODE; else intCheck(rm, 0, 8); return round(n, n.e + 1, rm); }; P.isEqualTo = P.eq = function(y, b) { return compare(this, new BigNumber(y, b)) === 0; }; P.isFinite = function() { return !!this.c; }; P.isGreaterThan = P.gt = function(y, b) { return compare(this, new BigNumber(y, b)) > 0; }; P.isGreaterThanOrEqualTo = P.gte = function(y, b) { return (b = compare(this, new BigNumber(y, b))) === 1 || b === 0; }; P.isInteger = function() { return !!this.c && bitFloor(this.e / LOG_BASE) > this.c.length - 2; }; P.isLessThan = P.lt = function(y, b) { return compare(this, new BigNumber(y, b)) < 0; }; P.isLessThanOrEqualTo = P.lte = function(y, b) { return (b = compare(this, new BigNumber(y, b))) === -1 || b === 0; }; P.isNaN = function() { return !this.s; }; P.isNegative = function() { return this.s < 0; }; P.isPositive = function() { return this.s > 0; }; P.isZero = function() { return !!this.c && this.c[0] == 0; }; P.minus = function(y, b) { var i, j, t, xLTy, x = this, a = x.s; y = new BigNumber(y, b); b = y.s; if (!a || !b) return new BigNumber(NaN); if (a != b) { y.s = -b; return x.plus(y); } var xe = x.e / LOG_BASE, ye = y.e / LOG_BASE, xc = x.c, yc = y.c; if (!xe || !ye) { if (!xc || !yc) return xc ? (y.s = -b, y) : new BigNumber(yc ? x : NaN); if (!xc[0] || !yc[0]) { return yc[0] ? (y.s = -b, y) : new BigNumber(xc[0] ? x : ROUNDING_MODE == 3 ? -0 : 0); } } xe = bitFloor(xe); ye = bitFloor(ye); xc = xc.slice(); if (a = xe - ye) { if (xLTy = a < 0) { a = -a; t = xc; } else { ye = xe; t = yc; } t.reverse(); for (b = a; b--; t.push(0)); t.reverse(); } else { j = (xLTy = (a = xc.length) < (b = yc.length)) ? a : b; for (a = b = 0; b < j; b++) { if (xc[b] != yc[b]) { xLTy = xc[b] < yc[b]; break; } } } if (xLTy) { t = xc; xc = yc; yc = t; y.s = -y.s; } b = (j = yc.length) - (i = xc.length); if (b > 0) for (; b--; xc[i++] = 0); b = BASE - 1; for (; j > a;) { if (xc[--j] < yc[j]) { for (i = j; i && !xc[--i]; xc[i] = b); --xc[i]; xc[j] += BASE; } xc[j] -= yc[j]; } for (; xc[0] == 0; xc.splice(0, 1), --ye); if (!xc[0]) { y.s = ROUNDING_MODE == 3 ? -1 : 1; y.c = [y.e = 0]; return y; } return normalise(y, xc, ye); }; P.modulo = P.mod = function(y, b) { var q, s, x = this; y = new BigNumber(y, b); if (!x.c || !y.s || y.c && !y.c[0]) { return new BigNumber(NaN); } else if (!y.c || x.c && !x.c[0]) { return new BigNumber(x); } if (MODULO_MODE == 9) { s = y.s; y.s = 1; q = div(x, y, 0, 3); y.s = s; q.s *= s; } else { q = div(x, y, 0, MODULO_MODE); } y = x.minus(q.times(y)); if (!y.c[0] && MODULO_MODE == 1) y.s = x.s; return y; }; P.multipliedBy = P.times = function(y, b) { var c, e, i, j, k, m, xcL, xlo, xhi, ycL, ylo, yhi, zc, base, sqrtBase, x = this, xc = x.c, yc = (y = new BigNumber(y, b)).c; if (!xc || !yc || !xc[0] || !yc[0]) { if (!x.s || !y.s || xc && !xc[0] && !yc || yc && !yc[0] && !xc) { y.c = y.e = y.s = null; } else { y.s *= x.s; if (!xc || !yc) { y.c = y.e = null; } else { y.c = [0]; y.e = 0; } } return y; } e = bitFloor(x.e / LOG_BASE) + bitFloor(y.e / LOG_BASE); y.s *= x.s; xcL = xc.length; ycL = yc.length; if (xcL < ycL) { zc = xc; xc = yc; yc = zc; i = xcL; xcL = ycL; ycL = i; } for (i = xcL + ycL, zc = []; i--; zc.push(0)); base = BASE; sqrtBase = SQRT_BASE; for (i = ycL; --i >= 0;) { c = 0; ylo = yc[i] % sqrtBase; yhi = yc[i] / sqrtBase | 0; for (k = xcL, j = i + k; j > i;) { xlo = xc[--k] % sqrtBase; xhi = xc[k] / sqrtBase | 0; m = yhi * xlo + xhi * ylo; xlo = ylo * xlo + m % sqrtBase * sqrtBase + zc[j] + c; c = (xlo / base | 0) + (m / sqrtBase | 0) + yhi * xhi; zc[j--] = xlo % base; } zc[j] = c; } if (c) { ++e; } else { zc.splice(0, 1); } return normalise(y, zc, e); }; P.negated = function() { var x = new BigNumber(this); x.s = -x.s || null; return x; }; P.plus = function(y, b) { var t, x = this, a = x.s; y = new BigNumber(y, b); b = y.s; if (!a || !b) return new BigNumber(NaN); if (a != b) { y.s = -b; return x.minus(y); } var xe = x.e / LOG_BASE, ye = y.e / LOG_BASE, xc = x.c, yc = y.c; if (!xe || !ye) { if (!xc || !yc) return new BigNumber(a / 0); if (!xc[0] || !yc[0]) return yc[0] ? y : new BigNumber(xc[0] ? x : a * 0); } xe = bitFloor(xe); ye = bitFloor(ye); xc = xc.slice(); if (a = xe - ye) { if (a > 0) { ye = xe; t = yc; } else { a = -a; t = xc; } t.reverse(); for (; a--; t.push(0)); t.reverse(); } a = xc.length; b = yc.length; if (a - b < 0) { t = yc; yc = xc; xc = t; b = a; } for (a = 0; b;) { a = (xc[--b] = xc[b] + yc[b] + a) / BASE | 0; xc[b] = BASE === xc[b] ? 0 : xc[b] % BASE; } if (a) { xc = [a].concat(xc); ++ye; } return normalise(y, xc, ye); }; P.precision = P.sd = function(sd, rm) { var c, n, v, x = this; if (sd != null && sd !== !!sd) { intCheck(sd, 1, MAX); if (rm == null) rm = ROUNDING_MODE; else intCheck(rm, 0, 8); return round(new BigNumber(x), sd, rm); } if (!(c = x.c)) return null; v = c.length - 1; n = v * LOG_BASE + 1; if (v = c[v]) { for (; v % 10 == 0; v /= 10, n--); for (v = c[0]; v >= 10; v /= 10, n++); } if (sd && x.e + 1 > n) n = x.e + 1; return n; }; P.shiftedBy = function(k) { intCheck(k, -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER); return this.times("1e" + k); }; P.squareRoot = P.sqrt = function() { var m, n, r, rep, t, x = this, c = x.c, s = x.s, e = x.e, dp = DECIMAL_PLACES + 4, half = new BigNumber("0.5"); if (s !== 1 || !c || !c[0]) { return new BigNumber(!s || s < 0 && (!c || c[0]) ? NaN : c ? x : 1 / 0); } s = Math.sqrt(+valueOf(x)); if (s == 0 || s == 1 / 0) { n = coeffToString(c); if ((n.length + e) % 2 == 0) n += "0"; s = Math.sqrt(+n); e = bitFloor((e + 1) / 2) - (e < 0 || e % 2); if (s == 1 / 0) { n = "5e" + e; } else { n = s.toExponential(); n = n.slice(0, n.indexOf("e") + 1) + e; } r = new BigNumber(n); } else { r = new BigNumber(s + ""); } if (r.c[0]) { e = r.e; s = e + dp; if (s < 3) s = 0; for (;;) { t = r; r = half.times(t.plus(div(x, t, dp, 1))); if (coeffToString(t.c).slice(0, s) === (n = coeffToString(r.c)).slice(0, s)) { if (r.e < e) --s; n = n.slice(s - 3, s + 1); if (n == "9999" || !rep && n == "4999") { if (!rep) { round(t, t.e + DECIMAL_PLACES + 2, 0); if (t.times(t).eq(x)) { r = t; break; } } dp += 4; s += 4; rep = 1; } else { if (!+n || !+n.slice(1) && n.charAt(0) == "5") { round(r, r.e + DECIMAL_PLACES + 2, 1); m = !r.times(r).eq(x); } break; } } } } return round(r, r.e + DECIMAL_PLACES + 1, ROUNDING_MODE, m); }; P.toExponential = function(dp, rm) { if (dp != null) { intCheck(dp, 0, MAX); dp++; } return format(this, dp, rm, 1); }; P.toFixed = function(dp, rm) { if (dp != null) { intCheck(dp, 0, MAX); dp = dp + this.e + 1; } return format(this, dp, rm); }; P.toFormat = function(dp, rm, format) { var str, x = this; if (format == null) { if (dp != null && rm && typeof rm == "object") { format = rm; rm = null; } else if (dp && typeof dp == "object") { format = dp; dp = rm = null; } else { format = FORMAT; } } else if (typeof format != "object") { throw Error(bignumberError + "Argument not an object: " + format); } str = x.toFixed(dp, rm); if (x.c) { var i, arr = str.split("."), g1 = +format.groupSize, g2 = +format.secondaryGroupSize, groupSeparator = format.groupSeparator || "", intPart = arr[0], fractionPart = arr[1], isNeg = x.s < 0, intDigits = isNeg ? intPart.slice(1) : intPart, len = intDigits.length; if (g2) { i = g1; g1 = g2; g2 = i; len -= i; } if (g1 > 0 && len > 0) { i = len % g1 || g1; intPart = intDigits.substr(0, i); for (; i < len; i += g1) intPart += groupSeparator + intDigits.substr(i, g1); if (g2 > 0) intPart += groupSeparator + intDigits.slice(i); if (isNeg) intPart = "-" + intPart; } str = fractionPart ? intPart + (format.decimalSeparator || "") + ((g2 = +format.fractionGroupSize) ? fractionPart.replace(new RegExp("\\d{" + g2 + "}\\B", "g"), "$&" + (format.fractionGroupSeparator || "")) : fractionPart) : intPart; } return (format.prefix || "") + str + (format.suffix || ""); }; P.toFraction = function(md) { var d, d0, d1, d2, e, exp, n, n0, n1, q, r, s, x = this, xc = x.c; if (md != null) { n = new BigNumber(md); if (!n.isInteger() && (n.c || n.s !== 1) || n.lt(ONE)) { throw Error(bignumberError + "Argument " + (n.isInteger() ? "out of range: " : "not an integer: ") + valueOf(n)); } } if (!xc) return new BigNumber(x); d = new BigNumber(ONE); n1 = d0 = new BigNumber(ONE); d1 = n0 = new BigNumber(ONE); s = coeffToString(xc); e = d.e = s.length - x.e - 1; d.c[0] = POWS_TEN[(exp = e % LOG_BASE) < 0 ? LOG_BASE + exp : exp]; md = !md || n.comparedTo(d) > 0 ? e > 0 ? d : n1 : n; exp = MAX_EXP; MAX_EXP = 1 / 0; n = new BigNumber(s); n0.c[0] = 0; for (;;) { q = div(n, d, 0, 1); d2 = d0.plus(q.times(d1)); if (d2.comparedTo(md) == 1) break; d0 = d1; d1 = d2; n1 = n0.plus(q.times(d2 = n1)); n0 = d2; d = n.minus(q.times(d2 = d)); n = d2; } d2 = div(md.minus(d0), d1, 0, 1); n0 = n0.plus(d2.times(n1)); d0 = d0.plus(d2.times(d1)); n0.s = n1.s = x.s; e = e * 2; r = div(n1, d1, e, ROUNDING_MODE).minus(x).abs().comparedTo(div(n0, d0, e, ROUNDING_MODE).minus(x).abs()) < 1 ? [n1, d1] : [n0, d0]; MAX_EXP = exp; return r; }; P.toNumber = function() { return +valueOf(this); }; P.toPrecision = function(sd, rm) { if (sd != null) intCheck(sd, 1, MAX); return format(this, sd, rm, 2); }; P.toString = function(b) { var str, n = this, s = n.s, e = n.e; if (e === null) { if (s) { str = "Infinity"; if (s < 0) str = "-" + str; } else { str = "NaN"; } } else { if (b == null) { str = e <= TO_EXP_NEG || e >= TO_EXP_POS ? toExponential(coeffToString(n.c), e) : toFixedPoint(coeffToString(n.c), e, "0"); } else if (b === 10 && alphabetHasNormalDecimalDigits) { n = round(new BigNumber(n), DECIMAL_PLACES + e + 1, ROUNDING_MODE); str = toFixedPoint(coeffToString(n.c), n.e, "0"); } else { intCheck(b, 2, ALPHABET.length, "Base"); str = convertBase(toFixedPoint(coeffToString(n.c), e, "0"), 10, b, s, true); } if (s < 0 && n.c[0]) str = "-" + str; } return str; }; P.valueOf = P.toJSON = function() { return valueOf(this); }; P._isBigNumber = true; P[Symbol.toStringTag] = "BigNumber"; P[Symbol.for("nodejs.util.inspect.custom")] = P.valueOf; if (configObject != null) BigNumber.set(configObject); return BigNumber; } function bitFloor(n) { var i = n | 0; return n > 0 || n === i ? i : i - 1; } function coeffToString(a) { var s, z, i = 1, j = a.length, r = a[0] + ""; for (; i < j;) { s = a[i++] + ""; z = LOG_BASE - s.length; for (; z--; s = "0" + s); r += s; } for (j = r.length; r.charCodeAt(--j) === 48;); return r.slice(0, j + 1 || 1); } function compare(x, y) { var a, b, xc = x.c, yc = y.c, i = x.s, j = y.s, k = x.e, l = y.e; if (!i || !j) return null; a = xc && !xc[0]; b = yc && !yc[0]; if (a || b) return a ? b ? 0 : -j : i; if (i != j) return i; a = i < 0; b = k == l; if (!xc || !yc) return b ? 0 : !xc ^ a ? 1 : -1; if (!b) return k > l ^ a ? 1 : -1; j = (k = xc.length) < (l = yc.length) ? k : l; for (i = 0; i < j; i++) if (xc[i] != yc[i]) return xc[i] > yc[i] ^ a ? 1 : -1; return k == l ? 0 : k > l ^ a ? 1 : -1; } function intCheck(n, min, max, name) { if (n < min || n > max || n !== mathfloor(n)) { throw Error(bignumberError + (name || "Argument") + (typeof n == "number" ? n < min || n > max ? " out of range: " : " not an integer: " : " not a primitive number: ") + String(n)); } } function isOdd(n) { var k = n.c.length - 1; return bitFloor(n.e / LOG_BASE) == k && n.c[k] % 2 != 0; } function toExponential(str, e) { return (str.length > 1 ? str.charAt(0) + "." + str.slice(1) : str) + (e < 0 ? "e" : "e+") + e; } function toFixedPoint(str, e, z) { var len, zs; if (e < 0) { for (zs = z + "."; ++e; zs += z); str = zs + str; } else { len = str.length; if (++e > len) { for (zs = z, e -= len; --e; zs += z); str += zs; } else if (e < len) { str = str.slice(0, e) + "." + str.slice(e); } } return str; } var isNumeric, mathceil, mathfloor, bignumberError, tooManyDigits, BASE, LOG_BASE, MAX_SAFE_INTEGER, POWS_TEN, SQRT_BASE, MAX, BigNumber; var init_bignumber = __esmMin((() => { isNumeric = /^-?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i, mathceil = Math.ceil, mathfloor = Math.floor, bignumberError = "[BigNumber Error] ", tooManyDigits = bignumberError + "Number primitive has more than 15 significant digits: ", BASE = 0x5af3107a4000, LOG_BASE = 14, MAX_SAFE_INTEGER = 9007199254740991, POWS_TEN = [ 1, 10, 100, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 0xe8d4a51000, 0x9184e72a000 ], SQRT_BASE = 1e7, MAX = 1e9; BigNumber = clone$2(); })); //#endregion //#region ../node_modules/json-bigint/lib/stringify.js var require_stringify$3 = /* @__PURE__ */ __commonJSMin(((exports, module) => { var BigNumber = (init_bignumber(), __toCommonJS(bignumber_exports)); var JSON = module.exports; (function() { "use strict"; function f(n) { return n < 10 ? "0" + n : n; } var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, gap, indent, meta = { "\b": "\\b", " ": "\\t", "\n": "\\n", "\f": "\\f", "\r": "\\r", "\"": "\\\"", "\\": "\\\\" }, rep; function quote(string) { escapable.lastIndex = 0; return escapable.test(string) ? "\"" + string.replace(escapable, function(a) { var c = meta[a]; return typeof c === "string" ? c : "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4); }) + "\"" : "\"" + string + "\""; } function str(key, holder) { var i, k, v, length, mind = gap, partial, value = holder[key], isBigNumber = value != null && (value instanceof BigNumber || BigNumber.isBigNumber(value)); if (value && typeof value === "object" && typeof value.toJSON === "function") { value = value.toJSON(key); } if (typeof rep === "function") { value = rep.call(holder, key, value); } switch (typeof value) { case "string": if (isBigNumber) { return value; } else { return quote(value); } case "number": return isFinite(value) ? String(value) : "null"; case "boolean": case "null": case "bigint": return String(value); case "object": if (!value) { return "null"; } gap += indent; partial = []; if (Object.prototype.toString.apply(value) === "[object Array]") { length = value.length; for (i = 0; i < length; i += 1) { partial[i] = str(i, value) || "null"; } v = partial.length === 0 ? "[]" : gap ? "[\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "]" : "[" + partial.join(",") + "]"; gap = mind; return v; } if (rep && typeof rep === "object") { length = rep.length; for (i = 0; i < length; i += 1) { if (typeof rep[i] === "string") { k = rep[i]; v = str(k, value); if (v) { partial.push(quote(k) + (gap ? ": " : ":") + v); } } } } else { Object.keys(value).forEach(function(k) { var v = str(k, value); if (v) { partial.push(quote(k) + (gap ? ": " : ":") + v); } }); } v = partial.length === 0 ? "{}" : gap ? "{\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "}" : "{" + partial.join(",") + "}"; gap = mind; return v; } } if (typeof JSON.stringify !== "function") { JSON.stringify = function(value, replacer, space) { var i; gap = ""; indent = ""; if (typeof space === "number") { for (i = 0; i < space; i += 1) { indent += " "; } } else if (typeof space === "string") { indent = space; } rep = replacer; if (replacer && typeof replacer !== "function" && (typeof replacer !== "object" || typeof replacer.length !== "number")) { throw new Error("JSON.stringify"); } return str("", { "": value }); }; } })(); })); //#endregion //#region ../node_modules/json-bigint/lib/parse.js var require_parse$6 = /* @__PURE__ */ __commonJSMin(((exports, module) => { var BigNumber = null; const suspectProtoRx = /(?:_|\\u005[Ff])(?:_|\\u005[Ff])(?:p|\\u0070)(?:r|\\u0072)(?:o|\\u006[Ff])(?:t|\\u0074)(?:o|\\u006[Ff])(?:_|\\u005[Ff])(?:_|\\u005[Ff])/; const suspectConstructorRx = /(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)/; var json_parse = function(options) { "use strict"; var _options = { strict: false, storeAsString: false, alwaysParseAsBig: false, useNativeBigInt: false, protoAction: "error", constructorAction: "error" }; if (options !== undefined && options !== null) { if (options.strict === true) { _options.strict = true; } if (options.storeAsString === true) { _options.storeAsString = true; } _options.alwaysParseAsBig = options.alwaysParseAsBig === true ? options.alwaysParseAsBig : false; _options.useNativeBigInt = options.useNativeBigInt === true ? options.useNativeBigInt : false; if (typeof options.constructorAction !== "undefined") { if (options.constructorAction === "error" || options.constructorAction === "ignore" || options.constructorAction === "preserve") { _options.constructorAction = options.constructorAction; } else { throw new Error(`Incorrect value for constructorAction option, must be "error", "ignore" or undefined but passed ${options.constructorAction}`); } } if (typeof options.protoAction !== "undefined") { if (options.protoAction === "error" || options.protoAction === "ignore" || options.protoAction === "preserve") { _options.protoAction = options.protoAction; } else { throw new Error(`Incorrect value for protoAction option, must be "error", "ignore" or undefined but passed ${options.protoAction}`); } } } var at, ch, escapee = { "\"": "\"", "\\": "\\", "/": "/", b: "\b", f: "\f", n: "\n", r: "\r", t: " " }, text, error = function(m) { throw { name: "SyntaxError", message: m, at, text }; }, next = function(c) { if (c && c !== ch) { error("Expected '" + c + "' instead of '" + ch + "'"); } ch = text.charAt(at); at += 1; return ch; }, number = function() { var number, string = ""; if (ch === "-") { string = "-"; next("-"); } while (ch >= "0" && ch <= "9") { string += ch; next(); } if (ch === ".") { string += "."; while (next() && ch >= "0" && ch <= "9") { string += ch; } } if (ch === "e" || ch === "E") { string += ch; next(); if (ch === "-" || ch === "+") { string += ch; next(); } while (ch >= "0" && ch <= "9") { string += ch; next(); } } number = +string; if (!isFinite(number)) { error("Bad number"); } else { if (BigNumber == null) BigNumber = (init_bignumber(), __toCommonJS(bignumber_exports)); if (string.length > 15) return _options.storeAsString ? string : _options.useNativeBigInt ? BigInt(string) : new BigNumber(string); else return !_options.alwaysParseAsBig ? number : _options.useNativeBigInt ? BigInt(number) : new BigNumber(number); } }, string = function() { var hex, i, string = "", uffff; if (ch === "\"") { var startAt = at; while (next()) { if (ch === "\"") { if (at - 1 > startAt) string += text.substring(startAt, at - 1); next(); return string; } if (ch === "\\") { if (at - 1 > startAt) string += text.substring(startAt, at - 1); next(); if (ch === "u") { uffff = 0; for (i = 0; i < 4; i += 1) { hex = parseInt(next(), 16); if (!isFinite(hex)) { break; } uffff = uffff * 16 + hex; } string += String.fromCharCode(uffff); } else if (typeof escapee[ch] === "string") { string += escapee[ch]; } else { break; } startAt = at; } } } error("Bad string"); }, white = function() { while (ch && ch <= " ") { next(); } }, word = function() { switch (ch) { case "t": next("t"); next("r"); next("u"); next("e"); return true; case "f": next("f"); next("a"); next("l"); next("s"); next("e"); return false; case "n": next("n"); next("u"); next("l"); next("l"); return null; } error("Unexpected '" + ch + "'"); }, value, array = function() { var array = []; if (ch === "[") { next("["); white(); if (ch === "]") { next("]"); return array; } while (ch) { array.push(value()); white(); if (ch === "]") { next("]"); return array; } next(","); white(); } } error("Bad array"); }, object = function() { var key, object = Object.create(null); if (ch === "{") { next("{"); white(); if (ch === "}") { next("}"); return object; } while (ch) { key = string(); white(); next(":"); if (_options.strict === true && Object.hasOwnProperty.call(object, key)) { error("Duplicate key \"" + key + "\""); } if (suspectProtoRx.test(key) === true) { if (_options.protoAction === "error") { error("Object contains forbidden prototype property"); } else if (_options.protoAction === "ignore") { value(); } else { object[key] = value(); } } else if (suspectConstructorRx.test(key) === true) { if (_options.constructorAction === "error") { error("Object contains forbidden constructor property"); } else if (_options.constructorAction === "ignore") { value(); } else { object[key] = value(); } } else { object[key] = value(); } white(); if (ch === "}") { next("}"); return object; } next(","); white(); } } error("Bad object"); }; value = function() { white(); switch (ch) { case "{": return object(); case "[": return array(); case "\"": return string(); case "-": return number(); default: return ch >= "0" && ch <= "9" ? number() : word(); } }; return function(source, reviver) { var result; text = source + ""; at = 0; ch = " "; result = value(); white(); if (ch) { error("Syntax error"); } return typeof reviver === "function" ? (function walk(holder, key) { var k, v, value = holder[key]; if (value && typeof value === "object") { Object.keys(value).forEach(function(k) { v = walk(value, k); if (v !== undefined) { value[k] = v; } else { delete value[k]; } }); } return reviver.call(holder, key, value); })({ "": result }, "") : result; }; }; module.exports = json_parse; })); //#endregion //#region ../node_modules/json-bigint/index.js var require_json_bigint = /* @__PURE__ */ __commonJSMin(((exports, module) => { var json_stringify = require_stringify$3().stringify; var json_parse = require_parse$6(); module.exports = function(options) { return { parse: json_parse(options), stringify: json_stringify }; }; module.exports.parse = json_parse(); module.exports.stringify = json_stringify; })); //#endregion //#region ../node_modules/node-forge/lib/forge.js var require_forge = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Node.js module for Forge. * * @author Dave Longley * * Copyright 2011-2016 Digital Bazaar, Inc. */ module.exports = { options: { usePureJavaScript: false } }; })); //#endregion //#region ../node_modules/node-forge/lib/baseN.js var require_baseN = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Base-N/Base-X encoding/decoding functions. * * Original implementation from base-x: * https://github.com/cryptocoinjs/base-x * * Which is MIT licensed: * * The MIT License (MIT) * * Copyright base-x contributors (c) 2016 * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ var api = {}; module.exports = api; var _reverseAlphabets = {}; /** * BaseN-encodes a Uint8Array using the given alphabet. * * @param input the Uint8Array to encode. * @param maxline the maximum number of encoded characters per line to use, * defaults to none. * * @return the baseN-encoded output string. */ api.encode = function(input, alphabet, maxline) { if (typeof alphabet !== "string") { throw new TypeError("\"alphabet\" must be a string."); } if (maxline !== undefined && typeof maxline !== "number") { throw new TypeError("\"maxline\" must be a number."); } var output = ""; if (!(input instanceof Uint8Array)) { output = _encodeWithByteBuffer(input, alphabet); } else { var i = 0; var base = alphabet.length; var first = alphabet.charAt(0); var digits = [0]; for (i = 0; i < input.length; ++i) { for (var j = 0, carry = input[i]; j < digits.length; ++j) { carry += digits[j] << 8; digits[j] = carry % base; carry = carry / base | 0; } while (carry > 0) { digits.push(carry % base); carry = carry / base | 0; } } for (i = 0; input[i] === 0 && i < input.length - 1; ++i) { output += first; } for (i = digits.length - 1; i >= 0; --i) { output += alphabet[digits[i]]; } } if (maxline) { var regex = new RegExp(".{1," + maxline + "}", "g"); output = output.match(regex).join("\r\n"); } return output; }; /** * Decodes a baseN-encoded (using the given alphabet) string to a * Uint8Array. * * @param input the baseN-encoded input string. * * @return the Uint8Array. */ api.decode = function(input, alphabet) { if (typeof input !== "string") { throw new TypeError("\"input\" must be a string."); } if (typeof alphabet !== "string") { throw new TypeError("\"alphabet\" must be a string."); } var table = _reverseAlphabets[alphabet]; if (!table) { table = _reverseAlphabets[alphabet] = []; for (var i = 0; i < alphabet.length; ++i) { table[alphabet.charCodeAt(i)] = i; } } input = input.replace(/\s/g, ""); var base = alphabet.length; var first = alphabet.charAt(0); var bytes = [0]; for (var i = 0; i < input.length; i++) { var value = table[input.charCodeAt(i)]; if (value === undefined) { return; } for (var j = 0, carry = value; j < bytes.length; ++j) { carry += bytes[j] * base; bytes[j] = carry & 255; carry >>= 8; } while (carry > 0) { bytes.push(carry & 255); carry >>= 8; } } for (var k = 0; input[k] === first && k < input.length - 1; ++k) { bytes.push(0); } if (typeof Buffer !== "undefined") { return Buffer.from(bytes.reverse()); } return new Uint8Array(bytes.reverse()); }; function _encodeWithByteBuffer(input, alphabet) { var i = 0; var base = alphabet.length; var first = alphabet.charAt(0); var digits = [0]; for (i = 0; i < input.length(); ++i) { for (var j = 0, carry = input.at(i); j < digits.length; ++j) { carry += digits[j] << 8; digits[j] = carry % base; carry = carry / base | 0; } while (carry > 0) { digits.push(carry % base); carry = carry / base | 0; } } var output = ""; for (i = 0; input.at(i) === 0 && i < input.length() - 1; ++i) { output += first; } for (i = digits.length - 1; i >= 0; --i) { output += alphabet[digits[i]]; } return output; } })); //#endregion //#region ../node_modules/node-forge/lib/util.js var require_util$8 = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Utility functions for web applications. * * @author Dave Longley * * Copyright (c) 2010-2018 Digital Bazaar, Inc. */ var forge = require_forge(); var baseN = require_baseN(); var util = module.exports = forge.util = forge.util || {}; (function() { if (typeof process !== "undefined" && process.nextTick && !process.browser) { util.nextTick = process.nextTick; if (typeof setImmediate === "function") { util.setImmediate = setImmediate; } else { util.setImmediate = util.nextTick; } return; } if (typeof setImmediate === "function") { util.setImmediate = function() { return setImmediate.apply(undefined, arguments); }; util.nextTick = function(callback) { return setImmediate(callback); }; return; } util.setImmediate = function(callback) { setTimeout(callback, 0); }; if (typeof window !== "undefined" && typeof window.postMessage === "function") { var msg = "forge.setImmediate"; var callbacks = []; util.setImmediate = function(callback) { callbacks.push(callback); if (callbacks.length === 1) { window.postMessage(msg, "*"); } }; function handler(event) { if (event.source === window && event.data === msg) { event.stopPropagation(); var copy = callbacks.slice(); callbacks.length = 0; copy.forEach(function(callback) { callback(); }); } } window.addEventListener("message", handler, true); } if (typeof MutationObserver !== "undefined") { var now = Date.now(); var attr = true; var div = document.createElement("div"); var callbacks = []; new MutationObserver(function() { var copy = callbacks.slice(); callbacks.length = 0; copy.forEach(function(callback) { callback(); }); }).observe(div, { attributes: true }); var oldSetImmediate = util.setImmediate; util.setImmediate = function(callback) { if (Date.now() - now > 15) { now = Date.now(); oldSetImmediate(callback); } else { callbacks.push(callback); if (callbacks.length === 1) { div.setAttribute("a", attr = !attr); } } }; } util.nextTick = util.setImmediate; })(); util.isNodejs = typeof process !== "undefined" && process.versions && process.versions.node; util.globalScope = (function() { if (util.isNodejs) { return global; } return typeof self === "undefined" ? window : self; })(); util.isArray = Array.isArray || function(x) { return Object.prototype.toString.call(x) === "[object Array]"; }; util.isArrayBuffer = function(x) { return typeof ArrayBuffer !== "undefined" && x instanceof ArrayBuffer; }; util.isArrayBufferView = function(x) { return x && util.isArrayBuffer(x.buffer) && x.byteLength !== undefined; }; /** * Ensure a bits param is 8, 16, 24, or 32. Used to validate input for * algorithms where bit manipulation, JavaScript limitations, and/or algorithm * design only allow for byte operations of a limited size. * * @param n number of bits. * * Throw Error if n invalid. */ function _checkBitsParam(n) { if (!(n === 8 || n === 16 || n === 24 || n === 32)) { throw new Error("Only 8, 16, 24, or 32 bits supported: " + n); } } util.ByteBuffer = ByteStringBuffer; /** Buffer w/BinaryString backing */ /** * Constructor for a binary string backed byte buffer. * * @param [b] the bytes to wrap (either encoded as string, one byte per * character, or as an ArrayBuffer or Typed Array). */ function ByteStringBuffer(b) { this.data = ""; this.read = 0; if (typeof b === "string") { this.data = b; } else if (util.isArrayBuffer(b) || util.isArrayBufferView(b)) { if (typeof Buffer !== "undefined" && b instanceof Buffer) { this.data = b.toString("binary"); } else { var arr = new Uint8Array(b); try { this.data = String.fromCharCode.apply(null, arr); } catch (e) { for (var i = 0; i < arr.length; ++i) { this.putByte(arr[i]); } } } } else if (b instanceof ByteStringBuffer || typeof b === "object" && typeof b.data === "string" && typeof b.read === "number") { this.data = b.data; this.read = b.read; } this._constructedStringLength = 0; } util.ByteStringBuffer = ByteStringBuffer; var _MAX_CONSTRUCTED_STRING_LENGTH = 4096; util.ByteStringBuffer.prototype._optimizeConstructedString = function(x) { this._constructedStringLength += x; if (this._constructedStringLength > _MAX_CONSTRUCTED_STRING_LENGTH) { this.data.substr(0, 1); this._constructedStringLength = 0; } }; /** * Gets the number of bytes in this buffer. * * @return the number of bytes in this buffer. */ util.ByteStringBuffer.prototype.length = function() { return this.data.length - this.read; }; /** * Gets whether or not this buffer is empty. * * @return true if this buffer is empty, false if not. */ util.ByteStringBuffer.prototype.isEmpty = function() { return this.length() <= 0; }; /** * Puts a byte in this buffer. * * @param b the byte to put. * * @return this buffer. */ util.ByteStringBuffer.prototype.putByte = function(b) { return this.putBytes(String.fromCharCode(b)); }; /** * Puts a byte in this buffer N times. * * @param b the byte to put. * @param n the number of bytes of value b to put. * * @return this buffer. */ util.ByteStringBuffer.prototype.fillWithByte = function(b, n) { b = String.fromCharCode(b); var d = this.data; while (n > 0) { if (n & 1) { d += b; } n >>>= 1; if (n > 0) { b += b; } } this.data = d; this._optimizeConstructedString(n); return this; }; /** * Puts bytes in this buffer. * * @param bytes the bytes (as a binary encoded string) to put. * * @return this buffer. */ util.ByteStringBuffer.prototype.putBytes = function(bytes) { this.data += bytes; this._optimizeConstructedString(bytes.length); return this; }; /** * Puts a UTF-16 encoded string into this buffer. * * @param str the string to put. * * @return this buffer. */ util.ByteStringBuffer.prototype.putString = function(str) { return this.putBytes(util.encodeUtf8(str)); }; /** * Puts a 16-bit integer in this buffer in big-endian order. * * @param i the 16-bit integer. * * @return this buffer. */ util.ByteStringBuffer.prototype.putInt16 = function(i) { return this.putBytes(String.fromCharCode(i >> 8 & 255) + String.fromCharCode(i & 255)); }; /** * Puts a 24-bit integer in this buffer in big-endian order. * * @param i the 24-bit integer. * * @return this buffer. */ util.ByteStringBuffer.prototype.putInt24 = function(i) { return this.putBytes(String.fromCharCode(i >> 16 & 255) + String.fromCharCode(i >> 8 & 255) + String.fromCharCode(i & 255)); }; /** * Puts a 32-bit integer in this buffer in big-endian order. * * @param i the 32-bit integer. * * @return this buffer. */ util.ByteStringBuffer.prototype.putInt32 = function(i) { return this.putBytes(String.fromCharCode(i >> 24 & 255) + String.fromCharCode(i >> 16 & 255) + String.fromCharCode(i >> 8 & 255) + String.fromCharCode(i & 255)); }; /** * Puts a 16-bit integer in this buffer in little-endian order. * * @param i the 16-bit integer. * * @return this buffer. */ util.ByteStringBuffer.prototype.putInt16Le = function(i) { return this.putBytes(String.fromCharCode(i & 255) + String.fromCharCode(i >> 8 & 255)); }; /** * Puts a 24-bit integer in this buffer in little-endian order. * * @param i the 24-bit integer. * * @return this buffer. */ util.ByteStringBuffer.prototype.putInt24Le = function(i) { return this.putBytes(String.fromCharCode(i & 255) + String.fromCharCode(i >> 8 & 255) + String.fromCharCode(i >> 16 & 255)); }; /** * Puts a 32-bit integer in this buffer in little-endian order. * * @param i the 32-bit integer. * * @return this buffer. */ util.ByteStringBuffer.prototype.putInt32Le = function(i) { return this.putBytes(String.fromCharCode(i & 255) + String.fromCharCode(i >> 8 & 255) + String.fromCharCode(i >> 16 & 255) + String.fromCharCode(i >> 24 & 255)); }; /** * Puts an n-bit integer in this buffer in big-endian order. * * @param i the n-bit integer. * @param n the number of bits in the integer (8, 16, 24, or 32). * * @return this buffer. */ util.ByteStringBuffer.prototype.putInt = function(i, n) { _checkBitsParam(n); var bytes = ""; do { n -= 8; bytes += String.fromCharCode(i >> n & 255); } while (n > 0); return this.putBytes(bytes); }; /** * Puts a signed n-bit integer in this buffer in big-endian order. Two's * complement representation is used. * * @param i the n-bit integer. * @param n the number of bits in the integer (8, 16, 24, or 32). * * @return this buffer. */ util.ByteStringBuffer.prototype.putSignedInt = function(i, n) { if (i < 0) { i += 2 << n - 1; } return this.putInt(i, n); }; /** * Puts the given buffer into this buffer. * * @param buffer the buffer to put into this one. * * @return this buffer. */ util.ByteStringBuffer.prototype.putBuffer = function(buffer) { return this.putBytes(buffer.getBytes()); }; /** * Gets a byte from this buffer and advances the read pointer by 1. * * @return the byte. */ util.ByteStringBuffer.prototype.getByte = function() { return this.data.charCodeAt(this.read++); }; /** * Gets a uint16 from this buffer in big-endian order and advances the read * pointer by 2. * * @return the uint16. */ util.ByteStringBuffer.prototype.getInt16 = function() { var rval = this.data.charCodeAt(this.read) << 8 ^ this.data.charCodeAt(this.read + 1); this.read += 2; return rval; }; /** * Gets a uint24 from this buffer in big-endian order and advances the read * pointer by 3. * * @return the uint24. */ util.ByteStringBuffer.prototype.getInt24 = function() { var rval = this.data.charCodeAt(this.read) << 16 ^ this.data.charCodeAt(this.read + 1) << 8 ^ this.data.charCodeAt(this.read + 2); this.read += 3; return rval; }; /** * Gets a uint32 from this buffer in big-endian order and advances the read * pointer by 4. * * @return the word. */ util.ByteStringBuffer.prototype.getInt32 = function() { var rval = this.data.charCodeAt(this.read) << 24 ^ this.data.charCodeAt(this.read + 1) << 16 ^ this.data.charCodeAt(this.read + 2) << 8 ^ this.data.charCodeAt(this.read + 3); this.read += 4; return rval; }; /** * Gets a uint16 from this buffer in little-endian order and advances the read * pointer by 2. * * @return the uint16. */ util.ByteStringBuffer.prototype.getInt16Le = function() { var rval = this.data.charCodeAt(this.read) ^ this.data.charCodeAt(this.read + 1) << 8; this.read += 2; return rval; }; /** * Gets a uint24 from this buffer in little-endian order and advances the read * pointer by 3. * * @return the uint24. */ util.ByteStringBuffer.prototype.getInt24Le = function() { var rval = this.data.charCodeAt(this.read) ^ this.data.charCodeAt(this.read + 1) << 8 ^ this.data.charCodeAt(this.read + 2) << 16; this.read += 3; return rval; }; /** * Gets a uint32 from this buffer in little-endian order and advances the read * pointer by 4. * * @return the word. */ util.ByteStringBuffer.prototype.getInt32Le = function() { var rval = this.data.charCodeAt(this.read) ^ this.data.charCodeAt(this.read + 1) << 8 ^ this.data.charCodeAt(this.read + 2) << 16 ^ this.data.charCodeAt(this.read + 3) << 24; this.read += 4; return rval; }; /** * Gets an n-bit integer from this buffer in big-endian order and advances the * read pointer by ceil(n/8). * * @param n the number of bits in the integer (8, 16, 24, or 32). * * @return the integer. */ util.ByteStringBuffer.prototype.getInt = function(n) { _checkBitsParam(n); var rval = 0; do { rval = (rval << 8) + this.data.charCodeAt(this.read++); n -= 8; } while (n > 0); return rval; }; /** * Gets a signed n-bit integer from this buffer in big-endian order, using * two's complement, and advances the read pointer by n/8. * * @param n the number of bits in the integer (8, 16, 24, or 32). * * @return the integer. */ util.ByteStringBuffer.prototype.getSignedInt = function(n) { var x = this.getInt(n); var max = 2 << n - 2; if (x >= max) { x -= max << 1; } return x; }; /** * Reads bytes out as a binary encoded string and clears them from the * buffer. Note that the resulting string is binary encoded (in node.js this * encoding is referred to as `binary`, it is *not* `utf8`). * * @param count the number of bytes to read, undefined or null for all. * * @return a binary encoded string of bytes. */ util.ByteStringBuffer.prototype.getBytes = function(count) { var rval; if (count) { count = Math.min(this.length(), count); rval = this.data.slice(this.read, this.read + count); this.read += count; } else if (count === 0) { rval = ""; } else { rval = this.read === 0 ? this.data : this.data.slice(this.read); this.clear(); } return rval; }; /** * Gets a binary encoded string of the bytes from this buffer without * modifying the read pointer. * * @param count the number of bytes to get, omit to get all. * * @return a string full of binary encoded characters. */ util.ByteStringBuffer.prototype.bytes = function(count) { return typeof count === "undefined" ? this.data.slice(this.read) : this.data.slice(this.read, this.read + count); }; /** * Gets a byte at the given index without modifying the read pointer. * * @param i the byte index. * * @return the byte. */ util.ByteStringBuffer.prototype.at = function(i) { return this.data.charCodeAt(this.read + i); }; /** * Puts a byte at the given index without modifying the read pointer. * * @param i the byte index. * @param b the byte to put. * * @return this buffer. */ util.ByteStringBuffer.prototype.setAt = function(i, b) { this.data = this.data.substr(0, this.read + i) + String.fromCharCode(b) + this.data.substr(this.read + i + 1); return this; }; /** * Gets the last byte without modifying the read pointer. * * @return the last byte. */ util.ByteStringBuffer.prototype.last = function() { return this.data.charCodeAt(this.data.length - 1); }; /** * Creates a copy of this buffer. * * @return the copy. */ util.ByteStringBuffer.prototype.copy = function() { var c = util.createBuffer(this.data); c.read = this.read; return c; }; /** * Compacts this buffer. * * @return this buffer. */ util.ByteStringBuffer.prototype.compact = function() { if (this.read > 0) { this.data = this.data.slice(this.read); this.read = 0; } return this; }; /** * Clears this buffer. * * @return this buffer. */ util.ByteStringBuffer.prototype.clear = function() { this.data = ""; this.read = 0; return this; }; /** * Shortens this buffer by triming bytes off of the end of this buffer. * * @param count the number of bytes to trim off. * * @return this buffer. */ util.ByteStringBuffer.prototype.truncate = function(count) { var len = Math.max(0, this.length() - count); this.data = this.data.substr(this.read, len); this.read = 0; return this; }; /** * Converts this buffer to a hexadecimal string. * * @return a hexadecimal string. */ util.ByteStringBuffer.prototype.toHex = function() { var rval = ""; for (var i = this.read; i < this.data.length; ++i) { var b = this.data.charCodeAt(i); if (b < 16) { rval += "0"; } rval += b.toString(16); } return rval; }; /** * Converts this buffer to a UTF-16 string (standard JavaScript string). * * @return a UTF-16 string. */ util.ByteStringBuffer.prototype.toString = function() { return util.decodeUtf8(this.bytes()); }; /** End Buffer w/BinaryString backing */ /** Buffer w/UInt8Array backing */ /** * FIXME: Experimental. Do not use yet. * * Constructor for an ArrayBuffer-backed byte buffer. * * The buffer may be constructed from a string, an ArrayBuffer, DataView, or a * TypedArray. * * If a string is given, its encoding should be provided as an option, * otherwise it will default to 'binary'. A 'binary' string is encoded such * that each character is one byte in length and size. * * If an ArrayBuffer, DataView, or TypedArray is given, it will be used * *directly* without any copying. Note that, if a write to the buffer requires * more space, the buffer will allocate a new backing ArrayBuffer to * accommodate. The starting read and write offsets for the buffer may be * given as options. * * @param [b] the initial bytes for this buffer. * @param options the options to use: * [readOffset] the starting read offset to use (default: 0). * [writeOffset] the starting write offset to use (default: the * length of the first parameter). * [growSize] the minimum amount, in bytes, to grow the buffer by to * accommodate writes (default: 1024). * [encoding] the encoding ('binary', 'utf8', 'utf16', 'hex') for the * first parameter, if it is a string (default: 'binary'). */ function DataBuffer(b, options) { options = options || {}; this.read = options.readOffset || 0; this.growSize = options.growSize || 1024; var isArrayBuffer = util.isArrayBuffer(b); var isArrayBufferView = util.isArrayBufferView(b); if (isArrayBuffer || isArrayBufferView) { if (isArrayBuffer) { this.data = new DataView(b); } else { this.data = new DataView(b.buffer, b.byteOffset, b.byteLength); } this.write = "writeOffset" in options ? options.writeOffset : this.data.byteLength; return; } this.data = new DataView(new ArrayBuffer(0)); this.write = 0; if (b !== null && b !== undefined) { this.putBytes(b); } if ("writeOffset" in options) { this.write = options.writeOffset; } } util.DataBuffer = DataBuffer; /** * Gets the number of bytes in this buffer. * * @return the number of bytes in this buffer. */ util.DataBuffer.prototype.length = function() { return this.write - this.read; }; /** * Gets whether or not this buffer is empty. * * @return true if this buffer is empty, false if not. */ util.DataBuffer.prototype.isEmpty = function() { return this.length() <= 0; }; /** * Ensures this buffer has enough empty space to accommodate the given number * of bytes. An optional parameter may be given that indicates a minimum * amount to grow the buffer if necessary. If the parameter is not given, * the buffer will be grown by some previously-specified default amount * or heuristic. * * @param amount the number of bytes to accommodate. * @param [growSize] the minimum amount, in bytes, to grow the buffer by if * necessary. */ util.DataBuffer.prototype.accommodate = function(amount, growSize) { if (this.length() >= amount) { return this; } growSize = Math.max(growSize || this.growSize, amount); var src = new Uint8Array(this.data.buffer, this.data.byteOffset, this.data.byteLength); var dst = new Uint8Array(this.length() + growSize); dst.set(src); this.data = new DataView(dst.buffer); return this; }; /** * Puts a byte in this buffer. * * @param b the byte to put. * * @return this buffer. */ util.DataBuffer.prototype.putByte = function(b) { this.accommodate(1); this.data.setUint8(this.write++, b); return this; }; /** * Puts a byte in this buffer N times. * * @param b the byte to put. * @param n the number of bytes of value b to put. * * @return this buffer. */ util.DataBuffer.prototype.fillWithByte = function(b, n) { this.accommodate(n); for (var i = 0; i < n; ++i) { this.data.setUint8(b); } return this; }; /** * Puts bytes in this buffer. The bytes may be given as a string, an * ArrayBuffer, a DataView, or a TypedArray. * * @param bytes the bytes to put. * @param [encoding] the encoding for the first parameter ('binary', 'utf8', * 'utf16', 'hex'), if it is a string (default: 'binary'). * * @return this buffer. */ util.DataBuffer.prototype.putBytes = function(bytes, encoding) { if (util.isArrayBufferView(bytes)) { var src = new Uint8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength); var len = src.byteLength - src.byteOffset; this.accommodate(len); var dst = new Uint8Array(this.data.buffer, this.write); dst.set(src); this.write += len; return this; } if (util.isArrayBuffer(bytes)) { var src = new Uint8Array(bytes); this.accommodate(src.byteLength); var dst = new Uint8Array(this.data.buffer); dst.set(src, this.write); this.write += src.byteLength; return this; } if (bytes instanceof util.DataBuffer || typeof bytes === "object" && typeof bytes.read === "number" && typeof bytes.write === "number" && util.isArrayBufferView(bytes.data)) { var src = new Uint8Array(bytes.data.byteLength, bytes.read, bytes.length()); this.accommodate(src.byteLength); var dst = new Uint8Array(bytes.data.byteLength, this.write); dst.set(src); this.write += src.byteLength; return this; } if (bytes instanceof util.ByteStringBuffer) { bytes = bytes.data; encoding = "binary"; } encoding = encoding || "binary"; if (typeof bytes === "string") { var view; if (encoding === "hex") { this.accommodate(Math.ceil(bytes.length / 2)); view = new Uint8Array(this.data.buffer, this.write); this.write += util.binary.hex.decode(bytes, view, this.write); return this; } if (encoding === "base64") { this.accommodate(Math.ceil(bytes.length / 4) * 3); view = new Uint8Array(this.data.buffer, this.write); this.write += util.binary.base64.decode(bytes, view, this.write); return this; } if (encoding === "utf8") { bytes = util.encodeUtf8(bytes); encoding = "binary"; } if (encoding === "binary" || encoding === "raw") { this.accommodate(bytes.length); view = new Uint8Array(this.data.buffer, this.write); this.write += util.binary.raw.decode(view); return this; } if (encoding === "utf16") { this.accommodate(bytes.length * 2); view = new Uint16Array(this.data.buffer, this.write); this.write += util.text.utf16.encode(view); return this; } throw new Error("Invalid encoding: " + encoding); } throw Error("Invalid parameter: " + bytes); }; /** * Puts the given buffer into this buffer. * * @param buffer the buffer to put into this one. * * @return this buffer. */ util.DataBuffer.prototype.putBuffer = function(buffer) { this.putBytes(buffer); buffer.clear(); return this; }; /** * Puts a string into this buffer. * * @param str the string to put. * @param [encoding] the encoding for the string (default: 'utf16'). * * @return this buffer. */ util.DataBuffer.prototype.putString = function(str) { return this.putBytes(str, "utf16"); }; /** * Puts a 16-bit integer in this buffer in big-endian order. * * @param i the 16-bit integer. * * @return this buffer. */ util.DataBuffer.prototype.putInt16 = function(i) { this.accommodate(2); this.data.setInt16(this.write, i); this.write += 2; return this; }; /** * Puts a 24-bit integer in this buffer in big-endian order. * * @param i the 24-bit integer. * * @return this buffer. */ util.DataBuffer.prototype.putInt24 = function(i) { this.accommodate(3); this.data.setInt16(this.write, i >> 8 & 65535); this.data.setInt8(this.write, i >> 16 & 255); this.write += 3; return this; }; /** * Puts a 32-bit integer in this buffer in big-endian order. * * @param i the 32-bit integer. * * @return this buffer. */ util.DataBuffer.prototype.putInt32 = function(i) { this.accommodate(4); this.data.setInt32(this.write, i); this.write += 4; return this; }; /** * Puts a 16-bit integer in this buffer in little-endian order. * * @param i the 16-bit integer. * * @return this buffer. */ util.DataBuffer.prototype.putInt16Le = function(i) { this.accommodate(2); this.data.setInt16(this.write, i, true); this.write += 2; return this; }; /** * Puts a 24-bit integer in this buffer in little-endian order. * * @param i the 24-bit integer. * * @return this buffer. */ util.DataBuffer.prototype.putInt24Le = function(i) { this.accommodate(3); this.data.setInt8(this.write, i >> 16 & 255); this.data.setInt16(this.write, i >> 8 & 65535, true); this.write += 3; return this; }; /** * Puts a 32-bit integer in this buffer in little-endian order. * * @param i the 32-bit integer. * * @return this buffer. */ util.DataBuffer.prototype.putInt32Le = function(i) { this.accommodate(4); this.data.setInt32(this.write, i, true); this.write += 4; return this; }; /** * Puts an n-bit integer in this buffer in big-endian order. * * @param i the n-bit integer. * @param n the number of bits in the integer (8, 16, 24, or 32). * * @return this buffer. */ util.DataBuffer.prototype.putInt = function(i, n) { _checkBitsParam(n); this.accommodate(n / 8); do { n -= 8; this.data.setInt8(this.write++, i >> n & 255); } while (n > 0); return this; }; /** * Puts a signed n-bit integer in this buffer in big-endian order. Two's * complement representation is used. * * @param i the n-bit integer. * @param n the number of bits in the integer. * * @return this buffer. */ util.DataBuffer.prototype.putSignedInt = function(i, n) { _checkBitsParam(n); this.accommodate(n / 8); if (i < 0) { i += 2 << n - 1; } return this.putInt(i, n); }; /** * Gets a byte from this buffer and advances the read pointer by 1. * * @return the byte. */ util.DataBuffer.prototype.getByte = function() { return this.data.getInt8(this.read++); }; /** * Gets a uint16 from this buffer in big-endian order and advances the read * pointer by 2. * * @return the uint16. */ util.DataBuffer.prototype.getInt16 = function() { var rval = this.data.getInt16(this.read); this.read += 2; return rval; }; /** * Gets a uint24 from this buffer in big-endian order and advances the read * pointer by 3. * * @return the uint24. */ util.DataBuffer.prototype.getInt24 = function() { var rval = this.data.getInt16(this.read) << 8 ^ this.data.getInt8(this.read + 2); this.read += 3; return rval; }; /** * Gets a uint32 from this buffer in big-endian order and advances the read * pointer by 4. * * @return the word. */ util.DataBuffer.prototype.getInt32 = function() { var rval = this.data.getInt32(this.read); this.read += 4; return rval; }; /** * Gets a uint16 from this buffer in little-endian order and advances the read * pointer by 2. * * @return the uint16. */ util.DataBuffer.prototype.getInt16Le = function() { var rval = this.data.getInt16(this.read, true); this.read += 2; return rval; }; /** * Gets a uint24 from this buffer in little-endian order and advances the read * pointer by 3. * * @return the uint24. */ util.DataBuffer.prototype.getInt24Le = function() { var rval = this.data.getInt8(this.read) ^ this.data.getInt16(this.read + 1, true) << 8; this.read += 3; return rval; }; /** * Gets a uint32 from this buffer in little-endian order and advances the read * pointer by 4. * * @return the word. */ util.DataBuffer.prototype.getInt32Le = function() { var rval = this.data.getInt32(this.read, true); this.read += 4; return rval; }; /** * Gets an n-bit integer from this buffer in big-endian order and advances the * read pointer by n/8. * * @param n the number of bits in the integer (8, 16, 24, or 32). * * @return the integer. */ util.DataBuffer.prototype.getInt = function(n) { _checkBitsParam(n); var rval = 0; do { rval = (rval << 8) + this.data.getInt8(this.read++); n -= 8; } while (n > 0); return rval; }; /** * Gets a signed n-bit integer from this buffer in big-endian order, using * two's complement, and advances the read pointer by n/8. * * @param n the number of bits in the integer (8, 16, 24, or 32). * * @return the integer. */ util.DataBuffer.prototype.getSignedInt = function(n) { var x = this.getInt(n); var max = 2 << n - 2; if (x >= max) { x -= max << 1; } return x; }; /** * Reads bytes out as a binary encoded string and clears them from the * buffer. * * @param count the number of bytes to read, undefined or null for all. * * @return a binary encoded string of bytes. */ util.DataBuffer.prototype.getBytes = function(count) { var rval; if (count) { count = Math.min(this.length(), count); rval = this.data.slice(this.read, this.read + count); this.read += count; } else if (count === 0) { rval = ""; } else { rval = this.read === 0 ? this.data : this.data.slice(this.read); this.clear(); } return rval; }; /** * Gets a binary encoded string of the bytes from this buffer without * modifying the read pointer. * * @param count the number of bytes to get, omit to get all. * * @return a string full of binary encoded characters. */ util.DataBuffer.prototype.bytes = function(count) { return typeof count === "undefined" ? this.data.slice(this.read) : this.data.slice(this.read, this.read + count); }; /** * Gets a byte at the given index without modifying the read pointer. * * @param i the byte index. * * @return the byte. */ util.DataBuffer.prototype.at = function(i) { return this.data.getUint8(this.read + i); }; /** * Puts a byte at the given index without modifying the read pointer. * * @param i the byte index. * @param b the byte to put. * * @return this buffer. */ util.DataBuffer.prototype.setAt = function(i, b) { this.data.setUint8(i, b); return this; }; /** * Gets the last byte without modifying the read pointer. * * @return the last byte. */ util.DataBuffer.prototype.last = function() { return this.data.getUint8(this.write - 1); }; /** * Creates a copy of this buffer. * * @return the copy. */ util.DataBuffer.prototype.copy = function() { return new util.DataBuffer(this); }; /** * Compacts this buffer. * * @return this buffer. */ util.DataBuffer.prototype.compact = function() { if (this.read > 0) { var src = new Uint8Array(this.data.buffer, this.read); var dst = new Uint8Array(src.byteLength); dst.set(src); this.data = new DataView(dst); this.write -= this.read; this.read = 0; } return this; }; /** * Clears this buffer. * * @return this buffer. */ util.DataBuffer.prototype.clear = function() { this.data = new DataView(new ArrayBuffer(0)); this.read = this.write = 0; return this; }; /** * Shortens this buffer by triming bytes off of the end of this buffer. * * @param count the number of bytes to trim off. * * @return this buffer. */ util.DataBuffer.prototype.truncate = function(count) { this.write = Math.max(0, this.length() - count); this.read = Math.min(this.read, this.write); return this; }; /** * Converts this buffer to a hexadecimal string. * * @return a hexadecimal string. */ util.DataBuffer.prototype.toHex = function() { var rval = ""; for (var i = this.read; i < this.data.byteLength; ++i) { var b = this.data.getUint8(i); if (b < 16) { rval += "0"; } rval += b.toString(16); } return rval; }; /** * Converts this buffer to a string, using the given encoding. If no * encoding is given, 'utf8' (UTF-8) is used. * * @param [encoding] the encoding to use: 'binary', 'utf8', 'utf16', 'hex', * 'base64' (default: 'utf8'). * * @return a string representation of the bytes in this buffer. */ util.DataBuffer.prototype.toString = function(encoding) { var view = new Uint8Array(this.data, this.read, this.length()); encoding = encoding || "utf8"; if (encoding === "binary" || encoding === "raw") { return util.binary.raw.encode(view); } if (encoding === "hex") { return util.binary.hex.encode(view); } if (encoding === "base64") { return util.binary.base64.encode(view); } if (encoding === "utf8") { return util.text.utf8.decode(view); } if (encoding === "utf16") { return util.text.utf16.decode(view); } throw new Error("Invalid encoding: " + encoding); }; /** End Buffer w/UInt8Array backing */ /** * Creates a buffer that stores bytes. A value may be given to populate the * buffer with data. This value can either be string of encoded bytes or a * regular string of characters. When passing a string of binary encoded * bytes, the encoding `raw` should be given. This is also the default. When * passing a string of characters, the encoding `utf8` should be given. * * @param [input] a string with encoded bytes to store in the buffer. * @param [encoding] (default: 'raw', other: 'utf8'). */ util.createBuffer = function(input, encoding) { encoding = encoding || "raw"; if (input !== undefined && encoding === "utf8") { input = util.encodeUtf8(input); } return new util.ByteBuffer(input); }; /** * Fills a string with a particular value. If you want the string to be a byte * string, pass in String.fromCharCode(theByte). * * @param c the character to fill the string with, use String.fromCharCode * to fill the string with a byte value. * @param n the number of characters of value c to fill with. * * @return the filled string. */ util.fillString = function(c, n) { var s = ""; while (n > 0) { if (n & 1) { s += c; } n >>>= 1; if (n > 0) { c += c; } } return s; }; /** * Performs a per byte XOR between two byte strings and returns the result as a * string of bytes. * * @param s1 first string of bytes. * @param s2 second string of bytes. * @param n the number of bytes to XOR. * * @return the XOR'd result. */ util.xorBytes = function(s1, s2, n) { var s3 = ""; var b = ""; var t = ""; var i = 0; var c = 0; for (; n > 0; --n, ++i) { b = s1.charCodeAt(i) ^ s2.charCodeAt(i); if (c >= 10) { s3 += t; t = ""; c = 0; } t += String.fromCharCode(b); ++c; } s3 += t; return s3; }; /** * Converts a hex string into a 'binary' encoded string of bytes. * * @param hex the hexadecimal string to convert. * * @return the binary-encoded string of bytes. */ util.hexToBytes = function(hex) { var rval = ""; var i = 0; if (hex.length & 1 == 1) { i = 1; rval += String.fromCharCode(parseInt(hex[0], 16)); } for (; i < hex.length; i += 2) { rval += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); } return rval; }; /** * Converts a 'binary' encoded string of bytes to hex. * * @param bytes the byte string to convert. * * @return the string of hexadecimal characters. */ util.bytesToHex = function(bytes) { return util.createBuffer(bytes).toHex(); }; /** * Converts an 32-bit integer to 4-big-endian byte string. * * @param i the integer. * * @return the byte string. */ util.int32ToBytes = function(i) { return String.fromCharCode(i >> 24 & 255) + String.fromCharCode(i >> 16 & 255) + String.fromCharCode(i >> 8 & 255) + String.fromCharCode(i & 255); }; var _base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; var _base64Idx = [ 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, 64, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 ]; var _base58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; /** * Base64 encodes a 'binary' encoded string of bytes. * * @param input the binary encoded string of bytes to base64-encode. * @param maxline the maximum number of encoded characters per line to use, * defaults to none. * * @return the base64-encoded output. */ util.encode64 = function(input, maxline) { var line = ""; var output = ""; var chr1, chr2, chr3; var i = 0; while (i < input.length) { chr1 = input.charCodeAt(i++); chr2 = input.charCodeAt(i++); chr3 = input.charCodeAt(i++); line += _base64.charAt(chr1 >> 2); line += _base64.charAt((chr1 & 3) << 4 | chr2 >> 4); if (isNaN(chr2)) { line += "=="; } else { line += _base64.charAt((chr2 & 15) << 2 | chr3 >> 6); line += isNaN(chr3) ? "=" : _base64.charAt(chr3 & 63); } if (maxline && line.length > maxline) { output += line.substr(0, maxline) + "\r\n"; line = line.substr(maxline); } } output += line; return output; }; /** * Base64 decodes a string into a 'binary' encoded string of bytes. * * @param input the base64-encoded input. * * @return the binary encoded string. */ util.decode64 = function(input) { input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); var output = ""; var enc1, enc2, enc3, enc4; var i = 0; while (i < input.length) { enc1 = _base64Idx[input.charCodeAt(i++) - 43]; enc2 = _base64Idx[input.charCodeAt(i++) - 43]; enc3 = _base64Idx[input.charCodeAt(i++) - 43]; enc4 = _base64Idx[input.charCodeAt(i++) - 43]; output += String.fromCharCode(enc1 << 2 | enc2 >> 4); if (enc3 !== 64) { output += String.fromCharCode((enc2 & 15) << 4 | enc3 >> 2); if (enc4 !== 64) { output += String.fromCharCode((enc3 & 3) << 6 | enc4); } } } return output; }; /** * Encodes the given string of characters (a standard JavaScript * string) as a binary encoded string where the bytes represent * a UTF-8 encoded string of characters. Non-ASCII characters will be * encoded as multiple bytes according to UTF-8. * * @param str a standard string of characters to encode. * * @return the binary encoded string. */ util.encodeUtf8 = function(str) { return unescape(encodeURIComponent(str)); }; /** * Decodes a binary encoded string that contains bytes that * represent a UTF-8 encoded string of characters -- into a * string of characters (a standard JavaScript string). * * @param str the binary encoded string to decode. * * @return the resulting standard string of characters. */ util.decodeUtf8 = function(str) { return decodeURIComponent(escape(str)); }; util.binary = { raw: {}, hex: {}, base64: {}, base58: {}, baseN: { encode: baseN.encode, decode: baseN.decode } }; /** * Encodes a Uint8Array as a binary-encoded string. This encoding uses * a value between 0 and 255 for each character. * * @param bytes the Uint8Array to encode. * * @return the binary-encoded string. */ util.binary.raw.encode = function(bytes) { return String.fromCharCode.apply(null, bytes); }; /** * Decodes a binary-encoded string to a Uint8Array. This encoding uses * a value between 0 and 255 for each character. * * @param str the binary-encoded string to decode. * @param [output] an optional Uint8Array to write the output to; if it * is too small, an exception will be thrown. * @param [offset] the start offset for writing to the output (default: 0). * * @return the Uint8Array or the number of bytes written if output was given. */ util.binary.raw.decode = function(str, output, offset) { var out = output; if (!out) { out = new Uint8Array(str.length); } offset = offset || 0; var j = offset; for (var i = 0; i < str.length; ++i) { out[j++] = str.charCodeAt(i); } return output ? j - offset : out; }; /** * Encodes a 'binary' string, ArrayBuffer, DataView, TypedArray, or * ByteBuffer as a string of hexadecimal characters. * * @param bytes the bytes to convert. * * @return the string of hexadecimal characters. */ util.binary.hex.encode = util.bytesToHex; /** * Decodes a hex-encoded string to a Uint8Array. * * @param hex the hexadecimal string to convert. * @param [output] an optional Uint8Array to write the output to; if it * is too small, an exception will be thrown. * @param [offset] the start offset for writing to the output (default: 0). * * @return the Uint8Array or the number of bytes written if output was given. */ util.binary.hex.decode = function(hex, output, offset) { var out = output; if (!out) { out = new Uint8Array(Math.ceil(hex.length / 2)); } offset = offset || 0; var i = 0, j = offset; if (hex.length & 1) { i = 1; out[j++] = parseInt(hex[0], 16); } for (; i < hex.length; i += 2) { out[j++] = parseInt(hex.substr(i, 2), 16); } return output ? j - offset : out; }; /** * Base64-encodes a Uint8Array. * * @param input the Uint8Array to encode. * @param maxline the maximum number of encoded characters per line to use, * defaults to none. * * @return the base64-encoded output string. */ util.binary.base64.encode = function(input, maxline) { var line = ""; var output = ""; var chr1, chr2, chr3; var i = 0; while (i < input.byteLength) { chr1 = input[i++]; chr2 = input[i++]; chr3 = input[i++]; line += _base64.charAt(chr1 >> 2); line += _base64.charAt((chr1 & 3) << 4 | chr2 >> 4); if (isNaN(chr2)) { line += "=="; } else { line += _base64.charAt((chr2 & 15) << 2 | chr3 >> 6); line += isNaN(chr3) ? "=" : _base64.charAt(chr3 & 63); } if (maxline && line.length > maxline) { output += line.substr(0, maxline) + "\r\n"; line = line.substr(maxline); } } output += line; return output; }; /** * Decodes a base64-encoded string to a Uint8Array. * * @param input the base64-encoded input string. * @param [output] an optional Uint8Array to write the output to; if it * is too small, an exception will be thrown. * @param [offset] the start offset for writing to the output (default: 0). * * @return the Uint8Array or the number of bytes written if output was given. */ util.binary.base64.decode = function(input, output, offset) { var out = output; if (!out) { out = new Uint8Array(Math.ceil(input.length / 4) * 3); } input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); offset = offset || 0; var enc1, enc2, enc3, enc4; var i = 0, j = offset; while (i < input.length) { enc1 = _base64Idx[input.charCodeAt(i++) - 43]; enc2 = _base64Idx[input.charCodeAt(i++) - 43]; enc3 = _base64Idx[input.charCodeAt(i++) - 43]; enc4 = _base64Idx[input.charCodeAt(i++) - 43]; out[j++] = enc1 << 2 | enc2 >> 4; if (enc3 !== 64) { out[j++] = (enc2 & 15) << 4 | enc3 >> 2; if (enc4 !== 64) { out[j++] = (enc3 & 3) << 6 | enc4; } } } return output ? j - offset : out.subarray(0, j); }; util.binary.base58.encode = function(input, maxline) { return util.binary.baseN.encode(input, _base58, maxline); }; util.binary.base58.decode = function(input, maxline) { return util.binary.baseN.decode(input, _base58, maxline); }; util.text = { utf8: {}, utf16: {} }; /** * Encodes the given string as UTF-8 in a Uint8Array. * * @param str the string to encode. * @param [output] an optional Uint8Array to write the output to; if it * is too small, an exception will be thrown. * @param [offset] the start offset for writing to the output (default: 0). * * @return the Uint8Array or the number of bytes written if output was given. */ util.text.utf8.encode = function(str, output, offset) { str = util.encodeUtf8(str); var out = output; if (!out) { out = new Uint8Array(str.length); } offset = offset || 0; var j = offset; for (var i = 0; i < str.length; ++i) { out[j++] = str.charCodeAt(i); } return output ? j - offset : out; }; /** * Decodes the UTF-8 contents from a Uint8Array. * * @param bytes the Uint8Array to decode. * * @return the resulting string. */ util.text.utf8.decode = function(bytes) { return util.decodeUtf8(String.fromCharCode.apply(null, bytes)); }; /** * Encodes the given string as UTF-16 in a Uint8Array. * * @param str the string to encode. * @param [output] an optional Uint8Array to write the output to; if it * is too small, an exception will be thrown. * @param [offset] the start offset for writing to the output (default: 0). * * @return the Uint8Array or the number of bytes written if output was given. */ util.text.utf16.encode = function(str, output, offset) { var out = output; if (!out) { out = new Uint8Array(str.length * 2); } var view = new Uint16Array(out.buffer); offset = offset || 0; var j = offset; var k = offset; for (var i = 0; i < str.length; ++i) { view[k++] = str.charCodeAt(i); j += 2; } return output ? j - offset : out; }; /** * Decodes the UTF-16 contents from a Uint8Array. * * @param bytes the Uint8Array to decode. * * @return the resulting string. */ util.text.utf16.decode = function(bytes) { return String.fromCharCode.apply(null, new Uint16Array(bytes.buffer)); }; /** * Deflates the given data using a flash interface. * * @param api the flash interface. * @param bytes the data. * @param raw true to return only raw deflate data, false to include zlib * header and trailer. * * @return the deflated data as a string. */ util.deflate = function(api, bytes, raw) { bytes = util.decode64(api.deflate(util.encode64(bytes)).rval); if (raw) { var start = 2; var flg = bytes.charCodeAt(1); if (flg & 32) { start = 6; } bytes = bytes.substring(start, bytes.length - 4); } return bytes; }; /** * Inflates the given data using a flash interface. * * @param api the flash interface. * @param bytes the data. * @param raw true if the incoming data has no zlib header or trailer and is * raw DEFLATE data. * * @return the inflated data as a string, null on error. */ util.inflate = function(api, bytes, raw) { var rval = api.inflate(util.encode64(bytes)).rval; return rval === null ? null : util.decode64(rval); }; /** * Sets a storage object. * * @param api the storage interface. * @param id the storage ID to use. * @param obj the storage object, null to remove. */ var _setStorageObject = function(api, id, obj) { if (!api) { throw new Error("WebStorage not available."); } var rval; if (obj === null) { rval = api.removeItem(id); } else { obj = util.encode64(JSON.stringify(obj)); rval = api.setItem(id, obj); } if (typeof rval !== "undefined" && rval.rval !== true) { var error = new Error(rval.error.message); error.id = rval.error.id; error.name = rval.error.name; throw error; } }; /** * Gets a storage object. * * @param api the storage interface. * @param id the storage ID to use. * * @return the storage object entry or null if none exists. */ var _getStorageObject = function(api, id) { if (!api) { throw new Error("WebStorage not available."); } var rval = api.getItem(id); if (api.init) { if (rval.rval === null) { if (rval.error) { var error = new Error(rval.error.message); error.id = rval.error.id; error.name = rval.error.name; throw error; } rval = null; } else { rval = rval.rval; } } if (rval !== null) { rval = JSON.parse(util.decode64(rval)); } return rval; }; /** * Stores an item in local storage. * * @param api the storage interface. * @param id the storage ID to use. * @param key the key for the item. * @param data the data for the item (any javascript object/primitive). */ var _setItem = function(api, id, key, data) { var obj = _getStorageObject(api, id); if (obj === null) { obj = {}; } obj[key] = data; _setStorageObject(api, id, obj); }; /** * Gets an item from local storage. * * @param api the storage interface. * @param id the storage ID to use. * @param key the key for the item. * * @return the item. */ var _getItem = function(api, id, key) { var rval = _getStorageObject(api, id); if (rval !== null) { rval = key in rval ? rval[key] : null; } return rval; }; /** * Removes an item from local storage. * * @param api the storage interface. * @param id the storage ID to use. * @param key the key for the item. */ var _removeItem = function(api, id, key) { var obj = _getStorageObject(api, id); if (obj !== null && key in obj) { delete obj[key]; var empty = true; for (var prop in obj) { empty = false; break; } if (empty) { obj = null; } _setStorageObject(api, id, obj); } }; /** * Clears the local disk storage identified by the given ID. * * @param api the storage interface. * @param id the storage ID to use. */ var _clearItems = function(api, id) { _setStorageObject(api, id, null); }; /** * Calls a storage function. * * @param func the function to call. * @param args the arguments for the function. * @param location the location argument. * * @return the return value from the function. */ var _callStorageFunction = function(func, args, location) { var rval = null; if (typeof location === "undefined") { location = ["web", "flash"]; } var type; var done = false; var exception = null; for (var idx in location) { type = location[idx]; try { if (type === "flash" || type === "both") { if (args[0] === null) { throw new Error("Flash local storage not available."); } rval = func.apply(this, args); done = type === "flash"; } if (type === "web" || type === "both") { args[0] = localStorage; rval = func.apply(this, args); done = true; } } catch (ex) { exception = ex; } if (done) { break; } } if (!done) { throw exception; } return rval; }; /** * Stores an item on local disk. * * The available types of local storage include 'flash', 'web', and 'both'. * * The type 'flash' refers to flash local storage (SharedObject). In order * to use flash local storage, the 'api' parameter must be valid. The type * 'web' refers to WebStorage, if supported by the browser. The type 'both' * refers to storing using both 'flash' and 'web', not just one or the * other. * * The location array should list the storage types to use in order of * preference: * * ['flash']: flash only storage * ['web']: web only storage * ['both']: try to store in both * ['flash','web']: store in flash first, but if not available, 'web' * ['web','flash']: store in web first, but if not available, 'flash' * * The location array defaults to: ['web', 'flash'] * * @param api the flash interface, null to use only WebStorage. * @param id the storage ID to use. * @param key the key for the item. * @param data the data for the item (any javascript object/primitive). * @param location an array with the preferred types of storage to use. */ util.setItem = function(api, id, key, data, location) { _callStorageFunction(_setItem, arguments, location); }; /** * Gets an item on local disk. * * Set setItem() for details on storage types. * * @param api the flash interface, null to use only WebStorage. * @param id the storage ID to use. * @param key the key for the item. * @param location an array with the preferred types of storage to use. * * @return the item. */ util.getItem = function(api, id, key, location) { return _callStorageFunction(_getItem, arguments, location); }; /** * Removes an item on local disk. * * Set setItem() for details on storage types. * * @param api the flash interface. * @param id the storage ID to use. * @param key the key for the item. * @param location an array with the preferred types of storage to use. */ util.removeItem = function(api, id, key, location) { _callStorageFunction(_removeItem, arguments, location); }; /** * Clears the local disk storage identified by the given ID. * * Set setItem() for details on storage types. * * @param api the flash interface if flash is available. * @param id the storage ID to use. * @param location an array with the preferred types of storage to use. */ util.clearItems = function(api, id, location) { _callStorageFunction(_clearItems, arguments, location); }; /** * Check if an object is empty. * * Taken from: * http://stackoverflow.com/questions/679915/how-do-i-test-for-an-empty-javascript-object-from-json/679937#679937 * * @param object the object to check. */ util.isEmpty = function(obj) { for (var prop in obj) { if (obj.hasOwnProperty(prop)) { return false; } } return true; }; /** * Format with simple printf-style interpolation. * * %%: literal '%' * %s,%o: convert next argument into a string. * * @param format the string to format. * @param ... arguments to interpolate into the format string. */ util.format = function(format) { var re = /%./g; var match; var part; var argi = 0; var parts = []; var last = 0; while (match = re.exec(format)) { part = format.substring(last, re.lastIndex - 2); if (part.length > 0) { parts.push(part); } last = re.lastIndex; var code = match[0][1]; switch (code) { case "s": case "o": if (argi < arguments.length) { parts.push(arguments[argi++ + 1]); } else { parts.push(""); } break; case "%": parts.push("%"); break; default: parts.push("<%" + code + "?>"); } } parts.push(format.substring(last)); return parts.join(""); }; /** * Formats a number. * * http://snipplr.com/view/5945/javascript-numberformat--ported-from-php/ */ util.formatNumber = function(number, decimals, dec_point, thousands_sep) { var n = number, c = isNaN(decimals = Math.abs(decimals)) ? 2 : decimals; var d = dec_point === undefined ? "," : dec_point; var t = thousands_sep === undefined ? "." : thousands_sep, s = n < 0 ? "-" : ""; var i = parseInt(n = Math.abs(+n || 0).toFixed(c), 10) + ""; var j = i.length > 3 ? i.length % 3 : 0; return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : ""); }; /** * Formats a byte size. * * http://snipplr.com/view/5949/format-humanize-file-byte-size-presentation-in-javascript/ */ util.formatSize = function(size) { if (size >= 1073741824) { size = util.formatNumber(size / 1073741824, 2, ".", "") + " GiB"; } else if (size >= 1048576) { size = util.formatNumber(size / 1048576, 2, ".", "") + " MiB"; } else if (size >= 1024) { size = util.formatNumber(size / 1024, 0) + " KiB"; } else { size = util.formatNumber(size, 0) + " bytes"; } return size; }; /** * Converts an IPv4 or IPv6 string representation into bytes (in network order). * * @param ip the IPv4 or IPv6 address to convert. * * @return the 4-byte IPv6 or 16-byte IPv6 address or null if the address can't * be parsed. */ util.bytesFromIP = function(ip) { if (ip.indexOf(".") !== -1) { return util.bytesFromIPv4(ip); } if (ip.indexOf(":") !== -1) { return util.bytesFromIPv6(ip); } return null; }; /** * Converts an IPv4 string representation into bytes (in network order). * * @param ip the IPv4 address to convert. * * @return the 4-byte address or null if the address can't be parsed. */ util.bytesFromIPv4 = function(ip) { ip = ip.split("."); if (ip.length !== 4) { return null; } var b = util.createBuffer(); for (var i = 0; i < ip.length; ++i) { var num = parseInt(ip[i], 10); if (isNaN(num)) { return null; } b.putByte(num); } return b.getBytes(); }; /** * Converts an IPv6 string representation into bytes (in network order). * * @param ip the IPv6 address to convert. * * @return the 16-byte address or null if the address can't be parsed. */ util.bytesFromIPv6 = function(ip) { var blanks = 0; ip = ip.split(":").filter(function(e) { if (e.length === 0) ++blanks; return true; }); var zeros = (8 - ip.length + blanks) * 2; var b = util.createBuffer(); for (var i = 0; i < 8; ++i) { if (!ip[i] || ip[i].length === 0) { b.fillWithByte(0, zeros); zeros = 0; continue; } var bytes = util.hexToBytes(ip[i]); if (bytes.length < 2) { b.putByte(0); } b.putBytes(bytes); } return b.getBytes(); }; /** * Converts 4-bytes into an IPv4 string representation or 16-bytes into * an IPv6 string representation. The bytes must be in network order. * * @param bytes the bytes to convert. * * @return the IPv4 or IPv6 string representation if 4 or 16 bytes, * respectively, are given, otherwise null. */ util.bytesToIP = function(bytes) { if (bytes.length === 4) { return util.bytesToIPv4(bytes); } if (bytes.length === 16) { return util.bytesToIPv6(bytes); } return null; }; /** * Converts 4-bytes into an IPv4 string representation. The bytes must be * in network order. * * @param bytes the bytes to convert. * * @return the IPv4 string representation or null for an invalid # of bytes. */ util.bytesToIPv4 = function(bytes) { if (bytes.length !== 4) { return null; } var ip = []; for (var i = 0; i < bytes.length; ++i) { ip.push(bytes.charCodeAt(i)); } return ip.join("."); }; /** * Converts 16-bytes into an IPv16 string representation. The bytes must be * in network order. * * @param bytes the bytes to convert. * * @return the IPv16 string representation or null for an invalid # of bytes. */ util.bytesToIPv6 = function(bytes) { if (bytes.length !== 16) { return null; } var ip = []; var zeroGroups = []; var zeroMaxGroup = 0; for (var i = 0; i < bytes.length; i += 2) { var hex = util.bytesToHex(bytes[i] + bytes[i + 1]); while (hex[0] === "0" && hex !== "0") { hex = hex.substr(1); } if (hex === "0") { var last = zeroGroups[zeroGroups.length - 1]; var idx = ip.length; if (!last || idx !== last.end + 1) { zeroGroups.push({ start: idx, end: idx }); } else { last.end = idx; if (last.end - last.start > zeroGroups[zeroMaxGroup].end - zeroGroups[zeroMaxGroup].start) { zeroMaxGroup = zeroGroups.length - 1; } } } ip.push(hex); } if (zeroGroups.length > 0) { var group = zeroGroups[zeroMaxGroup]; if (group.end - group.start > 0) { ip.splice(group.start, group.end - group.start + 1, ""); if (group.start === 0) { ip.unshift(""); } if (group.end === 7) { ip.push(""); } } } return ip.join(":"); }; /** * Estimates the number of processes that can be run concurrently. If * creating Web Workers, keep in mind that the main JavaScript process needs * its own core. * * @param options the options to use: * update true to force an update (not use the cached value). * @param callback(err, max) called once the operation completes. */ util.estimateCores = function(options, callback) { if (typeof options === "function") { callback = options; options = {}; } options = options || {}; if ("cores" in util && !options.update) { return callback(null, util.cores); } if (typeof navigator !== "undefined" && "hardwareConcurrency" in navigator && navigator.hardwareConcurrency > 0) { util.cores = navigator.hardwareConcurrency; return callback(null, util.cores); } if (typeof Worker === "undefined") { util.cores = 1; return callback(null, util.cores); } if (typeof Blob === "undefined") { util.cores = 2; return callback(null, util.cores); } var blobUrl = URL.createObjectURL(new Blob([ "(", function() { self.addEventListener("message", function(e) { var st = Date.now(); var et = st + 4; while (Date.now() < et); self.postMessage({ st, et }); }); }.toString(), ")()" ], { type: "application/javascript" })); sample([], 5, 16); function sample(max, samples, numWorkers) { if (samples === 0) { var avg = Math.floor(max.reduce(function(avg, x) { return avg + x; }, 0) / max.length); util.cores = Math.max(1, avg); URL.revokeObjectURL(blobUrl); return callback(null, util.cores); } map(numWorkers, function(err, results) { max.push(reduce(numWorkers, results)); sample(max, samples - 1, numWorkers); }); } function map(numWorkers, callback) { var workers = []; var results = []; for (var i = 0; i < numWorkers; ++i) { var worker = new Worker(blobUrl); worker.addEventListener("message", function(e) { results.push(e.data); if (results.length === numWorkers) { for (var i = 0; i < numWorkers; ++i) { workers[i].terminate(); } callback(null, results); } }); workers.push(worker); } for (var i = 0; i < numWorkers; ++i) { workers[i].postMessage(i); } } function reduce(numWorkers, results) { var overlaps = []; for (var n = 0; n < numWorkers; ++n) { var r1 = results[n]; var overlap = overlaps[n] = []; for (var i = 0; i < numWorkers; ++i) { if (n === i) { continue; } var r2 = results[i]; if (r1.st > r2.st && r1.st < r2.et || r2.st > r1.st && r2.st < r1.et) { overlap.push(i); } } } return overlaps.reduce(function(max, overlap) { return Math.max(max, overlap.length); }, 0); } }; })); //#endregion //#region ../node_modules/node-forge/lib/cipher.js var require_cipher = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Cipher base API. * * @author Dave Longley * * Copyright (c) 2010-2014 Digital Bazaar, Inc. */ var forge = require_forge(); require_util$8(); module.exports = forge.cipher = forge.cipher || {}; forge.cipher.algorithms = forge.cipher.algorithms || {}; /** * Creates a cipher object that can be used to encrypt data using the given * algorithm and key. The algorithm may be provided as a string value for a * previously registered algorithm or it may be given as a cipher algorithm * API object. * * @param algorithm the algorithm to use, either a string or an algorithm API * object. * @param key the key to use, as a binary-encoded string of bytes or a * byte buffer. * * @return the cipher. */ forge.cipher.createCipher = function(algorithm, key) { var api = algorithm; if (typeof api === "string") { api = forge.cipher.getAlgorithm(api); if (api) { api = api(); } } if (!api) { throw new Error("Unsupported algorithm: " + algorithm); } return new forge.cipher.BlockCipher({ algorithm: api, key, decrypt: false }); }; /** * Creates a decipher object that can be used to decrypt data using the given * algorithm and key. The algorithm may be provided as a string value for a * previously registered algorithm or it may be given as a cipher algorithm * API object. * * @param algorithm the algorithm to use, either a string or an algorithm API * object. * @param key the key to use, as a binary-encoded string of bytes or a * byte buffer. * * @return the cipher. */ forge.cipher.createDecipher = function(algorithm, key) { var api = algorithm; if (typeof api === "string") { api = forge.cipher.getAlgorithm(api); if (api) { api = api(); } } if (!api) { throw new Error("Unsupported algorithm: " + algorithm); } return new forge.cipher.BlockCipher({ algorithm: api, key, decrypt: true }); }; /** * Registers an algorithm by name. If the name was already registered, the * algorithm API object will be overwritten. * * @param name the name of the algorithm. * @param algorithm the algorithm API object. */ forge.cipher.registerAlgorithm = function(name, algorithm) { name = name.toUpperCase(); forge.cipher.algorithms[name] = algorithm; }; /** * Gets a registered algorithm by name. * * @param name the name of the algorithm. * * @return the algorithm, if found, null if not. */ forge.cipher.getAlgorithm = function(name) { name = name.toUpperCase(); if (name in forge.cipher.algorithms) { return forge.cipher.algorithms[name]; } return null; }; var BlockCipher = forge.cipher.BlockCipher = function(options) { this.algorithm = options.algorithm; this.mode = this.algorithm.mode; this.blockSize = this.mode.blockSize; this._finish = false; this._input = null; this.output = null; this._op = options.decrypt ? this.mode.decrypt : this.mode.encrypt; this._decrypt = options.decrypt; this.algorithm.initialize(options); }; /** * Starts or restarts the encryption or decryption process, whichever * was previously configured. * * For non-GCM mode, the IV may be a binary-encoded string of bytes, an array * of bytes, a byte buffer, or an array of 32-bit integers. If the IV is in * bytes, then it must be Nb (16) bytes in length. If the IV is given in as * 32-bit integers, then it must be 4 integers long. * * Note: an IV is not required or used in ECB mode. * * For GCM-mode, the IV must be given as a binary-encoded string of bytes or * a byte buffer. The number of bytes should be 12 (96 bits) as recommended * by NIST SP-800-38D but another length may be given. * * @param options the options to use: * iv the initialization vector to use as a binary-encoded string of * bytes, null to reuse the last ciphered block from a previous * update() (this "residue" method is for legacy support only). * additionalData additional authentication data as a binary-encoded * string of bytes, for 'GCM' mode, (default: none). * tagLength desired length of authentication tag, in bits, for * 'GCM' mode (0-128, default: 128). * tag the authentication tag to check if decrypting, as a * binary-encoded string of bytes. * output the output the buffer to write to, null to create one. */ BlockCipher.prototype.start = function(options) { options = options || {}; var opts = {}; for (var key in options) { opts[key] = options[key]; } opts.decrypt = this._decrypt; this._finish = false; this._input = forge.util.createBuffer(); this.output = options.output || forge.util.createBuffer(); this.mode.start(opts); }; /** * Updates the next block according to the cipher mode. * * @param input the buffer to read from. */ BlockCipher.prototype.update = function(input) { if (input) { this._input.putBuffer(input); } while (!this._op.call(this.mode, this._input, this.output, this._finish) && !this._finish) {} this._input.compact(); }; /** * Finishes encrypting or decrypting. * * @param pad a padding function to use in CBC mode, null for default, * signature(blockSize, buffer, decrypt). * * @return true if successful, false on error. */ BlockCipher.prototype.finish = function(pad) { if (pad && (this.mode.name === "ECB" || this.mode.name === "CBC")) { this.mode.pad = function(input) { return pad(this.blockSize, input, false); }; this.mode.unpad = function(output) { return pad(this.blockSize, output, true); }; } var options = {}; options.decrypt = this._decrypt; options.overflow = this._input.length() % this.blockSize; if (!this._decrypt && this.mode.pad) { if (!this.mode.pad(this._input, options)) { return false; } } this._finish = true; this.update(); if (this._decrypt && this.mode.unpad) { if (!this.mode.unpad(this.output, options)) { return false; } } if (this.mode.afterFinish) { if (!this.mode.afterFinish(this.output, options)) { return false; } } return true; }; })); //#endregion //#region ../node_modules/node-forge/lib/cipherModes.js var require_cipherModes = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Supported cipher modes. * * @author Dave Longley * * Copyright (c) 2010-2014 Digital Bazaar, Inc. */ var forge = require_forge(); require_util$8(); forge.cipher = forge.cipher || {}; var modes = module.exports = forge.cipher.modes = forge.cipher.modes || {}; /** Electronic codebook (ECB) (Don't use this; it's not secure) **/ modes.ecb = function(options) { options = options || {}; this.name = "ECB"; this.cipher = options.cipher; this.blockSize = options.blockSize || 16; this._ints = this.blockSize / 4; this._inBlock = new Array(this._ints); this._outBlock = new Array(this._ints); }; modes.ecb.prototype.start = function(options) {}; modes.ecb.prototype.encrypt = function(input, output, finish) { if (input.length() < this.blockSize && !(finish && input.length() > 0)) { return true; } for (var i = 0; i < this._ints; ++i) { this._inBlock[i] = input.getInt32(); } this.cipher.encrypt(this._inBlock, this._outBlock); for (var i = 0; i < this._ints; ++i) { output.putInt32(this._outBlock[i]); } }; modes.ecb.prototype.decrypt = function(input, output, finish) { if (input.length() < this.blockSize && !(finish && input.length() > 0)) { return true; } for (var i = 0; i < this._ints; ++i) { this._inBlock[i] = input.getInt32(); } this.cipher.decrypt(this._inBlock, this._outBlock); for (var i = 0; i < this._ints; ++i) { output.putInt32(this._outBlock[i]); } }; modes.ecb.prototype.pad = function(input, options) { var padding = input.length() === this.blockSize ? this.blockSize : this.blockSize - input.length(); input.fillWithByte(padding, padding); return true; }; modes.ecb.prototype.unpad = function(output, options) { if (options.overflow > 0) { return false; } var len = output.length(); var count = output.at(len - 1); if (count > this.blockSize << 2) { return false; } output.truncate(count); return true; }; /** Cipher-block Chaining (CBC) **/ modes.cbc = function(options) { options = options || {}; this.name = "CBC"; this.cipher = options.cipher; this.blockSize = options.blockSize || 16; this._ints = this.blockSize / 4; this._inBlock = new Array(this._ints); this._outBlock = new Array(this._ints); }; modes.cbc.prototype.start = function(options) { if (options.iv === null) { if (!this._prev) { throw new Error("Invalid IV parameter."); } this._iv = this._prev.slice(0); } else if (!("iv" in options)) { throw new Error("Invalid IV parameter."); } else { this._iv = transformIV(options.iv, this.blockSize); this._prev = this._iv.slice(0); } }; modes.cbc.prototype.encrypt = function(input, output, finish) { if (input.length() < this.blockSize && !(finish && input.length() > 0)) { return true; } for (var i = 0; i < this._ints; ++i) { this._inBlock[i] = this._prev[i] ^ input.getInt32(); } this.cipher.encrypt(this._inBlock, this._outBlock); for (var i = 0; i < this._ints; ++i) { output.putInt32(this._outBlock[i]); } this._prev = this._outBlock; }; modes.cbc.prototype.decrypt = function(input, output, finish) { if (input.length() < this.blockSize && !(finish && input.length() > 0)) { return true; } for (var i = 0; i < this._ints; ++i) { this._inBlock[i] = input.getInt32(); } this.cipher.decrypt(this._inBlock, this._outBlock); for (var i = 0; i < this._ints; ++i) { output.putInt32(this._prev[i] ^ this._outBlock[i]); } this._prev = this._inBlock.slice(0); }; modes.cbc.prototype.pad = function(input, options) { var padding = input.length() === this.blockSize ? this.blockSize : this.blockSize - input.length(); input.fillWithByte(padding, padding); return true; }; modes.cbc.prototype.unpad = function(output, options) { if (options.overflow > 0) { return false; } var len = output.length(); var count = output.at(len - 1); if (count > this.blockSize << 2) { return false; } output.truncate(count); return true; }; /** Cipher feedback (CFB) **/ modes.cfb = function(options) { options = options || {}; this.name = "CFB"; this.cipher = options.cipher; this.blockSize = options.blockSize || 16; this._ints = this.blockSize / 4; this._inBlock = null; this._outBlock = new Array(this._ints); this._partialBlock = new Array(this._ints); this._partialOutput = forge.util.createBuffer(); this._partialBytes = 0; }; modes.cfb.prototype.start = function(options) { if (!("iv" in options)) { throw new Error("Invalid IV parameter."); } this._iv = transformIV(options.iv, this.blockSize); this._inBlock = this._iv.slice(0); this._partialBytes = 0; }; modes.cfb.prototype.encrypt = function(input, output, finish) { var inputLength = input.length(); if (inputLength === 0) { return true; } this.cipher.encrypt(this._inBlock, this._outBlock); if (this._partialBytes === 0 && inputLength >= this.blockSize) { for (var i = 0; i < this._ints; ++i) { this._inBlock[i] = input.getInt32() ^ this._outBlock[i]; output.putInt32(this._inBlock[i]); } return; } var partialBytes = (this.blockSize - inputLength) % this.blockSize; if (partialBytes > 0) { partialBytes = this.blockSize - partialBytes; } this._partialOutput.clear(); for (var i = 0; i < this._ints; ++i) { this._partialBlock[i] = input.getInt32() ^ this._outBlock[i]; this._partialOutput.putInt32(this._partialBlock[i]); } if (partialBytes > 0) { input.read -= this.blockSize; } else { for (var i = 0; i < this._ints; ++i) { this._inBlock[i] = this._partialBlock[i]; } } if (this._partialBytes > 0) { this._partialOutput.getBytes(this._partialBytes); } if (partialBytes > 0 && !finish) { output.putBytes(this._partialOutput.getBytes(partialBytes - this._partialBytes)); this._partialBytes = partialBytes; return true; } output.putBytes(this._partialOutput.getBytes(inputLength - this._partialBytes)); this._partialBytes = 0; }; modes.cfb.prototype.decrypt = function(input, output, finish) { var inputLength = input.length(); if (inputLength === 0) { return true; } this.cipher.encrypt(this._inBlock, this._outBlock); if (this._partialBytes === 0 && inputLength >= this.blockSize) { for (var i = 0; i < this._ints; ++i) { this._inBlock[i] = input.getInt32(); output.putInt32(this._inBlock[i] ^ this._outBlock[i]); } return; } var partialBytes = (this.blockSize - inputLength) % this.blockSize; if (partialBytes > 0) { partialBytes = this.blockSize - partialBytes; } this._partialOutput.clear(); for (var i = 0; i < this._ints; ++i) { this._partialBlock[i] = input.getInt32(); this._partialOutput.putInt32(this._partialBlock[i] ^ this._outBlock[i]); } if (partialBytes > 0) { input.read -= this.blockSize; } else { for (var i = 0; i < this._ints; ++i) { this._inBlock[i] = this._partialBlock[i]; } } if (this._partialBytes > 0) { this._partialOutput.getBytes(this._partialBytes); } if (partialBytes > 0 && !finish) { output.putBytes(this._partialOutput.getBytes(partialBytes - this._partialBytes)); this._partialBytes = partialBytes; return true; } output.putBytes(this._partialOutput.getBytes(inputLength - this._partialBytes)); this._partialBytes = 0; }; /** Output feedback (OFB) **/ modes.ofb = function(options) { options = options || {}; this.name = "OFB"; this.cipher = options.cipher; this.blockSize = options.blockSize || 16; this._ints = this.blockSize / 4; this._inBlock = null; this._outBlock = new Array(this._ints); this._partialOutput = forge.util.createBuffer(); this._partialBytes = 0; }; modes.ofb.prototype.start = function(options) { if (!("iv" in options)) { throw new Error("Invalid IV parameter."); } this._iv = transformIV(options.iv, this.blockSize); this._inBlock = this._iv.slice(0); this._partialBytes = 0; }; modes.ofb.prototype.encrypt = function(input, output, finish) { var inputLength = input.length(); if (input.length() === 0) { return true; } this.cipher.encrypt(this._inBlock, this._outBlock); if (this._partialBytes === 0 && inputLength >= this.blockSize) { for (var i = 0; i < this._ints; ++i) { output.putInt32(input.getInt32() ^ this._outBlock[i]); this._inBlock[i] = this._outBlock[i]; } return; } var partialBytes = (this.blockSize - inputLength) % this.blockSize; if (partialBytes > 0) { partialBytes = this.blockSize - partialBytes; } this._partialOutput.clear(); for (var i = 0; i < this._ints; ++i) { this._partialOutput.putInt32(input.getInt32() ^ this._outBlock[i]); } if (partialBytes > 0) { input.read -= this.blockSize; } else { for (var i = 0; i < this._ints; ++i) { this._inBlock[i] = this._outBlock[i]; } } if (this._partialBytes > 0) { this._partialOutput.getBytes(this._partialBytes); } if (partialBytes > 0 && !finish) { output.putBytes(this._partialOutput.getBytes(partialBytes - this._partialBytes)); this._partialBytes = partialBytes; return true; } output.putBytes(this._partialOutput.getBytes(inputLength - this._partialBytes)); this._partialBytes = 0; }; modes.ofb.prototype.decrypt = modes.ofb.prototype.encrypt; /** Counter (CTR) **/ modes.ctr = function(options) { options = options || {}; this.name = "CTR"; this.cipher = options.cipher; this.blockSize = options.blockSize || 16; this._ints = this.blockSize / 4; this._inBlock = null; this._outBlock = new Array(this._ints); this._partialOutput = forge.util.createBuffer(); this._partialBytes = 0; }; modes.ctr.prototype.start = function(options) { if (!("iv" in options)) { throw new Error("Invalid IV parameter."); } this._iv = transformIV(options.iv, this.blockSize); this._inBlock = this._iv.slice(0); this._partialBytes = 0; }; modes.ctr.prototype.encrypt = function(input, output, finish) { var inputLength = input.length(); if (inputLength === 0) { return true; } this.cipher.encrypt(this._inBlock, this._outBlock); if (this._partialBytes === 0 && inputLength >= this.blockSize) { for (var i = 0; i < this._ints; ++i) { output.putInt32(input.getInt32() ^ this._outBlock[i]); } } else { var partialBytes = (this.blockSize - inputLength) % this.blockSize; if (partialBytes > 0) { partialBytes = this.blockSize - partialBytes; } this._partialOutput.clear(); for (var i = 0; i < this._ints; ++i) { this._partialOutput.putInt32(input.getInt32() ^ this._outBlock[i]); } if (partialBytes > 0) { input.read -= this.blockSize; } if (this._partialBytes > 0) { this._partialOutput.getBytes(this._partialBytes); } if (partialBytes > 0 && !finish) { output.putBytes(this._partialOutput.getBytes(partialBytes - this._partialBytes)); this._partialBytes = partialBytes; return true; } output.putBytes(this._partialOutput.getBytes(inputLength - this._partialBytes)); this._partialBytes = 0; } inc32(this._inBlock); }; modes.ctr.prototype.decrypt = modes.ctr.prototype.encrypt; /** Galois/Counter Mode (GCM) **/ modes.gcm = function(options) { options = options || {}; this.name = "GCM"; this.cipher = options.cipher; this.blockSize = options.blockSize || 16; this._ints = this.blockSize / 4; this._inBlock = new Array(this._ints); this._outBlock = new Array(this._ints); this._partialOutput = forge.util.createBuffer(); this._partialBytes = 0; this._R = 3774873600; }; modes.gcm.prototype.start = function(options) { if (!("iv" in options)) { throw new Error("Invalid IV parameter."); } var iv = forge.util.createBuffer(options.iv); this._cipherLength = 0; var additionalData; if ("additionalData" in options) { additionalData = forge.util.createBuffer(options.additionalData); } else { additionalData = forge.util.createBuffer(); } if ("tagLength" in options) { this._tagLength = options.tagLength; } else { this._tagLength = 128; } this._tag = null; if (options.decrypt) { this._tag = forge.util.createBuffer(options.tag).getBytes(); if (this._tag.length !== this._tagLength / 8) { throw new Error("Authentication tag does not match tag length."); } } this._hashBlock = new Array(this._ints); this.tag = null; this._hashSubkey = new Array(this._ints); this.cipher.encrypt([ 0, 0, 0, 0 ], this._hashSubkey); this.componentBits = 4; this._m = this.generateHashTable(this._hashSubkey, this.componentBits); var ivLength = iv.length(); if (ivLength === 12) { this._j0 = [ iv.getInt32(), iv.getInt32(), iv.getInt32(), 1 ]; } else { this._j0 = [ 0, 0, 0, 0 ]; while (iv.length() > 0) { this._j0 = this.ghash(this._hashSubkey, this._j0, [ iv.getInt32(), iv.getInt32(), iv.getInt32(), iv.getInt32() ]); } this._j0 = this.ghash(this._hashSubkey, this._j0, [0, 0].concat(from64To32(ivLength * 8))); } this._inBlock = this._j0.slice(0); inc32(this._inBlock); this._partialBytes = 0; additionalData = forge.util.createBuffer(additionalData); this._aDataLength = from64To32(additionalData.length() * 8); var overflow = additionalData.length() % this.blockSize; if (overflow) { additionalData.fillWithByte(0, this.blockSize - overflow); } this._s = [ 0, 0, 0, 0 ]; while (additionalData.length() > 0) { this._s = this.ghash(this._hashSubkey, this._s, [ additionalData.getInt32(), additionalData.getInt32(), additionalData.getInt32(), additionalData.getInt32() ]); } }; modes.gcm.prototype.encrypt = function(input, output, finish) { var inputLength = input.length(); if (inputLength === 0) { return true; } this.cipher.encrypt(this._inBlock, this._outBlock); if (this._partialBytes === 0 && inputLength >= this.blockSize) { for (var i = 0; i < this._ints; ++i) { output.putInt32(this._outBlock[i] ^= input.getInt32()); } this._cipherLength += this.blockSize; } else { var partialBytes = (this.blockSize - inputLength) % this.blockSize; if (partialBytes > 0) { partialBytes = this.blockSize - partialBytes; } this._partialOutput.clear(); for (var i = 0; i < this._ints; ++i) { this._partialOutput.putInt32(input.getInt32() ^ this._outBlock[i]); } if (partialBytes <= 0 || finish) { if (finish) { var overflow = inputLength % this.blockSize; this._cipherLength += overflow; this._partialOutput.truncate(this.blockSize - overflow); } else { this._cipherLength += this.blockSize; } for (var i = 0; i < this._ints; ++i) { this._outBlock[i] = this._partialOutput.getInt32(); } this._partialOutput.read -= this.blockSize; } if (this._partialBytes > 0) { this._partialOutput.getBytes(this._partialBytes); } if (partialBytes > 0 && !finish) { input.read -= this.blockSize; output.putBytes(this._partialOutput.getBytes(partialBytes - this._partialBytes)); this._partialBytes = partialBytes; return true; } output.putBytes(this._partialOutput.getBytes(inputLength - this._partialBytes)); this._partialBytes = 0; } this._s = this.ghash(this._hashSubkey, this._s, this._outBlock); inc32(this._inBlock); }; modes.gcm.prototype.decrypt = function(input, output, finish) { var inputLength = input.length(); if (inputLength < this.blockSize && !(finish && inputLength > 0)) { return true; } this.cipher.encrypt(this._inBlock, this._outBlock); inc32(this._inBlock); this._hashBlock[0] = input.getInt32(); this._hashBlock[1] = input.getInt32(); this._hashBlock[2] = input.getInt32(); this._hashBlock[3] = input.getInt32(); this._s = this.ghash(this._hashSubkey, this._s, this._hashBlock); for (var i = 0; i < this._ints; ++i) { output.putInt32(this._outBlock[i] ^ this._hashBlock[i]); } if (inputLength < this.blockSize) { this._cipherLength += inputLength % this.blockSize; } else { this._cipherLength += this.blockSize; } }; modes.gcm.prototype.afterFinish = function(output, options) { var rval = true; if (options.decrypt && options.overflow) { output.truncate(this.blockSize - options.overflow); } this.tag = forge.util.createBuffer(); var lengths = this._aDataLength.concat(from64To32(this._cipherLength * 8)); this._s = this.ghash(this._hashSubkey, this._s, lengths); var tag = []; this.cipher.encrypt(this._j0, tag); for (var i = 0; i < this._ints; ++i) { this.tag.putInt32(this._s[i] ^ tag[i]); } this.tag.truncate(this.tag.length() % (this._tagLength / 8)); if (options.decrypt && this.tag.bytes() !== this._tag) { rval = false; } return rval; }; /** * See NIST SP-800-38D 6.3 (Algorithm 1). This function performs Galois * field multiplication. The field, GF(2^128), is defined by the polynomial: * * x^128 + x^7 + x^2 + x + 1 * * Which is represented in little-endian binary form as: 11100001 (0xe1). When * the value of a coefficient is 1, a bit is set. The value R, is the * concatenation of this value and 120 zero bits, yielding a 128-bit value * which matches the block size. * * This function will multiply two elements (vectors of bytes), X and Y, in * the field GF(2^128). The result is initialized to zero. For each bit of * X (out of 128), x_i, if x_i is set, then the result is multiplied (XOR'd) * by the current value of Y. For each bit, the value of Y will be raised by * a power of x (multiplied by the polynomial x). This can be achieved by * shifting Y once to the right. If the current value of Y, prior to being * multiplied by x, has 0 as its LSB, then it is a 127th degree polynomial. * Otherwise, we must divide by R after shifting to find the remainder. * * @param x the first block to multiply by the second. * @param y the second block to multiply by the first. * * @return the block result of the multiplication. */ modes.gcm.prototype.multiply = function(x, y) { var z_i = [ 0, 0, 0, 0 ]; var v_i = y.slice(0); for (var i = 0; i < 128; ++i) { var x_i = x[i / 32 | 0] & 1 << 31 - i % 32; if (x_i) { z_i[0] ^= v_i[0]; z_i[1] ^= v_i[1]; z_i[2] ^= v_i[2]; z_i[3] ^= v_i[3]; } this.pow(v_i, v_i); } return z_i; }; modes.gcm.prototype.pow = function(x, out) { var lsb = x[3] & 1; for (var i = 3; i > 0; --i) { out[i] = x[i] >>> 1 | (x[i - 1] & 1) << 31; } out[0] = x[0] >>> 1; if (lsb) { out[0] ^= this._R; } }; modes.gcm.prototype.tableMultiply = function(x) { var z = [ 0, 0, 0, 0 ]; for (var i = 0; i < 32; ++i) { var idx = i / 8 | 0; var x_i = x[idx] >>> (7 - i % 8) * 4 & 15; var ah = this._m[i][x_i]; z[0] ^= ah[0]; z[1] ^= ah[1]; z[2] ^= ah[2]; z[3] ^= ah[3]; } return z; }; /** * A continuing version of the GHASH algorithm that operates on a single * block. The hash block, last hash value (Ym) and the new block to hash * are given. * * @param h the hash block. * @param y the previous value for Ym, use [0, 0, 0, 0] for a new hash. * @param x the block to hash. * * @return the hashed value (Ym). */ modes.gcm.prototype.ghash = function(h, y, x) { y[0] ^= x[0]; y[1] ^= x[1]; y[2] ^= x[2]; y[3] ^= x[3]; return this.tableMultiply(y); }; /** * Precomputes a table for multiplying against the hash subkey. This * mechanism provides a substantial speed increase over multiplication * performed without a table. The table-based multiplication this table is * for solves X * H by multiplying each component of X by H and then * composing the results together using XOR. * * This function can be used to generate tables with different bit sizes * for the components, however, this implementation assumes there are * 32 components of X (which is a 16 byte vector), therefore each component * takes 4-bits (so the table is constructed with bits=4). * * @param h the hash subkey. * @param bits the bit size for a component. */ modes.gcm.prototype.generateHashTable = function(h, bits) { var multiplier = 8 / bits; var perInt = 4 * multiplier; var size = 16 * multiplier; var m = new Array(size); for (var i = 0; i < size; ++i) { var tmp = [ 0, 0, 0, 0 ]; var idx = i / perInt | 0; var shft = (perInt - 1 - i % perInt) * bits; tmp[idx] = 1 << bits - 1 << shft; m[i] = this.generateSubHashTable(this.multiply(tmp, h), bits); } return m; }; /** * Generates a table for multiplying against the hash subkey for one * particular component (out of all possible component values). * * @param mid the pre-multiplied value for the middle key of the table. * @param bits the bit size for a component. */ modes.gcm.prototype.generateSubHashTable = function(mid, bits) { var size = 1 << bits; var half = size >>> 1; var m = new Array(size); m[half] = mid.slice(0); var i = half >>> 1; while (i > 0) { this.pow(m[2 * i], m[i] = []); i >>= 1; } i = 2; while (i < half) { for (var j = 1; j < i; ++j) { var m_i = m[i]; var m_j = m[j]; m[i + j] = [ m_i[0] ^ m_j[0], m_i[1] ^ m_j[1], m_i[2] ^ m_j[2], m_i[3] ^ m_j[3] ]; } i *= 2; } m[0] = [ 0, 0, 0, 0 ]; for (i = half + 1; i < size; ++i) { var c = m[i ^ half]; m[i] = [ mid[0] ^ c[0], mid[1] ^ c[1], mid[2] ^ c[2], mid[3] ^ c[3] ]; } return m; }; /** Utility functions */ function transformIV(iv, blockSize) { if (typeof iv === "string") { iv = forge.util.createBuffer(iv); } if (forge.util.isArray(iv) && iv.length > 4) { var tmp = iv; iv = forge.util.createBuffer(); for (var i = 0; i < tmp.length; ++i) { iv.putByte(tmp[i]); } } if (iv.length() < blockSize) { throw new Error("Invalid IV length; got " + iv.length() + " bytes and expected " + blockSize + " bytes."); } if (!forge.util.isArray(iv)) { var ints = []; var blocks = blockSize / 4; for (var i = 0; i < blocks; ++i) { ints.push(iv.getInt32()); } iv = ints; } return iv; } function inc32(block) { block[block.length - 1] = block[block.length - 1] + 1 & 4294967295; } function from64To32(num) { return [num / 4294967296 | 0, num & 4294967295]; } })); //#endregion //#region ../node_modules/node-forge/lib/aes.js var require_aes$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Advanced Encryption Standard (AES) implementation. * * This implementation is based on the public domain library 'jscrypto' which * was written by: * * Emily Stark (estark@stanford.edu) * Mike Hamburg (mhamburg@stanford.edu) * Dan Boneh (dabo@cs.stanford.edu) * * Parts of this code are based on the OpenSSL implementation of AES: * http://www.openssl.org * * @author Dave Longley * * Copyright (c) 2010-2014 Digital Bazaar, Inc. */ var forge = require_forge(); require_cipher(); require_cipherModes(); require_util$8(); module.exports = forge.aes = forge.aes || {}; /** * Deprecated. Instead, use: * * var cipher = forge.cipher.createCipher('AES-', key); * cipher.start({iv: iv}); * * Creates an AES cipher object to encrypt data using the given symmetric key. * The output will be stored in the 'output' member of the returned cipher. * * The key and iv may be given as a string of bytes, an array of bytes, * a byte buffer, or an array of 32-bit words. * * @param key the symmetric key to use. * @param iv the initialization vector to use. * @param output the buffer to write to, null to create one. * @param mode the cipher mode to use (default: 'CBC'). * * @return the cipher. */ forge.aes.startEncrypting = function(key, iv, output, mode) { var cipher = _createCipher({ key, output, decrypt: false, mode }); cipher.start(iv); return cipher; }; /** * Deprecated. Instead, use: * * var cipher = forge.cipher.createCipher('AES-', key); * * Creates an AES cipher object to encrypt data using the given symmetric key. * * The key may be given as a string of bytes, an array of bytes, a * byte buffer, or an array of 32-bit words. * * @param key the symmetric key to use. * @param mode the cipher mode to use (default: 'CBC'). * * @return the cipher. */ forge.aes.createEncryptionCipher = function(key, mode) { return _createCipher({ key, output: null, decrypt: false, mode }); }; /** * Deprecated. Instead, use: * * var decipher = forge.cipher.createDecipher('AES-', key); * decipher.start({iv: iv}); * * Creates an AES cipher object to decrypt data using the given symmetric key. * The output will be stored in the 'output' member of the returned cipher. * * The key and iv may be given as a string of bytes, an array of bytes, * a byte buffer, or an array of 32-bit words. * * @param key the symmetric key to use. * @param iv the initialization vector to use. * @param output the buffer to write to, null to create one. * @param mode the cipher mode to use (default: 'CBC'). * * @return the cipher. */ forge.aes.startDecrypting = function(key, iv, output, mode) { var cipher = _createCipher({ key, output, decrypt: true, mode }); cipher.start(iv); return cipher; }; /** * Deprecated. Instead, use: * * var decipher = forge.cipher.createDecipher('AES-', key); * * Creates an AES cipher object to decrypt data using the given symmetric key. * * The key may be given as a string of bytes, an array of bytes, a * byte buffer, or an array of 32-bit words. * * @param key the symmetric key to use. * @param mode the cipher mode to use (default: 'CBC'). * * @return the cipher. */ forge.aes.createDecryptionCipher = function(key, mode) { return _createCipher({ key, output: null, decrypt: true, mode }); }; /** * Creates a new AES cipher algorithm object. * * @param name the name of the algorithm. * @param mode the mode factory function. * * @return the AES algorithm object. */ forge.aes.Algorithm = function(name, mode) { if (!init) { initialize(); } var self = this; self.name = name; self.mode = new mode({ blockSize: 16, cipher: { encrypt: function(inBlock, outBlock) { return _updateBlock(self._w, inBlock, outBlock, false); }, decrypt: function(inBlock, outBlock) { return _updateBlock(self._w, inBlock, outBlock, true); } } }); self._init = false; }; /** * Initializes this AES algorithm by expanding its key. * * @param options the options to use. * key the key to use with this algorithm. * decrypt true if the algorithm should be initialized for decryption, * false for encryption. */ forge.aes.Algorithm.prototype.initialize = function(options) { if (this._init) { return; } var key = options.key; var tmp; if (typeof key === "string" && (key.length === 16 || key.length === 24 || key.length === 32)) { key = forge.util.createBuffer(key); } else if (forge.util.isArray(key) && (key.length === 16 || key.length === 24 || key.length === 32)) { tmp = key; key = forge.util.createBuffer(); for (var i = 0; i < tmp.length; ++i) { key.putByte(tmp[i]); } } if (!forge.util.isArray(key)) { tmp = key; key = []; var len = tmp.length(); if (len === 16 || len === 24 || len === 32) { len = len >>> 2; for (var i = 0; i < len; ++i) { key.push(tmp.getInt32()); } } } if (!forge.util.isArray(key) || !(key.length === 4 || key.length === 6 || key.length === 8)) { throw new Error("Invalid key parameter."); } var mode = this.mode.name; var encryptOp = [ "CFB", "OFB", "CTR", "GCM" ].indexOf(mode) !== -1; this._w = _expandKey(key, options.decrypt && !encryptOp); this._init = true; }; /** * Expands a key. Typically only used for testing. * * @param key the symmetric key to expand, as an array of 32-bit words. * @param decrypt true to expand for decryption, false for encryption. * * @return the expanded key. */ forge.aes._expandKey = function(key, decrypt) { if (!init) { initialize(); } return _expandKey(key, decrypt); }; /** * Updates a single block. Typically only used for testing. * * @param w the expanded key to use. * @param input an array of block-size 32-bit words. * @param output an array of block-size 32-bit words. * @param decrypt true to decrypt, false to encrypt. */ forge.aes._updateBlock = _updateBlock; /** Register AES algorithms **/ registerAlgorithm("AES-ECB", forge.cipher.modes.ecb); registerAlgorithm("AES-CBC", forge.cipher.modes.cbc); registerAlgorithm("AES-CFB", forge.cipher.modes.cfb); registerAlgorithm("AES-OFB", forge.cipher.modes.ofb); registerAlgorithm("AES-CTR", forge.cipher.modes.ctr); registerAlgorithm("AES-GCM", forge.cipher.modes.gcm); function registerAlgorithm(name, mode) { var factory = function() { return new forge.aes.Algorithm(name, mode); }; forge.cipher.registerAlgorithm(name, factory); } /** AES implementation **/ var init = false; var Nb = 4; var sbox; var isbox; var rcon; var mix; var imix; /** * Performs initialization, ie: precomputes tables to optimize for speed. * * One way to understand how AES works is to imagine that 'addition' and * 'multiplication' are interfaces that require certain mathematical * properties to hold true (ie: they are associative) but they might have * different implementations and produce different kinds of results ... * provided that their mathematical properties remain true. AES defines * its own methods of addition and multiplication but keeps some important * properties the same, ie: associativity and distributivity. The * explanation below tries to shed some light on how AES defines addition * and multiplication of bytes and 32-bit words in order to perform its * encryption and decryption algorithms. * * The basics: * * The AES algorithm views bytes as binary representations of polynomials * that have either 1 or 0 as the coefficients. It defines the addition * or subtraction of two bytes as the XOR operation. It also defines the * multiplication of two bytes as a finite field referred to as GF(2^8) * (Note: 'GF' means "Galois Field" which is a field that contains a finite * number of elements so GF(2^8) has 256 elements). * * This means that any two bytes can be represented as binary polynomials; * when they multiplied together and modularly reduced by an irreducible * polynomial of the 8th degree, the results are the field GF(2^8). The * specific irreducible polynomial that AES uses in hexadecimal is 0x11b. * This multiplication is associative with 0x01 as the identity: * * (b * 0x01 = GF(b, 0x01) = b). * * The operation GF(b, 0x02) can be performed at the byte level by left * shifting b once and then XOR'ing it (to perform the modular reduction) * with 0x11b if b is >= 128. Repeated application of the multiplication * of 0x02 can be used to implement the multiplication of any two bytes. * * For instance, multiplying 0x57 and 0x13, denoted as GF(0x57, 0x13), can * be performed by factoring 0x13 into 0x01, 0x02, and 0x10. Then these * factors can each be multiplied by 0x57 and then added together. To do * the multiplication, values for 0x57 multiplied by each of these 3 factors * can be precomputed and stored in a table. To add them, the values from * the table are XOR'd together. * * AES also defines addition and multiplication of words, that is 4-byte * numbers represented as polynomials of 3 degrees where the coefficients * are the values of the bytes. * * The word [a0, a1, a2, a3] is a polynomial a3x^3 + a2x^2 + a1x + a0. * * Addition is performed by XOR'ing like powers of x. Multiplication * is performed in two steps, the first is an algebriac expansion as * you would do normally (where addition is XOR). But the result is * a polynomial larger than 3 degrees and thus it cannot fit in a word. So * next the result is modularly reduced by an AES-specific polynomial of * degree 4 which will always produce a polynomial of less than 4 degrees * such that it will fit in a word. In AES, this polynomial is x^4 + 1. * * The modular product of two polynomials 'a' and 'b' is thus: * * d(x) = d3x^3 + d2x^2 + d1x + d0 * with * d0 = GF(a0, b0) ^ GF(a3, b1) ^ GF(a2, b2) ^ GF(a1, b3) * d1 = GF(a1, b0) ^ GF(a0, b1) ^ GF(a3, b2) ^ GF(a2, b3) * d2 = GF(a2, b0) ^ GF(a1, b1) ^ GF(a0, b2) ^ GF(a3, b3) * d3 = GF(a3, b0) ^ GF(a2, b1) ^ GF(a1, b2) ^ GF(a0, b3) * * As a matrix: * * [d0] = [a0 a3 a2 a1][b0] * [d1] [a1 a0 a3 a2][b1] * [d2] [a2 a1 a0 a3][b2] * [d3] [a3 a2 a1 a0][b3] * * Special polynomials defined by AES (0x02 == {02}): * a(x) = {03}x^3 + {01}x^2 + {01}x + {02} * a^-1(x) = {0b}x^3 + {0d}x^2 + {09}x + {0e}. * * These polynomials are used in the MixColumns() and InverseMixColumns() * operations, respectively, to cause each element in the state to affect * the output (referred to as diffusing). * * RotWord() uses: a0 = a1 = a2 = {00} and a3 = {01}, which is the * polynomial x3. * * The ShiftRows() method modifies the last 3 rows in the state (where * the state is 4 words with 4 bytes per word) by shifting bytes cyclically. * The 1st byte in the second row is moved to the end of the row. The 1st * and 2nd bytes in the third row are moved to the end of the row. The 1st, * 2nd, and 3rd bytes are moved in the fourth row. * * More details on how AES arithmetic works: * * In the polynomial representation of binary numbers, XOR performs addition * and subtraction and multiplication in GF(2^8) denoted as GF(a, b) * corresponds with the multiplication of polynomials modulo an irreducible * polynomial of degree 8. In other words, for AES, GF(a, b) will multiply * polynomial 'a' with polynomial 'b' and then do a modular reduction by * an AES-specific irreducible polynomial of degree 8. * * A polynomial is irreducible if its only divisors are one and itself. For * the AES algorithm, this irreducible polynomial is: * * m(x) = x^8 + x^4 + x^3 + x + 1, * * or {01}{1b} in hexadecimal notation, where each coefficient is a bit: * 100011011 = 283 = 0x11b. * * For example, GF(0x57, 0x83) = 0xc1 because * * 0x57 = 87 = 01010111 = x^6 + x^4 + x^2 + x + 1 * 0x85 = 131 = 10000101 = x^7 + x + 1 * * (x^6 + x^4 + x^2 + x + 1) * (x^7 + x + 1) * = x^13 + x^11 + x^9 + x^8 + x^7 + * x^7 + x^5 + x^3 + x^2 + x + * x^6 + x^4 + x^2 + x + 1 * = x^13 + x^11 + x^9 + x^8 + x^6 + x^5 + x^4 + x^3 + 1 = y * y modulo (x^8 + x^4 + x^3 + x + 1) * = x^7 + x^6 + 1. * * The modular reduction by m(x) guarantees the result will be a binary * polynomial of less than degree 8, so that it can fit in a byte. * * The operation to multiply a binary polynomial b with x (the polynomial * x in binary representation is 00000010) is: * * b_7x^8 + b_6x^7 + b_5x^6 + b_4x^5 + b_3x^4 + b_2x^3 + b_1x^2 + b_0x^1 * * To get GF(b, x) we must reduce that by m(x). If b_7 is 0 (that is the * most significant bit is 0 in b) then the result is already reduced. If * it is 1, then we can reduce it by subtracting m(x) via an XOR. * * It follows that multiplication by x (00000010 or 0x02) can be implemented * by performing a left shift followed by a conditional bitwise XOR with * 0x1b. This operation on bytes is denoted by xtime(). Multiplication by * higher powers of x can be implemented by repeated application of xtime(). * * By adding intermediate results, multiplication by any constant can be * implemented. For instance: * * GF(0x57, 0x13) = 0xfe because: * * xtime(b) = (b & 128) ? (b << 1 ^ 0x11b) : (b << 1) * * Note: We XOR with 0x11b instead of 0x1b because in javascript our * datatype for b can be larger than 1 byte, so a left shift will not * automatically eliminate bits that overflow a byte ... by XOR'ing the * overflow bit with 1 (the extra one from 0x11b) we zero it out. * * GF(0x57, 0x02) = xtime(0x57) = 0xae * GF(0x57, 0x04) = xtime(0xae) = 0x47 * GF(0x57, 0x08) = xtime(0x47) = 0x8e * GF(0x57, 0x10) = xtime(0x8e) = 0x07 * * GF(0x57, 0x13) = GF(0x57, (0x01 ^ 0x02 ^ 0x10)) * * And by the distributive property (since XOR is addition and GF() is * multiplication): * * = GF(0x57, 0x01) ^ GF(0x57, 0x02) ^ GF(0x57, 0x10) * = 0x57 ^ 0xae ^ 0x07 * = 0xfe. */ function initialize() { init = true; rcon = [ 0, 1, 2, 4, 8, 16, 32, 64, 128, 27, 54 ]; var xtime = new Array(256); for (var i = 0; i < 128; ++i) { xtime[i] = i << 1; xtime[i + 128] = i + 128 << 1 ^ 283; } sbox = new Array(256); isbox = new Array(256); mix = new Array(4); imix = new Array(4); for (var i = 0; i < 4; ++i) { mix[i] = new Array(256); imix[i] = new Array(256); } var e = 0, ei = 0, e2, e4, e8, sx, sx2, me, ime; for (var i = 0; i < 256; ++i) { sx = ei ^ ei << 1 ^ ei << 2 ^ ei << 3 ^ ei << 4; sx = sx >> 8 ^ sx & 255 ^ 99; sbox[e] = sx; isbox[sx] = e; sx2 = xtime[sx]; e2 = xtime[e]; e4 = xtime[e2]; e8 = xtime[e4]; me = sx2 << 24 ^ sx << 16 ^ sx << 8 ^ (sx ^ sx2); ime = (e2 ^ e4 ^ e8) << 24 ^ (e ^ e8) << 16 ^ (e ^ e4 ^ e8) << 8 ^ (e ^ e2 ^ e8); for (var n = 0; n < 4; ++n) { mix[n][e] = me; imix[n][sx] = ime; me = me << 24 | me >>> 8; ime = ime << 24 | ime >>> 8; } if (e === 0) { e = ei = 1; } else { e = e2 ^ xtime[xtime[xtime[e2 ^ e8]]]; ei ^= xtime[xtime[ei]]; } } } /** * Generates a key schedule using the AES key expansion algorithm. * * The AES algorithm takes the Cipher Key, K, and performs a Key Expansion * routine to generate a key schedule. The Key Expansion generates a total * of Nb*(Nr + 1) words: the algorithm requires an initial set of Nb words, * and each of the Nr rounds requires Nb words of key data. The resulting * key schedule consists of a linear array of 4-byte words, denoted [wi ], * with i in the range 0 <= i < Nb(Nr + 1). * * KeyExpansion(byte key[4*Nk], word w[Nb*(Nr+1)], Nk) * AES-128 (Nb=4, Nk=4, Nr=10) * AES-192 (Nb=4, Nk=6, Nr=12) * AES-256 (Nb=4, Nk=8, Nr=14) * Note: Nr=Nk+6. * * Nb is the number of columns (32-bit words) comprising the State (or * number of bytes in a block). For AES, Nb=4. * * @param key the key to schedule (as an array of 32-bit words). * @param decrypt true to modify the key schedule to decrypt, false not to. * * @return the generated key schedule. */ function _expandKey(key, decrypt) { var w = key.slice(0); var temp, iNk = 1; var Nk = w.length; var Nr1 = Nk + 6 + 1; var end = Nb * Nr1; for (var i = Nk; i < end; ++i) { temp = w[i - 1]; if (i % Nk === 0) { temp = sbox[temp >>> 16 & 255] << 24 ^ sbox[temp >>> 8 & 255] << 16 ^ sbox[temp & 255] << 8 ^ sbox[temp >>> 24] ^ rcon[iNk] << 24; iNk++; } else if (Nk > 6 && i % Nk === 4) { temp = sbox[temp >>> 24] << 24 ^ sbox[temp >>> 16 & 255] << 16 ^ sbox[temp >>> 8 & 255] << 8 ^ sbox[temp & 255]; } w[i] = w[i - Nk] ^ temp; } if (decrypt) { var tmp; var m0 = imix[0]; var m1 = imix[1]; var m2 = imix[2]; var m3 = imix[3]; var wnew = w.slice(0); end = w.length; for (var i = 0, wi = end - Nb; i < end; i += Nb, wi -= Nb) { if (i === 0 || i === end - Nb) { wnew[i] = w[wi]; wnew[i + 1] = w[wi + 3]; wnew[i + 2] = w[wi + 2]; wnew[i + 3] = w[wi + 1]; } else { for (var n = 0; n < Nb; ++n) { tmp = w[wi + n]; wnew[i + (3 & -n)] = m0[sbox[tmp >>> 24]] ^ m1[sbox[tmp >>> 16 & 255]] ^ m2[sbox[tmp >>> 8 & 255]] ^ m3[sbox[tmp & 255]]; } } } w = wnew; } return w; } /** * Updates a single block (16 bytes) using AES. The update will either * encrypt or decrypt the block. * * @param w the key schedule. * @param input the input block (an array of 32-bit words). * @param output the updated output block. * @param decrypt true to decrypt the block, false to encrypt it. */ function _updateBlock(w, input, output, decrypt) { var Nr = w.length / 4 - 1; var m0, m1, m2, m3, sub; if (decrypt) { m0 = imix[0]; m1 = imix[1]; m2 = imix[2]; m3 = imix[3]; sub = isbox; } else { m0 = mix[0]; m1 = mix[1]; m2 = mix[2]; m3 = mix[3]; sub = sbox; } var a, b, c, d, a2, b2, c2; a = input[0] ^ w[0]; b = input[decrypt ? 3 : 1] ^ w[1]; c = input[2] ^ w[2]; d = input[decrypt ? 1 : 3] ^ w[3]; var i = 3; for (var round = 1; round < Nr; ++round) { a2 = m0[a >>> 24] ^ m1[b >>> 16 & 255] ^ m2[c >>> 8 & 255] ^ m3[d & 255] ^ w[++i]; b2 = m0[b >>> 24] ^ m1[c >>> 16 & 255] ^ m2[d >>> 8 & 255] ^ m3[a & 255] ^ w[++i]; c2 = m0[c >>> 24] ^ m1[d >>> 16 & 255] ^ m2[a >>> 8 & 255] ^ m3[b & 255] ^ w[++i]; d = m0[d >>> 24] ^ m1[a >>> 16 & 255] ^ m2[b >>> 8 & 255] ^ m3[c & 255] ^ w[++i]; a = a2; b = b2; c = c2; } output[0] = sub[a >>> 24] << 24 ^ sub[b >>> 16 & 255] << 16 ^ sub[c >>> 8 & 255] << 8 ^ sub[d & 255] ^ w[++i]; output[decrypt ? 3 : 1] = sub[b >>> 24] << 24 ^ sub[c >>> 16 & 255] << 16 ^ sub[d >>> 8 & 255] << 8 ^ sub[a & 255] ^ w[++i]; output[2] = sub[c >>> 24] << 24 ^ sub[d >>> 16 & 255] << 16 ^ sub[a >>> 8 & 255] << 8 ^ sub[b & 255] ^ w[++i]; output[decrypt ? 1 : 3] = sub[d >>> 24] << 24 ^ sub[a >>> 16 & 255] << 16 ^ sub[b >>> 8 & 255] << 8 ^ sub[c & 255] ^ w[++i]; } /** * Deprecated. Instead, use: * * forge.cipher.createCipher('AES-', key); * forge.cipher.createDecipher('AES-', key); * * Creates a deprecated AES cipher object. This object's mode will default to * CBC (cipher-block-chaining). * * The key and iv may be given as a string of bytes, an array of bytes, a * byte buffer, or an array of 32-bit words. * * @param options the options to use. * key the symmetric key to use. * output the buffer to write to. * decrypt true for decryption, false for encryption. * mode the cipher mode to use (default: 'CBC'). * * @return the cipher. */ function _createCipher(options) { options = options || {}; var mode = (options.mode || "CBC").toUpperCase(); var algorithm = "AES-" + mode; var cipher; if (options.decrypt) { cipher = forge.cipher.createDecipher(algorithm, options.key); } else { cipher = forge.cipher.createCipher(algorithm, options.key); } var start = cipher.start; cipher.start = function(iv, options) { var output = null; if (options instanceof forge.util.ByteBuffer) { output = options; options = {}; } options = options || {}; options.output = output; options.iv = iv; start.call(cipher, options); }; return cipher; } })); //#endregion //#region ../node_modules/node-forge/lib/oids.js var require_oids = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Object IDs for ASN.1. * * @author Dave Longley * * Copyright (c) 2010-2013 Digital Bazaar, Inc. */ var forge = require_forge(); forge.pki = forge.pki || {}; var oids = module.exports = forge.pki.oids = forge.oids = forge.oids || {}; function _IN(id, name) { oids[id] = name; oids[name] = id; } function _I_(id, name) { oids[id] = name; } _IN("1.2.840.113549.1.1.1", "rsaEncryption"); _IN("1.2.840.113549.1.1.4", "md5WithRSAEncryption"); _IN("1.2.840.113549.1.1.5", "sha1WithRSAEncryption"); _IN("1.2.840.113549.1.1.7", "RSAES-OAEP"); _IN("1.2.840.113549.1.1.8", "mgf1"); _IN("1.2.840.113549.1.1.9", "pSpecified"); _IN("1.2.840.113549.1.1.10", "RSASSA-PSS"); _IN("1.2.840.113549.1.1.11", "sha256WithRSAEncryption"); _IN("1.2.840.113549.1.1.12", "sha384WithRSAEncryption"); _IN("1.2.840.113549.1.1.13", "sha512WithRSAEncryption"); _IN("1.3.101.112", "EdDSA25519"); _IN("1.2.840.10040.4.3", "dsa-with-sha1"); _IN("1.3.14.3.2.7", "desCBC"); _IN("1.3.14.3.2.26", "sha1"); _IN("1.3.14.3.2.29", "sha1WithRSASignature"); _IN("2.16.840.1.101.3.4.2.1", "sha256"); _IN("2.16.840.1.101.3.4.2.2", "sha384"); _IN("2.16.840.1.101.3.4.2.3", "sha512"); _IN("2.16.840.1.101.3.4.2.4", "sha224"); _IN("2.16.840.1.101.3.4.2.5", "sha512-224"); _IN("2.16.840.1.101.3.4.2.6", "sha512-256"); _IN("1.2.840.113549.2.2", "md2"); _IN("1.2.840.113549.2.5", "md5"); _IN("1.2.840.113549.1.7.1", "data"); _IN("1.2.840.113549.1.7.2", "signedData"); _IN("1.2.840.113549.1.7.3", "envelopedData"); _IN("1.2.840.113549.1.7.4", "signedAndEnvelopedData"); _IN("1.2.840.113549.1.7.5", "digestedData"); _IN("1.2.840.113549.1.7.6", "encryptedData"); _IN("1.2.840.113549.1.9.1", "emailAddress"); _IN("1.2.840.113549.1.9.2", "unstructuredName"); _IN("1.2.840.113549.1.9.3", "contentType"); _IN("1.2.840.113549.1.9.4", "messageDigest"); _IN("1.2.840.113549.1.9.5", "signingTime"); _IN("1.2.840.113549.1.9.6", "counterSignature"); _IN("1.2.840.113549.1.9.7", "challengePassword"); _IN("1.2.840.113549.1.9.8", "unstructuredAddress"); _IN("1.2.840.113549.1.9.14", "extensionRequest"); _IN("1.2.840.113549.1.9.20", "friendlyName"); _IN("1.2.840.113549.1.9.21", "localKeyId"); _IN("1.2.840.113549.1.9.22.1", "x509Certificate"); _IN("1.2.840.113549.1.12.10.1.1", "keyBag"); _IN("1.2.840.113549.1.12.10.1.2", "pkcs8ShroudedKeyBag"); _IN("1.2.840.113549.1.12.10.1.3", "certBag"); _IN("1.2.840.113549.1.12.10.1.4", "crlBag"); _IN("1.2.840.113549.1.12.10.1.5", "secretBag"); _IN("1.2.840.113549.1.12.10.1.6", "safeContentsBag"); _IN("1.2.840.113549.1.5.13", "pkcs5PBES2"); _IN("1.2.840.113549.1.5.12", "pkcs5PBKDF2"); _IN("1.2.840.113549.1.12.1.1", "pbeWithSHAAnd128BitRC4"); _IN("1.2.840.113549.1.12.1.2", "pbeWithSHAAnd40BitRC4"); _IN("1.2.840.113549.1.12.1.3", "pbeWithSHAAnd3-KeyTripleDES-CBC"); _IN("1.2.840.113549.1.12.1.4", "pbeWithSHAAnd2-KeyTripleDES-CBC"); _IN("1.2.840.113549.1.12.1.5", "pbeWithSHAAnd128BitRC2-CBC"); _IN("1.2.840.113549.1.12.1.6", "pbewithSHAAnd40BitRC2-CBC"); _IN("1.2.840.113549.2.7", "hmacWithSHA1"); _IN("1.2.840.113549.2.8", "hmacWithSHA224"); _IN("1.2.840.113549.2.9", "hmacWithSHA256"); _IN("1.2.840.113549.2.10", "hmacWithSHA384"); _IN("1.2.840.113549.2.11", "hmacWithSHA512"); _IN("1.2.840.113549.3.7", "des-EDE3-CBC"); _IN("2.16.840.1.101.3.4.1.2", "aes128-CBC"); _IN("2.16.840.1.101.3.4.1.22", "aes192-CBC"); _IN("2.16.840.1.101.3.4.1.42", "aes256-CBC"); _IN("2.5.4.3", "commonName"); _IN("2.5.4.4", "surname"); _IN("2.5.4.5", "serialNumber"); _IN("2.5.4.6", "countryName"); _IN("2.5.4.7", "localityName"); _IN("2.5.4.8", "stateOrProvinceName"); _IN("2.5.4.9", "streetAddress"); _IN("2.5.4.10", "organizationName"); _IN("2.5.4.11", "organizationalUnitName"); _IN("2.5.4.12", "title"); _IN("2.5.4.13", "description"); _IN("2.5.4.15", "businessCategory"); _IN("2.5.4.17", "postalCode"); _IN("2.5.4.42", "givenName"); _IN("1.3.6.1.4.1.311.60.2.1.2", "jurisdictionOfIncorporationStateOrProvinceName"); _IN("1.3.6.1.4.1.311.60.2.1.3", "jurisdictionOfIncorporationCountryName"); _IN("2.16.840.1.113730.1.1", "nsCertType"); _IN("2.16.840.1.113730.1.13", "nsComment"); _I_("2.5.29.1", "authorityKeyIdentifier"); _I_("2.5.29.2", "keyAttributes"); _I_("2.5.29.3", "certificatePolicies"); _I_("2.5.29.4", "keyUsageRestriction"); _I_("2.5.29.5", "policyMapping"); _I_("2.5.29.6", "subtreesConstraint"); _I_("2.5.29.7", "subjectAltName"); _I_("2.5.29.8", "issuerAltName"); _I_("2.5.29.9", "subjectDirectoryAttributes"); _I_("2.5.29.10", "basicConstraints"); _I_("2.5.29.11", "nameConstraints"); _I_("2.5.29.12", "policyConstraints"); _I_("2.5.29.13", "basicConstraints"); _IN("2.5.29.14", "subjectKeyIdentifier"); _IN("2.5.29.15", "keyUsage"); _I_("2.5.29.16", "privateKeyUsagePeriod"); _IN("2.5.29.17", "subjectAltName"); _IN("2.5.29.18", "issuerAltName"); _IN("2.5.29.19", "basicConstraints"); _I_("2.5.29.20", "cRLNumber"); _I_("2.5.29.21", "cRLReason"); _I_("2.5.29.22", "expirationDate"); _I_("2.5.29.23", "instructionCode"); _I_("2.5.29.24", "invalidityDate"); _I_("2.5.29.25", "cRLDistributionPoints"); _I_("2.5.29.26", "issuingDistributionPoint"); _I_("2.5.29.27", "deltaCRLIndicator"); _I_("2.5.29.28", "issuingDistributionPoint"); _I_("2.5.29.29", "certificateIssuer"); _I_("2.5.29.30", "nameConstraints"); _IN("2.5.29.31", "cRLDistributionPoints"); _IN("2.5.29.32", "certificatePolicies"); _I_("2.5.29.33", "policyMappings"); _I_("2.5.29.34", "policyConstraints"); _IN("2.5.29.35", "authorityKeyIdentifier"); _I_("2.5.29.36", "policyConstraints"); _IN("2.5.29.37", "extKeyUsage"); _I_("2.5.29.46", "freshestCRL"); _I_("2.5.29.54", "inhibitAnyPolicy"); _IN("1.3.6.1.4.1.11129.2.4.2", "timestampList"); _IN("1.3.6.1.5.5.7.1.1", "authorityInfoAccess"); _IN("1.3.6.1.5.5.7.3.1", "serverAuth"); _IN("1.3.6.1.5.5.7.3.2", "clientAuth"); _IN("1.3.6.1.5.5.7.3.3", "codeSigning"); _IN("1.3.6.1.5.5.7.3.4", "emailProtection"); _IN("1.3.6.1.5.5.7.3.8", "timeStamping"); })); //#endregion //#region ../node_modules/node-forge/lib/asn1.js var require_asn1 = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Javascript implementation of Abstract Syntax Notation Number One. * * @author Dave Longley * * Copyright (c) 2010-2015 Digital Bazaar, Inc. * * An API for storing data using the Abstract Syntax Notation Number One * format using DER (Distinguished Encoding Rules) encoding. This encoding is * commonly used to store data for PKI, i.e. X.509 Certificates, and this * implementation exists for that purpose. * * Abstract Syntax Notation Number One (ASN.1) is used to define the abstract * syntax of information without restricting the way the information is encoded * for transmission. It provides a standard that allows for open systems * communication. ASN.1 defines the syntax of information data and a number of * simple data types as well as a notation for describing them and specifying * values for them. * * The RSA algorithm creates public and private keys that are often stored in * X.509 or PKCS#X formats -- which use ASN.1 (encoded in DER format). This * class provides the most basic functionality required to store and load DSA * keys that are encoded according to ASN.1. * * The most common binary encodings for ASN.1 are BER (Basic Encoding Rules) * and DER (Distinguished Encoding Rules). DER is just a subset of BER that * has stricter requirements for how data must be encoded. * * Each ASN.1 structure has a tag (a byte identifying the ASN.1 structure type) * and a byte array for the value of this ASN1 structure which may be data or a * list of ASN.1 structures. * * Each ASN.1 structure using BER is (Tag-Length-Value): * * | byte 0 | bytes X | bytes Y | * |--------|---------|---------- * | tag | length | value | * * ASN.1 allows for tags to be of "High-tag-number form" which allows a tag to * be two or more octets, but that is not supported by this class. A tag is * only 1 byte. Bits 1-5 give the tag number (ie the data type within a * particular 'class'), 6 indicates whether or not the ASN.1 value is * constructed from other ASN.1 values, and bits 7 and 8 give the 'class'. If * bits 7 and 8 are both zero, the class is UNIVERSAL. If only bit 7 is set, * then the class is APPLICATION. If only bit 8 is set, then the class is * CONTEXT_SPECIFIC. If both bits 7 and 8 are set, then the class is PRIVATE. * The tag numbers for the data types for the class UNIVERSAL are listed below: * * UNIVERSAL 0 Reserved for use by the encoding rules * UNIVERSAL 1 Boolean type * UNIVERSAL 2 Integer type * UNIVERSAL 3 Bitstring type * UNIVERSAL 4 Octetstring type * UNIVERSAL 5 Null type * UNIVERSAL 6 Object identifier type * UNIVERSAL 7 Object descriptor type * UNIVERSAL 8 External type and Instance-of type * UNIVERSAL 9 Real type * UNIVERSAL 10 Enumerated type * UNIVERSAL 11 Embedded-pdv type * UNIVERSAL 12 UTF8String type * UNIVERSAL 13 Relative object identifier type * UNIVERSAL 14-15 Reserved for future editions * UNIVERSAL 16 Sequence and Sequence-of types * UNIVERSAL 17 Set and Set-of types * UNIVERSAL 18-22, 25-30 Character string types * UNIVERSAL 23-24 Time types * * The length of an ASN.1 structure is specified after the tag identifier. * There is a definite form and an indefinite form. The indefinite form may * be used if the encoding is constructed and not all immediately available. * The indefinite form is encoded using a length byte with only the 8th bit * set. The end of the constructed object is marked using end-of-contents * octets (two zero bytes). * * The definite form looks like this: * * The length may take up 1 or more bytes, it depends on the length of the * value of the ASN.1 structure. DER encoding requires that if the ASN.1 * structure has a value that has a length greater than 127, more than 1 byte * will be used to store its length, otherwise just one byte will be used. * This is strict. * * In the case that the length of the ASN.1 value is less than 127, 1 octet * (byte) is used to store the "short form" length. The 8th bit has a value of * 0 indicating the length is "short form" and not "long form" and bits 7-1 * give the length of the data. (The 8th bit is the left-most, most significant * bit: also known as big endian or network format). * * In the case that the length of the ASN.1 value is greater than 127, 2 to * 127 octets (bytes) are used to store the "long form" length. The first * byte's 8th bit is set to 1 to indicate the length is "long form." Bits 7-1 * give the number of additional octets. All following octets are in base 256 * with the most significant digit first (typical big-endian binary unsigned * integer storage). So, for instance, if the length of a value was 257, the * first byte would be set to: * * 10000010 = 130 = 0x82. * * This indicates there are 2 octets (base 256) for the length. The second and * third bytes (the octets just mentioned) would store the length in base 256: * * octet 2: 00000001 = 1 * 256^1 = 256 * octet 3: 00000001 = 1 * 256^0 = 1 * total = 257 * * The algorithm for converting a js integer value of 257 to base-256 is: * * var value = 257; * var bytes = []; * bytes[0] = (value >>> 8) & 0xFF; // most significant byte first * bytes[1] = value & 0xFF; // least significant byte last * * On the ASN.1 UNIVERSAL Object Identifier (OID) type: * * An OID can be written like: "value1.value2.value3...valueN" * * The DER encoding rules: * * The first byte has the value 40 * value1 + value2. * The following bytes, if any, encode the remaining values. Each value is * encoded in base 128, most significant digit first (big endian), with as * few digits as possible, and the most significant bit of each byte set * to 1 except the last in each value's encoding. For example: Given the * OID "1.2.840.113549", its DER encoding is (remember each byte except the * last one in each encoding is OR'd with 0x80): * * byte 1: 40 * 1 + 2 = 42 = 0x2A. * bytes 2-3: 128 * 6 + 72 = 840 = 6 72 = 6 72 = 0x0648 = 0x8648 * bytes 4-6: 16384 * 6 + 128 * 119 + 13 = 6 119 13 = 0x06770D = 0x86F70D * * The final value is: 0x2A864886F70D. * The full OID (including ASN.1 tag and length of 6 bytes) is: * 0x06062A864886F70D */ var forge = require_forge(); require_util$8(); require_oids(); var asn1 = module.exports = forge.asn1 = forge.asn1 || {}; /** * ASN.1 classes. */ asn1.Class = { UNIVERSAL: 0, APPLICATION: 64, CONTEXT_SPECIFIC: 128, PRIVATE: 192 }; /** * ASN.1 types. Not all types are supported by this implementation, only * those necessary to implement a simple PKI are implemented. */ asn1.Type = { NONE: 0, BOOLEAN: 1, INTEGER: 2, BITSTRING: 3, OCTETSTRING: 4, NULL: 5, OID: 6, ODESC: 7, EXTERNAL: 8, REAL: 9, ENUMERATED: 10, EMBEDDED: 11, UTF8: 12, ROID: 13, SEQUENCE: 16, SET: 17, PRINTABLESTRING: 19, IA5STRING: 22, UTCTIME: 23, GENERALIZEDTIME: 24, BMPSTRING: 30 }; /** * Creates a new asn1 object. * * @param tagClass the tag class for the object. * @param type the data type (tag number) for the object. * @param constructed true if the asn1 object is in constructed form. * @param value the value for the object, if it is not constructed. * @param [options] the options to use: * [bitStringContents] the plain BIT STRING content including padding * byte. * * @return the asn1 object. */ asn1.create = function(tagClass, type, constructed, value, options) { if (forge.util.isArray(value)) { var tmp = []; for (var i = 0; i < value.length; ++i) { if (value[i] !== undefined) { tmp.push(value[i]); } } value = tmp; } var obj = { tagClass, type, constructed, composed: constructed || forge.util.isArray(value), value }; if (options && "bitStringContents" in options) { obj.bitStringContents = options.bitStringContents; obj.original = asn1.copy(obj); } return obj; }; /** * Copies an asn1 object. * * @param obj the asn1 object. * @param [options] copy options: * [excludeBitStringContents] true to not copy bitStringContents * * @return the a copy of the asn1 object. */ asn1.copy = function(obj, options) { var copy; if (forge.util.isArray(obj)) { copy = []; for (var i = 0; i < obj.length; ++i) { copy.push(asn1.copy(obj[i], options)); } return copy; } if (typeof obj === "string") { return obj; } copy = { tagClass: obj.tagClass, type: obj.type, constructed: obj.constructed, composed: obj.composed, value: asn1.copy(obj.value, options) }; if (options && !options.excludeBitStringContents) { copy.bitStringContents = obj.bitStringContents; } return copy; }; /** * Compares asn1 objects for equality. * * Note this function does not run in constant time. * * @param obj1 the first asn1 object. * @param obj2 the second asn1 object. * @param [options] compare options: * [includeBitStringContents] true to compare bitStringContents * * @return true if the asn1 objects are equal. */ asn1.equals = function(obj1, obj2, options) { if (forge.util.isArray(obj1)) { if (!forge.util.isArray(obj2)) { return false; } if (obj1.length !== obj2.length) { return false; } for (var i = 0; i < obj1.length; ++i) { if (!asn1.equals(obj1[i], obj2[i])) { return false; } } return true; } if (typeof obj1 !== typeof obj2) { return false; } if (typeof obj1 === "string") { return obj1 === obj2; } var equal = obj1.tagClass === obj2.tagClass && obj1.type === obj2.type && obj1.constructed === obj2.constructed && obj1.composed === obj2.composed && asn1.equals(obj1.value, obj2.value); if (options && options.includeBitStringContents) { equal = equal && obj1.bitStringContents === obj2.bitStringContents; } return equal; }; /** * Gets the length of a BER-encoded ASN.1 value. * * In case the length is not specified, undefined is returned. * * @param b the BER-encoded ASN.1 byte buffer, starting with the first * length byte. * * @return the length of the BER-encoded ASN.1 value or undefined. */ asn1.getBerValueLength = function(b) { var b2 = b.getByte(); if (b2 === 128) { return undefined; } var length; var longForm = b2 & 128; if (!longForm) { length = b2; } else { length = b.getInt((b2 & 127) << 3); } return length; }; /** * Check if the byte buffer has enough bytes. Throws an Error if not. * * @param bytes the byte buffer to parse from. * @param remaining the bytes remaining in the current parsing state. * @param n the number of bytes the buffer must have. */ function _checkBufferLength(bytes, remaining, n) { if (n > remaining) { var error = new Error("Too few bytes to parse DER."); error.available = bytes.length(); error.remaining = remaining; error.requested = n; throw error; } } /** * Gets the length of a BER-encoded ASN.1 value. * * In case the length is not specified, undefined is returned. * * @param bytes the byte buffer to parse from. * @param remaining the bytes remaining in the current parsing state. * * @return the length of the BER-encoded ASN.1 value or undefined. */ var _getValueLength = function(bytes, remaining) { var b2 = bytes.getByte(); remaining--; if (b2 === 128) { return undefined; } var length; var longForm = b2 & 128; if (!longForm) { length = b2; } else { var longFormBytes = b2 & 127; _checkBufferLength(bytes, remaining, longFormBytes); length = bytes.getInt(longFormBytes << 3); } if (length < 0) { throw new Error("Negative length: " + length); } return length; }; /** * Parses an asn1 object from a byte buffer in DER format. * * @param bytes the byte buffer to parse from. * @param [strict] true to be strict when checking value lengths, false to * allow truncated values (default: true). * @param [options] object with options or boolean strict flag * [strict] true to be strict when checking value lengths, false to * allow truncated values (default: true). * [parseAllBytes] true to ensure all bytes are parsed * (default: true) * [decodeBitStrings] true to attempt to decode the content of * BIT STRINGs (not OCTET STRINGs) using strict mode. Note that * without schema support to understand the data context this can * erroneously decode values that happen to be valid ASN.1. This * flag will be deprecated or removed as soon as schema support is * available. (default: true) * * @throws Will throw an error for various malformed input conditions. * * @return the parsed asn1 object. */ asn1.fromDer = function(bytes, options) { if (options === undefined) { options = { strict: true, parseAllBytes: true, decodeBitStrings: true }; } if (typeof options === "boolean") { options = { strict: options, parseAllBytes: true, decodeBitStrings: true }; } if (!("strict" in options)) { options.strict = true; } if (!("parseAllBytes" in options)) { options.parseAllBytes = true; } if (!("decodeBitStrings" in options)) { options.decodeBitStrings = true; } if (typeof bytes === "string") { bytes = forge.util.createBuffer(bytes); } var byteCount = bytes.length(); var value = _fromDer(bytes, bytes.length(), 0, options); if (options.parseAllBytes && bytes.length() !== 0) { var error = new Error("Unparsed DER bytes remain after ASN.1 parsing."); error.byteCount = byteCount; error.remaining = bytes.length(); throw error; } return value; }; /** * Internal function to parse an asn1 object from a byte buffer in DER format. * * @param bytes the byte buffer to parse from. * @param remaining the number of bytes remaining for this chunk. * @param depth the current parsing depth. * @param options object with same options as fromDer(). * * @return the parsed asn1 object. */ function _fromDer(bytes, remaining, depth, options) { var start; _checkBufferLength(bytes, remaining, 2); var b1 = bytes.getByte(); remaining--; var tagClass = b1 & 192; var type = b1 & 31; start = bytes.length(); var length = _getValueLength(bytes, remaining); remaining -= start - bytes.length(); if (length !== undefined && length > remaining) { if (options.strict) { var error = new Error("Too few bytes to read ASN.1 value."); error.available = bytes.length(); error.remaining = remaining; error.requested = length; throw error; } length = remaining; } var value; var bitStringContents; var constructed = (b1 & 32) === 32; if (constructed) { value = []; if (length === undefined) { for (;;) { _checkBufferLength(bytes, remaining, 2); if (bytes.bytes(2) === String.fromCharCode(0, 0)) { bytes.getBytes(2); remaining -= 2; break; } start = bytes.length(); value.push(_fromDer(bytes, remaining, depth + 1, options)); remaining -= start - bytes.length(); } } else { while (length > 0) { start = bytes.length(); value.push(_fromDer(bytes, length, depth + 1, options)); remaining -= start - bytes.length(); length -= start - bytes.length(); } } } if (value === undefined && tagClass === asn1.Class.UNIVERSAL && type === asn1.Type.BITSTRING) { bitStringContents = bytes.bytes(length); } if (value === undefined && options.decodeBitStrings && tagClass === asn1.Class.UNIVERSAL && type === asn1.Type.BITSTRING && length > 1) { var savedRead = bytes.read; var savedRemaining = remaining; var unused = 0; if (type === asn1.Type.BITSTRING) { _checkBufferLength(bytes, remaining, 1); unused = bytes.getByte(); remaining--; } if (unused === 0) { try { start = bytes.length(); var subOptions = { strict: true, decodeBitStrings: true }; var composed = _fromDer(bytes, remaining, depth + 1, subOptions); var used = start - bytes.length(); remaining -= used; if (type == asn1.Type.BITSTRING) { used++; } var tc = composed.tagClass; if (used === length && (tc === asn1.Class.UNIVERSAL || tc === asn1.Class.CONTEXT_SPECIFIC)) { value = [composed]; } } catch (ex) {} } if (value === undefined) { bytes.read = savedRead; remaining = savedRemaining; } } if (value === undefined) { if (length === undefined) { if (options.strict) { throw new Error("Non-constructed ASN.1 object of indefinite length."); } length = remaining; } if (type === asn1.Type.BMPSTRING) { value = ""; for (; length > 0; length -= 2) { _checkBufferLength(bytes, remaining, 2); value += String.fromCharCode(bytes.getInt16()); remaining -= 2; } } else { value = bytes.getBytes(length); remaining -= length; } } var asn1Options = bitStringContents === undefined ? null : { bitStringContents }; return asn1.create(tagClass, type, constructed, value, asn1Options); } /** * Converts the given asn1 object to a buffer of bytes in DER format. * * @param asn1 the asn1 object to convert to bytes. * * @return the buffer of bytes. */ asn1.toDer = function(obj) { var bytes = forge.util.createBuffer(); var b1 = obj.tagClass | obj.type; var value = forge.util.createBuffer(); var useBitStringContents = false; if ("bitStringContents" in obj) { useBitStringContents = true; if (obj.original) { useBitStringContents = asn1.equals(obj, obj.original); } } if (useBitStringContents) { value.putBytes(obj.bitStringContents); } else if (obj.composed) { if (obj.constructed) { b1 |= 32; } else { value.putByte(0); } for (var i = 0; i < obj.value.length; ++i) { if (obj.value[i] !== undefined) { value.putBuffer(asn1.toDer(obj.value[i])); } } } else { if (obj.type === asn1.Type.BMPSTRING) { for (var i = 0; i < obj.value.length; ++i) { value.putInt16(obj.value.charCodeAt(i)); } } else { if (obj.type === asn1.Type.INTEGER && obj.value.length > 1 && (obj.value.charCodeAt(0) === 0 && (obj.value.charCodeAt(1) & 128) === 0 || obj.value.charCodeAt(0) === 255 && (obj.value.charCodeAt(1) & 128) === 128)) { value.putBytes(obj.value.substr(1)); } else { value.putBytes(obj.value); } } } bytes.putByte(b1); if (value.length() <= 127) { bytes.putByte(value.length() & 127); } else { var len = value.length(); var lenBytes = ""; do { lenBytes += String.fromCharCode(len & 255); len = len >>> 8; } while (len > 0); bytes.putByte(lenBytes.length | 128); for (var i = lenBytes.length - 1; i >= 0; --i) { bytes.putByte(lenBytes.charCodeAt(i)); } } bytes.putBuffer(value); return bytes; }; /** * Converts an OID dot-separated string to a byte buffer. The byte buffer * contains only the DER-encoded value, not any tag or length bytes. * * @param oid the OID dot-separated string. * * @return the byte buffer. */ asn1.oidToDer = function(oid) { var values = oid.split("."); var bytes = forge.util.createBuffer(); bytes.putByte(40 * parseInt(values[0], 10) + parseInt(values[1], 10)); var last, valueBytes, value, b; for (var i = 2; i < values.length; ++i) { last = true; valueBytes = []; value = parseInt(values[i], 10); do { b = value & 127; value = value >>> 7; if (!last) { b |= 128; } valueBytes.push(b); last = false; } while (value > 0); for (var n = valueBytes.length - 1; n >= 0; --n) { bytes.putByte(valueBytes[n]); } } return bytes; }; /** * Converts a DER-encoded byte buffer to an OID dot-separated string. The * byte buffer should contain only the DER-encoded value, not any tag or * length bytes. * * @param bytes the byte buffer. * * @return the OID dot-separated string. */ asn1.derToOid = function(bytes) { var oid; if (typeof bytes === "string") { bytes = forge.util.createBuffer(bytes); } var b = bytes.getByte(); oid = Math.floor(b / 40) + "." + b % 40; var value = 0; while (bytes.length() > 0) { b = bytes.getByte(); value = value << 7; if (b & 128) { value += b & 127; } else { oid += "." + (value + b); value = 0; } } return oid; }; /** * Converts a UTCTime value to a date. * * Note: GeneralizedTime has 4 digits for the year and is used for X.509 * dates past 2049. Parsing that structure hasn't been implemented yet. * * @param utc the UTCTime value to convert. * * @return the date. */ asn1.utcTimeToDate = function(utc) { var date = new Date(); var year = parseInt(utc.substr(0, 2), 10); year = year >= 50 ? 1900 + year : 2e3 + year; var MM = parseInt(utc.substr(2, 2), 10) - 1; var DD = parseInt(utc.substr(4, 2), 10); var hh = parseInt(utc.substr(6, 2), 10); var mm = parseInt(utc.substr(8, 2), 10); var ss = 0; if (utc.length > 11) { var c = utc.charAt(10); var end = 10; if (c !== "+" && c !== "-") { ss = parseInt(utc.substr(10, 2), 10); end += 2; } } date.setUTCFullYear(year, MM, DD); date.setUTCHours(hh, mm, ss, 0); if (end) { c = utc.charAt(end); if (c === "+" || c === "-") { var hhoffset = parseInt(utc.substr(end + 1, 2), 10); var mmoffset = parseInt(utc.substr(end + 4, 2), 10); var offset = hhoffset * 60 + mmoffset; offset *= 6e4; if (c === "+") { date.setTime(+date - offset); } else { date.setTime(+date + offset); } } } return date; }; /** * Converts a GeneralizedTime value to a date. * * @param gentime the GeneralizedTime value to convert. * * @return the date. */ asn1.generalizedTimeToDate = function(gentime) { var date = new Date(); var YYYY = parseInt(gentime.substr(0, 4), 10); var MM = parseInt(gentime.substr(4, 2), 10) - 1; var DD = parseInt(gentime.substr(6, 2), 10); var hh = parseInt(gentime.substr(8, 2), 10); var mm = parseInt(gentime.substr(10, 2), 10); var ss = parseInt(gentime.substr(12, 2), 10); var fff = 0; var offset = 0; var isUTC = false; if (gentime.charAt(gentime.length - 1) === "Z") { isUTC = true; } var end = gentime.length - 5, c = gentime.charAt(end); if (c === "+" || c === "-") { var hhoffset = parseInt(gentime.substr(end + 1, 2), 10); var mmoffset = parseInt(gentime.substr(end + 4, 2), 10); offset = hhoffset * 60 + mmoffset; offset *= 6e4; if (c === "+") { offset *= -1; } isUTC = true; } if (gentime.charAt(14) === ".") { fff = parseFloat(gentime.substr(14), 10) * 1e3; } if (isUTC) { date.setUTCFullYear(YYYY, MM, DD); date.setUTCHours(hh, mm, ss, fff); date.setTime(+date + offset); } else { date.setFullYear(YYYY, MM, DD); date.setHours(hh, mm, ss, fff); } return date; }; /** * Converts a date to a UTCTime value. * * Note: GeneralizedTime has 4 digits for the year and is used for X.509 * dates past 2049. Converting to a GeneralizedTime hasn't been * implemented yet. * * @param date the date to convert. * * @return the UTCTime value. */ asn1.dateToUtcTime = function(date) { if (typeof date === "string") { return date; } var rval = ""; var format = []; format.push(("" + date.getUTCFullYear()).substr(2)); format.push("" + (date.getUTCMonth() + 1)); format.push("" + date.getUTCDate()); format.push("" + date.getUTCHours()); format.push("" + date.getUTCMinutes()); format.push("" + date.getUTCSeconds()); for (var i = 0; i < format.length; ++i) { if (format[i].length < 2) { rval += "0"; } rval += format[i]; } rval += "Z"; return rval; }; /** * Converts a date to a GeneralizedTime value. * * @param date the date to convert. * * @return the GeneralizedTime value as a string. */ asn1.dateToGeneralizedTime = function(date) { if (typeof date === "string") { return date; } var rval = ""; var format = []; format.push("" + date.getUTCFullYear()); format.push("" + (date.getUTCMonth() + 1)); format.push("" + date.getUTCDate()); format.push("" + date.getUTCHours()); format.push("" + date.getUTCMinutes()); format.push("" + date.getUTCSeconds()); for (var i = 0; i < format.length; ++i) { if (format[i].length < 2) { rval += "0"; } rval += format[i]; } rval += "Z"; return rval; }; /** * Converts a javascript integer to a DER-encoded byte buffer to be used * as the value for an INTEGER type. * * @param x the integer. * * @return the byte buffer. */ asn1.integerToDer = function(x) { var rval = forge.util.createBuffer(); if (x >= -128 && x < 128) { return rval.putSignedInt(x, 8); } if (x >= -32768 && x < 32768) { return rval.putSignedInt(x, 16); } if (x >= -8388608 && x < 8388608) { return rval.putSignedInt(x, 24); } if (x >= -2147483648 && x < 2147483648) { return rval.putSignedInt(x, 32); } var error = new Error("Integer too large; max is 32-bits."); error.integer = x; throw error; }; /** * Converts a DER-encoded byte buffer to a javascript integer. This is * typically used to decode the value of an INTEGER type. * * @param bytes the byte buffer. * * @return the integer. */ asn1.derToInteger = function(bytes) { if (typeof bytes === "string") { bytes = forge.util.createBuffer(bytes); } var n = bytes.length() * 8; if (n > 32) { throw new Error("Integer too large; max is 32-bits."); } return bytes.getSignedInt(n); }; /** * Validates that the given ASN.1 object is at least a super set of the * given ASN.1 structure. Only tag classes and types are checked. An * optional map may also be provided to capture ASN.1 values while the * structure is checked. * * To capture an ASN.1 value, set an object in the validator's 'capture' * parameter to the key to use in the capture map. To capture the full * ASN.1 object, specify 'captureAsn1'. To capture BIT STRING bytes, including * the leading unused bits counter byte, specify 'captureBitStringContents'. * To capture BIT STRING bytes, without the leading unused bits counter byte, * specify 'captureBitStringValue'. * * Objects in the validator may set a field 'optional' to true to indicate * that it isn't necessary to pass validation. * * @param obj the ASN.1 object to validate. * @param v the ASN.1 structure validator. * @param capture an optional map to capture values in. * @param errors an optional array for storing validation errors. * * @return true on success, false on failure. */ asn1.validate = function(obj, v, capture, errors) { var rval = false; if ((obj.tagClass === v.tagClass || typeof v.tagClass === "undefined") && (obj.type === v.type || typeof v.type === "undefined")) { if (obj.constructed === v.constructed || typeof v.constructed === "undefined") { rval = true; if (v.value && forge.util.isArray(v.value)) { var j = 0; for (var i = 0; rval && i < v.value.length; ++i) { rval = v.value[i].optional || false; if (obj.value[j]) { rval = asn1.validate(obj.value[j], v.value[i], capture, errors); if (rval) { ++j; } else if (v.value[i].optional) { rval = true; } } if (!rval && errors) { errors.push("[" + v.name + "] " + "Tag class \"" + v.tagClass + "\", type \"" + v.type + "\" expected value length \"" + v.value.length + "\", got \"" + obj.value.length + "\""); } } } if (rval && capture) { if (v.capture) { capture[v.capture] = obj.value; } if (v.captureAsn1) { capture[v.captureAsn1] = obj; } if (v.captureBitStringContents && "bitStringContents" in obj) { capture[v.captureBitStringContents] = obj.bitStringContents; } if (v.captureBitStringValue && "bitStringContents" in obj) { var value; if (obj.bitStringContents.length < 2) { capture[v.captureBitStringValue] = ""; } else { var unused = obj.bitStringContents.charCodeAt(0); if (unused !== 0) { throw new Error("captureBitStringValue only supported for zero unused bits"); } capture[v.captureBitStringValue] = obj.bitStringContents.slice(1); } } } } else if (errors) { errors.push("[" + v.name + "] " + "Expected constructed \"" + v.constructed + "\", got \"" + obj.constructed + "\""); } } else if (errors) { if (obj.tagClass !== v.tagClass) { errors.push("[" + v.name + "] " + "Expected tag class \"" + v.tagClass + "\", got \"" + obj.tagClass + "\""); } if (obj.type !== v.type) { errors.push("[" + v.name + "] " + "Expected type \"" + v.type + "\", got \"" + obj.type + "\""); } } return rval; }; var _nonLatinRegex = /[^\\u0000-\\u00ff]/; /** * Pretty prints an ASN.1 object to a string. * * @param obj the object to write out. * @param level the level in the tree. * @param indentation the indentation to use. * * @return the string. */ asn1.prettyPrint = function(obj, level, indentation) { var rval = ""; level = level || 0; indentation = indentation || 2; if (level > 0) { rval += "\n"; } var indent = ""; for (var i = 0; i < level * indentation; ++i) { indent += " "; } rval += indent + "Tag: "; switch (obj.tagClass) { case asn1.Class.UNIVERSAL: rval += "Universal:"; break; case asn1.Class.APPLICATION: rval += "Application:"; break; case asn1.Class.CONTEXT_SPECIFIC: rval += "Context-Specific:"; break; case asn1.Class.PRIVATE: rval += "Private:"; break; } if (obj.tagClass === asn1.Class.UNIVERSAL) { rval += obj.type; switch (obj.type) { case asn1.Type.NONE: rval += " (None)"; break; case asn1.Type.BOOLEAN: rval += " (Boolean)"; break; case asn1.Type.INTEGER: rval += " (Integer)"; break; case asn1.Type.BITSTRING: rval += " (Bit string)"; break; case asn1.Type.OCTETSTRING: rval += " (Octet string)"; break; case asn1.Type.NULL: rval += " (Null)"; break; case asn1.Type.OID: rval += " (Object Identifier)"; break; case asn1.Type.ODESC: rval += " (Object Descriptor)"; break; case asn1.Type.EXTERNAL: rval += " (External or Instance of)"; break; case asn1.Type.REAL: rval += " (Real)"; break; case asn1.Type.ENUMERATED: rval += " (Enumerated)"; break; case asn1.Type.EMBEDDED: rval += " (Embedded PDV)"; break; case asn1.Type.UTF8: rval += " (UTF8)"; break; case asn1.Type.ROID: rval += " (Relative Object Identifier)"; break; case asn1.Type.SEQUENCE: rval += " (Sequence)"; break; case asn1.Type.SET: rval += " (Set)"; break; case asn1.Type.PRINTABLESTRING: rval += " (Printable String)"; break; case asn1.Type.IA5String: rval += " (IA5String (ASCII))"; break; case asn1.Type.UTCTIME: rval += " (UTC time)"; break; case asn1.Type.GENERALIZEDTIME: rval += " (Generalized time)"; break; case asn1.Type.BMPSTRING: rval += " (BMP String)"; break; } } else { rval += obj.type; } rval += "\n"; rval += indent + "Constructed: " + obj.constructed + "\n"; if (obj.composed) { var subvalues = 0; var sub = ""; for (var i = 0; i < obj.value.length; ++i) { if (obj.value[i] !== undefined) { subvalues += 1; sub += asn1.prettyPrint(obj.value[i], level + 1, indentation); if (i + 1 < obj.value.length) { sub += ","; } } } rval += indent + "Sub values: " + subvalues + sub; } else { rval += indent + "Value: "; if (obj.type === asn1.Type.OID) { var oid = asn1.derToOid(obj.value); rval += oid; if (forge.pki && forge.pki.oids) { if (oid in forge.pki.oids) { rval += " (" + forge.pki.oids[oid] + ") "; } } } if (obj.type === asn1.Type.INTEGER) { try { rval += asn1.derToInteger(obj.value); } catch (ex) { rval += "0x" + forge.util.bytesToHex(obj.value); } } else if (obj.type === asn1.Type.BITSTRING) { if (obj.value.length > 1) { rval += "0x" + forge.util.bytesToHex(obj.value.slice(1)); } else { rval += "(none)"; } if (obj.value.length > 0) { var unused = obj.value.charCodeAt(0); if (unused == 1) { rval += " (1 unused bit shown)"; } else if (unused > 1) { rval += " (" + unused + " unused bits shown)"; } } } else if (obj.type === asn1.Type.OCTETSTRING) { if (!_nonLatinRegex.test(obj.value)) { rval += "(" + obj.value + ") "; } rval += "0x" + forge.util.bytesToHex(obj.value); } else if (obj.type === asn1.Type.UTF8) { try { rval += forge.util.decodeUtf8(obj.value); } catch (e) { if (e.message === "URI malformed") { rval += "0x" + forge.util.bytesToHex(obj.value) + " (malformed UTF8)"; } else { throw e; } } } else if (obj.type === asn1.Type.PRINTABLESTRING || obj.type === asn1.Type.IA5String) { rval += obj.value; } else if (_nonLatinRegex.test(obj.value)) { rval += "0x" + forge.util.bytesToHex(obj.value); } else if (obj.value.length === 0) { rval += "[null]"; } else { rval += obj.value; } } return rval; }; })); //#endregion //#region ../node_modules/node-forge/lib/md.js var require_md = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Node.js module for Forge message digests. * * @author Dave Longley * * Copyright 2011-2017 Digital Bazaar, Inc. */ var forge = require_forge(); module.exports = forge.md = forge.md || {}; forge.md.algorithms = forge.md.algorithms || {}; })); //#endregion //#region ../node_modules/node-forge/lib/hmac.js var require_hmac$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Hash-based Message Authentication Code implementation. Requires a message * digest object that can be obtained, for example, from forge.md.sha1 or * forge.md.md5. * * @author Dave Longley * * Copyright (c) 2010-2012 Digital Bazaar, Inc. All rights reserved. */ var forge = require_forge(); require_md(); require_util$8(); var hmac = module.exports = forge.hmac = forge.hmac || {}; /** * Creates an HMAC object that uses the given message digest object. * * @return an HMAC object. */ hmac.create = function() { var _key = null; var _md = null; var _ipadding = null; var _opadding = null; var ctx = {}; /** * Starts or restarts the HMAC with the given key and message digest. * * @param md the message digest to use, null to reuse the previous one, * a string to use builtin 'sha1', 'md5', 'sha256'. * @param key the key to use as a string, array of bytes, byte buffer, * or null to reuse the previous key. */ ctx.start = function(md, key) { if (md !== null) { if (typeof md === "string") { md = md.toLowerCase(); if (md in forge.md.algorithms) { _md = forge.md.algorithms[md].create(); } else { throw new Error("Unknown hash algorithm \"" + md + "\""); } } else { _md = md; } } if (key === null) { key = _key; } else { if (typeof key === "string") { key = forge.util.createBuffer(key); } else if (forge.util.isArray(key)) { var tmp = key; key = forge.util.createBuffer(); for (var i = 0; i < tmp.length; ++i) { key.putByte(tmp[i]); } } var keylen = key.length(); if (keylen > _md.blockLength) { _md.start(); _md.update(key.bytes()); key = _md.digest(); } _ipadding = forge.util.createBuffer(); _opadding = forge.util.createBuffer(); keylen = key.length(); for (var i = 0; i < keylen; ++i) { var tmp = key.at(i); _ipadding.putByte(54 ^ tmp); _opadding.putByte(92 ^ tmp); } if (keylen < _md.blockLength) { var tmp = _md.blockLength - keylen; for (var i = 0; i < tmp; ++i) { _ipadding.putByte(54); _opadding.putByte(92); } } _key = key; _ipadding = _ipadding.bytes(); _opadding = _opadding.bytes(); } _md.start(); _md.update(_ipadding); }; /** * Updates the HMAC with the given message bytes. * * @param bytes the bytes to update with. */ ctx.update = function(bytes) { _md.update(bytes); }; /** * Produces the Message Authentication Code (MAC). * * @return a byte buffer containing the digest value. */ ctx.getMac = function() { var inner = _md.digest().bytes(); _md.start(); _md.update(_opadding); _md.update(inner); return _md.digest(); }; ctx.digest = ctx.getMac; return ctx; }; })); //#endregion //#region ../node_modules/node-forge/lib/md5.js var require_md5$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Message Digest Algorithm 5 with 128-bit digest (MD5) implementation. * * @author Dave Longley * * Copyright (c) 2010-2014 Digital Bazaar, Inc. */ var forge = require_forge(); require_md(); require_util$8(); var md5 = module.exports = forge.md5 = forge.md5 || {}; forge.md.md5 = forge.md.algorithms.md5 = md5; /** * Creates an MD5 message digest object. * * @return a message digest object. */ md5.create = function() { if (!_initialized) { _init(); } var _state = null; var _input = forge.util.createBuffer(); var _w = new Array(16); var md = { algorithm: "md5", blockLength: 64, digestLength: 16, messageLength: 0, fullMessageLength: null, messageLengthSize: 8 }; /** * Starts the digest. * * @return this digest object. */ md.start = function() { md.messageLength = 0; md.fullMessageLength = md.messageLength64 = []; var int32s = md.messageLengthSize / 4; for (var i = 0; i < int32s; ++i) { md.fullMessageLength.push(0); } _input = forge.util.createBuffer(); _state = { h0: 1732584193, h1: 4023233417, h2: 2562383102, h3: 271733878 }; return md; }; md.start(); /** * Updates the digest with the given message input. The given input can * treated as raw input (no encoding will be applied) or an encoding of * 'utf8' maybe given to encode the input using UTF-8. * * @param msg the message input to update with. * @param encoding the encoding to use (default: 'raw', other: 'utf8'). * * @return this digest object. */ md.update = function(msg, encoding) { if (encoding === "utf8") { msg = forge.util.encodeUtf8(msg); } var len = msg.length; md.messageLength += len; len = [len / 4294967296 >>> 0, len >>> 0]; for (var i = md.fullMessageLength.length - 1; i >= 0; --i) { md.fullMessageLength[i] += len[1]; len[1] = len[0] + (md.fullMessageLength[i] / 4294967296 >>> 0); md.fullMessageLength[i] = md.fullMessageLength[i] >>> 0; len[0] = len[1] / 4294967296 >>> 0; } _input.putBytes(msg); _update(_state, _w, _input); if (_input.read > 2048 || _input.length() === 0) { _input.compact(); } return md; }; /** * Produces the digest. * * @return a byte buffer containing the digest value. */ md.digest = function() { var finalBlock = forge.util.createBuffer(); finalBlock.putBytes(_input.bytes()); var remaining = md.fullMessageLength[md.fullMessageLength.length - 1] + md.messageLengthSize; var overflow = remaining & md.blockLength - 1; finalBlock.putBytes(_padding.substr(0, md.blockLength - overflow)); var bits, carry = 0; for (var i = md.fullMessageLength.length - 1; i >= 0; --i) { bits = md.fullMessageLength[i] * 8 + carry; carry = bits / 4294967296 >>> 0; finalBlock.putInt32Le(bits >>> 0); } var s2 = { h0: _state.h0, h1: _state.h1, h2: _state.h2, h3: _state.h3 }; _update(s2, _w, finalBlock); var rval = forge.util.createBuffer(); rval.putInt32Le(s2.h0); rval.putInt32Le(s2.h1); rval.putInt32Le(s2.h2); rval.putInt32Le(s2.h3); return rval; }; return md; }; var _padding = null; var _g = null; var _r = null; var _k = null; var _initialized = false; /** * Initializes the constant tables. */ function _init() { _padding = String.fromCharCode(128); _padding += forge.util.fillString(String.fromCharCode(0), 64); _g = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 ]; _r = [ 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 ]; _k = new Array(64); for (var i = 0; i < 64; ++i) { _k[i] = Math.floor(Math.abs(Math.sin(i + 1)) * 4294967296); } _initialized = true; } /** * Updates an MD5 state with the given byte buffer. * * @param s the MD5 state to update. * @param w the array to use to store words. * @param bytes the byte buffer to update with. */ function _update(s, w, bytes) { var t, a, b, c, d, f, r, i; var len = bytes.length(); while (len >= 64) { a = s.h0; b = s.h1; c = s.h2; d = s.h3; for (i = 0; i < 16; ++i) { w[i] = bytes.getInt32Le(); f = d ^ b & (c ^ d); t = a + f + _k[i] + w[i]; r = _r[i]; a = d; d = c; c = b; b += t << r | t >>> 32 - r; } for (; i < 32; ++i) { f = c ^ d & (b ^ c); t = a + f + _k[i] + w[_g[i]]; r = _r[i]; a = d; d = c; c = b; b += t << r | t >>> 32 - r; } for (; i < 48; ++i) { f = b ^ c ^ d; t = a + f + _k[i] + w[_g[i]]; r = _r[i]; a = d; d = c; c = b; b += t << r | t >>> 32 - r; } for (; i < 64; ++i) { f = c ^ (b | ~d); t = a + f + _k[i] + w[_g[i]]; r = _r[i]; a = d; d = c; c = b; b += t << r | t >>> 32 - r; } s.h0 = s.h0 + a | 0; s.h1 = s.h1 + b | 0; s.h2 = s.h2 + c | 0; s.h3 = s.h3 + d | 0; len -= 64; } } })); //#endregion //#region ../node_modules/node-forge/lib/pem.js var require_pem = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Javascript implementation of basic PEM (Privacy Enhanced Mail) algorithms. * * See: RFC 1421. * * @author Dave Longley * * Copyright (c) 2013-2014 Digital Bazaar, Inc. * * A Forge PEM object has the following fields: * * type: identifies the type of message (eg: "RSA PRIVATE KEY"). * * procType: identifies the type of processing performed on the message, * it has two subfields: version and type, eg: 4,ENCRYPTED. * * contentDomain: identifies the type of content in the message, typically * only uses the value: "RFC822". * * dekInfo: identifies the message encryption algorithm and mode and includes * any parameters for the algorithm, it has two subfields: algorithm and * parameters, eg: DES-CBC,F8143EDE5960C597. * * headers: contains all other PEM encapsulated headers -- where order is * significant (for pairing data like recipient ID + key info). * * body: the binary-encoded body. */ var forge = require_forge(); require_util$8(); var pem = module.exports = forge.pem = forge.pem || {}; /** * Encodes (serializes) the given PEM object. * * @param msg the PEM message object to encode. * @param options the options to use: * maxline the maximum characters per line for the body, (default: 64). * * @return the PEM-formatted string. */ pem.encode = function(msg, options) { options = options || {}; var rval = "-----BEGIN " + msg.type + "-----\r\n"; var header; if (msg.procType) { header = { name: "Proc-Type", values: [String(msg.procType.version), msg.procType.type] }; rval += foldHeader(header); } if (msg.contentDomain) { header = { name: "Content-Domain", values: [msg.contentDomain] }; rval += foldHeader(header); } if (msg.dekInfo) { header = { name: "DEK-Info", values: [msg.dekInfo.algorithm] }; if (msg.dekInfo.parameters) { header.values.push(msg.dekInfo.parameters); } rval += foldHeader(header); } if (msg.headers) { for (var i = 0; i < msg.headers.length; ++i) { rval += foldHeader(msg.headers[i]); } } if (msg.procType) { rval += "\r\n"; } rval += forge.util.encode64(msg.body, options.maxline || 64) + "\r\n"; rval += "-----END " + msg.type + "-----\r\n"; return rval; }; /** * Decodes (deserializes) all PEM messages found in the given string. * * @param str the PEM-formatted string to decode. * * @return the PEM message objects in an array. */ pem.decode = function(str) { var rval = []; var rMessage = /\s*-----BEGIN ([A-Z0-9- ]+)-----\r?\n?([\x21-\x7e\s]+?(?:\r?\n\r?\n))?([:A-Za-z0-9+\/=\s]+?)-----END \1-----/g; var rHeader = /([\x21-\x7e]+):\s*([\x21-\x7e\s^:]+)/; var rCRLF = /\r?\n/; var match; while (true) { match = rMessage.exec(str); if (!match) { break; } var type = match[1]; if (type === "NEW CERTIFICATE REQUEST") { type = "CERTIFICATE REQUEST"; } var msg = { type, procType: null, contentDomain: null, dekInfo: null, headers: [], body: forge.util.decode64(match[3]) }; rval.push(msg); if (!match[2]) { continue; } var lines = match[2].split(rCRLF); var li = 0; while (match && li < lines.length) { var line = lines[li].replace(/\s+$/, ""); for (var nl = li + 1; nl < lines.length; ++nl) { var next = lines[nl]; if (!/\s/.test(next[0])) { break; } line += next; li = nl; } match = line.match(rHeader); if (match) { var header = { name: match[1], values: [] }; var values = match[2].split(","); for (var vi = 0; vi < values.length; ++vi) { header.values.push(ltrim(values[vi])); } if (!msg.procType) { if (header.name !== "Proc-Type") { throw new Error("Invalid PEM formatted message. The first " + "encapsulated header must be \"Proc-Type\"."); } else if (header.values.length !== 2) { throw new Error("Invalid PEM formatted message. The \"Proc-Type\" " + "header must have two subfields."); } msg.procType = { version: values[0], type: values[1] }; } else if (!msg.contentDomain && header.name === "Content-Domain") { msg.contentDomain = values[0] || ""; } else if (!msg.dekInfo && header.name === "DEK-Info") { if (header.values.length === 0) { throw new Error("Invalid PEM formatted message. The \"DEK-Info\" " + "header must have at least one subfield."); } msg.dekInfo = { algorithm: values[0], parameters: values[1] || null }; } else { msg.headers.push(header); } } ++li; } if (msg.procType === "ENCRYPTED" && !msg.dekInfo) { throw new Error("Invalid PEM formatted message. The \"DEK-Info\" " + "header must be present if \"Proc-Type\" is \"ENCRYPTED\"."); } } if (rval.length === 0) { throw new Error("Invalid PEM formatted message."); } return rval; }; function foldHeader(header) { var rval = header.name + ": "; var values = []; var insertSpace = function(match, $1) { return " " + $1; }; for (var i = 0; i < header.values.length; ++i) { values.push(header.values[i].replace(/^(\S+\r\n)/, insertSpace)); } rval += values.join(",") + "\r\n"; var length = 0; var candidate = -1; for (var i = 0; i < rval.length; ++i, ++length) { if (length > 65 && candidate !== -1) { var insert = rval[candidate]; if (insert === ",") { ++candidate; rval = rval.substr(0, candidate) + "\r\n " + rval.substr(candidate); } else { rval = rval.substr(0, candidate) + "\r\n" + insert + rval.substr(candidate + 1); } length = i - candidate - 1; candidate = -1; ++i; } else if (rval[i] === " " || rval[i] === " " || rval[i] === ",") { candidate = i; } } return rval; } function ltrim(str) { return str.replace(/^\s+/, ""); } })); //#endregion //#region ../node_modules/node-forge/lib/des.js var require_des = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * DES (Data Encryption Standard) implementation. * * This implementation supports DES as well as 3DES-EDE in ECB and CBC mode. * It is based on the BSD-licensed implementation by Paul Tero: * * Paul Tero, July 2001 * http://www.tero.co.uk/des/ * * Optimised for performance with large blocks by * Michael Hayworth, November 2001 * http://www.netdealing.com * * THIS SOFTWARE IS PROVIDED "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 AUTHOR 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. * * @author Stefan Siegl * @author Dave Longley * * Copyright (c) 2012 Stefan Siegl * Copyright (c) 2012-2014 Digital Bazaar, Inc. */ var forge = require_forge(); require_cipher(); require_cipherModes(); require_util$8(); module.exports = forge.des = forge.des || {}; /** * Deprecated. Instead, use: * * var cipher = forge.cipher.createCipher('DES-', key); * cipher.start({iv: iv}); * * Creates an DES cipher object to encrypt data using the given symmetric key. * The output will be stored in the 'output' member of the returned cipher. * * The key and iv may be given as binary-encoded strings of bytes or * byte buffers. * * @param key the symmetric key to use (64 or 192 bits). * @param iv the initialization vector to use. * @param output the buffer to write to, null to create one. * @param mode the cipher mode to use (default: 'CBC' if IV is * given, 'ECB' if null). * * @return the cipher. */ forge.des.startEncrypting = function(key, iv, output, mode) { var cipher = _createCipher({ key, output, decrypt: false, mode: mode || (iv === null ? "ECB" : "CBC") }); cipher.start(iv); return cipher; }; /** * Deprecated. Instead, use: * * var cipher = forge.cipher.createCipher('DES-', key); * * Creates an DES cipher object to encrypt data using the given symmetric key. * * The key may be given as a binary-encoded string of bytes or a byte buffer. * * @param key the symmetric key to use (64 or 192 bits). * @param mode the cipher mode to use (default: 'CBC'). * * @return the cipher. */ forge.des.createEncryptionCipher = function(key, mode) { return _createCipher({ key, output: null, decrypt: false, mode }); }; /** * Deprecated. Instead, use: * * var decipher = forge.cipher.createDecipher('DES-', key); * decipher.start({iv: iv}); * * Creates an DES cipher object to decrypt data using the given symmetric key. * The output will be stored in the 'output' member of the returned cipher. * * The key and iv may be given as binary-encoded strings of bytes or * byte buffers. * * @param key the symmetric key to use (64 or 192 bits). * @param iv the initialization vector to use. * @param output the buffer to write to, null to create one. * @param mode the cipher mode to use (default: 'CBC' if IV is * given, 'ECB' if null). * * @return the cipher. */ forge.des.startDecrypting = function(key, iv, output, mode) { var cipher = _createCipher({ key, output, decrypt: true, mode: mode || (iv === null ? "ECB" : "CBC") }); cipher.start(iv); return cipher; }; /** * Deprecated. Instead, use: * * var decipher = forge.cipher.createDecipher('DES-', key); * * Creates an DES cipher object to decrypt data using the given symmetric key. * * The key may be given as a binary-encoded string of bytes or a byte buffer. * * @param key the symmetric key to use (64 or 192 bits). * @param mode the cipher mode to use (default: 'CBC'). * * @return the cipher. */ forge.des.createDecryptionCipher = function(key, mode) { return _createCipher({ key, output: null, decrypt: true, mode }); }; /** * Creates a new DES cipher algorithm object. * * @param name the name of the algorithm. * @param mode the mode factory function. * * @return the DES algorithm object. */ forge.des.Algorithm = function(name, mode) { var self = this; self.name = name; self.mode = new mode({ blockSize: 8, cipher: { encrypt: function(inBlock, outBlock) { return _updateBlock(self._keys, inBlock, outBlock, false); }, decrypt: function(inBlock, outBlock) { return _updateBlock(self._keys, inBlock, outBlock, true); } } }); self._init = false; }; /** * Initializes this DES algorithm by expanding its key. * * @param options the options to use. * key the key to use with this algorithm. * decrypt true if the algorithm should be initialized for decryption, * false for encryption. */ forge.des.Algorithm.prototype.initialize = function(options) { if (this._init) { return; } var key = forge.util.createBuffer(options.key); if (this.name.indexOf("3DES") === 0) { if (key.length() !== 24) { throw new Error("Invalid Triple-DES key size: " + key.length() * 8); } } this._keys = _createKeys(key); this._init = true; }; /** Register DES algorithms **/ registerAlgorithm("DES-ECB", forge.cipher.modes.ecb); registerAlgorithm("DES-CBC", forge.cipher.modes.cbc); registerAlgorithm("DES-CFB", forge.cipher.modes.cfb); registerAlgorithm("DES-OFB", forge.cipher.modes.ofb); registerAlgorithm("DES-CTR", forge.cipher.modes.ctr); registerAlgorithm("3DES-ECB", forge.cipher.modes.ecb); registerAlgorithm("3DES-CBC", forge.cipher.modes.cbc); registerAlgorithm("3DES-CFB", forge.cipher.modes.cfb); registerAlgorithm("3DES-OFB", forge.cipher.modes.ofb); registerAlgorithm("3DES-CTR", forge.cipher.modes.ctr); function registerAlgorithm(name, mode) { var factory = function() { return new forge.des.Algorithm(name, mode); }; forge.cipher.registerAlgorithm(name, factory); } /** DES implementation **/ var spfunction1 = [ 16843776, 0, 65536, 16843780, 16842756, 66564, 4, 65536, 1024, 16843776, 16843780, 1024, 16778244, 16842756, 16777216, 4, 1028, 16778240, 16778240, 66560, 66560, 16842752, 16842752, 16778244, 65540, 16777220, 16777220, 65540, 0, 1028, 66564, 16777216, 65536, 16843780, 4, 16842752, 16843776, 16777216, 16777216, 1024, 16842756, 65536, 66560, 16777220, 1024, 4, 16778244, 66564, 16843780, 65540, 16842752, 16778244, 16777220, 1028, 66564, 16843776, 1028, 16778240, 16778240, 0, 65540, 66560, 0, 16842756 ]; var spfunction2 = [ -2146402272, -2147450880, 32768, 1081376, 1048576, 32, -2146435040, -2147450848, -2147483616, -2146402272, -2146402304, -2147483648, -2147450880, 1048576, 32, -2146435040, 1081344, 1048608, -2147450848, 0, -2147483648, 32768, 1081376, -2146435072, 1048608, -2147483616, 0, 1081344, 32800, -2146402304, -2146435072, 32800, 0, 1081376, -2146435040, 1048576, -2147450848, -2146435072, -2146402304, 32768, -2146435072, -2147450880, 32, -2146402272, 1081376, 32, 32768, -2147483648, 32800, -2146402304, 1048576, -2147483616, 1048608, -2147450848, -2147483616, 1048608, 1081344, 0, -2147450880, 32800, -2147483648, -2146435040, -2146402272, 1081344 ]; var spfunction3 = [ 520, 134349312, 0, 134348808, 134218240, 0, 131592, 134218240, 131080, 134217736, 134217736, 131072, 134349320, 131080, 134348800, 520, 134217728, 8, 134349312, 512, 131584, 134348800, 134348808, 131592, 134218248, 131584, 131072, 134218248, 8, 134349320, 512, 134217728, 134349312, 134217728, 131080, 520, 131072, 134349312, 134218240, 0, 512, 131080, 134349320, 134218240, 134217736, 512, 0, 134348808, 134218248, 131072, 134217728, 134349320, 8, 131592, 131584, 134217736, 134348800, 134218248, 520, 134348800, 131592, 8, 134348808, 131584 ]; var spfunction4 = [ 8396801, 8321, 8321, 128, 8396928, 8388737, 8388609, 8193, 0, 8396800, 8396800, 8396929, 129, 0, 8388736, 8388609, 1, 8192, 8388608, 8396801, 128, 8388608, 8193, 8320, 8388737, 1, 8320, 8388736, 8192, 8396928, 8396929, 129, 8388736, 8388609, 8396800, 8396929, 129, 0, 0, 8396800, 8320, 8388736, 8388737, 1, 8396801, 8321, 8321, 128, 8396929, 129, 1, 8192, 8388609, 8193, 8396928, 8388737, 8193, 8320, 8388608, 8396801, 128, 8388608, 8192, 8396928 ]; var spfunction5 = [ 256, 34078976, 34078720, 1107296512, 524288, 256, 1073741824, 34078720, 1074266368, 524288, 33554688, 1074266368, 1107296512, 1107820544, 524544, 1073741824, 33554432, 1074266112, 1074266112, 0, 1073742080, 1107820800, 1107820800, 33554688, 1107820544, 1073742080, 0, 1107296256, 34078976, 33554432, 1107296256, 524544, 524288, 1107296512, 256, 33554432, 1073741824, 34078720, 1107296512, 1074266368, 33554688, 1073741824, 1107820544, 34078976, 1074266368, 256, 33554432, 1107820544, 1107820800, 524544, 1107296256, 1107820800, 34078720, 0, 1074266112, 1107296256, 524544, 33554688, 1073742080, 524288, 0, 1074266112, 34078976, 1073742080 ]; var spfunction6 = [ 536870928, 541065216, 16384, 541081616, 541065216, 16, 541081616, 4194304, 536887296, 4210704, 4194304, 536870928, 4194320, 536887296, 536870912, 16400, 0, 4194320, 536887312, 16384, 4210688, 536887312, 16, 541065232, 541065232, 0, 4210704, 541081600, 16400, 4210688, 541081600, 536870912, 536887296, 16, 541065232, 4210688, 541081616, 4194304, 16400, 536870928, 4194304, 536887296, 536870912, 16400, 536870928, 541081616, 4210688, 541065216, 4210704, 541081600, 0, 541065232, 16, 16384, 541065216, 4210704, 16384, 4194320, 536887312, 0, 541081600, 536870912, 4194320, 536887312 ]; var spfunction7 = [ 2097152, 69206018, 67110914, 0, 2048, 67110914, 2099202, 69208064, 69208066, 2097152, 0, 67108866, 2, 67108864, 69206018, 2050, 67110912, 2099202, 2097154, 67110912, 67108866, 69206016, 69208064, 2097154, 69206016, 2048, 2050, 69208066, 2099200, 2, 67108864, 2099200, 67108864, 2099200, 2097152, 67110914, 67110914, 69206018, 69206018, 2, 2097154, 67108864, 67110912, 2097152, 69208064, 2050, 2099202, 69208064, 2050, 67108866, 69208066, 69206016, 2099200, 0, 2, 69208066, 0, 2099202, 69206016, 2048, 67108866, 67110912, 2048, 2097154 ]; var spfunction8 = [ 268439616, 4096, 262144, 268701760, 268435456, 268439616, 64, 268435456, 262208, 268697600, 268701760, 266240, 268701696, 266304, 4096, 64, 268697600, 268435520, 268439552, 4160, 266240, 262208, 268697664, 268701696, 4160, 0, 0, 268697664, 268435520, 268439552, 266304, 262144, 266304, 262144, 268701696, 4096, 64, 268697664, 4096, 266304, 268439552, 64, 268435520, 268697600, 268697664, 268435456, 262144, 268439616, 0, 268701760, 262208, 268435520, 268697600, 268439552, 268439616, 0, 268701760, 266240, 266240, 4160, 4160, 262208, 268435456, 268701696 ]; /** * Create necessary sub keys. * * @param key the 64-bit or 192-bit key. * * @return the expanded keys. */ function _createKeys(key) { var pc2bytes0 = [ 0, 4, 536870912, 536870916, 65536, 65540, 536936448, 536936452, 512, 516, 536871424, 536871428, 66048, 66052, 536936960, 536936964 ], pc2bytes1 = [ 0, 1, 1048576, 1048577, 67108864, 67108865, 68157440, 68157441, 256, 257, 1048832, 1048833, 67109120, 67109121, 68157696, 68157697 ], pc2bytes2 = [ 0, 8, 2048, 2056, 16777216, 16777224, 16779264, 16779272, 0, 8, 2048, 2056, 16777216, 16777224, 16779264, 16779272 ], pc2bytes3 = [ 0, 2097152, 134217728, 136314880, 8192, 2105344, 134225920, 136323072, 131072, 2228224, 134348800, 136445952, 139264, 2236416, 134356992, 136454144 ], pc2bytes4 = [ 0, 262144, 16, 262160, 0, 262144, 16, 262160, 4096, 266240, 4112, 266256, 4096, 266240, 4112, 266256 ], pc2bytes5 = [ 0, 1024, 32, 1056, 0, 1024, 32, 1056, 33554432, 33555456, 33554464, 33555488, 33554432, 33555456, 33554464, 33555488 ], pc2bytes6 = [ 0, 268435456, 524288, 268959744, 2, 268435458, 524290, 268959746, 0, 268435456, 524288, 268959744, 2, 268435458, 524290, 268959746 ], pc2bytes7 = [ 0, 65536, 2048, 67584, 536870912, 536936448, 536872960, 536938496, 131072, 196608, 133120, 198656, 537001984, 537067520, 537004032, 537069568 ], pc2bytes8 = [ 0, 262144, 0, 262144, 2, 262146, 2, 262146, 33554432, 33816576, 33554432, 33816576, 33554434, 33816578, 33554434, 33816578 ], pc2bytes9 = [ 0, 268435456, 8, 268435464, 0, 268435456, 8, 268435464, 1024, 268436480, 1032, 268436488, 1024, 268436480, 1032, 268436488 ], pc2bytes10 = [ 0, 32, 0, 32, 1048576, 1048608, 1048576, 1048608, 8192, 8224, 8192, 8224, 1056768, 1056800, 1056768, 1056800 ], pc2bytes11 = [ 0, 16777216, 512, 16777728, 2097152, 18874368, 2097664, 18874880, 67108864, 83886080, 67109376, 83886592, 69206016, 85983232, 69206528, 85983744 ], pc2bytes12 = [ 0, 4096, 134217728, 134221824, 524288, 528384, 134742016, 134746112, 16, 4112, 134217744, 134221840, 524304, 528400, 134742032, 134746128 ], pc2bytes13 = [ 0, 4, 256, 260, 0, 4, 256, 260, 1, 5, 257, 261, 1, 5, 257, 261 ]; var iterations = key.length() > 8 ? 3 : 1; var keys = []; var shifts = [ 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0 ]; var n = 0, tmp; for (var j = 0; j < iterations; j++) { var left = key.getInt32(); var right = key.getInt32(); tmp = (left >>> 4 ^ right) & 252645135; right ^= tmp; left ^= tmp << 4; tmp = (right >>> -16 ^ left) & 65535; left ^= tmp; right ^= tmp << -16; tmp = (left >>> 2 ^ right) & 858993459; right ^= tmp; left ^= tmp << 2; tmp = (right >>> -16 ^ left) & 65535; left ^= tmp; right ^= tmp << -16; tmp = (left >>> 1 ^ right) & 1431655765; right ^= tmp; left ^= tmp << 1; tmp = (right >>> 8 ^ left) & 16711935; left ^= tmp; right ^= tmp << 8; tmp = (left >>> 1 ^ right) & 1431655765; right ^= tmp; left ^= tmp << 1; tmp = left << 8 | right >>> 20 & 240; left = right << 24 | right << 8 & 16711680 | right >>> 8 & 65280 | right >>> 24 & 240; right = tmp; for (var i = 0; i < shifts.length; ++i) { if (shifts[i]) { left = left << 2 | left >>> 26; right = right << 2 | right >>> 26; } else { left = left << 1 | left >>> 27; right = right << 1 | right >>> 27; } left &= -15; right &= -15; var lefttmp = pc2bytes0[left >>> 28] | pc2bytes1[left >>> 24 & 15] | pc2bytes2[left >>> 20 & 15] | pc2bytes3[left >>> 16 & 15] | pc2bytes4[left >>> 12 & 15] | pc2bytes5[left >>> 8 & 15] | pc2bytes6[left >>> 4 & 15]; var righttmp = pc2bytes7[right >>> 28] | pc2bytes8[right >>> 24 & 15] | pc2bytes9[right >>> 20 & 15] | pc2bytes10[right >>> 16 & 15] | pc2bytes11[right >>> 12 & 15] | pc2bytes12[right >>> 8 & 15] | pc2bytes13[right >>> 4 & 15]; tmp = (righttmp >>> 16 ^ lefttmp) & 65535; keys[n++] = lefttmp ^ tmp; keys[n++] = righttmp ^ tmp << 16; } } return keys; } /** * Updates a single block (1 byte) using DES. The update will either * encrypt or decrypt the block. * * @param keys the expanded keys. * @param input the input block (an array of 32-bit words). * @param output the updated output block. * @param decrypt true to decrypt the block, false to encrypt it. */ function _updateBlock(keys, input, output, decrypt) { var iterations = keys.length === 32 ? 3 : 9; var looping; if (iterations === 3) { looping = decrypt ? [ 30, -2, -2 ] : [ 0, 32, 2 ]; } else { looping = decrypt ? [ 94, 62, -2, 32, 64, 2, 30, -2, -2 ] : [ 0, 32, 2, 62, 30, -2, 64, 96, 2 ]; } var tmp; var left = input[0]; var right = input[1]; tmp = (left >>> 4 ^ right) & 252645135; right ^= tmp; left ^= tmp << 4; tmp = (left >>> 16 ^ right) & 65535; right ^= tmp; left ^= tmp << 16; tmp = (right >>> 2 ^ left) & 858993459; left ^= tmp; right ^= tmp << 2; tmp = (right >>> 8 ^ left) & 16711935; left ^= tmp; right ^= tmp << 8; tmp = (left >>> 1 ^ right) & 1431655765; right ^= tmp; left ^= tmp << 1; left = left << 1 | left >>> 31; right = right << 1 | right >>> 31; for (var j = 0; j < iterations; j += 3) { var endloop = looping[j + 1]; var loopinc = looping[j + 2]; for (var i = looping[j]; i != endloop; i += loopinc) { var right1 = right ^ keys[i]; var right2 = (right >>> 4 | right << 28) ^ keys[i + 1]; tmp = left; left = right; right = tmp ^ (spfunction2[right1 >>> 24 & 63] | spfunction4[right1 >>> 16 & 63] | spfunction6[right1 >>> 8 & 63] | spfunction8[right1 & 63] | spfunction1[right2 >>> 24 & 63] | spfunction3[right2 >>> 16 & 63] | spfunction5[right2 >>> 8 & 63] | spfunction7[right2 & 63]); } tmp = left; left = right; right = tmp; } left = left >>> 1 | left << 31; right = right >>> 1 | right << 31; tmp = (left >>> 1 ^ right) & 1431655765; right ^= tmp; left ^= tmp << 1; tmp = (right >>> 8 ^ left) & 16711935; left ^= tmp; right ^= tmp << 8; tmp = (right >>> 2 ^ left) & 858993459; left ^= tmp; right ^= tmp << 2; tmp = (left >>> 16 ^ right) & 65535; right ^= tmp; left ^= tmp << 16; tmp = (left >>> 4 ^ right) & 252645135; right ^= tmp; left ^= tmp << 4; output[0] = left; output[1] = right; } /** * Deprecated. Instead, use: * * forge.cipher.createCipher('DES-', key); * forge.cipher.createDecipher('DES-', key); * * Creates a deprecated DES cipher object. This object's mode will default to * CBC (cipher-block-chaining). * * The key may be given as a binary-encoded string of bytes or a byte buffer. * * @param options the options to use. * key the symmetric key to use (64 or 192 bits). * output the buffer to write to. * decrypt true for decryption, false for encryption. * mode the cipher mode to use (default: 'CBC'). * * @return the cipher. */ function _createCipher(options) { options = options || {}; var mode = (options.mode || "CBC").toUpperCase(); var algorithm = "DES-" + mode; var cipher; if (options.decrypt) { cipher = forge.cipher.createDecipher(algorithm, options.key); } else { cipher = forge.cipher.createCipher(algorithm, options.key); } var start = cipher.start; cipher.start = function(iv, options) { var output = null; if (options instanceof forge.util.ByteBuffer) { output = options; options = {}; } options = options || {}; options.output = output; options.iv = iv; start.call(cipher, options); }; return cipher; } })); //#endregion //#region ../node_modules/node-forge/lib/pbkdf2.js var require_pbkdf2$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Password-Based Key-Derivation Function #2 implementation. * * See RFC 2898 for details. * * @author Dave Longley * * Copyright (c) 2010-2013 Digital Bazaar, Inc. */ var forge = require_forge(); require_hmac$1(); require_md(); require_util$8(); var pkcs5 = forge.pkcs5 = forge.pkcs5 || {}; var crypto; if (forge.util.isNodejs && !forge.options.usePureJavaScript) { crypto = __require("crypto"); } /** * Derives a key from a password. * * @param p the password as a binary-encoded string of bytes. * @param s the salt as a binary-encoded string of bytes. * @param c the iteration count, a positive integer. * @param dkLen the intended length, in bytes, of the derived key, * (max: 2^32 - 1) * hash length of the PRF. * @param [md] the message digest (or algorithm identifier as a string) to use * in the PRF, defaults to SHA-1. * @param [callback(err, key)] presence triggers asynchronous version, called * once the operation completes. * * @return the derived key, as a binary-encoded string of bytes, for the * synchronous version (if no callback is specified). */ module.exports = forge.pbkdf2 = pkcs5.pbkdf2 = function(p, s, c, dkLen, md, callback) { if (typeof md === "function") { callback = md; md = null; } if (forge.util.isNodejs && !forge.options.usePureJavaScript && crypto.pbkdf2 && (md === null || typeof md !== "object") && (crypto.pbkdf2Sync.length > 4 || !md || md === "sha1")) { if (typeof md !== "string") { md = "sha1"; } p = Buffer.from(p, "binary"); s = Buffer.from(s, "binary"); if (!callback) { if (crypto.pbkdf2Sync.length === 4) { return crypto.pbkdf2Sync(p, s, c, dkLen).toString("binary"); } return crypto.pbkdf2Sync(p, s, c, dkLen, md).toString("binary"); } if (crypto.pbkdf2Sync.length === 4) { return crypto.pbkdf2(p, s, c, dkLen, function(err, key) { if (err) { return callback(err); } callback(null, key.toString("binary")); }); } return crypto.pbkdf2(p, s, c, dkLen, md, function(err, key) { if (err) { return callback(err); } callback(null, key.toString("binary")); }); } if (typeof md === "undefined" || md === null) { md = "sha1"; } if (typeof md === "string") { if (!(md in forge.md.algorithms)) { throw new Error("Unknown hash algorithm: " + md); } md = forge.md[md].create(); } var hLen = md.digestLength; if (dkLen > 4294967295 * hLen) { var err = new Error("Derived key is too long."); if (callback) { return callback(err); } throw err; } var len = Math.ceil(dkLen / hLen); var r = dkLen - (len - 1) * hLen; var prf = forge.hmac.create(); prf.start(md, p); var dk = ""; var xor, u_c, u_c1; if (!callback) { for (var i = 1; i <= len; ++i) { prf.start(null, null); prf.update(s); prf.update(forge.util.int32ToBytes(i)); xor = u_c1 = prf.digest().getBytes(); for (var j = 2; j <= c; ++j) { prf.start(null, null); prf.update(u_c1); u_c = prf.digest().getBytes(); xor = forge.util.xorBytes(xor, u_c, hLen); u_c1 = u_c; } dk += i < len ? xor : xor.substr(0, r); } return dk; } var i = 1, j; function outer() { if (i > len) { return callback(null, dk); } prf.start(null, null); prf.update(s); prf.update(forge.util.int32ToBytes(i)); xor = u_c1 = prf.digest().getBytes(); j = 2; inner(); } function inner() { if (j <= c) { prf.start(null, null); prf.update(u_c1); u_c = prf.digest().getBytes(); xor = forge.util.xorBytes(xor, u_c, hLen); u_c1 = u_c; ++j; return forge.util.setImmediate(inner); } dk += i < len ? xor : xor.substr(0, r); ++i; outer(); } outer(); }; })); //#endregion //#region ../node_modules/node-forge/lib/sha256.js var require_sha256$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Secure Hash Algorithm with 256-bit digest (SHA-256) implementation. * * See FIPS 180-2 for details. * * @author Dave Longley * * Copyright (c) 2010-2015 Digital Bazaar, Inc. */ var forge = require_forge(); require_md(); require_util$8(); var sha256 = module.exports = forge.sha256 = forge.sha256 || {}; forge.md.sha256 = forge.md.algorithms.sha256 = sha256; /** * Creates a SHA-256 message digest object. * * @return a message digest object. */ sha256.create = function() { if (!_initialized) { _init(); } var _state = null; var _input = forge.util.createBuffer(); var _w = new Array(64); var md = { algorithm: "sha256", blockLength: 64, digestLength: 32, messageLength: 0, fullMessageLength: null, messageLengthSize: 8 }; /** * Starts the digest. * * @return this digest object. */ md.start = function() { md.messageLength = 0; md.fullMessageLength = md.messageLength64 = []; var int32s = md.messageLengthSize / 4; for (var i = 0; i < int32s; ++i) { md.fullMessageLength.push(0); } _input = forge.util.createBuffer(); _state = { h0: 1779033703, h1: 3144134277, h2: 1013904242, h3: 2773480762, h4: 1359893119, h5: 2600822924, h6: 528734635, h7: 1541459225 }; return md; }; md.start(); /** * Updates the digest with the given message input. The given input can * treated as raw input (no encoding will be applied) or an encoding of * 'utf8' maybe given to encode the input using UTF-8. * * @param msg the message input to update with. * @param encoding the encoding to use (default: 'raw', other: 'utf8'). * * @return this digest object. */ md.update = function(msg, encoding) { if (encoding === "utf8") { msg = forge.util.encodeUtf8(msg); } var len = msg.length; md.messageLength += len; len = [len / 4294967296 >>> 0, len >>> 0]; for (var i = md.fullMessageLength.length - 1; i >= 0; --i) { md.fullMessageLength[i] += len[1]; len[1] = len[0] + (md.fullMessageLength[i] / 4294967296 >>> 0); md.fullMessageLength[i] = md.fullMessageLength[i] >>> 0; len[0] = len[1] / 4294967296 >>> 0; } _input.putBytes(msg); _update(_state, _w, _input); if (_input.read > 2048 || _input.length() === 0) { _input.compact(); } return md; }; /** * Produces the digest. * * @return a byte buffer containing the digest value. */ md.digest = function() { var finalBlock = forge.util.createBuffer(); finalBlock.putBytes(_input.bytes()); var remaining = md.fullMessageLength[md.fullMessageLength.length - 1] + md.messageLengthSize; var overflow = remaining & md.blockLength - 1; finalBlock.putBytes(_padding.substr(0, md.blockLength - overflow)); var next, carry; var bits = md.fullMessageLength[0] * 8; for (var i = 0; i < md.fullMessageLength.length - 1; ++i) { next = md.fullMessageLength[i + 1] * 8; carry = next / 4294967296 >>> 0; bits += carry; finalBlock.putInt32(bits >>> 0); bits = next >>> 0; } finalBlock.putInt32(bits); var s2 = { h0: _state.h0, h1: _state.h1, h2: _state.h2, h3: _state.h3, h4: _state.h4, h5: _state.h5, h6: _state.h6, h7: _state.h7 }; _update(s2, _w, finalBlock); var rval = forge.util.createBuffer(); rval.putInt32(s2.h0); rval.putInt32(s2.h1); rval.putInt32(s2.h2); rval.putInt32(s2.h3); rval.putInt32(s2.h4); rval.putInt32(s2.h5); rval.putInt32(s2.h6); rval.putInt32(s2.h7); return rval; }; return md; }; var _padding = null; var _initialized = false; var _k = null; /** * Initializes the constant tables. */ function _init() { _padding = String.fromCharCode(128); _padding += forge.util.fillString(String.fromCharCode(0), 64); _k = [ 1116352408, 1899447441, 3049323471, 3921009573, 961987163, 1508970993, 2453635748, 2870763221, 3624381080, 310598401, 607225278, 1426881987, 1925078388, 2162078206, 2614888103, 3248222580, 3835390401, 4022224774, 264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, 2554220882, 2821834349, 2952996808, 3210313671, 3336571891, 3584528711, 113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291, 1695183700, 1986661051, 2177026350, 2456956037, 2730485921, 2820302411, 3259730800, 3345764771, 3516065817, 3600352804, 4094571909, 275423344, 430227734, 506948616, 659060556, 883997877, 958139571, 1322822218, 1537002063, 1747873779, 1955562222, 2024104815, 2227730452, 2361852424, 2428436474, 2756734187, 3204031479, 3329325298 ]; _initialized = true; } /** * Updates a SHA-256 state with the given byte buffer. * * @param s the SHA-256 state to update. * @param w the array to use to store words. * @param bytes the byte buffer to update with. */ function _update(s, w, bytes) { var t1, t2, s0, s1, ch, maj, i, a, b, c, d, e, f, g, h; var len = bytes.length(); while (len >= 64) { for (i = 0; i < 16; ++i) { w[i] = bytes.getInt32(); } for (; i < 64; ++i) { t1 = w[i - 2]; t1 = (t1 >>> 17 | t1 << 15) ^ (t1 >>> 19 | t1 << 13) ^ t1 >>> 10; t2 = w[i - 15]; t2 = (t2 >>> 7 | t2 << 25) ^ (t2 >>> 18 | t2 << 14) ^ t2 >>> 3; w[i] = t1 + w[i - 7] + t2 + w[i - 16] | 0; } a = s.h0; b = s.h1; c = s.h2; d = s.h3; e = s.h4; f = s.h5; g = s.h6; h = s.h7; for (i = 0; i < 64; ++i) { s1 = (e >>> 6 | e << 26) ^ (e >>> 11 | e << 21) ^ (e >>> 25 | e << 7); ch = g ^ e & (f ^ g); s0 = (a >>> 2 | a << 30) ^ (a >>> 13 | a << 19) ^ (a >>> 22 | a << 10); maj = a & b | c & (a ^ b); t1 = h + s1 + ch + _k[i] + w[i]; t2 = s0 + maj; h = g; g = f; f = e; e = d + t1 >>> 0; d = c; c = b; b = a; a = t1 + t2 >>> 0; } s.h0 = s.h0 + a | 0; s.h1 = s.h1 + b | 0; s.h2 = s.h2 + c | 0; s.h3 = s.h3 + d | 0; s.h4 = s.h4 + e | 0; s.h5 = s.h5 + f | 0; s.h6 = s.h6 + g | 0; s.h7 = s.h7 + h | 0; len -= 64; } } })); //#endregion //#region ../node_modules/node-forge/lib/prng.js var require_prng = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * A javascript implementation of a cryptographically-secure * Pseudo Random Number Generator (PRNG). The Fortuna algorithm is followed * here though the use of SHA-256 is not enforced; when generating an * a PRNG context, the hashing algorithm and block cipher used for * the generator are specified via a plugin. * * @author Dave Longley * * Copyright (c) 2010-2014 Digital Bazaar, Inc. */ var forge = require_forge(); require_util$8(); var _crypto = null; if (forge.util.isNodejs && !forge.options.usePureJavaScript && !process.versions["node-webkit"]) { _crypto = __require("crypto"); } var prng = module.exports = forge.prng = forge.prng || {}; /** * Creates a new PRNG context. * * A PRNG plugin must be passed in that will provide: * * 1. A function that initializes the key and seed of a PRNG context. It * will be given a 16 byte key and a 16 byte seed. Any key expansion * or transformation of the seed from a byte string into an array of * integers (or similar) should be performed. * 2. The cryptographic function used by the generator. It takes a key and * a seed. * 3. A seed increment function. It takes the seed and returns seed + 1. * 4. An api to create a message digest. * * For an example, see random.js. * * @param plugin the PRNG plugin to use. */ prng.create = function(plugin) { var ctx = { plugin, key: null, seed: null, time: null, reseeds: 0, generated: 0, keyBytes: "" }; var md = plugin.md; var pools = new Array(32); for (var i = 0; i < 32; ++i) { pools[i] = md.create(); } ctx.pools = pools; ctx.pool = 0; /** * Generates random bytes. The bytes may be generated synchronously or * asynchronously. Web workers must use the asynchronous interface or * else the behavior is undefined. * * @param count the number of random bytes to generate. * @param [callback(err, bytes)] called once the operation completes. * * @return count random bytes as a string. */ ctx.generate = function(count, callback) { if (!callback) { return ctx.generateSync(count); } var cipher = ctx.plugin.cipher; var increment = ctx.plugin.increment; var formatKey = ctx.plugin.formatKey; var formatSeed = ctx.plugin.formatSeed; var b = forge.util.createBuffer(); ctx.key = null; generate(); function generate(err) { if (err) { return callback(err); } if (b.length() >= count) { return callback(null, b.getBytes(count)); } if (ctx.generated > 1048575) { ctx.key = null; } if (ctx.key === null) { return forge.util.nextTick(function() { _reseed(generate); }); } var bytes = cipher(ctx.key, ctx.seed); ctx.generated += bytes.length; b.putBytes(bytes); ctx.key = formatKey(cipher(ctx.key, increment(ctx.seed))); ctx.seed = formatSeed(cipher(ctx.key, ctx.seed)); forge.util.setImmediate(generate); } }; /** * Generates random bytes synchronously. * * @param count the number of random bytes to generate. * * @return count random bytes as a string. */ ctx.generateSync = function(count) { var cipher = ctx.plugin.cipher; var increment = ctx.plugin.increment; var formatKey = ctx.plugin.formatKey; var formatSeed = ctx.plugin.formatSeed; ctx.key = null; var b = forge.util.createBuffer(); while (b.length() < count) { if (ctx.generated > 1048575) { ctx.key = null; } if (ctx.key === null) { _reseedSync(); } var bytes = cipher(ctx.key, ctx.seed); ctx.generated += bytes.length; b.putBytes(bytes); ctx.key = formatKey(cipher(ctx.key, increment(ctx.seed))); ctx.seed = formatSeed(cipher(ctx.key, ctx.seed)); } return b.getBytes(count); }; /** * Private function that asynchronously reseeds a generator. * * @param callback(err) called once the operation completes. */ function _reseed(callback) { if (ctx.pools[0].messageLength >= 32) { _seed(); return callback(); } var needed = 32 - ctx.pools[0].messageLength << 5; ctx.seedFile(needed, function(err, bytes) { if (err) { return callback(err); } ctx.collect(bytes); _seed(); callback(); }); } /** * Private function that synchronously reseeds a generator. */ function _reseedSync() { if (ctx.pools[0].messageLength >= 32) { return _seed(); } var needed = 32 - ctx.pools[0].messageLength << 5; ctx.collect(ctx.seedFileSync(needed)); _seed(); } /** * Private function that seeds a generator once enough bytes are available. */ function _seed() { ctx.reseeds = ctx.reseeds === 4294967295 ? 0 : ctx.reseeds + 1; var md = ctx.plugin.md.create(); md.update(ctx.keyBytes); var _2powK = 1; for (var k = 0; k < 32; ++k) { if (ctx.reseeds % _2powK === 0) { md.update(ctx.pools[k].digest().getBytes()); ctx.pools[k].start(); } _2powK = _2powK << 1; } ctx.keyBytes = md.digest().getBytes(); md.start(); md.update(ctx.keyBytes); var seedBytes = md.digest().getBytes(); ctx.key = ctx.plugin.formatKey(ctx.keyBytes); ctx.seed = ctx.plugin.formatSeed(seedBytes); ctx.generated = 0; } /** * The built-in default seedFile. This seedFile is used when entropy * is needed immediately. * * @param needed the number of bytes that are needed. * * @return the random bytes. */ function defaultSeedFile(needed) { var getRandomValues = null; var globalScope = forge.util.globalScope; var _crypto = globalScope.crypto || globalScope.msCrypto; if (_crypto && _crypto.getRandomValues) { getRandomValues = function(arr) { return _crypto.getRandomValues(arr); }; } var b = forge.util.createBuffer(); if (getRandomValues) { while (b.length() < needed) { var count = Math.max(1, Math.min(needed - b.length(), 65536) / 4); var entropy = new Uint32Array(Math.floor(count)); try { getRandomValues(entropy); for (var i = 0; i < entropy.length; ++i) { b.putInt32(entropy[i]); } } catch (e) { if (!(typeof QuotaExceededError !== "undefined" && e instanceof QuotaExceededError)) { throw e; } } } } if (b.length() < needed) { var hi, lo, next; var seed = Math.floor(Math.random() * 65536); while (b.length() < needed) { lo = 16807 * (seed & 65535); hi = 16807 * (seed >> 16); lo += (hi & 32767) << 16; lo += hi >> 15; lo = (lo & 2147483647) + (lo >> 31); seed = lo & 4294967295; for (var i = 0; i < 3; ++i) { next = seed >>> (i << 3); next ^= Math.floor(Math.random() * 256); b.putByte(next & 255); } } } return b.getBytes(needed); } if (_crypto) { ctx.seedFile = function(needed, callback) { _crypto.randomBytes(needed, function(err, bytes) { if (err) { return callback(err); } callback(null, bytes.toString()); }); }; ctx.seedFileSync = function(needed) { return _crypto.randomBytes(needed).toString(); }; } else { ctx.seedFile = function(needed, callback) { try { callback(null, defaultSeedFile(needed)); } catch (e) { callback(e); } }; ctx.seedFileSync = defaultSeedFile; } /** * Adds entropy to a prng ctx's accumulator. * * @param bytes the bytes of entropy as a string. */ ctx.collect = function(bytes) { var count = bytes.length; for (var i = 0; i < count; ++i) { ctx.pools[ctx.pool].update(bytes.substr(i, 1)); ctx.pool = ctx.pool === 31 ? 0 : ctx.pool + 1; } }; /** * Collects an integer of n bits. * * @param i the integer entropy. * @param n the number of bits in the integer. */ ctx.collectInt = function(i, n) { var bytes = ""; for (var x = 0; x < n; x += 8) { bytes += String.fromCharCode(i >> x & 255); } ctx.collect(bytes); }; /** * Registers a Web Worker to receive immediate entropy from the main thread. * This method is required until Web Workers can access the native crypto * API. This method should be called twice for each created worker, once in * the main thread, and once in the worker itself. * * @param worker the worker to register. */ ctx.registerWorker = function(worker) { if (worker === self) { ctx.seedFile = function(needed, callback) { function listener(e) { var data = e.data; if (data.forge && data.forge.prng) { self.removeEventListener("message", listener); callback(data.forge.prng.err, data.forge.prng.bytes); } } self.addEventListener("message", listener); self.postMessage({ forge: { prng: { needed } } }); }; } else { var listener = function(e) { var data = e.data; if (data.forge && data.forge.prng) { ctx.seedFile(data.forge.prng.needed, function(err, bytes) { worker.postMessage({ forge: { prng: { err, bytes } } }); }); } }; worker.addEventListener("message", listener); } }; return ctx; }; })); //#endregion //#region ../node_modules/node-forge/lib/random.js var require_random = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * An API for getting cryptographically-secure random bytes. The bytes are * generated using the Fortuna algorithm devised by Bruce Schneier and * Niels Ferguson. * * Getting strong random bytes is not yet easy to do in javascript. The only * truish random entropy that can be collected is from the mouse, keyboard, or * from timing with respect to page loads, etc. This generator makes a poor * attempt at providing random bytes when those sources haven't yet provided * enough entropy to initially seed or to reseed the PRNG. * * @author Dave Longley * * Copyright (c) 2009-2014 Digital Bazaar, Inc. */ var forge = require_forge(); require_aes$1(); require_sha256$1(); require_prng(); require_util$8(); (function() { if (forge.random && forge.random.getBytes) { module.exports = forge.random; return; } (function(jQuery) { var prng_aes = {}; var _prng_aes_output = new Array(4); var _prng_aes_buffer = forge.util.createBuffer(); prng_aes.formatKey = function(key) { var tmp = forge.util.createBuffer(key); key = new Array(4); key[0] = tmp.getInt32(); key[1] = tmp.getInt32(); key[2] = tmp.getInt32(); key[3] = tmp.getInt32(); return forge.aes._expandKey(key, false); }; prng_aes.formatSeed = function(seed) { var tmp = forge.util.createBuffer(seed); seed = new Array(4); seed[0] = tmp.getInt32(); seed[1] = tmp.getInt32(); seed[2] = tmp.getInt32(); seed[3] = tmp.getInt32(); return seed; }; prng_aes.cipher = function(key, seed) { forge.aes._updateBlock(key, seed, _prng_aes_output, false); _prng_aes_buffer.putInt32(_prng_aes_output[0]); _prng_aes_buffer.putInt32(_prng_aes_output[1]); _prng_aes_buffer.putInt32(_prng_aes_output[2]); _prng_aes_buffer.putInt32(_prng_aes_output[3]); return _prng_aes_buffer.getBytes(); }; prng_aes.increment = function(seed) { ++seed[3]; return seed; }; prng_aes.md = forge.md.sha256; /** * Creates a new PRNG. */ function spawnPrng() { var ctx = forge.prng.create(prng_aes); /** * Gets random bytes. If a native secure crypto API is unavailable, this * method tries to make the bytes more unpredictable by drawing from data that * can be collected from the user of the browser, eg: mouse movement. * * If a callback is given, this method will be called asynchronously. * * @param count the number of random bytes to get. * @param [callback(err, bytes)] called once the operation completes. * * @return the random bytes in a string. */ ctx.getBytes = function(count, callback) { return ctx.generate(count, callback); }; /** * Gets random bytes asynchronously. If a native secure crypto API is * unavailable, this method tries to make the bytes more unpredictable by * drawing from data that can be collected from the user of the browser, * eg: mouse movement. * * @param count the number of random bytes to get. * * @return the random bytes in a string. */ ctx.getBytesSync = function(count) { return ctx.generate(count); }; return ctx; } var _ctx = spawnPrng(); var getRandomValues = null; var globalScope = forge.util.globalScope; var _crypto = globalScope.crypto || globalScope.msCrypto; if (_crypto && _crypto.getRandomValues) { getRandomValues = function(arr) { return _crypto.getRandomValues(arr); }; } if (forge.options.usePureJavaScript || !forge.util.isNodejs && !getRandomValues) { if (typeof window === "undefined" || window.document === undefined) {} _ctx.collectInt(+new Date(), 32); if (typeof navigator !== "undefined") { var _navBytes = ""; for (var key in navigator) { try { if (typeof navigator[key] == "string") { _navBytes += navigator[key]; } } catch (e) {} } _ctx.collect(_navBytes); _navBytes = null; } if (jQuery) { jQuery().mousemove(function(e) { _ctx.collectInt(e.clientX, 16); _ctx.collectInt(e.clientY, 16); }); jQuery().keypress(function(e) { _ctx.collectInt(e.charCode, 8); }); } } if (!forge.random) { forge.random = _ctx; } else { for (var key in _ctx) { forge.random[key] = _ctx[key]; } } forge.random.createInstance = spawnPrng; module.exports = forge.random; })(typeof jQuery !== "undefined" ? jQuery : null); })(); })); //#endregion //#region ../node_modules/node-forge/lib/rc2.js var require_rc2 = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * RC2 implementation. * * @author Stefan Siegl * * Copyright (c) 2012 Stefan Siegl * * Information on the RC2 cipher is available from RFC #2268, * http://www.ietf.org/rfc/rfc2268.txt */ var forge = require_forge(); require_util$8(); var piTable = [ 217, 120, 249, 196, 25, 221, 181, 237, 40, 233, 253, 121, 74, 160, 216, 157, 198, 126, 55, 131, 43, 118, 83, 142, 98, 76, 100, 136, 68, 139, 251, 162, 23, 154, 89, 245, 135, 179, 79, 19, 97, 69, 109, 141, 9, 129, 125, 50, 189, 143, 64, 235, 134, 183, 123, 11, 240, 149, 33, 34, 92, 107, 78, 130, 84, 214, 101, 147, 206, 96, 178, 28, 115, 86, 192, 20, 167, 140, 241, 220, 18, 117, 202, 31, 59, 190, 228, 209, 66, 61, 212, 48, 163, 60, 182, 38, 111, 191, 14, 218, 70, 105, 7, 87, 39, 242, 29, 155, 188, 148, 67, 3, 248, 17, 199, 246, 144, 239, 62, 231, 6, 195, 213, 47, 200, 102, 30, 215, 8, 232, 234, 222, 128, 82, 238, 247, 132, 170, 114, 172, 53, 77, 106, 42, 150, 26, 210, 113, 90, 21, 73, 116, 75, 159, 208, 94, 4, 24, 164, 236, 194, 224, 65, 110, 15, 81, 203, 204, 36, 145, 175, 80, 161, 244, 112, 57, 153, 124, 58, 133, 35, 184, 180, 122, 252, 2, 54, 91, 37, 85, 151, 49, 45, 93, 250, 152, 227, 138, 146, 174, 5, 223, 41, 16, 103, 108, 186, 201, 211, 0, 230, 207, 225, 158, 168, 44, 99, 22, 1, 63, 88, 226, 137, 169, 13, 56, 52, 27, 171, 51, 255, 176, 187, 72, 12, 95, 185, 177, 205, 46, 197, 243, 219, 71, 229, 165, 156, 119, 10, 166, 32, 104, 254, 127, 193, 173 ]; var s = [ 1, 2, 3, 5 ]; /** * Rotate a word left by given number of bits. * * Bits that are shifted out on the left are put back in on the right * hand side. * * @param word The word to shift left. * @param bits The number of bits to shift by. * @return The rotated word. */ var rol = function(word, bits) { return word << bits & 65535 | (word & 65535) >> 16 - bits; }; /** * Rotate a word right by given number of bits. * * Bits that are shifted out on the right are put back in on the left * hand side. * * @param word The word to shift right. * @param bits The number of bits to shift by. * @return The rotated word. */ var ror = function(word, bits) { return (word & 65535) >> bits | word << 16 - bits & 65535; }; module.exports = forge.rc2 = forge.rc2 || {}; /** * Perform RC2 key expansion as per RFC #2268, section 2. * * @param key variable-length user key (between 1 and 128 bytes) * @param effKeyBits number of effective key bits (default: 128) * @return the expanded RC2 key (ByteBuffer of 128 bytes) */ forge.rc2.expandKey = function(key, effKeyBits) { if (typeof key === "string") { key = forge.util.createBuffer(key); } effKeyBits = effKeyBits || 128; var L = key; var T = key.length(); var T1 = effKeyBits; var T8 = Math.ceil(T1 / 8); var TM = 255 >> (T1 & 7); var i; for (i = T; i < 128; i++) { L.putByte(piTable[L.at(i - 1) + L.at(i - T) & 255]); } L.setAt(128 - T8, piTable[L.at(128 - T8) & TM]); for (i = 127 - T8; i >= 0; i--) { L.setAt(i, piTable[L.at(i + 1) ^ L.at(i + T8)]); } return L; }; /** * Creates a RC2 cipher object. * * @param key the symmetric key to use (as base for key generation). * @param bits the number of effective key bits. * @param encrypt false for decryption, true for encryption. * * @return the cipher. */ var createCipher = function(key, bits, encrypt) { var _finish = false, _input = null, _output = null, _iv = null; var mixRound, mashRound; var i, j, K = []; key = forge.rc2.expandKey(key, bits); for (i = 0; i < 64; i++) { K.push(key.getInt16Le()); } if (encrypt) { /** * Perform one mixing round "in place". * * @param R Array of four words to perform mixing on. */ mixRound = function(R) { for (i = 0; i < 4; i++) { R[i] += K[j] + (R[(i + 3) % 4] & R[(i + 2) % 4]) + (~R[(i + 3) % 4] & R[(i + 1) % 4]); R[i] = rol(R[i], s[i]); j++; } }; /** * Perform one mashing round "in place". * * @param R Array of four words to perform mashing on. */ mashRound = function(R) { for (i = 0; i < 4; i++) { R[i] += K[R[(i + 3) % 4] & 63]; } }; } else { /** * Perform one r-mixing round "in place". * * @param R Array of four words to perform mixing on. */ mixRound = function(R) { for (i = 3; i >= 0; i--) { R[i] = ror(R[i], s[i]); R[i] -= K[j] + (R[(i + 3) % 4] & R[(i + 2) % 4]) + (~R[(i + 3) % 4] & R[(i + 1) % 4]); j--; } }; /** * Perform one r-mashing round "in place". * * @param R Array of four words to perform mashing on. */ mashRound = function(R) { for (i = 3; i >= 0; i--) { R[i] -= K[R[(i + 3) % 4] & 63]; } }; } /** * Run the specified cipher execution plan. * * This function takes four words from the input buffer, applies the IV on * it (if requested) and runs the provided execution plan. * * The plan must be put together in form of a array of arrays. Where the * outer one is simply a list of steps to perform and the inner one needs * to have two elements: the first one telling how many rounds to perform, * the second one telling what to do (i.e. the function to call). * * @param {Array} plan The plan to execute. */ var runPlan = function(plan) { var R = []; for (i = 0; i < 4; i++) { var val = _input.getInt16Le(); if (_iv !== null) { if (encrypt) { val ^= _iv.getInt16Le(); } else { _iv.putInt16Le(val); } } R.push(val & 65535); } j = encrypt ? 0 : 63; for (var ptr = 0; ptr < plan.length; ptr++) { for (var ctr = 0; ctr < plan[ptr][0]; ctr++) { plan[ptr][1](R); } } for (i = 0; i < 4; i++) { if (_iv !== null) { if (encrypt) { _iv.putInt16Le(R[i]); } else { R[i] ^= _iv.getInt16Le(); } } _output.putInt16Le(R[i]); } }; var cipher = null; cipher = { start: function(iv, output) { if (iv) { if (typeof iv === "string") { iv = forge.util.createBuffer(iv); } } _finish = false; _input = forge.util.createBuffer(); _output = output || new forge.util.createBuffer(); _iv = iv; cipher.output = _output; }, update: function(input) { if (!_finish) { _input.putBuffer(input); } while (_input.length() >= 8) { runPlan([ [5, mixRound], [1, mashRound], [6, mixRound], [1, mashRound], [5, mixRound] ]); } }, finish: function(pad) { var rval = true; if (encrypt) { if (pad) { rval = pad(8, _input, !encrypt); } else { var padding = _input.length() === 8 ? 8 : 8 - _input.length(); _input.fillWithByte(padding, padding); } } if (rval) { _finish = true; cipher.update(); } if (!encrypt) { rval = _input.length() === 0; if (rval) { if (pad) { rval = pad(8, _output, !encrypt); } else { var len = _output.length(); var count = _output.at(len - 1); if (count > len) { rval = false; } else { _output.truncate(count); } } } } return rval; } }; return cipher; }; /** * Creates an RC2 cipher object to encrypt data in ECB or CBC mode using the * given symmetric key. The output will be stored in the 'output' member * of the returned cipher. * * The key and iv may be given as a string of bytes or a byte buffer. * The cipher is initialized to use 128 effective key bits. * * @param key the symmetric key to use. * @param iv the initialization vector to use. * @param output the buffer to write to, null to create one. * * @return the cipher. */ forge.rc2.startEncrypting = function(key, iv, output) { var cipher = forge.rc2.createEncryptionCipher(key, 128); cipher.start(iv, output); return cipher; }; /** * Creates an RC2 cipher object to encrypt data in ECB or CBC mode using the * given symmetric key. * * The key may be given as a string of bytes or a byte buffer. * * To start encrypting call start() on the cipher with an iv and optional * output buffer. * * @param key the symmetric key to use. * * @return the cipher. */ forge.rc2.createEncryptionCipher = function(key, bits) { return createCipher(key, bits, true); }; /** * Creates an RC2 cipher object to decrypt data in ECB or CBC mode using the * given symmetric key. The output will be stored in the 'output' member * of the returned cipher. * * The key and iv may be given as a string of bytes or a byte buffer. * The cipher is initialized to use 128 effective key bits. * * @param key the symmetric key to use. * @param iv the initialization vector to use. * @param output the buffer to write to, null to create one. * * @return the cipher. */ forge.rc2.startDecrypting = function(key, iv, output) { var cipher = forge.rc2.createDecryptionCipher(key, 128); cipher.start(iv, output); return cipher; }; /** * Creates an RC2 cipher object to decrypt data in ECB or CBC mode using the * given symmetric key. * * The key may be given as a string of bytes or a byte buffer. * * To start decrypting call start() on the cipher with an iv and optional * output buffer. * * @param key the symmetric key to use. * * @return the cipher. */ forge.rc2.createDecryptionCipher = function(key, bits) { return createCipher(key, bits, false); }; })); //#endregion //#region ../node_modules/node-forge/lib/jsbn.js var require_jsbn = /* @__PURE__ */ __commonJSMin(((exports, module) => { var forge = require_forge(); module.exports = forge.jsbn = forge.jsbn || {}; var dbits; var canary = 0xdeadbeefcafe; var j_lm = (canary & 16777215) == 15715070; function BigInteger(a, b, c) { this.data = []; if (a != null) if ("number" == typeof a) this.fromNumber(a, b, c); else if (b == null && "string" != typeof a) this.fromString(a, 256); else this.fromString(a, b); } forge.jsbn.BigInteger = BigInteger; function nbi() { return new BigInteger(null); } function am1(i, x, w, j, c, n) { while (--n >= 0) { var v = x * this.data[i++] + w.data[j] + c; c = Math.floor(v / 67108864); w.data[j++] = v & 67108863; } return c; } function am2(i, x, w, j, c, n) { var xl = x & 32767, xh = x >> 15; while (--n >= 0) { var l = this.data[i] & 32767; var h = this.data[i++] >> 15; var m = xh * l + h * xl; l = xl * l + ((m & 32767) << 15) + w.data[j] + (c & 1073741823); c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30); w.data[j++] = l & 1073741823; } return c; } function am3(i, x, w, j, c, n) { var xl = x & 16383, xh = x >> 14; while (--n >= 0) { var l = this.data[i] & 16383; var h = this.data[i++] >> 14; var m = xh * l + h * xl; l = xl * l + ((m & 16383) << 14) + w.data[j] + c; c = (l >> 28) + (m >> 14) + xh * h; w.data[j++] = l & 268435455; } return c; } if (typeof navigator === "undefined") { BigInteger.prototype.am = am3; dbits = 28; } else if (j_lm && navigator.appName == "Microsoft Internet Explorer") { BigInteger.prototype.am = am2; dbits = 30; } else if (j_lm && navigator.appName != "Netscape") { BigInteger.prototype.am = am1; dbits = 26; } else { BigInteger.prototype.am = am3; dbits = 28; } BigInteger.prototype.DB = dbits; BigInteger.prototype.DM = (1 << dbits) - 1; BigInteger.prototype.DV = 1 << dbits; var BI_FP = 52; BigInteger.prototype.FV = Math.pow(2, BI_FP); BigInteger.prototype.F1 = BI_FP - dbits; BigInteger.prototype.F2 = 2 * dbits - BI_FP; var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz"; var BI_RC = new Array(); var rr, vv; rr = "0".charCodeAt(0); for (vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv; rr = "a".charCodeAt(0); for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; rr = "A".charCodeAt(0); for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; function int2char(n) { return BI_RM.charAt(n); } function intAt(s, i) { var c = BI_RC[s.charCodeAt(i)]; return c == null ? -1 : c; } function bnpCopyTo(r) { for (var i = this.t - 1; i >= 0; --i) r.data[i] = this.data[i]; r.t = this.t; r.s = this.s; } function bnpFromInt(x) { this.t = 1; this.s = x < 0 ? -1 : 0; if (x > 0) this.data[0] = x; else if (x < -1) this.data[0] = x + this.DV; else this.t = 0; } function nbv(i) { var r = nbi(); r.fromInt(i); return r; } function bnpFromString(s, b) { var k; if (b == 16) k = 4; else if (b == 8) k = 3; else if (b == 256) k = 8; else if (b == 2) k = 1; else if (b == 32) k = 5; else if (b == 4) k = 2; else { this.fromRadix(s, b); return; } this.t = 0; this.s = 0; var i = s.length, mi = false, sh = 0; while (--i >= 0) { var x = k == 8 ? s[i] & 255 : intAt(s, i); if (x < 0) { if (s.charAt(i) == "-") mi = true; continue; } mi = false; if (sh == 0) this.data[this.t++] = x; else if (sh + k > this.DB) { this.data[this.t - 1] |= (x & (1 << this.DB - sh) - 1) << sh; this.data[this.t++] = x >> this.DB - sh; } else this.data[this.t - 1] |= x << sh; sh += k; if (sh >= this.DB) sh -= this.DB; } if (k == 8 && (s[0] & 128) != 0) { this.s = -1; if (sh > 0) this.data[this.t - 1] |= (1 << this.DB - sh) - 1 << sh; } this.clamp(); if (mi) BigInteger.ZERO.subTo(this, this); } function bnpClamp() { var c = this.s & this.DM; while (this.t > 0 && this.data[this.t - 1] == c) --this.t; } function bnToString(b) { if (this.s < 0) return "-" + this.negate().toString(b); var k; if (b == 16) k = 4; else if (b == 8) k = 3; else if (b == 2) k = 1; else if (b == 32) k = 5; else if (b == 4) k = 2; else return this.toRadix(b); var km = (1 << k) - 1, d, m = false, r = "", i = this.t; var p = this.DB - i * this.DB % k; if (i-- > 0) { if (p < this.DB && (d = this.data[i] >> p) > 0) { m = true; r = int2char(d); } while (i >= 0) { if (p < k) { d = (this.data[i] & (1 << p) - 1) << k - p; d |= this.data[--i] >> (p += this.DB - k); } else { d = this.data[i] >> (p -= k) & km; if (p <= 0) { p += this.DB; --i; } } if (d > 0) m = true; if (m) r += int2char(d); } } return m ? r : "0"; } function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this, r); return r; } function bnAbs() { return this.s < 0 ? this.negate() : this; } function bnCompareTo(a) { var r = this.s - a.s; if (r != 0) return r; var i = this.t; r = i - a.t; if (r != 0) return this.s < 0 ? -r : r; while (--i >= 0) if ((r = this.data[i] - a.data[i]) != 0) return r; return 0; } function nbits(x) { var r = 1, t; if ((t = x >>> 16) != 0) { x = t; r += 16; } if ((t = x >> 8) != 0) { x = t; r += 8; } if ((t = x >> 4) != 0) { x = t; r += 4; } if ((t = x >> 2) != 0) { x = t; r += 2; } if ((t = x >> 1) != 0) { x = t; r += 1; } return r; } function bnBitLength() { if (this.t <= 0) return 0; return this.DB * (this.t - 1) + nbits(this.data[this.t - 1] ^ this.s & this.DM); } function bnpDLShiftTo(n, r) { var i; for (i = this.t - 1; i >= 0; --i) r.data[i + n] = this.data[i]; for (i = n - 1; i >= 0; --i) r.data[i] = 0; r.t = this.t + n; r.s = this.s; } function bnpDRShiftTo(n, r) { for (var i = n; i < this.t; ++i) r.data[i - n] = this.data[i]; r.t = Math.max(this.t - n, 0); r.s = this.s; } function bnpLShiftTo(n, r) { var bs = n % this.DB; var cbs = this.DB - bs; var bm = (1 << cbs) - 1; var ds = Math.floor(n / this.DB), c = this.s << bs & this.DM, i; for (i = this.t - 1; i >= 0; --i) { r.data[i + ds + 1] = this.data[i] >> cbs | c; c = (this.data[i] & bm) << bs; } for (i = ds - 1; i >= 0; --i) r.data[i] = 0; r.data[ds] = c; r.t = this.t + ds + 1; r.s = this.s; r.clamp(); } function bnpRShiftTo(n, r) { r.s = this.s; var ds = Math.floor(n / this.DB); if (ds >= this.t) { r.t = 0; return; } var bs = n % this.DB; var cbs = this.DB - bs; var bm = (1 << bs) - 1; r.data[0] = this.data[ds] >> bs; for (var i = ds + 1; i < this.t; ++i) { r.data[i - ds - 1] |= (this.data[i] & bm) << cbs; r.data[i - ds] = this.data[i] >> bs; } if (bs > 0) r.data[this.t - ds - 1] |= (this.s & bm) << cbs; r.t = this.t - ds; r.clamp(); } function bnpSubTo(a, r) { var i = 0, c = 0, m = Math.min(a.t, this.t); while (i < m) { c += this.data[i] - a.data[i]; r.data[i++] = c & this.DM; c >>= this.DB; } if (a.t < this.t) { c -= a.s; while (i < this.t) { c += this.data[i]; r.data[i++] = c & this.DM; c >>= this.DB; } c += this.s; } else { c += this.s; while (i < a.t) { c -= a.data[i]; r.data[i++] = c & this.DM; c >>= this.DB; } c -= a.s; } r.s = c < 0 ? -1 : 0; if (c < -1) r.data[i++] = this.DV + c; else if (c > 0) r.data[i++] = c; r.t = i; r.clamp(); } function bnpMultiplyTo(a, r) { var x = this.abs(), y = a.abs(); var i = x.t; r.t = i + y.t; while (--i >= 0) r.data[i] = 0; for (i = 0; i < y.t; ++i) r.data[i + x.t] = x.am(0, y.data[i], r, i, 0, x.t); r.s = 0; r.clamp(); if (this.s != a.s) BigInteger.ZERO.subTo(r, r); } function bnpSquareTo(r) { var x = this.abs(); var i = r.t = 2 * x.t; while (--i >= 0) r.data[i] = 0; for (i = 0; i < x.t - 1; ++i) { var c = x.am(i, x.data[i], r, 2 * i, 0, 1); if ((r.data[i + x.t] += x.am(i + 1, 2 * x.data[i], r, 2 * i + 1, c, x.t - i - 1)) >= x.DV) { r.data[i + x.t] -= x.DV; r.data[i + x.t + 1] = 1; } } if (r.t > 0) r.data[r.t - 1] += x.am(i, x.data[i], r, 2 * i, 0, 1); r.s = 0; r.clamp(); } function bnpDivRemTo(m, q, r) { var pm = m.abs(); if (pm.t <= 0) return; var pt = this.abs(); if (pt.t < pm.t) { if (q != null) q.fromInt(0); if (r != null) this.copyTo(r); return; } if (r == null) r = nbi(); var y = nbi(), ts = this.s, ms = m.s; var nsh = this.DB - nbits(pm.data[pm.t - 1]); if (nsh > 0) { pm.lShiftTo(nsh, y); pt.lShiftTo(nsh, r); } else { pm.copyTo(y); pt.copyTo(r); } var ys = y.t; var y0 = y.data[ys - 1]; if (y0 == 0) return; var yt = y0 * (1 << this.F1) + (ys > 1 ? y.data[ys - 2] >> this.F2 : 0); var d1 = this.FV / yt, d2 = (1 << this.F1) / yt, e = 1 << this.F2; var i = r.t, j = i - ys, t = q == null ? nbi() : q; y.dlShiftTo(j, t); if (r.compareTo(t) >= 0) { r.data[r.t++] = 1; r.subTo(t, r); } BigInteger.ONE.dlShiftTo(ys, t); t.subTo(y, y); while (y.t < ys) y.data[y.t++] = 0; while (--j >= 0) { var qd = r.data[--i] == y0 ? this.DM : Math.floor(r.data[i] * d1 + (r.data[i - 1] + e) * d2); if ((r.data[i] += y.am(0, qd, r, j, 0, ys)) < qd) { y.dlShiftTo(j, t); r.subTo(t, r); while (r.data[i] < --qd) r.subTo(t, r); } } if (q != null) { r.drShiftTo(ys, q); if (ts != ms) BigInteger.ZERO.subTo(q, q); } r.t = ys; r.clamp(); if (nsh > 0) r.rShiftTo(nsh, r); if (ts < 0) BigInteger.ZERO.subTo(r, r); } function bnMod(a) { var r = nbi(); this.abs().divRemTo(a, null, r); if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r); return r; } function Classic(m) { this.m = m; } function cConvert(x) { if (x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); else return x; } function cRevert(x) { return x; } function cReduce(x) { x.divRemTo(this.m, null, x); } function cMulTo(x, y, r) { x.multiplyTo(y, r); this.reduce(r); } function cSqrTo(x, r) { x.squareTo(r); this.reduce(r); } Classic.prototype.convert = cConvert; Classic.prototype.revert = cRevert; Classic.prototype.reduce = cReduce; Classic.prototype.mulTo = cMulTo; Classic.prototype.sqrTo = cSqrTo; function bnpInvDigit() { if (this.t < 1) return 0; var x = this.data[0]; if ((x & 1) == 0) return 0; var y = x & 3; y = y * (2 - (x & 15) * y) & 15; y = y * (2 - (x & 255) * y) & 255; y = y * (2 - ((x & 65535) * y & 65535)) & 65535; y = y * (2 - x * y % this.DV) % this.DV; return y > 0 ? this.DV - y : -y; } function Montgomery(m) { this.m = m; this.mp = m.invDigit(); this.mpl = this.mp & 32767; this.mph = this.mp >> 15; this.um = (1 << m.DB - 15) - 1; this.mt2 = 2 * m.t; } function montConvert(x) { var r = nbi(); x.abs().dlShiftTo(this.m.t, r); r.divRemTo(this.m, null, r); if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r, r); return r; } function montRevert(x) { var r = nbi(); x.copyTo(r); this.reduce(r); return r; } function montReduce(x) { while (x.t <= this.mt2) x.data[x.t++] = 0; for (var i = 0; i < this.m.t; ++i) { var j = x.data[i] & 32767; var u0 = j * this.mpl + ((j * this.mph + (x.data[i] >> 15) * this.mpl & this.um) << 15) & x.DM; j = i + this.m.t; x.data[j] += this.m.am(0, u0, x, i, 0, this.m.t); while (x.data[j] >= x.DV) { x.data[j] -= x.DV; x.data[++j]++; } } x.clamp(); x.drShiftTo(this.m.t, x); if (x.compareTo(this.m) >= 0) x.subTo(this.m, x); } function montSqrTo(x, r) { x.squareTo(r); this.reduce(r); } function montMulTo(x, y, r) { x.multiplyTo(y, r); this.reduce(r); } Montgomery.prototype.convert = montConvert; Montgomery.prototype.revert = montRevert; Montgomery.prototype.reduce = montReduce; Montgomery.prototype.mulTo = montMulTo; Montgomery.prototype.sqrTo = montSqrTo; function bnpIsEven() { return (this.t > 0 ? this.data[0] & 1 : this.s) == 0; } function bnpExp(e, z) { if (e > 4294967295 || e < 1) return BigInteger.ONE; var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e) - 1; g.copyTo(r); while (--i >= 0) { z.sqrTo(r, r2); if ((e & 1 << i) > 0) z.mulTo(r2, g, r); else { var t = r; r = r2; r2 = t; } } return z.revert(r); } function bnModPowInt(e, m) { var z; if (e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); return this.exp(e, z); } BigInteger.prototype.copyTo = bnpCopyTo; BigInteger.prototype.fromInt = bnpFromInt; BigInteger.prototype.fromString = bnpFromString; BigInteger.prototype.clamp = bnpClamp; BigInteger.prototype.dlShiftTo = bnpDLShiftTo; BigInteger.prototype.drShiftTo = bnpDRShiftTo; BigInteger.prototype.lShiftTo = bnpLShiftTo; BigInteger.prototype.rShiftTo = bnpRShiftTo; BigInteger.prototype.subTo = bnpSubTo; BigInteger.prototype.multiplyTo = bnpMultiplyTo; BigInteger.prototype.squareTo = bnpSquareTo; BigInteger.prototype.divRemTo = bnpDivRemTo; BigInteger.prototype.invDigit = bnpInvDigit; BigInteger.prototype.isEven = bnpIsEven; BigInteger.prototype.exp = bnpExp; BigInteger.prototype.toString = bnToString; BigInteger.prototype.negate = bnNegate; BigInteger.prototype.abs = bnAbs; BigInteger.prototype.compareTo = bnCompareTo; BigInteger.prototype.bitLength = bnBitLength; BigInteger.prototype.mod = bnMod; BigInteger.prototype.modPowInt = bnModPowInt; BigInteger.ZERO = nbv(0); BigInteger.ONE = nbv(1); function bnClone() { var r = nbi(); this.copyTo(r); return r; } function bnIntValue() { if (this.s < 0) { if (this.t == 1) return this.data[0] - this.DV; else if (this.t == 0) return -1; } else if (this.t == 1) return this.data[0]; else if (this.t == 0) return 0; return (this.data[1] & (1 << 32 - this.DB) - 1) << this.DB | this.data[0]; } function bnByteValue() { return this.t == 0 ? this.s : this.data[0] << 24 >> 24; } function bnShortValue() { return this.t == 0 ? this.s : this.data[0] << 16 >> 16; } function bnpChunkSize(r) { return Math.floor(Math.LN2 * this.DB / Math.log(r)); } function bnSigNum() { if (this.s < 0) return -1; else if (this.t <= 0 || this.t == 1 && this.data[0] <= 0) return 0; else return 1; } function bnpToRadix(b) { if (b == null) b = 10; if (this.signum() == 0 || b < 2 || b > 36) return "0"; var cs = this.chunkSize(b); var a = Math.pow(b, cs); var d = nbv(a), y = nbi(), z = nbi(), r = ""; this.divRemTo(d, y, z); while (y.signum() > 0) { r = (a + z.intValue()).toString(b).substr(1) + r; y.divRemTo(d, y, z); } return z.intValue().toString(b) + r; } function bnpFromRadix(s, b) { this.fromInt(0); if (b == null) b = 10; var cs = this.chunkSize(b); var d = Math.pow(b, cs), mi = false, j = 0, w = 0; for (var i = 0; i < s.length; ++i) { var x = intAt(s, i); if (x < 0) { if (s.charAt(i) == "-" && this.signum() == 0) mi = true; continue; } w = b * w + x; if (++j >= cs) { this.dMultiply(d); this.dAddOffset(w, 0); j = 0; w = 0; } } if (j > 0) { this.dMultiply(Math.pow(b, j)); this.dAddOffset(w, 0); } if (mi) BigInteger.ZERO.subTo(this, this); } function bnpFromNumber(a, b, c) { if ("number" == typeof b) { if (a < 2) this.fromInt(1); else { this.fromNumber(a, c); if (!this.testBit(a - 1)) this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this); if (this.isEven()) this.dAddOffset(1, 0); while (!this.isProbablePrime(b)) { this.dAddOffset(2, 0); if (this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a - 1), this); } } } else { var x = new Array(), t = a & 7; x.length = (a >> 3) + 1; b.nextBytes(x); if (t > 0) x[0] &= (1 << t) - 1; else x[0] = 0; this.fromString(x, 256); } } function bnToByteArray() { var i = this.t, r = new Array(); r[0] = this.s; var p = this.DB - i * this.DB % 8, d, k = 0; if (i-- > 0) { if (p < this.DB && (d = this.data[i] >> p) != (this.s & this.DM) >> p) r[k++] = d | this.s << this.DB - p; while (i >= 0) { if (p < 8) { d = (this.data[i] & (1 << p) - 1) << 8 - p; d |= this.data[--i] >> (p += this.DB - 8); } else { d = this.data[i] >> (p -= 8) & 255; if (p <= 0) { p += this.DB; --i; } } if ((d & 128) != 0) d |= -256; if (k == 0 && (this.s & 128) != (d & 128)) ++k; if (k > 0 || d != this.s) r[k++] = d; } } return r; } function bnEquals(a) { return this.compareTo(a) == 0; } function bnMin(a) { return this.compareTo(a) < 0 ? this : a; } function bnMax(a) { return this.compareTo(a) > 0 ? this : a; } function bnpBitwiseTo(a, op, r) { var i, f, m = Math.min(a.t, this.t); for (i = 0; i < m; ++i) r.data[i] = op(this.data[i], a.data[i]); if (a.t < this.t) { f = a.s & this.DM; for (i = m; i < this.t; ++i) r.data[i] = op(this.data[i], f); r.t = this.t; } else { f = this.s & this.DM; for (i = m; i < a.t; ++i) r.data[i] = op(f, a.data[i]); r.t = a.t; } r.s = op(this.s, a.s); r.clamp(); } function op_and(x, y) { return x & y; } function bnAnd(a) { var r = nbi(); this.bitwiseTo(a, op_and, r); return r; } function op_or(x, y) { return x | y; } function bnOr(a) { var r = nbi(); this.bitwiseTo(a, op_or, r); return r; } function op_xor(x, y) { return x ^ y; } function bnXor(a) { var r = nbi(); this.bitwiseTo(a, op_xor, r); return r; } function op_andnot(x, y) { return x & ~y; } function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a, op_andnot, r); return r; } function bnNot() { var r = nbi(); for (var i = 0; i < this.t; ++i) r.data[i] = this.DM & ~this.data[i]; r.t = this.t; r.s = ~this.s; return r; } function bnShiftLeft(n) { var r = nbi(); if (n < 0) this.rShiftTo(-n, r); else this.lShiftTo(n, r); return r; } function bnShiftRight(n) { var r = nbi(); if (n < 0) this.lShiftTo(-n, r); else this.rShiftTo(n, r); return r; } function lbit(x) { if (x == 0) return -1; var r = 0; if ((x & 65535) == 0) { x >>= 16; r += 16; } if ((x & 255) == 0) { x >>= 8; r += 8; } if ((x & 15) == 0) { x >>= 4; r += 4; } if ((x & 3) == 0) { x >>= 2; r += 2; } if ((x & 1) == 0) ++r; return r; } function bnGetLowestSetBit() { for (var i = 0; i < this.t; ++i) if (this.data[i] != 0) return i * this.DB + lbit(this.data[i]); if (this.s < 0) return this.t * this.DB; return -1; } function cbit(x) { var r = 0; while (x != 0) { x &= x - 1; ++r; } return r; } function bnBitCount() { var r = 0, x = this.s & this.DM; for (var i = 0; i < this.t; ++i) r += cbit(this.data[i] ^ x); return r; } function bnTestBit(n) { var j = Math.floor(n / this.DB); if (j >= this.t) return this.s != 0; return (this.data[j] & 1 << n % this.DB) != 0; } function bnpChangeBit(n, op) { var r = BigInteger.ONE.shiftLeft(n); this.bitwiseTo(r, op, r); return r; } function bnSetBit(n) { return this.changeBit(n, op_or); } function bnClearBit(n) { return this.changeBit(n, op_andnot); } function bnFlipBit(n) { return this.changeBit(n, op_xor); } function bnpAddTo(a, r) { var i = 0, c = 0, m = Math.min(a.t, this.t); while (i < m) { c += this.data[i] + a.data[i]; r.data[i++] = c & this.DM; c >>= this.DB; } if (a.t < this.t) { c += a.s; while (i < this.t) { c += this.data[i]; r.data[i++] = c & this.DM; c >>= this.DB; } c += this.s; } else { c += this.s; while (i < a.t) { c += a.data[i]; r.data[i++] = c & this.DM; c >>= this.DB; } c += a.s; } r.s = c < 0 ? -1 : 0; if (c > 0) r.data[i++] = c; else if (c < -1) r.data[i++] = this.DV + c; r.t = i; r.clamp(); } function bnAdd(a) { var r = nbi(); this.addTo(a, r); return r; } function bnSubtract(a) { var r = nbi(); this.subTo(a, r); return r; } function bnMultiply(a) { var r = nbi(); this.multiplyTo(a, r); return r; } function bnDivide(a) { var r = nbi(); this.divRemTo(a, r, null); return r; } function bnRemainder(a) { var r = nbi(); this.divRemTo(a, null, r); return r; } function bnDivideAndRemainder(a) { var q = nbi(), r = nbi(); this.divRemTo(a, q, r); return new Array(q, r); } function bnpDMultiply(n) { this.data[this.t] = this.am(0, n - 1, this, 0, 0, this.t); ++this.t; this.clamp(); } function bnpDAddOffset(n, w) { if (n == 0) return; while (this.t <= w) this.data[this.t++] = 0; this.data[w] += n; while (this.data[w] >= this.DV) { this.data[w] -= this.DV; if (++w >= this.t) this.data[this.t++] = 0; ++this.data[w]; } } function NullExp() {} function nNop(x) { return x; } function nMulTo(x, y, r) { x.multiplyTo(y, r); } function nSqrTo(x, r) { x.squareTo(r); } NullExp.prototype.convert = nNop; NullExp.prototype.revert = nNop; NullExp.prototype.mulTo = nMulTo; NullExp.prototype.sqrTo = nSqrTo; function bnPow(e) { return this.exp(e, new NullExp()); } function bnpMultiplyLowerTo(a, n, r) { var i = Math.min(this.t + a.t, n); r.s = 0; r.t = i; while (i > 0) r.data[--i] = 0; var j; for (j = r.t - this.t; i < j; ++i) r.data[i + this.t] = this.am(0, a.data[i], r, i, 0, this.t); for (j = Math.min(a.t, n); i < j; ++i) this.am(0, a.data[i], r, i, 0, n - i); r.clamp(); } function bnpMultiplyUpperTo(a, n, r) { --n; var i = r.t = this.t + a.t - n; r.s = 0; while (--i >= 0) r.data[i] = 0; for (i = Math.max(n - this.t, 0); i < a.t; ++i) r.data[this.t + i - n] = this.am(n - i, a.data[i], r, 0, 0, this.t + i - n); r.clamp(); r.drShiftTo(1, r); } function Barrett(m) { this.r2 = nbi(); this.q3 = nbi(); BigInteger.ONE.dlShiftTo(2 * m.t, this.r2); this.mu = this.r2.divide(m); this.m = m; } function barrettConvert(x) { if (x.s < 0 || x.t > 2 * this.m.t) return x.mod(this.m); else if (x.compareTo(this.m) < 0) return x; else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; } } function barrettRevert(x) { return x; } function barrettReduce(x) { x.drShiftTo(this.m.t - 1, this.r2); if (x.t > this.m.t + 1) { x.t = this.m.t + 1; x.clamp(); } this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3); this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2); while (x.compareTo(this.r2) < 0) x.dAddOffset(1, this.m.t + 1); x.subTo(this.r2, x); while (x.compareTo(this.m) >= 0) x.subTo(this.m, x); } function barrettSqrTo(x, r) { x.squareTo(r); this.reduce(r); } function barrettMulTo(x, y, r) { x.multiplyTo(y, r); this.reduce(r); } Barrett.prototype.convert = barrettConvert; Barrett.prototype.revert = barrettRevert; Barrett.prototype.reduce = barrettReduce; Barrett.prototype.mulTo = barrettMulTo; Barrett.prototype.sqrTo = barrettSqrTo; function bnModPow(e, m) { var i = e.bitLength(), k, r = nbv(1), z; if (i <= 0) return r; else if (i < 18) k = 1; else if (i < 48) k = 3; else if (i < 144) k = 4; else if (i < 768) k = 5; else k = 6; if (i < 8) z = new Classic(m); else if (m.isEven()) z = new Barrett(m); else z = new Montgomery(m); var g = new Array(), n = 3, k1 = k - 1, km = (1 << k) - 1; g[1] = z.convert(this); if (k > 1) { var g2 = nbi(); z.sqrTo(g[1], g2); while (n <= km) { g[n] = nbi(); z.mulTo(g2, g[n - 2], g[n]); n += 2; } } var j = e.t - 1, w, is1 = true, r2 = nbi(), t; i = nbits(e.data[j]) - 1; while (j >= 0) { if (i >= k1) w = e.data[j] >> i - k1 & km; else { w = (e.data[j] & (1 << i + 1) - 1) << k1 - i; if (j > 0) w |= e.data[j - 1] >> this.DB + i - k1; } n = k; while ((w & 1) == 0) { w >>= 1; --n; } if ((i -= n) < 0) { i += this.DB; --j; } if (is1) { g[w].copyTo(r); is1 = false; } else { while (n > 1) { z.sqrTo(r, r2); z.sqrTo(r2, r); n -= 2; } if (n > 0) z.sqrTo(r, r2); else { t = r; r = r2; r2 = t; } z.mulTo(r2, g[w], r); } while (j >= 0 && (e.data[j] & 1 << i) == 0) { z.sqrTo(r, r2); t = r; r = r2; r2 = t; if (--i < 0) { i = this.DB - 1; --j; } } } return z.revert(r); } function bnGCD(a) { var x = this.s < 0 ? this.negate() : this.clone(); var y = a.s < 0 ? a.negate() : a.clone(); if (x.compareTo(y) < 0) { var t = x; x = y; y = t; } var i = x.getLowestSetBit(), g = y.getLowestSetBit(); if (g < 0) return x; if (i < g) g = i; if (g > 0) { x.rShiftTo(g, x); y.rShiftTo(g, y); } while (x.signum() > 0) { if ((i = x.getLowestSetBit()) > 0) x.rShiftTo(i, x); if ((i = y.getLowestSetBit()) > 0) y.rShiftTo(i, y); if (x.compareTo(y) >= 0) { x.subTo(y, x); x.rShiftTo(1, x); } else { y.subTo(x, y); y.rShiftTo(1, y); } } if (g > 0) y.lShiftTo(g, y); return y; } function bnpModInt(n) { if (n <= 0) return 0; var d = this.DV % n, r = this.s < 0 ? n - 1 : 0; if (this.t > 0) if (d == 0) r = this.data[0] % n; else for (var i = this.t - 1; i >= 0; --i) r = (d * r + this.data[i]) % n; return r; } function bnModInverse(m) { var ac = m.isEven(); if (this.isEven() && ac || m.signum() == 0) return BigInteger.ZERO; var u = m.clone(), v = this.clone(); var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1); while (u.signum() != 0) { while (u.isEven()) { u.rShiftTo(1, u); if (ac) { if (!a.isEven() || !b.isEven()) { a.addTo(this, a); b.subTo(m, b); } a.rShiftTo(1, a); } else if (!b.isEven()) b.subTo(m, b); b.rShiftTo(1, b); } while (v.isEven()) { v.rShiftTo(1, v); if (ac) { if (!c.isEven() || !d.isEven()) { c.addTo(this, c); d.subTo(m, d); } c.rShiftTo(1, c); } else if (!d.isEven()) d.subTo(m, d); d.rShiftTo(1, d); } if (u.compareTo(v) >= 0) { u.subTo(v, u); if (ac) a.subTo(c, a); b.subTo(d, b); } else { v.subTo(u, v); if (ac) c.subTo(a, c); d.subTo(b, d); } } if (v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; if (d.compareTo(m) >= 0) return d.subtract(m); if (d.signum() < 0) d.addTo(m, d); else return d; if (d.signum() < 0) return d.add(m); else return d; } var lowprimes = [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509 ]; var lplim = (1 << 26) / lowprimes[lowprimes.length - 1]; function bnIsProbablePrime(t) { var i, x = this.abs(); if (x.t == 1 && x.data[0] <= lowprimes[lowprimes.length - 1]) { for (i = 0; i < lowprimes.length; ++i) if (x.data[0] == lowprimes[i]) return true; return false; } if (x.isEven()) return false; i = 1; while (i < lowprimes.length) { var m = lowprimes[i], j = i + 1; while (j < lowprimes.length && m < lplim) m *= lowprimes[j++]; m = x.modInt(m); while (i < j) if (m % lowprimes[i++] == 0) return false; } return x.millerRabin(t); } function bnpMillerRabin(t) { var n1 = this.subtract(BigInteger.ONE); var k = n1.getLowestSetBit(); if (k <= 0) return false; var r = n1.shiftRight(k); var prng = bnGetPrng(); var a; for (var i = 0; i < t; ++i) { do { a = new BigInteger(this.bitLength(), prng); } while (a.compareTo(BigInteger.ONE) <= 0 || a.compareTo(n1) >= 0); var y = a.modPow(r, this); if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { var j = 1; while (j++ < k && y.compareTo(n1) != 0) { y = y.modPowInt(2, this); if (y.compareTo(BigInteger.ONE) == 0) return false; } if (y.compareTo(n1) != 0) return false; } } return true; } function bnGetPrng() { return { nextBytes: function(x) { for (var i = 0; i < x.length; ++i) { x[i] = Math.floor(Math.random() * 256); } } }; } BigInteger.prototype.chunkSize = bnpChunkSize; BigInteger.prototype.toRadix = bnpToRadix; BigInteger.prototype.fromRadix = bnpFromRadix; BigInteger.prototype.fromNumber = bnpFromNumber; BigInteger.prototype.bitwiseTo = bnpBitwiseTo; BigInteger.prototype.changeBit = bnpChangeBit; BigInteger.prototype.addTo = bnpAddTo; BigInteger.prototype.dMultiply = bnpDMultiply; BigInteger.prototype.dAddOffset = bnpDAddOffset; BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; BigInteger.prototype.modInt = bnpModInt; BigInteger.prototype.millerRabin = bnpMillerRabin; BigInteger.prototype.clone = bnClone; BigInteger.prototype.intValue = bnIntValue; BigInteger.prototype.byteValue = bnByteValue; BigInteger.prototype.shortValue = bnShortValue; BigInteger.prototype.signum = bnSigNum; BigInteger.prototype.toByteArray = bnToByteArray; BigInteger.prototype.equals = bnEquals; BigInteger.prototype.min = bnMin; BigInteger.prototype.max = bnMax; BigInteger.prototype.and = bnAnd; BigInteger.prototype.or = bnOr; BigInteger.prototype.xor = bnXor; BigInteger.prototype.andNot = bnAndNot; BigInteger.prototype.not = bnNot; BigInteger.prototype.shiftLeft = bnShiftLeft; BigInteger.prototype.shiftRight = bnShiftRight; BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; BigInteger.prototype.bitCount = bnBitCount; BigInteger.prototype.testBit = bnTestBit; BigInteger.prototype.setBit = bnSetBit; BigInteger.prototype.clearBit = bnClearBit; BigInteger.prototype.flipBit = bnFlipBit; BigInteger.prototype.add = bnAdd; BigInteger.prototype.subtract = bnSubtract; BigInteger.prototype.multiply = bnMultiply; BigInteger.prototype.divide = bnDivide; BigInteger.prototype.remainder = bnRemainder; BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder; BigInteger.prototype.modPow = bnModPow; BigInteger.prototype.modInverse = bnModInverse; BigInteger.prototype.pow = bnPow; BigInteger.prototype.gcd = bnGCD; BigInteger.prototype.isProbablePrime = bnIsProbablePrime; })); //#endregion //#region ../node_modules/node-forge/lib/sha1.js var require_sha1$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Secure Hash Algorithm with 160-bit digest (SHA-1) implementation. * * @author Dave Longley * * Copyright (c) 2010-2015 Digital Bazaar, Inc. */ var forge = require_forge(); require_md(); require_util$8(); var sha1 = module.exports = forge.sha1 = forge.sha1 || {}; forge.md.sha1 = forge.md.algorithms.sha1 = sha1; /** * Creates a SHA-1 message digest object. * * @return a message digest object. */ sha1.create = function() { if (!_initialized) { _init(); } var _state = null; var _input = forge.util.createBuffer(); var _w = new Array(80); var md = { algorithm: "sha1", blockLength: 64, digestLength: 20, messageLength: 0, fullMessageLength: null, messageLengthSize: 8 }; /** * Starts the digest. * * @return this digest object. */ md.start = function() { md.messageLength = 0; md.fullMessageLength = md.messageLength64 = []; var int32s = md.messageLengthSize / 4; for (var i = 0; i < int32s; ++i) { md.fullMessageLength.push(0); } _input = forge.util.createBuffer(); _state = { h0: 1732584193, h1: 4023233417, h2: 2562383102, h3: 271733878, h4: 3285377520 }; return md; }; md.start(); /** * Updates the digest with the given message input. The given input can * treated as raw input (no encoding will be applied) or an encoding of * 'utf8' maybe given to encode the input using UTF-8. * * @param msg the message input to update with. * @param encoding the encoding to use (default: 'raw', other: 'utf8'). * * @return this digest object. */ md.update = function(msg, encoding) { if (encoding === "utf8") { msg = forge.util.encodeUtf8(msg); } var len = msg.length; md.messageLength += len; len = [len / 4294967296 >>> 0, len >>> 0]; for (var i = md.fullMessageLength.length - 1; i >= 0; --i) { md.fullMessageLength[i] += len[1]; len[1] = len[0] + (md.fullMessageLength[i] / 4294967296 >>> 0); md.fullMessageLength[i] = md.fullMessageLength[i] >>> 0; len[0] = len[1] / 4294967296 >>> 0; } _input.putBytes(msg); _update(_state, _w, _input); if (_input.read > 2048 || _input.length() === 0) { _input.compact(); } return md; }; /** * Produces the digest. * * @return a byte buffer containing the digest value. */ md.digest = function() { var finalBlock = forge.util.createBuffer(); finalBlock.putBytes(_input.bytes()); var remaining = md.fullMessageLength[md.fullMessageLength.length - 1] + md.messageLengthSize; var overflow = remaining & md.blockLength - 1; finalBlock.putBytes(_padding.substr(0, md.blockLength - overflow)); var next, carry; var bits = md.fullMessageLength[0] * 8; for (var i = 0; i < md.fullMessageLength.length - 1; ++i) { next = md.fullMessageLength[i + 1] * 8; carry = next / 4294967296 >>> 0; bits += carry; finalBlock.putInt32(bits >>> 0); bits = next >>> 0; } finalBlock.putInt32(bits); var s2 = { h0: _state.h0, h1: _state.h1, h2: _state.h2, h3: _state.h3, h4: _state.h4 }; _update(s2, _w, finalBlock); var rval = forge.util.createBuffer(); rval.putInt32(s2.h0); rval.putInt32(s2.h1); rval.putInt32(s2.h2); rval.putInt32(s2.h3); rval.putInt32(s2.h4); return rval; }; return md; }; var _padding = null; var _initialized = false; /** * Initializes the constant tables. */ function _init() { _padding = String.fromCharCode(128); _padding += forge.util.fillString(String.fromCharCode(0), 64); _initialized = true; } /** * Updates a SHA-1 state with the given byte buffer. * * @param s the SHA-1 state to update. * @param w the array to use to store words. * @param bytes the byte buffer to update with. */ function _update(s, w, bytes) { var t, a, b, c, d, e, f, i; var len = bytes.length(); while (len >= 64) { a = s.h0; b = s.h1; c = s.h2; d = s.h3; e = s.h4; for (i = 0; i < 16; ++i) { t = bytes.getInt32(); w[i] = t; f = d ^ b & (c ^ d); t = (a << 5 | a >>> 27) + f + e + 1518500249 + t; e = d; d = c; c = (b << 30 | b >>> 2) >>> 0; b = a; a = t; } for (; i < 20; ++i) { t = w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]; t = t << 1 | t >>> 31; w[i] = t; f = d ^ b & (c ^ d); t = (a << 5 | a >>> 27) + f + e + 1518500249 + t; e = d; d = c; c = (b << 30 | b >>> 2) >>> 0; b = a; a = t; } for (; i < 32; ++i) { t = w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]; t = t << 1 | t >>> 31; w[i] = t; f = b ^ c ^ d; t = (a << 5 | a >>> 27) + f + e + 1859775393 + t; e = d; d = c; c = (b << 30 | b >>> 2) >>> 0; b = a; a = t; } for (; i < 40; ++i) { t = w[i - 6] ^ w[i - 16] ^ w[i - 28] ^ w[i - 32]; t = t << 2 | t >>> 30; w[i] = t; f = b ^ c ^ d; t = (a << 5 | a >>> 27) + f + e + 1859775393 + t; e = d; d = c; c = (b << 30 | b >>> 2) >>> 0; b = a; a = t; } for (; i < 60; ++i) { t = w[i - 6] ^ w[i - 16] ^ w[i - 28] ^ w[i - 32]; t = t << 2 | t >>> 30; w[i] = t; f = b & c | d & (b ^ c); t = (a << 5 | a >>> 27) + f + e + 2400959708 + t; e = d; d = c; c = (b << 30 | b >>> 2) >>> 0; b = a; a = t; } for (; i < 80; ++i) { t = w[i - 6] ^ w[i - 16] ^ w[i - 28] ^ w[i - 32]; t = t << 2 | t >>> 30; w[i] = t; f = b ^ c ^ d; t = (a << 5 | a >>> 27) + f + e + 3395469782 + t; e = d; d = c; c = (b << 30 | b >>> 2) >>> 0; b = a; a = t; } s.h0 = s.h0 + a | 0; s.h1 = s.h1 + b | 0; s.h2 = s.h2 + c | 0; s.h3 = s.h3 + d | 0; s.h4 = s.h4 + e | 0; len -= 64; } } })); //#endregion //#region ../node_modules/node-forge/lib/pkcs1.js var require_pkcs1 = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Partial implementation of PKCS#1 v2.2: RSA-OEAP * * Modified but based on the following MIT and BSD licensed code: * * https://github.com/kjur/jsjws/blob/master/rsa.js: * * The 'jsjws'(JSON Web Signature JavaScript Library) License * * Copyright (c) 2012 Kenji Urushima * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * http://webrsa.cvs.sourceforge.net/viewvc/webrsa/Client/RSAES-OAEP.js?content-type=text%2Fplain: * * RSAES-OAEP.js * $Id: RSAES-OAEP.js,v 1.1.1.1 2003/03/19 15:37:20 ellispritchard Exp $ * JavaScript Implementation of PKCS #1 v2.1 RSA CRYPTOGRAPHY STANDARD (RSA Laboratories, June 14, 2002) * Copyright (C) Ellis Pritchard, Guardian Unlimited 2003. * Contact: ellis@nukinetics.com * Distributed under the BSD License. * * Official documentation: http://www.rsa.com/rsalabs/node.asp?id=2125 * * @author Evan Jones (http://evanjones.ca/) * @author Dave Longley * * Copyright (c) 2013-2014 Digital Bazaar, Inc. */ var forge = require_forge(); require_util$8(); require_random(); require_sha1$1(); var pkcs1 = module.exports = forge.pkcs1 = forge.pkcs1 || {}; /** * Encode the given RSAES-OAEP message (M) using key, with optional label (L) * and seed. * * This method does not perform RSA encryption, it only encodes the message * using RSAES-OAEP. * * @param key the RSA key to use. * @param message the message to encode. * @param options the options to use: * label an optional label to use. * seed the seed to use. * md the message digest object to use, undefined for SHA-1. * mgf1 optional mgf1 parameters: * md the message digest object to use for MGF1. * * @return the encoded message bytes. */ pkcs1.encode_rsa_oaep = function(key, message, options) { var label; var seed; var md; var mgf1Md; if (typeof options === "string") { label = options; seed = arguments[3] || undefined; md = arguments[4] || undefined; } else if (options) { label = options.label || undefined; seed = options.seed || undefined; md = options.md || undefined; if (options.mgf1 && options.mgf1.md) { mgf1Md = options.mgf1.md; } } if (!md) { md = forge.md.sha1.create(); } else { md.start(); } if (!mgf1Md) { mgf1Md = md; } var keyLength = Math.ceil(key.n.bitLength() / 8); var maxLength = keyLength - 2 * md.digestLength - 2; if (message.length > maxLength) { var error = new Error("RSAES-OAEP input message length is too long."); error.length = message.length; error.maxLength = maxLength; throw error; } if (!label) { label = ""; } md.update(label, "raw"); var lHash = md.digest(); var PS = ""; var PS_length = maxLength - message.length; for (var i = 0; i < PS_length; i++) { PS += "\0"; } var DB = lHash.getBytes() + PS + "" + message; if (!seed) { seed = forge.random.getBytes(md.digestLength); } else if (seed.length !== md.digestLength) { var error = new Error("Invalid RSAES-OAEP seed. The seed length must " + "match the digest length."); error.seedLength = seed.length; error.digestLength = md.digestLength; throw error; } var dbMask = rsa_mgf1(seed, keyLength - md.digestLength - 1, mgf1Md); var maskedDB = forge.util.xorBytes(DB, dbMask, DB.length); var seedMask = rsa_mgf1(maskedDB, md.digestLength, mgf1Md); var maskedSeed = forge.util.xorBytes(seed, seedMask, seed.length); return "\0" + maskedSeed + maskedDB; }; /** * Decode the given RSAES-OAEP encoded message (EM) using key, with optional * label (L). * * This method does not perform RSA decryption, it only decodes the message * using RSAES-OAEP. * * @param key the RSA key to use. * @param em the encoded message to decode. * @param options the options to use: * label an optional label to use. * md the message digest object to use for OAEP, undefined for SHA-1. * mgf1 optional mgf1 parameters: * md the message digest object to use for MGF1. * * @return the decoded message bytes. */ pkcs1.decode_rsa_oaep = function(key, em, options) { var label; var md; var mgf1Md; if (typeof options === "string") { label = options; md = arguments[3] || undefined; } else if (options) { label = options.label || undefined; md = options.md || undefined; if (options.mgf1 && options.mgf1.md) { mgf1Md = options.mgf1.md; } } var keyLength = Math.ceil(key.n.bitLength() / 8); if (em.length !== keyLength) { var error = new Error("RSAES-OAEP encoded message length is invalid."); error.length = em.length; error.expectedLength = keyLength; throw error; } if (md === undefined) { md = forge.md.sha1.create(); } else { md.start(); } if (!mgf1Md) { mgf1Md = md; } if (keyLength < 2 * md.digestLength + 2) { throw new Error("RSAES-OAEP key is too short for the hash function."); } if (!label) { label = ""; } md.update(label, "raw"); var lHash = md.digest().getBytes(); var y = em.charAt(0); var maskedSeed = em.substring(1, md.digestLength + 1); var maskedDB = em.substring(1 + md.digestLength); var seedMask = rsa_mgf1(maskedDB, md.digestLength, mgf1Md); var seed = forge.util.xorBytes(maskedSeed, seedMask, maskedSeed.length); var dbMask = rsa_mgf1(seed, keyLength - md.digestLength - 1, mgf1Md); var db = forge.util.xorBytes(maskedDB, dbMask, maskedDB.length); var lHashPrime = db.substring(0, md.digestLength); var error = y !== "\0"; for (var i = 0; i < md.digestLength; ++i) { error |= lHash.charAt(i) !== lHashPrime.charAt(i); } var in_ps = 1; var index = md.digestLength; for (var j = md.digestLength; j < db.length; j++) { var code = db.charCodeAt(j); var is_0 = code & 1 ^ 1; var error_mask = in_ps ? 65534 : 0; error |= code & error_mask; in_ps = in_ps & is_0; index += in_ps; } if (error || db.charCodeAt(index) !== 1) { throw new Error("Invalid RSAES-OAEP padding."); } return db.substring(index + 1); }; function rsa_mgf1(seed, maskLength, hash) { if (!hash) { hash = forge.md.sha1.create(); } var t = ""; var count = Math.ceil(maskLength / hash.digestLength); for (var i = 0; i < count; ++i) { var c = String.fromCharCode(i >> 24 & 255, i >> 16 & 255, i >> 8 & 255, i & 255); hash.start(); hash.update(seed + c); t += hash.digest().getBytes(); } return t.substring(0, maskLength); } })); //#endregion //#region ../node_modules/node-forge/lib/prime.js var require_prime = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Prime number generation API. * * @author Dave Longley * * Copyright (c) 2014 Digital Bazaar, Inc. */ var forge = require_forge(); require_util$8(); require_jsbn(); require_random(); (function() { if (forge.prime) { module.exports = forge.prime; return; } var prime = module.exports = forge.prime = forge.prime || {}; var BigInteger = forge.jsbn.BigInteger; var GCD_30_DELTA = [ 6, 4, 2, 4, 2, 4, 6, 2 ]; var THIRTY = new BigInteger(null); THIRTY.fromInt(30); var op_or = function(x, y) { return x | y; }; /** * Generates a random probable prime with the given number of bits. * * Alternative algorithms can be specified by name as a string or as an * object with custom options like so: * * { * name: 'PRIMEINC', * options: { * maxBlockTime: , * millerRabinTests: , * workerScript: , * workers: . * workLoad: the size of the work load, ie: number of possible prime * numbers for each web worker to check per work assignment, * (default: 100). * } * } * * @param bits the number of bits for the prime number. * @param options the options to use. * [algorithm] the algorithm to use (default: 'PRIMEINC'). * [prng] a custom crypto-secure pseudo-random number generator to use, * that must define "getBytesSync". * * @return callback(err, num) called once the operation completes. */ prime.generateProbablePrime = function(bits, options, callback) { if (typeof options === "function") { callback = options; options = {}; } options = options || {}; var algorithm = options.algorithm || "PRIMEINC"; if (typeof algorithm === "string") { algorithm = { name: algorithm }; } algorithm.options = algorithm.options || {}; var prng = options.prng || forge.random; var rng = { nextBytes: function(x) { var b = prng.getBytesSync(x.length); for (var i = 0; i < x.length; ++i) { x[i] = b.charCodeAt(i); } } }; if (algorithm.name === "PRIMEINC") { return primeincFindPrime(bits, rng, algorithm.options, callback); } throw new Error("Invalid prime generation algorithm: " + algorithm.name); }; function primeincFindPrime(bits, rng, options, callback) { if ("workers" in options) { return primeincFindPrimeWithWorkers(bits, rng, options, callback); } return primeincFindPrimeWithoutWorkers(bits, rng, options, callback); } function primeincFindPrimeWithoutWorkers(bits, rng, options, callback) { var num = generateRandom(bits, rng); var deltaIdx = 0; var mrTests = getMillerRabinTests(num.bitLength()); if ("millerRabinTests" in options) { mrTests = options.millerRabinTests; } var maxBlockTime = 10; if ("maxBlockTime" in options) { maxBlockTime = options.maxBlockTime; } _primeinc(num, bits, rng, deltaIdx, mrTests, maxBlockTime, callback); } function _primeinc(num, bits, rng, deltaIdx, mrTests, maxBlockTime, callback) { var start = +new Date(); do { if (num.bitLength() > bits) { num = generateRandom(bits, rng); } if (num.isProbablePrime(mrTests)) { return callback(null, num); } num.dAddOffset(GCD_30_DELTA[deltaIdx++ % 8], 0); } while (maxBlockTime < 0 || +new Date() - start < maxBlockTime); forge.util.setImmediate(function() { _primeinc(num, bits, rng, deltaIdx, mrTests, maxBlockTime, callback); }); } function primeincFindPrimeWithWorkers(bits, rng, options, callback) { if (typeof Worker === "undefined") { return primeincFindPrimeWithoutWorkers(bits, rng, options, callback); } var num = generateRandom(bits, rng); var numWorkers = options.workers; var workLoad = options.workLoad || 100; var range = workLoad * 30 / 8; var workerScript = options.workerScript || "forge/prime.worker.js"; if (numWorkers === -1) { return forge.util.estimateCores(function(err, cores) { if (err) { cores = 2; } numWorkers = cores - 1; generate(); }); } generate(); function generate() { numWorkers = Math.max(1, numWorkers); var workers = []; for (var i = 0; i < numWorkers; ++i) { workers[i] = new Worker(workerScript); } var running = numWorkers; for (var i = 0; i < numWorkers; ++i) { workers[i].addEventListener("message", workerMessage); } var found = false; function workerMessage(e) { if (found) { return; } --running; var data = e.data; if (data.found) { for (var i = 0; i < workers.length; ++i) { workers[i].terminate(); } found = true; return callback(null, new BigInteger(data.prime, 16)); } if (num.bitLength() > bits) { num = generateRandom(bits, rng); } var hex = num.toString(16); e.target.postMessage({ hex, workLoad }); num.dAddOffset(range, 0); } } } /** * Generates a random number using the given number of bits and RNG. * * @param bits the number of bits for the number. * @param rng the random number generator to use. * * @return the random number. */ function generateRandom(bits, rng) { var num = new BigInteger(bits, rng); var bits1 = bits - 1; if (!num.testBit(bits1)) { num.bitwiseTo(BigInteger.ONE.shiftLeft(bits1), op_or, num); } num.dAddOffset(31 - num.mod(THIRTY).byteValue(), 0); return num; } /** * Returns the required number of Miller-Rabin tests to generate a * prime with an error probability of (1/2)^80. * * See Handbook of Applied Cryptography Chapter 4, Table 4.4. * * @param bits the bit size. * * @return the required number of iterations. */ function getMillerRabinTests(bits) { if (bits <= 100) return 27; if (bits <= 150) return 18; if (bits <= 200) return 15; if (bits <= 250) return 12; if (bits <= 300) return 9; if (bits <= 350) return 8; if (bits <= 400) return 7; if (bits <= 500) return 6; if (bits <= 600) return 5; if (bits <= 800) return 4; if (bits <= 1250) return 3; return 2; } })(); })); //#endregion //#region ../node_modules/node-forge/lib/rsa.js var require_rsa = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Javascript implementation of basic RSA algorithms. * * @author Dave Longley * * Copyright (c) 2010-2014 Digital Bazaar, Inc. * * The only algorithm currently supported for PKI is RSA. * * An RSA key is often stored in ASN.1 DER format. The SubjectPublicKeyInfo * ASN.1 structure is composed of an algorithm of type AlgorithmIdentifier * and a subjectPublicKey of type bit string. * * The AlgorithmIdentifier contains an Object Identifier (OID) and parameters * for the algorithm, if any. In the case of RSA, there aren't any. * * SubjectPublicKeyInfo ::= SEQUENCE { * algorithm AlgorithmIdentifier, * subjectPublicKey BIT STRING * } * * AlgorithmIdentifer ::= SEQUENCE { * algorithm OBJECT IDENTIFIER, * parameters ANY DEFINED BY algorithm OPTIONAL * } * * For an RSA public key, the subjectPublicKey is: * * RSAPublicKey ::= SEQUENCE { * modulus INTEGER, -- n * publicExponent INTEGER -- e * } * * PrivateKeyInfo ::= SEQUENCE { * version Version, * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, * privateKey PrivateKey, * attributes [0] IMPLICIT Attributes OPTIONAL * } * * Version ::= INTEGER * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier * PrivateKey ::= OCTET STRING * Attributes ::= SET OF Attribute * * An RSA private key as the following structure: * * RSAPrivateKey ::= SEQUENCE { * version Version, * modulus INTEGER, -- n * publicExponent INTEGER, -- e * privateExponent INTEGER, -- d * prime1 INTEGER, -- p * prime2 INTEGER, -- q * exponent1 INTEGER, -- d mod (p-1) * exponent2 INTEGER, -- d mod (q-1) * coefficient INTEGER -- (inverse of q) mod p * } * * Version ::= INTEGER * * The OID for the RSA key algorithm is: 1.2.840.113549.1.1.1 */ var forge = require_forge(); require_asn1(); require_jsbn(); require_oids(); require_pkcs1(); require_prime(); require_random(); require_util$8(); if (typeof BigInteger === "undefined") { var BigInteger = forge.jsbn.BigInteger; } var _crypto = forge.util.isNodejs ? __require("crypto") : null; var asn1 = forge.asn1; var util = forge.util; forge.pki = forge.pki || {}; module.exports = forge.pki.rsa = forge.rsa = forge.rsa || {}; var pki = forge.pki; var GCD_30_DELTA = [ 6, 4, 2, 4, 2, 4, 6, 2 ]; var privateKeyValidator = { name: "PrivateKeyInfo", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [ { name: "PrivateKeyInfo.version", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.INTEGER, constructed: false, capture: "privateKeyVersion" }, { name: "PrivateKeyInfo.privateKeyAlgorithm", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "AlgorithmIdentifier.algorithm", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OID, constructed: false, capture: "privateKeyOid" }] }, { name: "PrivateKeyInfo", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OCTETSTRING, constructed: false, capture: "privateKey" } ] }; var rsaPrivateKeyValidator = { name: "RSAPrivateKey", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [ { name: "RSAPrivateKey.version", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.INTEGER, constructed: false, capture: "privateKeyVersion" }, { name: "RSAPrivateKey.modulus", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.INTEGER, constructed: false, capture: "privateKeyModulus" }, { name: "RSAPrivateKey.publicExponent", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.INTEGER, constructed: false, capture: "privateKeyPublicExponent" }, { name: "RSAPrivateKey.privateExponent", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.INTEGER, constructed: false, capture: "privateKeyPrivateExponent" }, { name: "RSAPrivateKey.prime1", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.INTEGER, constructed: false, capture: "privateKeyPrime1" }, { name: "RSAPrivateKey.prime2", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.INTEGER, constructed: false, capture: "privateKeyPrime2" }, { name: "RSAPrivateKey.exponent1", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.INTEGER, constructed: false, capture: "privateKeyExponent1" }, { name: "RSAPrivateKey.exponent2", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.INTEGER, constructed: false, capture: "privateKeyExponent2" }, { name: "RSAPrivateKey.coefficient", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.INTEGER, constructed: false, capture: "privateKeyCoefficient" } ] }; var rsaPublicKeyValidator = { name: "RSAPublicKey", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "RSAPublicKey.modulus", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.INTEGER, constructed: false, capture: "publicKeyModulus" }, { name: "RSAPublicKey.exponent", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.INTEGER, constructed: false, capture: "publicKeyExponent" }] }; var publicKeyValidator = forge.pki.rsa.publicKeyValidator = { name: "SubjectPublicKeyInfo", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, captureAsn1: "subjectPublicKeyInfo", value: [{ name: "SubjectPublicKeyInfo.AlgorithmIdentifier", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "AlgorithmIdentifier.algorithm", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OID, constructed: false, capture: "publicKeyOid" }] }, { name: "SubjectPublicKeyInfo.subjectPublicKey", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.BITSTRING, constructed: false, value: [{ name: "SubjectPublicKeyInfo.subjectPublicKey.RSAPublicKey", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, optional: true, captureAsn1: "rsaPublicKey" }] }] }; var digestInfoValidator = { name: "DigestInfo", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "DigestInfo.DigestAlgorithm", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "DigestInfo.DigestAlgorithm.algorithmIdentifier", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OID, constructed: false, capture: "algorithmIdentifier" }, { name: "DigestInfo.DigestAlgorithm.parameters", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.NULL, capture: "parameters", optional: true, constructed: false }] }, { name: "DigestInfo.digest", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OCTETSTRING, constructed: false, capture: "digest" }] }; /** * Wrap digest in DigestInfo object. * * This function implements EMSA-PKCS1-v1_5-ENCODE as per RFC 3447. * * DigestInfo ::= SEQUENCE { * digestAlgorithm DigestAlgorithmIdentifier, * digest Digest * } * * DigestAlgorithmIdentifier ::= AlgorithmIdentifier * Digest ::= OCTET STRING * * @param md the message digest object with the hash to sign. * * @return the encoded message (ready for RSA encrytion) */ var emsaPkcs1v15encode = function(md) { var oid; if (md.algorithm in pki.oids) { oid = pki.oids[md.algorithm]; } else { var error = new Error("Unknown message digest algorithm."); error.algorithm = md.algorithm; throw error; } var oidBytes = asn1.oidToDer(oid).getBytes(); var digestInfo = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []); var digestAlgorithm = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []); digestAlgorithm.value.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, oidBytes)); digestAlgorithm.value.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, "")); var digest = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, md.digest().getBytes()); digestInfo.value.push(digestAlgorithm); digestInfo.value.push(digest); return asn1.toDer(digestInfo).getBytes(); }; /** * Performs x^c mod n (RSA encryption or decryption operation). * * @param x the number to raise and mod. * @param key the key to use. * @param pub true if the key is public, false if private. * * @return the result of x^c mod n. */ var _modPow = function(x, key, pub) { if (pub) { return x.modPow(key.e, key.n); } if (!key.p || !key.q) { return x.modPow(key.d, key.n); } if (!key.dP) { key.dP = key.d.mod(key.p.subtract(BigInteger.ONE)); } if (!key.dQ) { key.dQ = key.d.mod(key.q.subtract(BigInteger.ONE)); } if (!key.qInv) { key.qInv = key.q.modInverse(key.p); } var r; do { r = new BigInteger(forge.util.bytesToHex(forge.random.getBytes(key.n.bitLength() / 8)), 16); } while (r.compareTo(key.n) >= 0 || !r.gcd(key.n).equals(BigInteger.ONE)); x = x.multiply(r.modPow(key.e, key.n)).mod(key.n); var xp = x.mod(key.p).modPow(key.dP, key.p); var xq = x.mod(key.q).modPow(key.dQ, key.q); while (xp.compareTo(xq) < 0) { xp = xp.add(key.p); } var y = xp.subtract(xq).multiply(key.qInv).mod(key.p).multiply(key.q).add(xq); y = y.multiply(r.modInverse(key.n)).mod(key.n); return y; }; /** * NOTE: THIS METHOD IS DEPRECATED, use 'sign' on a private key object or * 'encrypt' on a public key object instead. * * Performs RSA encryption. * * The parameter bt controls whether to put padding bytes before the * message passed in. Set bt to either true or false to disable padding * completely (in order to handle e.g. EMSA-PSS encoding seperately before), * signaling whether the encryption operation is a public key operation * (i.e. encrypting data) or not, i.e. private key operation (data signing). * * For PKCS#1 v1.5 padding pass in the block type to use, i.e. either 0x01 * (for signing) or 0x02 (for encryption). The key operation mode (private * or public) is derived from this flag in that case). * * @param m the message to encrypt as a byte string. * @param key the RSA key to use. * @param bt for PKCS#1 v1.5 padding, the block type to use * (0x01 for private key, 0x02 for public), * to disable padding: true = public key, false = private key. * * @return the encrypted bytes as a string. */ pki.rsa.encrypt = function(m, key, bt) { var pub = bt; var eb; var k = Math.ceil(key.n.bitLength() / 8); if (bt !== false && bt !== true) { pub = bt === 2; eb = _encodePkcs1_v1_5(m, key, bt); } else { eb = forge.util.createBuffer(); eb.putBytes(m); } var x = new BigInteger(eb.toHex(), 16); var y = _modPow(x, key, pub); var yhex = y.toString(16); var ed = forge.util.createBuffer(); var zeros = k - Math.ceil(yhex.length / 2); while (zeros > 0) { ed.putByte(0); --zeros; } ed.putBytes(forge.util.hexToBytes(yhex)); return ed.getBytes(); }; /** * NOTE: THIS METHOD IS DEPRECATED, use 'decrypt' on a private key object or * 'verify' on a public key object instead. * * Performs RSA decryption. * * The parameter ml controls whether to apply PKCS#1 v1.5 padding * or not. Set ml = false to disable padding removal completely * (in order to handle e.g. EMSA-PSS later on) and simply pass back * the RSA encryption block. * * @param ed the encrypted data to decrypt in as a byte string. * @param key the RSA key to use. * @param pub true for a public key operation, false for private. * @param ml the message length, if known, false to disable padding. * * @return the decrypted message as a byte string. */ pki.rsa.decrypt = function(ed, key, pub, ml) { var k = Math.ceil(key.n.bitLength() / 8); if (ed.length !== k) { var error = new Error("Encrypted message length is invalid."); error.length = ed.length; error.expected = k; throw error; } var y = new BigInteger(forge.util.createBuffer(ed).toHex(), 16); if (y.compareTo(key.n) >= 0) { throw new Error("Encrypted message is invalid."); } var x = _modPow(y, key, pub); var xhex = x.toString(16); var eb = forge.util.createBuffer(); var zeros = k - Math.ceil(xhex.length / 2); while (zeros > 0) { eb.putByte(0); --zeros; } eb.putBytes(forge.util.hexToBytes(xhex)); if (ml !== false) { return _decodePkcs1_v1_5(eb.getBytes(), key, pub); } return eb.getBytes(); }; /** * Creates an RSA key-pair generation state object. It is used to allow * key-generation to be performed in steps. It also allows for a UI to * display progress updates. * * @param bits the size for the private key in bits, defaults to 2048. * @param e the public exponent to use, defaults to 65537 (0x10001). * @param [options] the options to use. * prng a custom crypto-secure pseudo-random number generator to use, * that must define "getBytesSync". * algorithm the algorithm to use (default: 'PRIMEINC'). * * @return the state object to use to generate the key-pair. */ pki.rsa.createKeyPairGenerationState = function(bits, e, options) { if (typeof bits === "string") { bits = parseInt(bits, 10); } bits = bits || 2048; options = options || {}; var prng = options.prng || forge.random; var rng = { nextBytes: function(x) { var b = prng.getBytesSync(x.length); for (var i = 0; i < x.length; ++i) { x[i] = b.charCodeAt(i); } } }; var algorithm = options.algorithm || "PRIMEINC"; var rval; if (algorithm === "PRIMEINC") { rval = { algorithm, state: 0, bits, rng, eInt: e || 65537, e: new BigInteger(null), p: null, q: null, qBits: bits >> 1, pBits: bits - (bits >> 1), pqState: 0, num: null, keys: null }; rval.e.fromInt(rval.eInt); } else { throw new Error("Invalid key generation algorithm: " + algorithm); } return rval; }; /** * Attempts to runs the key-generation algorithm for at most n seconds * (approximately) using the given state. When key-generation has completed, * the keys will be stored in state.keys. * * To use this function to update a UI while generating a key or to prevent * causing browser lockups/warnings, set "n" to a value other than 0. A * simple pattern for generating a key and showing a progress indicator is: * * var state = pki.rsa.createKeyPairGenerationState(2048); * var step = function() { * // step key-generation, run algorithm for 100 ms, repeat * if(!forge.pki.rsa.stepKeyPairGenerationState(state, 100)) { * setTimeout(step, 1); * } else { * // key-generation complete * // TODO: turn off progress indicator here * // TODO: use the generated key-pair in "state.keys" * } * }; * // TODO: turn on progress indicator here * setTimeout(step, 0); * * @param state the state to use. * @param n the maximum number of milliseconds to run the algorithm for, 0 * to run the algorithm to completion. * * @return true if the key-generation completed, false if not. */ pki.rsa.stepKeyPairGenerationState = function(state, n) { if (!("algorithm" in state)) { state.algorithm = "PRIMEINC"; } var THIRTY = new BigInteger(null); THIRTY.fromInt(30); var deltaIdx = 0; var op_or = function(x, y) { return x | y; }; var t1 = +new Date(); var t2; var total = 0; while (state.keys === null && (n <= 0 || total < n)) { if (state.state === 0) { var bits = state.p === null ? state.pBits : state.qBits; var bits1 = bits - 1; if (state.pqState === 0) { state.num = new BigInteger(bits, state.rng); if (!state.num.testBit(bits1)) { state.num.bitwiseTo(BigInteger.ONE.shiftLeft(bits1), op_or, state.num); } state.num.dAddOffset(31 - state.num.mod(THIRTY).byteValue(), 0); deltaIdx = 0; ++state.pqState; } else if (state.pqState === 1) { if (state.num.bitLength() > bits) { state.pqState = 0; } else if (state.num.isProbablePrime(_getMillerRabinTests(state.num.bitLength()))) { ++state.pqState; } else { state.num.dAddOffset(GCD_30_DELTA[deltaIdx++ % 8], 0); } } else if (state.pqState === 2) { state.pqState = state.num.subtract(BigInteger.ONE).gcd(state.e).compareTo(BigInteger.ONE) === 0 ? 3 : 0; } else if (state.pqState === 3) { state.pqState = 0; if (state.p === null) { state.p = state.num; } else { state.q = state.num; } if (state.p !== null && state.q !== null) { ++state.state; } state.num = null; } } else if (state.state === 1) { if (state.p.compareTo(state.q) < 0) { state.num = state.p; state.p = state.q; state.q = state.num; } ++state.state; } else if (state.state === 2) { state.p1 = state.p.subtract(BigInteger.ONE); state.q1 = state.q.subtract(BigInteger.ONE); state.phi = state.p1.multiply(state.q1); ++state.state; } else if (state.state === 3) { if (state.phi.gcd(state.e).compareTo(BigInteger.ONE) === 0) { ++state.state; } else { state.p = null; state.q = null; state.state = 0; } } else if (state.state === 4) { state.n = state.p.multiply(state.q); if (state.n.bitLength() === state.bits) { ++state.state; } else { state.q = null; state.state = 0; } } else if (state.state === 5) { var d = state.e.modInverse(state.phi); state.keys = { privateKey: pki.rsa.setPrivateKey(state.n, state.e, d, state.p, state.q, d.mod(state.p1), d.mod(state.q1), state.q.modInverse(state.p)), publicKey: pki.rsa.setPublicKey(state.n, state.e) }; } t2 = +new Date(); total += t2 - t1; t1 = t2; } return state.keys !== null; }; /** * Generates an RSA public-private key pair in a single call. * * To generate a key-pair in steps (to allow for progress updates and to * prevent blocking or warnings in slow browsers) then use the key-pair * generation state functions. * * To generate a key-pair asynchronously (either through web-workers, if * available, or by breaking up the work on the main thread), pass a * callback function. * * @param [bits] the size for the private key in bits, defaults to 2048. * @param [e] the public exponent to use, defaults to 65537. * @param [options] options for key-pair generation, if given then 'bits' * and 'e' must *not* be given: * bits the size for the private key in bits, (default: 2048). * e the public exponent to use, (default: 65537 (0x10001)). * workerScript the worker script URL. * workers the number of web workers (if supported) to use, * (default: 2). * workLoad the size of the work load, ie: number of possible prime * numbers for each web worker to check per work assignment, * (default: 100). * prng a custom crypto-secure pseudo-random number generator to use, * that must define "getBytesSync". Disables use of native APIs. * algorithm the algorithm to use (default: 'PRIMEINC'). * @param [callback(err, keypair)] called once the operation completes. * * @return an object with privateKey and publicKey properties. */ pki.rsa.generateKeyPair = function(bits, e, options, callback) { if (arguments.length === 1) { if (typeof bits === "object") { options = bits; bits = undefined; } else if (typeof bits === "function") { callback = bits; bits = undefined; } } else if (arguments.length === 2) { if (typeof bits === "number") { if (typeof e === "function") { callback = e; e = undefined; } else if (typeof e !== "number") { options = e; e = undefined; } } else { options = bits; callback = e; bits = undefined; e = undefined; } } else if (arguments.length === 3) { if (typeof e === "number") { if (typeof options === "function") { callback = options; options = undefined; } } else { callback = options; options = e; e = undefined; } } options = options || {}; if (bits === undefined) { bits = options.bits || 2048; } if (e === undefined) { e = options.e || 65537; } if (!forge.options.usePureJavaScript && !options.prng && bits >= 256 && bits <= 16384 && (e === 65537 || e === 3)) { if (callback) { if (_detectNodeCrypto("generateKeyPair")) { return _crypto.generateKeyPair("rsa", { modulusLength: bits, publicExponent: e, publicKeyEncoding: { type: "spki", format: "pem" }, privateKeyEncoding: { type: "pkcs8", format: "pem" } }, function(err, pub, priv) { if (err) { return callback(err); } callback(null, { privateKey: pki.privateKeyFromPem(priv), publicKey: pki.publicKeyFromPem(pub) }); }); } if (_detectSubtleCrypto("generateKey") && _detectSubtleCrypto("exportKey")) { return util.globalScope.crypto.subtle.generateKey({ name: "RSASSA-PKCS1-v1_5", modulusLength: bits, publicExponent: _intToUint8Array(e), hash: { name: "SHA-256" } }, true, ["sign", "verify"]).then(function(pair) { return util.globalScope.crypto.subtle.exportKey("pkcs8", pair.privateKey); }).then(undefined, function(err) { callback(err); }).then(function(pkcs8) { if (pkcs8) { var privateKey = pki.privateKeyFromAsn1(asn1.fromDer(forge.util.createBuffer(pkcs8))); callback(null, { privateKey, publicKey: pki.setRsaPublicKey(privateKey.n, privateKey.e) }); } }); } if (_detectSubtleMsCrypto("generateKey") && _detectSubtleMsCrypto("exportKey")) { var genOp = util.globalScope.msCrypto.subtle.generateKey({ name: "RSASSA-PKCS1-v1_5", modulusLength: bits, publicExponent: _intToUint8Array(e), hash: { name: "SHA-256" } }, true, ["sign", "verify"]); genOp.oncomplete = function(e) { var pair = e.target.result; var exportOp = util.globalScope.msCrypto.subtle.exportKey("pkcs8", pair.privateKey); exportOp.oncomplete = function(e) { var pkcs8 = e.target.result; var privateKey = pki.privateKeyFromAsn1(asn1.fromDer(forge.util.createBuffer(pkcs8))); callback(null, { privateKey, publicKey: pki.setRsaPublicKey(privateKey.n, privateKey.e) }); }; exportOp.onerror = function(err) { callback(err); }; }; genOp.onerror = function(err) { callback(err); }; return; } } else { if (_detectNodeCrypto("generateKeyPairSync")) { var keypair = _crypto.generateKeyPairSync("rsa", { modulusLength: bits, publicExponent: e, publicKeyEncoding: { type: "spki", format: "pem" }, privateKeyEncoding: { type: "pkcs8", format: "pem" } }); return { privateKey: pki.privateKeyFromPem(keypair.privateKey), publicKey: pki.publicKeyFromPem(keypair.publicKey) }; } } } var state = pki.rsa.createKeyPairGenerationState(bits, e, options); if (!callback) { pki.rsa.stepKeyPairGenerationState(state, 0); return state.keys; } _generateKeyPair(state, options, callback); }; /** * Sets an RSA public key from BigIntegers modulus and exponent. * * @param n the modulus. * @param e the exponent. * * @return the public key. */ pki.setRsaPublicKey = pki.rsa.setPublicKey = function(n, e) { var key = { n, e }; /** * Encrypts the given data with this public key. Newer applications * should use the 'RSA-OAEP' decryption scheme, 'RSAES-PKCS1-V1_5' is for * legacy applications. * * @param data the byte string to encrypt. * @param scheme the encryption scheme to use: * 'RSAES-PKCS1-V1_5' (default), * 'RSA-OAEP', * 'RAW', 'NONE', or null to perform raw RSA encryption, * an object with an 'encode' property set to a function * with the signature 'function(data, key)' that returns * a binary-encoded string representing the encoded data. * @param schemeOptions any scheme-specific options. * * @return the encrypted byte string. */ key.encrypt = function(data, scheme, schemeOptions) { if (typeof scheme === "string") { scheme = scheme.toUpperCase(); } else if (scheme === undefined) { scheme = "RSAES-PKCS1-V1_5"; } if (scheme === "RSAES-PKCS1-V1_5") { scheme = { encode: function(m, key, pub) { return _encodePkcs1_v1_5(m, key, 2).getBytes(); } }; } else if (scheme === "RSA-OAEP" || scheme === "RSAES-OAEP") { scheme = { encode: function(m, key) { return forge.pkcs1.encode_rsa_oaep(key, m, schemeOptions); } }; } else if ([ "RAW", "NONE", "NULL", null ].indexOf(scheme) !== -1) { scheme = { encode: function(e) { return e; } }; } else if (typeof scheme === "string") { throw new Error("Unsupported encryption scheme: \"" + scheme + "\"."); } var e = scheme.encode(data, key, true); return pki.rsa.encrypt(e, key, true); }; /** * Verifies the given signature against the given digest. * * PKCS#1 supports multiple (currently two) signature schemes: * RSASSA-PKCS1-V1_5 and RSASSA-PSS. * * By default this implementation uses the "old scheme", i.e. * RSASSA-PKCS1-V1_5, in which case once RSA-decrypted, the * signature is an OCTET STRING that holds a DigestInfo. * * DigestInfo ::= SEQUENCE { * digestAlgorithm DigestAlgorithmIdentifier, * digest Digest * } * DigestAlgorithmIdentifier ::= AlgorithmIdentifier * Digest ::= OCTET STRING * * To perform PSS signature verification, provide an instance * of Forge PSS object as the scheme parameter. * * @param digest the message digest hash to compare against the signature, * as a binary-encoded string. * @param signature the signature to verify, as a binary-encoded string. * @param scheme signature verification scheme to use: * 'RSASSA-PKCS1-V1_5' or undefined for RSASSA PKCS#1 v1.5, * a Forge PSS object for RSASSA-PSS, * 'NONE' or null for none, DigestInfo will not be expected, but * PKCS#1 v1.5 padding will still be used. * @param options optional verify options * _parseAllDigestBytes testing flag to control parsing of all * digest bytes. Unsupported and not for general usage. * (default: true) * * @return true if the signature was verified, false if not. */ key.verify = function(digest, signature, scheme, options) { if (typeof scheme === "string") { scheme = scheme.toUpperCase(); } else if (scheme === undefined) { scheme = "RSASSA-PKCS1-V1_5"; } if (options === undefined) { options = { _parseAllDigestBytes: true }; } if (!("_parseAllDigestBytes" in options)) { options._parseAllDigestBytes = true; } if (scheme === "RSASSA-PKCS1-V1_5") { scheme = { verify: function(digest, d) { d = _decodePkcs1_v1_5(d, key, true); var obj = asn1.fromDer(d, { parseAllBytes: options._parseAllDigestBytes }); var capture = {}; var errors = []; if (!asn1.validate(obj, digestInfoValidator, capture, errors)) { var error = new Error("ASN.1 object does not contain a valid RSASSA-PKCS1-v1_5 " + "DigestInfo value."); error.errors = errors; throw error; } var oid = asn1.derToOid(capture.algorithmIdentifier); if (!(oid === forge.oids.md2 || oid === forge.oids.md5 || oid === forge.oids.sha1 || oid === forge.oids.sha224 || oid === forge.oids.sha256 || oid === forge.oids.sha384 || oid === forge.oids.sha512 || oid === forge.oids["sha512-224"] || oid === forge.oids["sha512-256"])) { var error = new Error("Unknown RSASSA-PKCS1-v1_5 DigestAlgorithm identifier."); error.oid = oid; throw error; } if (oid === forge.oids.md2 || oid === forge.oids.md5) { if (!("parameters" in capture)) { throw new Error("ASN.1 object does not contain a valid RSASSA-PKCS1-v1_5 " + "DigestInfo value. " + "Missing algorithm identifer NULL parameters."); } } return digest === capture.digest; } }; } else if (scheme === "NONE" || scheme === "NULL" || scheme === null) { scheme = { verify: function(digest, d) { d = _decodePkcs1_v1_5(d, key, true); return digest === d; } }; } var d = pki.rsa.decrypt(signature, key, true, false); return scheme.verify(digest, d, key.n.bitLength()); }; return key; }; /** * Sets an RSA private key from BigIntegers modulus, exponent, primes, * prime exponents, and modular multiplicative inverse. * * @param n the modulus. * @param e the public exponent. * @param d the private exponent ((inverse of e) mod n). * @param p the first prime. * @param q the second prime. * @param dP exponent1 (d mod (p-1)). * @param dQ exponent2 (d mod (q-1)). * @param qInv ((inverse of q) mod p) * * @return the private key. */ pki.setRsaPrivateKey = pki.rsa.setPrivateKey = function(n, e, d, p, q, dP, dQ, qInv) { var key = { n, e, d, p, q, dP, dQ, qInv }; /** * Decrypts the given data with this private key. The decryption scheme * must match the one used to encrypt the data. * * @param data the byte string to decrypt. * @param scheme the decryption scheme to use: * 'RSAES-PKCS1-V1_5' (default), * 'RSA-OAEP', * 'RAW', 'NONE', or null to perform raw RSA decryption. * @param schemeOptions any scheme-specific options. * * @return the decrypted byte string. */ key.decrypt = function(data, scheme, schemeOptions) { if (typeof scheme === "string") { scheme = scheme.toUpperCase(); } else if (scheme === undefined) { scheme = "RSAES-PKCS1-V1_5"; } var d = pki.rsa.decrypt(data, key, false, false); if (scheme === "RSAES-PKCS1-V1_5") { scheme = { decode: _decodePkcs1_v1_5 }; } else if (scheme === "RSA-OAEP" || scheme === "RSAES-OAEP") { scheme = { decode: function(d, key) { return forge.pkcs1.decode_rsa_oaep(key, d, schemeOptions); } }; } else if ([ "RAW", "NONE", "NULL", null ].indexOf(scheme) !== -1) { scheme = { decode: function(d) { return d; } }; } else { throw new Error("Unsupported encryption scheme: \"" + scheme + "\"."); } return scheme.decode(d, key, false); }; /** * Signs the given digest, producing a signature. * * PKCS#1 supports multiple (currently two) signature schemes: * RSASSA-PKCS1-V1_5 and RSASSA-PSS. * * By default this implementation uses the "old scheme", i.e. * RSASSA-PKCS1-V1_5. In order to generate a PSS signature, provide * an instance of Forge PSS object as the scheme parameter. * * @param md the message digest object with the hash to sign. * @param scheme the signature scheme to use: * 'RSASSA-PKCS1-V1_5' or undefined for RSASSA PKCS#1 v1.5, * a Forge PSS object for RSASSA-PSS, * 'NONE' or null for none, DigestInfo will not be used but * PKCS#1 v1.5 padding will still be used. * * @return the signature as a byte string. */ key.sign = function(md, scheme) { var bt = false; if (typeof scheme === "string") { scheme = scheme.toUpperCase(); } if (scheme === undefined || scheme === "RSASSA-PKCS1-V1_5") { scheme = { encode: emsaPkcs1v15encode }; bt = 1; } else if (scheme === "NONE" || scheme === "NULL" || scheme === null) { scheme = { encode: function() { return md; } }; bt = 1; } var d = scheme.encode(md, key.n.bitLength()); return pki.rsa.encrypt(d, key, bt); }; return key; }; /** * Wraps an RSAPrivateKey ASN.1 object in an ASN.1 PrivateKeyInfo object. * * @param rsaKey the ASN.1 RSAPrivateKey. * * @return the ASN.1 PrivateKeyInfo. */ pki.wrapRsaPrivateKey = function(rsaKey) { return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, asn1.integerToDer(0).getBytes()), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(pki.oids.rsaEncryption).getBytes()), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, "")]), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, asn1.toDer(rsaKey).getBytes()) ]); }; /** * Converts a private key from an ASN.1 object. * * @param obj the ASN.1 representation of a PrivateKeyInfo containing an * RSAPrivateKey or an RSAPrivateKey. * * @return the private key. */ pki.privateKeyFromAsn1 = function(obj) { var capture = {}; var errors = []; if (asn1.validate(obj, privateKeyValidator, capture, errors)) { obj = asn1.fromDer(forge.util.createBuffer(capture.privateKey)); } capture = {}; errors = []; if (!asn1.validate(obj, rsaPrivateKeyValidator, capture, errors)) { var error = new Error("Cannot read private key. " + "ASN.1 object does not contain an RSAPrivateKey."); error.errors = errors; throw error; } var n, e, d, p, q, dP, dQ, qInv; n = forge.util.createBuffer(capture.privateKeyModulus).toHex(); e = forge.util.createBuffer(capture.privateKeyPublicExponent).toHex(); d = forge.util.createBuffer(capture.privateKeyPrivateExponent).toHex(); p = forge.util.createBuffer(capture.privateKeyPrime1).toHex(); q = forge.util.createBuffer(capture.privateKeyPrime2).toHex(); dP = forge.util.createBuffer(capture.privateKeyExponent1).toHex(); dQ = forge.util.createBuffer(capture.privateKeyExponent2).toHex(); qInv = forge.util.createBuffer(capture.privateKeyCoefficient).toHex(); return pki.setRsaPrivateKey(new BigInteger(n, 16), new BigInteger(e, 16), new BigInteger(d, 16), new BigInteger(p, 16), new BigInteger(q, 16), new BigInteger(dP, 16), new BigInteger(dQ, 16), new BigInteger(qInv, 16)); }; /** * Converts a private key to an ASN.1 RSAPrivateKey. * * @param key the private key. * * @return the ASN.1 representation of an RSAPrivateKey. */ pki.privateKeyToAsn1 = pki.privateKeyToRSAPrivateKey = function(key) { return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, asn1.integerToDer(0).getBytes()), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, _bnToBytes(key.n)), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, _bnToBytes(key.e)), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, _bnToBytes(key.d)), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, _bnToBytes(key.p)), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, _bnToBytes(key.q)), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, _bnToBytes(key.dP)), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, _bnToBytes(key.dQ)), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, _bnToBytes(key.qInv)) ]); }; /** * Converts a public key from an ASN.1 SubjectPublicKeyInfo or RSAPublicKey. * * @param obj the asn1 representation of a SubjectPublicKeyInfo or RSAPublicKey. * * @return the public key. */ pki.publicKeyFromAsn1 = function(obj) { var capture = {}; var errors = []; if (asn1.validate(obj, publicKeyValidator, capture, errors)) { var oid = asn1.derToOid(capture.publicKeyOid); if (oid !== pki.oids.rsaEncryption) { var error = new Error("Cannot read public key. Unknown OID."); error.oid = oid; throw error; } obj = capture.rsaPublicKey; } errors = []; if (!asn1.validate(obj, rsaPublicKeyValidator, capture, errors)) { var error = new Error("Cannot read public key. " + "ASN.1 object does not contain an RSAPublicKey."); error.errors = errors; throw error; } var n = forge.util.createBuffer(capture.publicKeyModulus).toHex(); var e = forge.util.createBuffer(capture.publicKeyExponent).toHex(); return pki.setRsaPublicKey(new BigInteger(n, 16), new BigInteger(e, 16)); }; /** * Converts a public key to an ASN.1 SubjectPublicKeyInfo. * * @param key the public key. * * @return the asn1 representation of a SubjectPublicKeyInfo. */ pki.publicKeyToAsn1 = pki.publicKeyToSubjectPublicKeyInfo = function(key) { return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(pki.oids.rsaEncryption).getBytes()), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, "")]), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false, [pki.publicKeyToRSAPublicKey(key)])]); }; /** * Converts a public key to an ASN.1 RSAPublicKey. * * @param key the public key. * * @return the asn1 representation of a RSAPublicKey. */ pki.publicKeyToRSAPublicKey = function(key) { return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, _bnToBytes(key.n)), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, _bnToBytes(key.e))]); }; /** * Encodes a message using PKCS#1 v1.5 padding. * * @param m the message to encode. * @param key the RSA key to use. * @param bt the block type to use, i.e. either 0x01 (for signing) or 0x02 * (for encryption). * * @return the padded byte buffer. */ function _encodePkcs1_v1_5(m, key, bt) { var eb = forge.util.createBuffer(); var k = Math.ceil(key.n.bitLength() / 8); if (m.length > k - 11) { var error = new Error("Message is too long for PKCS#1 v1.5 padding."); error.length = m.length; error.max = k - 11; throw error; } eb.putByte(0); eb.putByte(bt); var padNum = k - 3 - m.length; var padByte; if (bt === 0 || bt === 1) { padByte = bt === 0 ? 0 : 255; for (var i = 0; i < padNum; ++i) { eb.putByte(padByte); } } else { while (padNum > 0) { var numZeros = 0; var padBytes = forge.random.getBytes(padNum); for (var i = 0; i < padNum; ++i) { padByte = padBytes.charCodeAt(i); if (padByte === 0) { ++numZeros; } else { eb.putByte(padByte); } } padNum = numZeros; } } eb.putByte(0); eb.putBytes(m); return eb; } /** * Decodes a message using PKCS#1 v1.5 padding. * * @param em the message to decode. * @param key the RSA key to use. * @param pub true if the key is a public key, false if it is private. * @param ml the message length, if specified. * * @return the decoded bytes. */ function _decodePkcs1_v1_5(em, key, pub, ml) { var k = Math.ceil(key.n.bitLength() / 8); var eb = forge.util.createBuffer(em); var first = eb.getByte(); var bt = eb.getByte(); if (first !== 0 || pub && bt !== 0 && bt !== 1 || !pub && bt != 2 || pub && bt === 0 && typeof ml === "undefined") { throw new Error("Encryption block is invalid."); } var padNum = 0; if (bt === 0) { padNum = k - 3 - ml; for (var i = 0; i < padNum; ++i) { if (eb.getByte() !== 0) { throw new Error("Encryption block is invalid."); } } } else if (bt === 1) { padNum = 0; while (eb.length() > 1) { if (eb.getByte() !== 255) { --eb.read; break; } ++padNum; } } else if (bt === 2) { padNum = 0; while (eb.length() > 1) { if (eb.getByte() === 0) { --eb.read; break; } ++padNum; } } var zero = eb.getByte(); if (zero !== 0 || padNum !== k - 3 - eb.length()) { throw new Error("Encryption block is invalid."); } return eb.getBytes(); } /** * Runs the key-generation algorithm asynchronously, either in the background * via Web Workers, or using the main thread and setImmediate. * * @param state the key-pair generation state. * @param [options] options for key-pair generation: * workerScript the worker script URL. * workers the number of web workers (if supported) to use, * (default: 2, -1 to use estimated cores minus one). * workLoad the size of the work load, ie: number of possible prime * numbers for each web worker to check per work assignment, * (default: 100). * @param callback(err, keypair) called once the operation completes. */ function _generateKeyPair(state, options, callback) { if (typeof options === "function") { callback = options; options = {}; } options = options || {}; var opts = { algorithm: { name: options.algorithm || "PRIMEINC", options: { workers: options.workers || 2, workLoad: options.workLoad || 100, workerScript: options.workerScript } } }; if ("prng" in options) { opts.prng = options.prng; } generate(); function generate() { getPrime(state.pBits, function(err, num) { if (err) { return callback(err); } state.p = num; if (state.q !== null) { return finish(err, state.q); } getPrime(state.qBits, finish); }); } function getPrime(bits, callback) { forge.prime.generateProbablePrime(bits, opts, callback); } function finish(err, num) { if (err) { return callback(err); } state.q = num; if (state.p.compareTo(state.q) < 0) { var tmp = state.p; state.p = state.q; state.q = tmp; } if (state.p.subtract(BigInteger.ONE).gcd(state.e).compareTo(BigInteger.ONE) !== 0) { state.p = null; generate(); return; } if (state.q.subtract(BigInteger.ONE).gcd(state.e).compareTo(BigInteger.ONE) !== 0) { state.q = null; getPrime(state.qBits, finish); return; } state.p1 = state.p.subtract(BigInteger.ONE); state.q1 = state.q.subtract(BigInteger.ONE); state.phi = state.p1.multiply(state.q1); if (state.phi.gcd(state.e).compareTo(BigInteger.ONE) !== 0) { state.p = state.q = null; generate(); return; } state.n = state.p.multiply(state.q); if (state.n.bitLength() !== state.bits) { state.q = null; getPrime(state.qBits, finish); return; } var d = state.e.modInverse(state.phi); state.keys = { privateKey: pki.rsa.setPrivateKey(state.n, state.e, d, state.p, state.q, d.mod(state.p1), d.mod(state.q1), state.q.modInverse(state.p)), publicKey: pki.rsa.setPublicKey(state.n, state.e) }; callback(null, state.keys); } } /** * Converts a positive BigInteger into 2's-complement big-endian bytes. * * @param b the big integer to convert. * * @return the bytes. */ function _bnToBytes(b) { var hex = b.toString(16); if (hex[0] >= "8") { hex = "00" + hex; } var bytes = forge.util.hexToBytes(hex); if (bytes.length > 1 && (bytes.charCodeAt(0) === 0 && (bytes.charCodeAt(1) & 128) === 0 || bytes.charCodeAt(0) === 255 && (bytes.charCodeAt(1) & 128) === 128)) { return bytes.substr(1); } return bytes; } /** * Returns the required number of Miller-Rabin tests to generate a * prime with an error probability of (1/2)^80. * * See Handbook of Applied Cryptography Chapter 4, Table 4.4. * * @param bits the bit size. * * @return the required number of iterations. */ function _getMillerRabinTests(bits) { if (bits <= 100) return 27; if (bits <= 150) return 18; if (bits <= 200) return 15; if (bits <= 250) return 12; if (bits <= 300) return 9; if (bits <= 350) return 8; if (bits <= 400) return 7; if (bits <= 500) return 6; if (bits <= 600) return 5; if (bits <= 800) return 4; if (bits <= 1250) return 3; return 2; } /** * Performs feature detection on the Node crypto interface. * * @param fn the feature (function) to detect. * * @return true if detected, false if not. */ function _detectNodeCrypto(fn) { return forge.util.isNodejs && typeof _crypto[fn] === "function"; } /** * Performs feature detection on the SubtleCrypto interface. * * @param fn the feature (function) to detect. * * @return true if detected, false if not. */ function _detectSubtleCrypto(fn) { return typeof util.globalScope !== "undefined" && typeof util.globalScope.crypto === "object" && typeof util.globalScope.crypto.subtle === "object" && typeof util.globalScope.crypto.subtle[fn] === "function"; } /** * Performs feature detection on the deprecated Microsoft Internet Explorer * outdated SubtleCrypto interface. This function should only be used after * checking for the modern, standard SubtleCrypto interface. * * @param fn the feature (function) to detect. * * @return true if detected, false if not. */ function _detectSubtleMsCrypto(fn) { return typeof util.globalScope !== "undefined" && typeof util.globalScope.msCrypto === "object" && typeof util.globalScope.msCrypto.subtle === "object" && typeof util.globalScope.msCrypto.subtle[fn] === "function"; } function _intToUint8Array(x) { var bytes = forge.util.hexToBytes(x.toString(16)); var buffer = new Uint8Array(bytes.length); for (var i = 0; i < bytes.length; ++i) { buffer[i] = bytes.charCodeAt(i); } return buffer; } function _privateKeyFromJwk(jwk) { if (jwk.kty !== "RSA") { throw new Error("Unsupported key algorithm \"" + jwk.kty + "\"; algorithm must be \"RSA\"."); } return pki.setRsaPrivateKey(_base64ToBigInt(jwk.n), _base64ToBigInt(jwk.e), _base64ToBigInt(jwk.d), _base64ToBigInt(jwk.p), _base64ToBigInt(jwk.q), _base64ToBigInt(jwk.dp), _base64ToBigInt(jwk.dq), _base64ToBigInt(jwk.qi)); } function _publicKeyFromJwk(jwk) { if (jwk.kty !== "RSA") { throw new Error("Key algorithm must be \"RSA\"."); } return pki.setRsaPublicKey(_base64ToBigInt(jwk.n), _base64ToBigInt(jwk.e)); } function _base64ToBigInt(b64) { return new BigInteger(forge.util.bytesToHex(forge.util.decode64(b64)), 16); } })); //#endregion //#region ../node_modules/node-forge/lib/pbe.js var require_pbe = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Password-based encryption functions. * * @author Dave Longley * @author Stefan Siegl * * Copyright (c) 2010-2013 Digital Bazaar, Inc. * Copyright (c) 2012 Stefan Siegl * * An EncryptedPrivateKeyInfo: * * EncryptedPrivateKeyInfo ::= SEQUENCE { * encryptionAlgorithm EncryptionAlgorithmIdentifier, * encryptedData EncryptedData } * * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier * * EncryptedData ::= OCTET STRING */ var forge = require_forge(); require_aes$1(); require_asn1(); require_des(); require_md(); require_oids(); require_pbkdf2$1(); require_pem(); require_random(); require_rc2(); require_rsa(); require_util$8(); if (typeof BigInteger === "undefined") { var BigInteger = forge.jsbn.BigInteger; } var asn1 = forge.asn1; var pki = forge.pki = forge.pki || {}; module.exports = pki.pbe = forge.pbe = forge.pbe || {}; var oids = pki.oids; var encryptedPrivateKeyValidator = { name: "EncryptedPrivateKeyInfo", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "EncryptedPrivateKeyInfo.encryptionAlgorithm", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "AlgorithmIdentifier.algorithm", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OID, constructed: false, capture: "encryptionOid" }, { name: "AlgorithmIdentifier.parameters", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, captureAsn1: "encryptionParams" }] }, { name: "EncryptedPrivateKeyInfo.encryptedData", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OCTETSTRING, constructed: false, capture: "encryptedData" }] }; var PBES2AlgorithmsValidator = { name: "PBES2Algorithms", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "PBES2Algorithms.keyDerivationFunc", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "PBES2Algorithms.keyDerivationFunc.oid", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OID, constructed: false, capture: "kdfOid" }, { name: "PBES2Algorithms.params", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [ { name: "PBES2Algorithms.params.salt", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OCTETSTRING, constructed: false, capture: "kdfSalt" }, { name: "PBES2Algorithms.params.iterationCount", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.INTEGER, constructed: false, capture: "kdfIterationCount" }, { name: "PBES2Algorithms.params.keyLength", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.INTEGER, constructed: false, optional: true, capture: "keyLength" }, { name: "PBES2Algorithms.params.prf", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, optional: true, value: [{ name: "PBES2Algorithms.params.prf.algorithm", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OID, constructed: false, capture: "prfOid" }] } ] }] }, { name: "PBES2Algorithms.encryptionScheme", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "PBES2Algorithms.encryptionScheme.oid", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OID, constructed: false, capture: "encOid" }, { name: "PBES2Algorithms.encryptionScheme.iv", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OCTETSTRING, constructed: false, capture: "encIv" }] }] }; var pkcs12PbeParamsValidator = { name: "pkcs-12PbeParams", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "pkcs-12PbeParams.salt", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OCTETSTRING, constructed: false, capture: "salt" }, { name: "pkcs-12PbeParams.iterations", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.INTEGER, constructed: false, capture: "iterations" }] }; /** * Encrypts a ASN.1 PrivateKeyInfo object, producing an EncryptedPrivateKeyInfo. * * PBES2Algorithms ALGORITHM-IDENTIFIER ::= * { {PBES2-params IDENTIFIED BY id-PBES2}, ...} * * id-PBES2 OBJECT IDENTIFIER ::= {pkcs-5 13} * * PBES2-params ::= SEQUENCE { * keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}}, * encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} * } * * PBES2-KDFs ALGORITHM-IDENTIFIER ::= * { {PBKDF2-params IDENTIFIED BY id-PBKDF2}, ... } * * PBES2-Encs ALGORITHM-IDENTIFIER ::= { ... } * * PBKDF2-params ::= SEQUENCE { * salt CHOICE { * specified OCTET STRING, * otherSource AlgorithmIdentifier {{PBKDF2-SaltSources}} * }, * iterationCount INTEGER (1..MAX), * keyLength INTEGER (1..MAX) OPTIONAL, * prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1 * } * * @param obj the ASN.1 PrivateKeyInfo object. * @param password the password to encrypt with. * @param options: * algorithm the encryption algorithm to use * ('aes128', 'aes192', 'aes256', '3des'), defaults to 'aes128'. * count the iteration count to use. * saltSize the salt size to use. * prfAlgorithm the PRF message digest algorithm to use * ('sha1', 'sha224', 'sha256', 'sha384', 'sha512') * * @return the ASN.1 EncryptedPrivateKeyInfo. */ pki.encryptPrivateKeyInfo = function(obj, password, options) { options = options || {}; options.saltSize = options.saltSize || 8; options.count = options.count || 2048; options.algorithm = options.algorithm || "aes128"; options.prfAlgorithm = options.prfAlgorithm || "sha1"; var salt = forge.random.getBytesSync(options.saltSize); var count = options.count; var countBytes = asn1.integerToDer(count); var dkLen; var encryptionAlgorithm; var encryptedData; if (options.algorithm.indexOf("aes") === 0 || options.algorithm === "des") { var ivLen, encOid, cipherFn; switch (options.algorithm) { case "aes128": dkLen = 16; ivLen = 16; encOid = oids["aes128-CBC"]; cipherFn = forge.aes.createEncryptionCipher; break; case "aes192": dkLen = 24; ivLen = 16; encOid = oids["aes192-CBC"]; cipherFn = forge.aes.createEncryptionCipher; break; case "aes256": dkLen = 32; ivLen = 16; encOid = oids["aes256-CBC"]; cipherFn = forge.aes.createEncryptionCipher; break; case "des": dkLen = 8; ivLen = 8; encOid = oids["desCBC"]; cipherFn = forge.des.createEncryptionCipher; break; default: var error = new Error("Cannot encrypt private key. Unknown encryption algorithm."); error.algorithm = options.algorithm; throw error; } var prfAlgorithm = "hmacWith" + options.prfAlgorithm.toUpperCase(); var md = prfAlgorithmToMessageDigest(prfAlgorithm); var dk = forge.pkcs5.pbkdf2(password, salt, count, dkLen, md); var iv = forge.random.getBytesSync(ivLen); var cipher = cipherFn(dk); cipher.start(iv); cipher.update(asn1.toDer(obj)); cipher.finish(); encryptedData = cipher.output.getBytes(); var params = createPbkdf2Params(salt, countBytes, dkLen, prfAlgorithm); encryptionAlgorithm = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(oids["pkcs5PBES2"]).getBytes()), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(oids["pkcs5PBKDF2"]).getBytes()), params]), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(encOid).getBytes()), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, iv)])])]); } else if (options.algorithm === "3des") { dkLen = 24; var saltBytes = new forge.util.ByteBuffer(salt); var dk = pki.pbe.generatePkcs12Key(password, saltBytes, 1, count, dkLen); var iv = pki.pbe.generatePkcs12Key(password, saltBytes, 2, count, dkLen); var cipher = forge.des.createEncryptionCipher(dk); cipher.start(iv); cipher.update(asn1.toDer(obj)); cipher.finish(); encryptedData = cipher.output.getBytes(); encryptionAlgorithm = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(oids["pbeWithSHAAnd3-KeyTripleDES-CBC"]).getBytes()), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, salt), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, countBytes.getBytes())])]); } else { var error = new Error("Cannot encrypt private key. Unknown encryption algorithm."); error.algorithm = options.algorithm; throw error; } var rval = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [encryptionAlgorithm, asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, encryptedData)]); return rval; }; /** * Decrypts a ASN.1 PrivateKeyInfo object. * * @param obj the ASN.1 EncryptedPrivateKeyInfo object. * @param password the password to decrypt with. * * @return the ASN.1 PrivateKeyInfo on success, null on failure. */ pki.decryptPrivateKeyInfo = function(obj, password) { var rval = null; var capture = {}; var errors = []; if (!asn1.validate(obj, encryptedPrivateKeyValidator, capture, errors)) { var error = new Error("Cannot read encrypted private key. " + "ASN.1 object is not a supported EncryptedPrivateKeyInfo."); error.errors = errors; throw error; } var oid = asn1.derToOid(capture.encryptionOid); var cipher = pki.pbe.getCipher(oid, capture.encryptionParams, password); var encrypted = forge.util.createBuffer(capture.encryptedData); cipher.update(encrypted); if (cipher.finish()) { rval = asn1.fromDer(cipher.output); } return rval; }; /** * Converts a EncryptedPrivateKeyInfo to PEM format. * * @param epki the EncryptedPrivateKeyInfo. * @param maxline the maximum characters per line, defaults to 64. * * @return the PEM-formatted encrypted private key. */ pki.encryptedPrivateKeyToPem = function(epki, maxline) { var msg = { type: "ENCRYPTED PRIVATE KEY", body: asn1.toDer(epki).getBytes() }; return forge.pem.encode(msg, { maxline }); }; /** * Converts a PEM-encoded EncryptedPrivateKeyInfo to ASN.1 format. Decryption * is not performed. * * @param pem the EncryptedPrivateKeyInfo in PEM-format. * * @return the ASN.1 EncryptedPrivateKeyInfo. */ pki.encryptedPrivateKeyFromPem = function(pem) { var msg = forge.pem.decode(pem)[0]; if (msg.type !== "ENCRYPTED PRIVATE KEY") { var error = new Error("Could not convert encrypted private key from PEM; " + "PEM header type is \"ENCRYPTED PRIVATE KEY\"."); error.headerType = msg.type; throw error; } if (msg.procType && msg.procType.type === "ENCRYPTED") { throw new Error("Could not convert encrypted private key from PEM; " + "PEM is encrypted."); } return asn1.fromDer(msg.body); }; /** * Encrypts an RSA private key. By default, the key will be wrapped in * a PrivateKeyInfo and encrypted to produce a PKCS#8 EncryptedPrivateKeyInfo. * This is the standard, preferred way to encrypt a private key. * * To produce a non-standard PEM-encrypted private key that uses encapsulated * headers to indicate the encryption algorithm (old-style non-PKCS#8 OpenSSL * private key encryption), set the 'legacy' option to true. Note: Using this * option will cause the iteration count to be forced to 1. * * Note: The 'des' algorithm is supported, but it is not considered to be * secure because it only uses a single 56-bit key. If possible, it is highly * recommended that a different algorithm be used. * * @param rsaKey the RSA key to encrypt. * @param password the password to use. * @param options: * algorithm: the encryption algorithm to use * ('aes128', 'aes192', 'aes256', '3des', 'des'). * count: the iteration count to use. * saltSize: the salt size to use. * legacy: output an old non-PKCS#8 PEM-encrypted+encapsulated * headers (DEK-Info) private key. * * @return the PEM-encoded ASN.1 EncryptedPrivateKeyInfo. */ pki.encryptRsaPrivateKey = function(rsaKey, password, options) { options = options || {}; if (!options.legacy) { var rval = pki.wrapRsaPrivateKey(pki.privateKeyToAsn1(rsaKey)); rval = pki.encryptPrivateKeyInfo(rval, password, options); return pki.encryptedPrivateKeyToPem(rval); } var algorithm; var iv; var dkLen; var cipherFn; switch (options.algorithm) { case "aes128": algorithm = "AES-128-CBC"; dkLen = 16; iv = forge.random.getBytesSync(16); cipherFn = forge.aes.createEncryptionCipher; break; case "aes192": algorithm = "AES-192-CBC"; dkLen = 24; iv = forge.random.getBytesSync(16); cipherFn = forge.aes.createEncryptionCipher; break; case "aes256": algorithm = "AES-256-CBC"; dkLen = 32; iv = forge.random.getBytesSync(16); cipherFn = forge.aes.createEncryptionCipher; break; case "3des": algorithm = "DES-EDE3-CBC"; dkLen = 24; iv = forge.random.getBytesSync(8); cipherFn = forge.des.createEncryptionCipher; break; case "des": algorithm = "DES-CBC"; dkLen = 8; iv = forge.random.getBytesSync(8); cipherFn = forge.des.createEncryptionCipher; break; default: var error = new Error("Could not encrypt RSA private key; unsupported " + "encryption algorithm \"" + options.algorithm + "\"."); error.algorithm = options.algorithm; throw error; } var dk = forge.pbe.opensslDeriveBytes(password, iv.substr(0, 8), dkLen); var cipher = cipherFn(dk); cipher.start(iv); cipher.update(asn1.toDer(pki.privateKeyToAsn1(rsaKey))); cipher.finish(); var msg = { type: "RSA PRIVATE KEY", procType: { version: "4", type: "ENCRYPTED" }, dekInfo: { algorithm, parameters: forge.util.bytesToHex(iv).toUpperCase() }, body: cipher.output.getBytes() }; return forge.pem.encode(msg); }; /** * Decrypts an RSA private key. * * @param pem the PEM-formatted EncryptedPrivateKeyInfo to decrypt. * @param password the password to use. * * @return the RSA key on success, null on failure. */ pki.decryptRsaPrivateKey = function(pem, password) { var rval = null; var msg = forge.pem.decode(pem)[0]; if (msg.type !== "ENCRYPTED PRIVATE KEY" && msg.type !== "PRIVATE KEY" && msg.type !== "RSA PRIVATE KEY") { var error = new Error("Could not convert private key from PEM; PEM header type " + "is not \"ENCRYPTED PRIVATE KEY\", \"PRIVATE KEY\", or \"RSA PRIVATE KEY\"."); error.headerType = error; throw error; } if (msg.procType && msg.procType.type === "ENCRYPTED") { var dkLen; var cipherFn; switch (msg.dekInfo.algorithm) { case "DES-CBC": dkLen = 8; cipherFn = forge.des.createDecryptionCipher; break; case "DES-EDE3-CBC": dkLen = 24; cipherFn = forge.des.createDecryptionCipher; break; case "AES-128-CBC": dkLen = 16; cipherFn = forge.aes.createDecryptionCipher; break; case "AES-192-CBC": dkLen = 24; cipherFn = forge.aes.createDecryptionCipher; break; case "AES-256-CBC": dkLen = 32; cipherFn = forge.aes.createDecryptionCipher; break; case "RC2-40-CBC": dkLen = 5; cipherFn = function(key) { return forge.rc2.createDecryptionCipher(key, 40); }; break; case "RC2-64-CBC": dkLen = 8; cipherFn = function(key) { return forge.rc2.createDecryptionCipher(key, 64); }; break; case "RC2-128-CBC": dkLen = 16; cipherFn = function(key) { return forge.rc2.createDecryptionCipher(key, 128); }; break; default: var error = new Error("Could not decrypt private key; unsupported " + "encryption algorithm \"" + msg.dekInfo.algorithm + "\"."); error.algorithm = msg.dekInfo.algorithm; throw error; } var iv = forge.util.hexToBytes(msg.dekInfo.parameters); var dk = forge.pbe.opensslDeriveBytes(password, iv.substr(0, 8), dkLen); var cipher = cipherFn(dk); cipher.start(iv); cipher.update(forge.util.createBuffer(msg.body)); if (cipher.finish()) { rval = cipher.output.getBytes(); } else { return rval; } } else { rval = msg.body; } if (msg.type === "ENCRYPTED PRIVATE KEY") { rval = pki.decryptPrivateKeyInfo(asn1.fromDer(rval), password); } else { rval = asn1.fromDer(rval); } if (rval !== null) { rval = pki.privateKeyFromAsn1(rval); } return rval; }; /** * Derives a PKCS#12 key. * * @param password the password to derive the key material from, null or * undefined for none. * @param salt the salt, as a ByteBuffer, to use. * @param id the PKCS#12 ID byte (1 = key material, 2 = IV, 3 = MAC). * @param iter the iteration count. * @param n the number of bytes to derive from the password. * @param md the message digest to use, defaults to SHA-1. * * @return a ByteBuffer with the bytes derived from the password. */ pki.pbe.generatePkcs12Key = function(password, salt, id, iter, n, md) { var j, l; if (typeof md === "undefined" || md === null) { if (!("sha1" in forge.md)) { throw new Error("\"sha1\" hash algorithm unavailable."); } md = forge.md.sha1.create(); } var u = md.digestLength; var v = md.blockLength; var result = new forge.util.ByteBuffer(); var passBuf = new forge.util.ByteBuffer(); if (password !== null && password !== undefined) { for (l = 0; l < password.length; l++) { passBuf.putInt16(password.charCodeAt(l)); } passBuf.putInt16(0); } var p = passBuf.length(); var s = salt.length(); var D = new forge.util.ByteBuffer(); D.fillWithByte(id, v); var Slen = v * Math.ceil(s / v); var S = new forge.util.ByteBuffer(); for (l = 0; l < Slen; l++) { S.putByte(salt.at(l % s)); } var Plen = v * Math.ceil(p / v); var P = new forge.util.ByteBuffer(); for (l = 0; l < Plen; l++) { P.putByte(passBuf.at(l % p)); } var I = S; I.putBuffer(P); var c = Math.ceil(n / u); for (var i = 1; i <= c; i++) { var buf = new forge.util.ByteBuffer(); buf.putBytes(D.bytes()); buf.putBytes(I.bytes()); for (var round = 0; round < iter; round++) { md.start(); md.update(buf.getBytes()); buf = md.digest(); } var B = new forge.util.ByteBuffer(); for (l = 0; l < v; l++) { B.putByte(buf.at(l % u)); } var k = Math.ceil(s / v) + Math.ceil(p / v); var Inew = new forge.util.ByteBuffer(); for (j = 0; j < k; j++) { var chunk = new forge.util.ByteBuffer(I.getBytes(v)); var x = 511; for (l = B.length() - 1; l >= 0; l--) { x = x >> 8; x += B.at(l) + chunk.at(l); chunk.setAt(l, x & 255); } Inew.putBuffer(chunk); } I = Inew; result.putBuffer(buf); } result.truncate(result.length() - n); return result; }; /** * Get new Forge cipher object instance. * * @param oid the OID (in string notation). * @param params the ASN.1 params object. * @param password the password to decrypt with. * * @return new cipher object instance. */ pki.pbe.getCipher = function(oid, params, password) { switch (oid) { case pki.oids["pkcs5PBES2"]: return pki.pbe.getCipherForPBES2(oid, params, password); case pki.oids["pbeWithSHAAnd3-KeyTripleDES-CBC"]: case pki.oids["pbewithSHAAnd40BitRC2-CBC"]: return pki.pbe.getCipherForPKCS12PBE(oid, params, password); default: var error = new Error("Cannot read encrypted PBE data block. Unsupported OID."); error.oid = oid; error.supportedOids = [ "pkcs5PBES2", "pbeWithSHAAnd3-KeyTripleDES-CBC", "pbewithSHAAnd40BitRC2-CBC" ]; throw error; } }; /** * Get new Forge cipher object instance according to PBES2 params block. * * The returned cipher instance is already started using the IV * from PBES2 parameter block. * * @param oid the PKCS#5 PBKDF2 OID (in string notation). * @param params the ASN.1 PBES2-params object. * @param password the password to decrypt with. * * @return new cipher object instance. */ pki.pbe.getCipherForPBES2 = function(oid, params, password) { var capture = {}; var errors = []; if (!asn1.validate(params, PBES2AlgorithmsValidator, capture, errors)) { var error = new Error("Cannot read password-based-encryption algorithm " + "parameters. ASN.1 object is not a supported EncryptedPrivateKeyInfo."); error.errors = errors; throw error; } oid = asn1.derToOid(capture.kdfOid); if (oid !== pki.oids["pkcs5PBKDF2"]) { var error = new Error("Cannot read encrypted private key. " + "Unsupported key derivation function OID."); error.oid = oid; error.supportedOids = ["pkcs5PBKDF2"]; throw error; } oid = asn1.derToOid(capture.encOid); if (oid !== pki.oids["aes128-CBC"] && oid !== pki.oids["aes192-CBC"] && oid !== pki.oids["aes256-CBC"] && oid !== pki.oids["des-EDE3-CBC"] && oid !== pki.oids["desCBC"]) { var error = new Error("Cannot read encrypted private key. " + "Unsupported encryption scheme OID."); error.oid = oid; error.supportedOids = [ "aes128-CBC", "aes192-CBC", "aes256-CBC", "des-EDE3-CBC", "desCBC" ]; throw error; } var salt = capture.kdfSalt; var count = forge.util.createBuffer(capture.kdfIterationCount); count = count.getInt(count.length() << 3); var dkLen; var cipherFn; switch (pki.oids[oid]) { case "aes128-CBC": dkLen = 16; cipherFn = forge.aes.createDecryptionCipher; break; case "aes192-CBC": dkLen = 24; cipherFn = forge.aes.createDecryptionCipher; break; case "aes256-CBC": dkLen = 32; cipherFn = forge.aes.createDecryptionCipher; break; case "des-EDE3-CBC": dkLen = 24; cipherFn = forge.des.createDecryptionCipher; break; case "desCBC": dkLen = 8; cipherFn = forge.des.createDecryptionCipher; break; } var md = prfOidToMessageDigest(capture.prfOid); var dk = forge.pkcs5.pbkdf2(password, salt, count, dkLen, md); var iv = capture.encIv; var cipher = cipherFn(dk); cipher.start(iv); return cipher; }; /** * Get new Forge cipher object instance for PKCS#12 PBE. * * The returned cipher instance is already started using the key & IV * derived from the provided password and PKCS#12 PBE salt. * * @param oid The PKCS#12 PBE OID (in string notation). * @param params The ASN.1 PKCS#12 PBE-params object. * @param password The password to decrypt with. * * @return the new cipher object instance. */ pki.pbe.getCipherForPKCS12PBE = function(oid, params, password) { var capture = {}; var errors = []; if (!asn1.validate(params, pkcs12PbeParamsValidator, capture, errors)) { var error = new Error("Cannot read password-based-encryption algorithm " + "parameters. ASN.1 object is not a supported EncryptedPrivateKeyInfo."); error.errors = errors; throw error; } var salt = forge.util.createBuffer(capture.salt); var count = forge.util.createBuffer(capture.iterations); count = count.getInt(count.length() << 3); var dkLen, dIvLen, cipherFn; switch (oid) { case pki.oids["pbeWithSHAAnd3-KeyTripleDES-CBC"]: dkLen = 24; dIvLen = 8; cipherFn = forge.des.startDecrypting; break; case pki.oids["pbewithSHAAnd40BitRC2-CBC"]: dkLen = 5; dIvLen = 8; cipherFn = function(key, iv) { var cipher = forge.rc2.createDecryptionCipher(key, 40); cipher.start(iv, null); return cipher; }; break; default: var error = new Error("Cannot read PKCS #12 PBE data block. Unsupported OID."); error.oid = oid; throw error; } var md = prfOidToMessageDigest(capture.prfOid); var key = pki.pbe.generatePkcs12Key(password, salt, 1, count, dkLen, md); md.start(); var iv = pki.pbe.generatePkcs12Key(password, salt, 2, count, dIvLen, md); return cipherFn(key, iv); }; /** * OpenSSL's legacy key derivation function. * * See: http://www.openssl.org/docs/crypto/EVP_BytesToKey.html * * @param password the password to derive the key from. * @param salt the salt to use, null for none. * @param dkLen the number of bytes needed for the derived key. * @param [options] the options to use: * [md] an optional message digest object to use. */ pki.pbe.opensslDeriveBytes = function(password, salt, dkLen, md) { if (typeof md === "undefined" || md === null) { if (!("md5" in forge.md)) { throw new Error("\"md5\" hash algorithm unavailable."); } md = forge.md.md5.create(); } if (salt === null) { salt = ""; } var digests = [hash(md, password + salt)]; for (var length = 16, i = 1; length < dkLen; ++i, length += 16) { digests.push(hash(md, digests[i - 1] + password + salt)); } return digests.join("").substr(0, dkLen); }; function hash(md, bytes) { return md.start().update(bytes).digest().getBytes(); } function prfOidToMessageDigest(prfOid) { var prfAlgorithm; if (!prfOid) { prfAlgorithm = "hmacWithSHA1"; } else { prfAlgorithm = pki.oids[asn1.derToOid(prfOid)]; if (!prfAlgorithm) { var error = new Error("Unsupported PRF OID."); error.oid = prfOid; error.supported = [ "hmacWithSHA1", "hmacWithSHA224", "hmacWithSHA256", "hmacWithSHA384", "hmacWithSHA512" ]; throw error; } } return prfAlgorithmToMessageDigest(prfAlgorithm); } function prfAlgorithmToMessageDigest(prfAlgorithm) { var factory = forge.md; switch (prfAlgorithm) { case "hmacWithSHA224": factory = forge.md.sha512; case "hmacWithSHA1": case "hmacWithSHA256": case "hmacWithSHA384": case "hmacWithSHA512": prfAlgorithm = prfAlgorithm.substr(8).toLowerCase(); break; default: var error = new Error("Unsupported PRF algorithm."); error.algorithm = prfAlgorithm; error.supported = [ "hmacWithSHA1", "hmacWithSHA224", "hmacWithSHA256", "hmacWithSHA384", "hmacWithSHA512" ]; throw error; } if (!factory || !(prfAlgorithm in factory)) { throw new Error("Unknown hash algorithm: " + prfAlgorithm); } return factory[prfAlgorithm].create(); } function createPbkdf2Params(salt, countBytes, dkLen, prfAlgorithm) { var params = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, salt), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, countBytes.getBytes())]); if (prfAlgorithm !== "hmacWithSHA1") { params.value.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, forge.util.hexToBytes(dkLen.toString(16))), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(pki.oids[prfAlgorithm]).getBytes()), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, "")])); } return params; } })); //#endregion //#region ../node_modules/node-forge/lib/pkcs7asn1.js var require_pkcs7asn1 = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Javascript implementation of ASN.1 validators for PKCS#7 v1.5. * * @author Dave Longley * @author Stefan Siegl * * Copyright (c) 2012-2015 Digital Bazaar, Inc. * Copyright (c) 2012 Stefan Siegl * * The ASN.1 representation of PKCS#7 is as follows * (see RFC #2315 for details, http://www.ietf.org/rfc/rfc2315.txt): * * A PKCS#7 message consists of a ContentInfo on root level, which may * contain any number of further ContentInfo nested into it. * * ContentInfo ::= SEQUENCE { * contentType ContentType, * content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL * } * * ContentType ::= OBJECT IDENTIFIER * * EnvelopedData ::= SEQUENCE { * version Version, * recipientInfos RecipientInfos, * encryptedContentInfo EncryptedContentInfo * } * * EncryptedData ::= SEQUENCE { * version Version, * encryptedContentInfo EncryptedContentInfo * } * * id-signedData OBJECT IDENTIFIER ::= { iso(1) member-body(2) * us(840) rsadsi(113549) pkcs(1) pkcs7(7) 2 } * * SignedData ::= SEQUENCE { * version INTEGER, * digestAlgorithms DigestAlgorithmIdentifiers, * contentInfo ContentInfo, * certificates [0] IMPLICIT Certificates OPTIONAL, * crls [1] IMPLICIT CertificateRevocationLists OPTIONAL, * signerInfos SignerInfos * } * * SignerInfos ::= SET OF SignerInfo * * SignerInfo ::= SEQUENCE { * version Version, * issuerAndSerialNumber IssuerAndSerialNumber, * digestAlgorithm DigestAlgorithmIdentifier, * authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL, * digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier, * encryptedDigest EncryptedDigest, * unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL * } * * EncryptedDigest ::= OCTET STRING * * Attributes ::= SET OF Attribute * * Attribute ::= SEQUENCE { * attrType OBJECT IDENTIFIER, * attrValues SET OF AttributeValue * } * * AttributeValue ::= ANY * * Version ::= INTEGER * * RecipientInfos ::= SET OF RecipientInfo * * EncryptedContentInfo ::= SEQUENCE { * contentType ContentType, * contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier, * encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL * } * * ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier * * The AlgorithmIdentifier contains an Object Identifier (OID) and parameters * for the algorithm, if any. In the case of AES and DES3, there is only one, * the IV. * * AlgorithmIdentifer ::= SEQUENCE { * algorithm OBJECT IDENTIFIER, * parameters ANY DEFINED BY algorithm OPTIONAL * } * * EncryptedContent ::= OCTET STRING * * RecipientInfo ::= SEQUENCE { * version Version, * issuerAndSerialNumber IssuerAndSerialNumber, * keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier, * encryptedKey EncryptedKey * } * * IssuerAndSerialNumber ::= SEQUENCE { * issuer Name, * serialNumber CertificateSerialNumber * } * * CertificateSerialNumber ::= INTEGER * * KeyEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier * * EncryptedKey ::= OCTET STRING */ var forge = require_forge(); require_asn1(); require_util$8(); var asn1 = forge.asn1; var p7v = module.exports = forge.pkcs7asn1 = forge.pkcs7asn1 || {}; forge.pkcs7 = forge.pkcs7 || {}; forge.pkcs7.asn1 = p7v; var contentInfoValidator = { name: "ContentInfo", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "ContentInfo.ContentType", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OID, constructed: false, capture: "contentType" }, { name: "ContentInfo.content", tagClass: asn1.Class.CONTEXT_SPECIFIC, type: 0, constructed: true, optional: true, captureAsn1: "content" }] }; p7v.contentInfoValidator = contentInfoValidator; var encryptedContentInfoValidator = { name: "EncryptedContentInfo", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [ { name: "EncryptedContentInfo.contentType", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OID, constructed: false, capture: "contentType" }, { name: "EncryptedContentInfo.contentEncryptionAlgorithm", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "EncryptedContentInfo.contentEncryptionAlgorithm.algorithm", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OID, constructed: false, capture: "encAlgorithm" }, { name: "EncryptedContentInfo.contentEncryptionAlgorithm.parameter", tagClass: asn1.Class.UNIVERSAL, captureAsn1: "encParameter" }] }, { name: "EncryptedContentInfo.encryptedContent", tagClass: asn1.Class.CONTEXT_SPECIFIC, type: 0, capture: "encryptedContent", captureAsn1: "encryptedContentAsn1" } ] }; p7v.envelopedDataValidator = { name: "EnvelopedData", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "EnvelopedData.Version", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.INTEGER, constructed: false, capture: "version" }, { name: "EnvelopedData.RecipientInfos", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SET, constructed: true, captureAsn1: "recipientInfos" }].concat(encryptedContentInfoValidator) }; p7v.encryptedDataValidator = { name: "EncryptedData", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "EncryptedData.Version", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.INTEGER, constructed: false, capture: "version" }].concat(encryptedContentInfoValidator) }; var signerValidator = { name: "SignerInfo", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [ { name: "SignerInfo.version", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.INTEGER, constructed: false }, { name: "SignerInfo.issuerAndSerialNumber", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "SignerInfo.issuerAndSerialNumber.issuer", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, captureAsn1: "issuer" }, { name: "SignerInfo.issuerAndSerialNumber.serialNumber", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.INTEGER, constructed: false, capture: "serial" }] }, { name: "SignerInfo.digestAlgorithm", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "SignerInfo.digestAlgorithm.algorithm", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OID, constructed: false, capture: "digestAlgorithm" }, { name: "SignerInfo.digestAlgorithm.parameter", tagClass: asn1.Class.UNIVERSAL, constructed: false, captureAsn1: "digestParameter", optional: true }] }, { name: "SignerInfo.authenticatedAttributes", tagClass: asn1.Class.CONTEXT_SPECIFIC, type: 0, constructed: true, optional: true, capture: "authenticatedAttributes" }, { name: "SignerInfo.digestEncryptionAlgorithm", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, capture: "signatureAlgorithm" }, { name: "SignerInfo.encryptedDigest", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OCTETSTRING, constructed: false, capture: "signature" }, { name: "SignerInfo.unauthenticatedAttributes", tagClass: asn1.Class.CONTEXT_SPECIFIC, type: 1, constructed: true, optional: true, capture: "unauthenticatedAttributes" } ] }; p7v.signedDataValidator = { name: "SignedData", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [ { name: "SignedData.Version", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.INTEGER, constructed: false, capture: "version" }, { name: "SignedData.DigestAlgorithms", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SET, constructed: true, captureAsn1: "digestAlgorithms" }, contentInfoValidator, { name: "SignedData.Certificates", tagClass: asn1.Class.CONTEXT_SPECIFIC, type: 0, optional: true, captureAsn1: "certificates" }, { name: "SignedData.CertificateRevocationLists", tagClass: asn1.Class.CONTEXT_SPECIFIC, type: 1, optional: true, captureAsn1: "crls" }, { name: "SignedData.SignerInfos", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SET, capture: "signerInfos", optional: true, value: [signerValidator] } ] }; p7v.recipientInfoValidator = { name: "RecipientInfo", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [ { name: "RecipientInfo.version", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.INTEGER, constructed: false, capture: "version" }, { name: "RecipientInfo.issuerAndSerial", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "RecipientInfo.issuerAndSerial.issuer", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, captureAsn1: "issuer" }, { name: "RecipientInfo.issuerAndSerial.serialNumber", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.INTEGER, constructed: false, capture: "serial" }] }, { name: "RecipientInfo.keyEncryptionAlgorithm", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "RecipientInfo.keyEncryptionAlgorithm.algorithm", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OID, constructed: false, capture: "encAlgorithm" }, { name: "RecipientInfo.keyEncryptionAlgorithm.parameter", tagClass: asn1.Class.UNIVERSAL, constructed: false, captureAsn1: "encParameter", optional: true }] }, { name: "RecipientInfo.encryptedKey", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OCTETSTRING, constructed: false, capture: "encKey" } ] }; })); //#endregion //#region ../node_modules/node-forge/lib/mgf1.js var require_mgf1 = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Javascript implementation of mask generation function MGF1. * * @author Stefan Siegl * @author Dave Longley * * Copyright (c) 2012 Stefan Siegl * Copyright (c) 2014 Digital Bazaar, Inc. */ var forge = require_forge(); require_util$8(); forge.mgf = forge.mgf || {}; var mgf1 = module.exports = forge.mgf.mgf1 = forge.mgf1 = forge.mgf1 || {}; /** * Creates a MGF1 mask generation function object. * * @param md the message digest API to use (eg: forge.md.sha1.create()). * * @return a mask generation function object. */ mgf1.create = function(md) { var mgf = { generate: function(seed, maskLen) { var t = new forge.util.ByteBuffer(); var len = Math.ceil(maskLen / md.digestLength); for (var i = 0; i < len; i++) { var c = new forge.util.ByteBuffer(); c.putInt32(i); md.start(); md.update(seed + c.getBytes()); t.putBuffer(md.digest()); } t.truncate(t.length() - maskLen); return t.getBytes(); } }; return mgf; }; })); //#endregion //#region ../node_modules/node-forge/lib/mgf.js var require_mgf = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Node.js module for Forge mask generation functions. * * @author Stefan Siegl * * Copyright 2012 Stefan Siegl */ var forge = require_forge(); require_mgf1(); module.exports = forge.mgf = forge.mgf || {}; forge.mgf.mgf1 = forge.mgf1; })); //#endregion //#region ../node_modules/node-forge/lib/pss.js var require_pss = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Javascript implementation of PKCS#1 PSS signature padding. * * @author Stefan Siegl * * Copyright (c) 2012 Stefan Siegl */ var forge = require_forge(); require_random(); require_util$8(); var pss = module.exports = forge.pss = forge.pss || {}; /** * Creates a PSS signature scheme object. * * There are several ways to provide a salt for encoding: * * 1. Specify the saltLength only and the built-in PRNG will generate it. * 2. Specify the saltLength and a custom PRNG with 'getBytesSync' defined that * will be used. * 3. Specify the salt itself as a forge.util.ByteBuffer. * * @param options the options to use: * md the message digest object to use, a forge md instance. * mgf the mask generation function to use, a forge mgf instance. * [saltLength] the length of the salt in octets. * [prng] the pseudo-random number generator to use to produce a salt. * [salt] the salt to use when encoding. * * @return a signature scheme object. */ pss.create = function(options) { if (arguments.length === 3) { options = { md: arguments[0], mgf: arguments[1], saltLength: arguments[2] }; } var hash = options.md; var mgf = options.mgf; var hLen = hash.digestLength; var salt_ = options.salt || null; if (typeof salt_ === "string") { salt_ = forge.util.createBuffer(salt_); } var sLen; if ("saltLength" in options) { sLen = options.saltLength; } else if (salt_ !== null) { sLen = salt_.length(); } else { throw new Error("Salt length not specified or specific salt not given."); } if (salt_ !== null && salt_.length() !== sLen) { throw new Error("Given salt length does not match length of given salt."); } var prng = options.prng || forge.random; var pssobj = {}; /** * Encodes a PSS signature. * * This function implements EMSA-PSS-ENCODE as per RFC 3447, section 9.1.1. * * @param md the message digest object with the hash to sign. * @param modsBits the length of the RSA modulus in bits. * * @return the encoded message as a binary-encoded string of length * ceil((modBits - 1) / 8). */ pssobj.encode = function(md, modBits) { var i; var emBits = modBits - 1; var emLen = Math.ceil(emBits / 8); var mHash = md.digest().getBytes(); if (emLen < hLen + sLen + 2) { throw new Error("Message is too long to encrypt."); } var salt; if (salt_ === null) { salt = prng.getBytesSync(sLen); } else { salt = salt_.bytes(); } var m_ = new forge.util.ByteBuffer(); m_.fillWithByte(0, 8); m_.putBytes(mHash); m_.putBytes(salt); hash.start(); hash.update(m_.getBytes()); var h = hash.digest().getBytes(); var ps = new forge.util.ByteBuffer(); ps.fillWithByte(0, emLen - sLen - hLen - 2); ps.putByte(1); ps.putBytes(salt); var db = ps.getBytes(); var maskLen = emLen - hLen - 1; var dbMask = mgf.generate(h, maskLen); var maskedDB = ""; for (i = 0; i < maskLen; i++) { maskedDB += String.fromCharCode(db.charCodeAt(i) ^ dbMask.charCodeAt(i)); } var mask = 65280 >> 8 * emLen - emBits & 255; maskedDB = String.fromCharCode(maskedDB.charCodeAt(0) & ~mask) + maskedDB.substr(1); return maskedDB + h + String.fromCharCode(188); }; /** * Verifies a PSS signature. * * This function implements EMSA-PSS-VERIFY as per RFC 3447, section 9.1.2. * * @param mHash the message digest hash, as a binary-encoded string, to * compare against the signature. * @param em the encoded message, as a binary-encoded string * (RSA decryption result). * @param modsBits the length of the RSA modulus in bits. * * @return true if the signature was verified, false if not. */ pssobj.verify = function(mHash, em, modBits) { var i; var emBits = modBits - 1; var emLen = Math.ceil(emBits / 8); em = em.substr(-emLen); if (emLen < hLen + sLen + 2) { throw new Error("Inconsistent parameters to PSS signature verification."); } if (em.charCodeAt(emLen - 1) !== 188) { throw new Error("Encoded message does not end in 0xBC."); } var maskLen = emLen - hLen - 1; var maskedDB = em.substr(0, maskLen); var h = em.substr(maskLen, hLen); var mask = 65280 >> 8 * emLen - emBits & 255; if ((maskedDB.charCodeAt(0) & mask) !== 0) { throw new Error("Bits beyond keysize not zero as expected."); } var dbMask = mgf.generate(h, maskLen); var db = ""; for (i = 0; i < maskLen; i++) { db += String.fromCharCode(maskedDB.charCodeAt(i) ^ dbMask.charCodeAt(i)); } db = String.fromCharCode(db.charCodeAt(0) & ~mask) + db.substr(1); var checkLen = emLen - hLen - sLen - 2; for (i = 0; i < checkLen; i++) { if (db.charCodeAt(i) !== 0) { throw new Error("Leftmost octets not zero as expected"); } } if (db.charCodeAt(checkLen) !== 1) { throw new Error("Inconsistent PSS signature, 0x01 marker not found"); } var salt = db.substr(-sLen); var m_ = new forge.util.ByteBuffer(); m_.fillWithByte(0, 8); m_.putBytes(mHash); m_.putBytes(salt); hash.start(); hash.update(m_.getBytes()); var h_ = hash.digest().getBytes(); return h === h_; }; return pssobj; }; })); //#endregion //#region ../node_modules/node-forge/lib/x509.js var require_x509 = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Javascript implementation of X.509 and related components (such as * Certification Signing Requests) of a Public Key Infrastructure. * * @author Dave Longley * * Copyright (c) 2010-2014 Digital Bazaar, Inc. * * The ASN.1 representation of an X.509v3 certificate is as follows * (see RFC 2459): * * Certificate ::= SEQUENCE { * tbsCertificate TBSCertificate, * signatureAlgorithm AlgorithmIdentifier, * signatureValue BIT STRING * } * * TBSCertificate ::= SEQUENCE { * version [0] EXPLICIT Version DEFAULT v1, * serialNumber CertificateSerialNumber, * signature AlgorithmIdentifier, * issuer Name, * validity Validity, * subject Name, * subjectPublicKeyInfo SubjectPublicKeyInfo, * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, * -- If present, version shall be v2 or v3 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, * -- If present, version shall be v2 or v3 * extensions [3] EXPLICIT Extensions OPTIONAL * -- If present, version shall be v3 * } * * Version ::= INTEGER { v1(0), v2(1), v3(2) } * * CertificateSerialNumber ::= INTEGER * * Name ::= CHOICE { * // only one possible choice for now * RDNSequence * } * * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName * * RelativeDistinguishedName ::= SET OF AttributeTypeAndValue * * AttributeTypeAndValue ::= SEQUENCE { * type AttributeType, * value AttributeValue * } * AttributeType ::= OBJECT IDENTIFIER * AttributeValue ::= ANY DEFINED BY AttributeType * * Validity ::= SEQUENCE { * notBefore Time, * notAfter Time * } * * Time ::= CHOICE { * utcTime UTCTime, * generalTime GeneralizedTime * } * * UniqueIdentifier ::= BIT STRING * * SubjectPublicKeyInfo ::= SEQUENCE { * algorithm AlgorithmIdentifier, * subjectPublicKey BIT STRING * } * * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension * * Extension ::= SEQUENCE { * extnID OBJECT IDENTIFIER, * critical BOOLEAN DEFAULT FALSE, * extnValue OCTET STRING * } * * The only key algorithm currently supported for PKI is RSA. * * RSASSA-PSS signatures are described in RFC 3447 and RFC 4055. * * PKCS#10 v1.7 describes certificate signing requests: * * CertificationRequestInfo: * * CertificationRequestInfo ::= SEQUENCE { * version INTEGER { v1(0) } (v1,...), * subject Name, * subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }}, * attributes [0] Attributes{{ CRIAttributes }} * } * * Attributes { ATTRIBUTE:IOSet } ::= SET OF Attribute{{ IOSet }} * * CRIAttributes ATTRIBUTE ::= { * ... -- add any locally defined attributes here -- } * * Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE { * type ATTRIBUTE.&id({IOSet}), * values SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{@type}) * } * * CertificationRequest ::= SEQUENCE { * certificationRequestInfo CertificationRequestInfo, * signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }}, * signature BIT STRING * } */ var forge = require_forge(); require_aes$1(); require_asn1(); require_des(); require_md(); require_mgf(); require_oids(); require_pem(); require_pss(); require_rsa(); require_util$8(); var asn1 = forge.asn1; var pki = module.exports = forge.pki = forge.pki || {}; var oids = pki.oids; var _shortNames = {}; _shortNames["CN"] = oids["commonName"]; _shortNames["commonName"] = "CN"; _shortNames["C"] = oids["countryName"]; _shortNames["countryName"] = "C"; _shortNames["L"] = oids["localityName"]; _shortNames["localityName"] = "L"; _shortNames["ST"] = oids["stateOrProvinceName"]; _shortNames["stateOrProvinceName"] = "ST"; _shortNames["O"] = oids["organizationName"]; _shortNames["organizationName"] = "O"; _shortNames["OU"] = oids["organizationalUnitName"]; _shortNames["organizationalUnitName"] = "OU"; _shortNames["E"] = oids["emailAddress"]; _shortNames["emailAddress"] = "E"; var publicKeyValidator = forge.pki.rsa.publicKeyValidator; var x509CertificateValidator = { name: "Certificate", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [ { name: "Certificate.TBSCertificate", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, captureAsn1: "tbsCertificate", value: [ { name: "Certificate.TBSCertificate.version", tagClass: asn1.Class.CONTEXT_SPECIFIC, type: 0, constructed: true, optional: true, value: [{ name: "Certificate.TBSCertificate.version.integer", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.INTEGER, constructed: false, capture: "certVersion" }] }, { name: "Certificate.TBSCertificate.serialNumber", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.INTEGER, constructed: false, capture: "certSerialNumber" }, { name: "Certificate.TBSCertificate.signature", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "Certificate.TBSCertificate.signature.algorithm", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OID, constructed: false, capture: "certinfoSignatureOid" }, { name: "Certificate.TBSCertificate.signature.parameters", tagClass: asn1.Class.UNIVERSAL, optional: true, captureAsn1: "certinfoSignatureParams" }] }, { name: "Certificate.TBSCertificate.issuer", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, captureAsn1: "certIssuer" }, { name: "Certificate.TBSCertificate.validity", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [ { name: "Certificate.TBSCertificate.validity.notBefore (utc)", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.UTCTIME, constructed: false, optional: true, capture: "certValidity1UTCTime" }, { name: "Certificate.TBSCertificate.validity.notBefore (generalized)", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.GENERALIZEDTIME, constructed: false, optional: true, capture: "certValidity2GeneralizedTime" }, { name: "Certificate.TBSCertificate.validity.notAfter (utc)", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.UTCTIME, constructed: false, optional: true, capture: "certValidity3UTCTime" }, { name: "Certificate.TBSCertificate.validity.notAfter (generalized)", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.GENERALIZEDTIME, constructed: false, optional: true, capture: "certValidity4GeneralizedTime" } ] }, { name: "Certificate.TBSCertificate.subject", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, captureAsn1: "certSubject" }, publicKeyValidator, { name: "Certificate.TBSCertificate.issuerUniqueID", tagClass: asn1.Class.CONTEXT_SPECIFIC, type: 1, constructed: true, optional: true, value: [{ name: "Certificate.TBSCertificate.issuerUniqueID.id", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.BITSTRING, constructed: false, captureBitStringValue: "certIssuerUniqueId" }] }, { name: "Certificate.TBSCertificate.subjectUniqueID", tagClass: asn1.Class.CONTEXT_SPECIFIC, type: 2, constructed: true, optional: true, value: [{ name: "Certificate.TBSCertificate.subjectUniqueID.id", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.BITSTRING, constructed: false, captureBitStringValue: "certSubjectUniqueId" }] }, { name: "Certificate.TBSCertificate.extensions", tagClass: asn1.Class.CONTEXT_SPECIFIC, type: 3, constructed: true, captureAsn1: "certExtensions", optional: true } ] }, { name: "Certificate.signatureAlgorithm", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "Certificate.signatureAlgorithm.algorithm", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OID, constructed: false, capture: "certSignatureOid" }, { name: "Certificate.TBSCertificate.signature.parameters", tagClass: asn1.Class.UNIVERSAL, optional: true, captureAsn1: "certSignatureParams" }] }, { name: "Certificate.signatureValue", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.BITSTRING, constructed: false, captureBitStringValue: "certSignature" } ] }; var rsassaPssParameterValidator = { name: "rsapss", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [ { name: "rsapss.hashAlgorithm", tagClass: asn1.Class.CONTEXT_SPECIFIC, type: 0, constructed: true, value: [{ name: "rsapss.hashAlgorithm.AlgorithmIdentifier", tagClass: asn1.Class.UNIVERSAL, type: asn1.Class.SEQUENCE, constructed: true, optional: true, value: [{ name: "rsapss.hashAlgorithm.AlgorithmIdentifier.algorithm", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OID, constructed: false, capture: "hashOid" }] }] }, { name: "rsapss.maskGenAlgorithm", tagClass: asn1.Class.CONTEXT_SPECIFIC, type: 1, constructed: true, value: [{ name: "rsapss.maskGenAlgorithm.AlgorithmIdentifier", tagClass: asn1.Class.UNIVERSAL, type: asn1.Class.SEQUENCE, constructed: true, optional: true, value: [{ name: "rsapss.maskGenAlgorithm.AlgorithmIdentifier.algorithm", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OID, constructed: false, capture: "maskGenOid" }, { name: "rsapss.maskGenAlgorithm.AlgorithmIdentifier.params", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "rsapss.maskGenAlgorithm.AlgorithmIdentifier.params.algorithm", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OID, constructed: false, capture: "maskGenHashOid" }] }] }] }, { name: "rsapss.saltLength", tagClass: asn1.Class.CONTEXT_SPECIFIC, type: 2, optional: true, value: [{ name: "rsapss.saltLength.saltLength", tagClass: asn1.Class.UNIVERSAL, type: asn1.Class.INTEGER, constructed: false, capture: "saltLength" }] }, { name: "rsapss.trailerField", tagClass: asn1.Class.CONTEXT_SPECIFIC, type: 3, optional: true, value: [{ name: "rsapss.trailer.trailer", tagClass: asn1.Class.UNIVERSAL, type: asn1.Class.INTEGER, constructed: false, capture: "trailer" }] } ] }; var certificationRequestInfoValidator = { name: "CertificationRequestInfo", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, captureAsn1: "certificationRequestInfo", value: [ { name: "CertificationRequestInfo.integer", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.INTEGER, constructed: false, capture: "certificationRequestInfoVersion" }, { name: "CertificationRequestInfo.subject", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, captureAsn1: "certificationRequestInfoSubject" }, publicKeyValidator, { name: "CertificationRequestInfo.attributes", tagClass: asn1.Class.CONTEXT_SPECIFIC, type: 0, constructed: true, optional: true, capture: "certificationRequestInfoAttributes", value: [{ name: "CertificationRequestInfo.attributes", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "CertificationRequestInfo.attributes.type", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OID, constructed: false }, { name: "CertificationRequestInfo.attributes.value", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SET, constructed: true }] }] } ] }; var certificationRequestValidator = { name: "CertificationRequest", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, captureAsn1: "csr", value: [ certificationRequestInfoValidator, { name: "CertificationRequest.signatureAlgorithm", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "CertificationRequest.signatureAlgorithm.algorithm", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OID, constructed: false, capture: "csrSignatureOid" }, { name: "CertificationRequest.signatureAlgorithm.parameters", tagClass: asn1.Class.UNIVERSAL, optional: true, captureAsn1: "csrSignatureParams" }] }, { name: "CertificationRequest.signature", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.BITSTRING, constructed: false, captureBitStringValue: "csrSignature" } ] }; /** * Converts an RDNSequence of ASN.1 DER-encoded RelativeDistinguishedName * sets into an array with objects that have type and value properties. * * @param rdn the RDNSequence to convert. * @param md a message digest to append type and value to if provided. */ pki.RDNAttributesAsArray = function(rdn, md) { var rval = []; var set, attr, obj; for (var si = 0; si < rdn.value.length; ++si) { set = rdn.value[si]; for (var i = 0; i < set.value.length; ++i) { obj = {}; attr = set.value[i]; obj.type = asn1.derToOid(attr.value[0].value); obj.value = attr.value[1].value; obj.valueTagClass = attr.value[1].type; if (obj.type in oids) { obj.name = oids[obj.type]; if (obj.name in _shortNames) { obj.shortName = _shortNames[obj.name]; } } if (md) { md.update(obj.type); md.update(obj.value); } rval.push(obj); } } return rval; }; /** * Converts ASN.1 CRIAttributes into an array with objects that have type and * value properties. * * @param attributes the CRIAttributes to convert. */ pki.CRIAttributesAsArray = function(attributes) { var rval = []; for (var si = 0; si < attributes.length; ++si) { var seq = attributes[si]; var type = asn1.derToOid(seq.value[0].value); var values = seq.value[1].value; for (var vi = 0; vi < values.length; ++vi) { var obj = {}; obj.type = type; obj.value = values[vi].value; obj.valueTagClass = values[vi].type; if (obj.type in oids) { obj.name = oids[obj.type]; if (obj.name in _shortNames) { obj.shortName = _shortNames[obj.name]; } } if (obj.type === oids.extensionRequest) { obj.extensions = []; for (var ei = 0; ei < obj.value.length; ++ei) { obj.extensions.push(pki.certificateExtensionFromAsn1(obj.value[ei])); } } rval.push(obj); } } return rval; }; /** * Gets an issuer or subject attribute from its name, type, or short name. * * @param obj the issuer or subject object. * @param options a short name string or an object with: * shortName the short name for the attribute. * name the name for the attribute. * type the type for the attribute. * * @return the attribute. */ function _getAttribute(obj, options) { if (typeof options === "string") { options = { shortName: options }; } var rval = null; var attr; for (var i = 0; rval === null && i < obj.attributes.length; ++i) { attr = obj.attributes[i]; if (options.type && options.type === attr.type) { rval = attr; } else if (options.name && options.name === attr.name) { rval = attr; } else if (options.shortName && options.shortName === attr.shortName) { rval = attr; } } return rval; } /** * Converts signature parameters from ASN.1 structure. * * Currently only RSASSA-PSS supported. The PKCS#1 v1.5 signature scheme had * no parameters. * * RSASSA-PSS-params ::= SEQUENCE { * hashAlgorithm [0] HashAlgorithm DEFAULT * sha1Identifier, * maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT * mgf1SHA1Identifier, * saltLength [2] INTEGER DEFAULT 20, * trailerField [3] INTEGER DEFAULT 1 * } * * HashAlgorithm ::= AlgorithmIdentifier * * MaskGenAlgorithm ::= AlgorithmIdentifier * * AlgorithmIdentifer ::= SEQUENCE { * algorithm OBJECT IDENTIFIER, * parameters ANY DEFINED BY algorithm OPTIONAL * } * * @param oid The OID specifying the signature algorithm * @param obj The ASN.1 structure holding the parameters * @param fillDefaults Whether to use return default values where omitted * @return signature parameter object */ var _readSignatureParameters = function(oid, obj, fillDefaults) { var params = {}; if (oid !== oids["RSASSA-PSS"]) { return params; } if (fillDefaults) { params = { hash: { algorithmOid: oids["sha1"] }, mgf: { algorithmOid: oids["mgf1"], hash: { algorithmOid: oids["sha1"] } }, saltLength: 20 }; } var capture = {}; var errors = []; if (!asn1.validate(obj, rsassaPssParameterValidator, capture, errors)) { var error = new Error("Cannot read RSASSA-PSS parameter block."); error.errors = errors; throw error; } if (capture.hashOid !== undefined) { params.hash = params.hash || {}; params.hash.algorithmOid = asn1.derToOid(capture.hashOid); } if (capture.maskGenOid !== undefined) { params.mgf = params.mgf || {}; params.mgf.algorithmOid = asn1.derToOid(capture.maskGenOid); params.mgf.hash = params.mgf.hash || {}; params.mgf.hash.algorithmOid = asn1.derToOid(capture.maskGenHashOid); } if (capture.saltLength !== undefined) { params.saltLength = capture.saltLength.charCodeAt(0); } return params; }; /** * Create signature digest for OID. * * @param options * signatureOid: the OID specifying the signature algorithm. * type: a human readable type for error messages * @return a created md instance. throws if unknown oid. */ var _createSignatureDigest = function(options) { switch (oids[options.signatureOid]) { case "sha1WithRSAEncryption": case "sha1WithRSASignature": return forge.md.sha1.create(); case "md5WithRSAEncryption": return forge.md.md5.create(); case "sha256WithRSAEncryption": return forge.md.sha256.create(); case "sha384WithRSAEncryption": return forge.md.sha384.create(); case "sha512WithRSAEncryption": return forge.md.sha512.create(); case "RSASSA-PSS": return forge.md.sha256.create(); default: var error = new Error("Could not compute " + options.type + " digest. " + "Unknown signature OID."); error.signatureOid = options.signatureOid; throw error; } }; /** * Verify signature on certificate or CSR. * * @param options: * certificate the certificate or CSR to verify. * md the signature digest. * signature the signature * @return a created md instance. throws if unknown oid. */ var _verifySignature = function(options) { var cert = options.certificate; var scheme; switch (cert.signatureOid) { case oids.sha1WithRSAEncryption: case oids.sha1WithRSASignature: break; case oids["RSASSA-PSS"]: var hash, mgf; hash = oids[cert.signatureParameters.mgf.hash.algorithmOid]; if (hash === undefined || forge.md[hash] === undefined) { var error = new Error("Unsupported MGF hash function."); error.oid = cert.signatureParameters.mgf.hash.algorithmOid; error.name = hash; throw error; } mgf = oids[cert.signatureParameters.mgf.algorithmOid]; if (mgf === undefined || forge.mgf[mgf] === undefined) { var error = new Error("Unsupported MGF function."); error.oid = cert.signatureParameters.mgf.algorithmOid; error.name = mgf; throw error; } mgf = forge.mgf[mgf].create(forge.md[hash].create()); hash = oids[cert.signatureParameters.hash.algorithmOid]; if (hash === undefined || forge.md[hash] === undefined) { var error = new Error("Unsupported RSASSA-PSS hash function."); error.oid = cert.signatureParameters.hash.algorithmOid; error.name = hash; throw error; } scheme = forge.pss.create(forge.md[hash].create(), mgf, cert.signatureParameters.saltLength); break; } return cert.publicKey.verify(options.md.digest().getBytes(), options.signature, scheme); }; /** * Converts an X.509 certificate from PEM format. * * Note: If the certificate is to be verified then compute hash should * be set to true. This will scan the TBSCertificate part of the ASN.1 * object while it is converted so it doesn't need to be converted back * to ASN.1-DER-encoding later. * * @param pem the PEM-formatted certificate. * @param computeHash true to compute the hash for verification. * @param strict true to be strict when checking ASN.1 value lengths, false to * allow truncated values (default: true). * * @return the certificate. */ pki.certificateFromPem = function(pem, computeHash, strict) { var msg = forge.pem.decode(pem)[0]; if (msg.type !== "CERTIFICATE" && msg.type !== "X509 CERTIFICATE" && msg.type !== "TRUSTED CERTIFICATE") { var error = new Error("Could not convert certificate from PEM; PEM header type " + "is not \"CERTIFICATE\", \"X509 CERTIFICATE\", or \"TRUSTED CERTIFICATE\"."); error.headerType = msg.type; throw error; } if (msg.procType && msg.procType.type === "ENCRYPTED") { throw new Error("Could not convert certificate from PEM; PEM is encrypted."); } var obj = asn1.fromDer(msg.body, strict); return pki.certificateFromAsn1(obj, computeHash); }; /** * Converts an X.509 certificate to PEM format. * * @param cert the certificate. * @param maxline the maximum characters per line, defaults to 64. * * @return the PEM-formatted certificate. */ pki.certificateToPem = function(cert, maxline) { var msg = { type: "CERTIFICATE", body: asn1.toDer(pki.certificateToAsn1(cert)).getBytes() }; return forge.pem.encode(msg, { maxline }); }; /** * Converts an RSA public key from PEM format. * * @param pem the PEM-formatted public key. * * @return the public key. */ pki.publicKeyFromPem = function(pem) { var msg = forge.pem.decode(pem)[0]; if (msg.type !== "PUBLIC KEY" && msg.type !== "RSA PUBLIC KEY") { var error = new Error("Could not convert public key from PEM; PEM header " + "type is not \"PUBLIC KEY\" or \"RSA PUBLIC KEY\"."); error.headerType = msg.type; throw error; } if (msg.procType && msg.procType.type === "ENCRYPTED") { throw new Error("Could not convert public key from PEM; PEM is encrypted."); } var obj = asn1.fromDer(msg.body); return pki.publicKeyFromAsn1(obj); }; /** * Converts an RSA public key to PEM format (using a SubjectPublicKeyInfo). * * @param key the public key. * @param maxline the maximum characters per line, defaults to 64. * * @return the PEM-formatted public key. */ pki.publicKeyToPem = function(key, maxline) { var msg = { type: "PUBLIC KEY", body: asn1.toDer(pki.publicKeyToAsn1(key)).getBytes() }; return forge.pem.encode(msg, { maxline }); }; /** * Converts an RSA public key to PEM format (using an RSAPublicKey). * * @param key the public key. * @param maxline the maximum characters per line, defaults to 64. * * @return the PEM-formatted public key. */ pki.publicKeyToRSAPublicKeyPem = function(key, maxline) { var msg = { type: "RSA PUBLIC KEY", body: asn1.toDer(pki.publicKeyToRSAPublicKey(key)).getBytes() }; return forge.pem.encode(msg, { maxline }); }; /** * Gets a fingerprint for the given public key. * * @param options the options to use. * [md] the message digest object to use (defaults to forge.md.sha1). * [type] the type of fingerprint, such as 'RSAPublicKey', * 'SubjectPublicKeyInfo' (defaults to 'RSAPublicKey'). * [encoding] an alternative output encoding, such as 'hex' * (defaults to none, outputs a byte buffer). * [delimiter] the delimiter to use between bytes for 'hex' encoded * output, eg: ':' (defaults to none). * * @return the fingerprint as a byte buffer or other encoding based on options. */ pki.getPublicKeyFingerprint = function(key, options) { options = options || {}; var md = options.md || forge.md.sha1.create(); var type = options.type || "RSAPublicKey"; var bytes; switch (type) { case "RSAPublicKey": bytes = asn1.toDer(pki.publicKeyToRSAPublicKey(key)).getBytes(); break; case "SubjectPublicKeyInfo": bytes = asn1.toDer(pki.publicKeyToAsn1(key)).getBytes(); break; default: throw new Error("Unknown fingerprint type \"" + options.type + "\"."); } md.start(); md.update(bytes); var digest = md.digest(); if (options.encoding === "hex") { var hex = digest.toHex(); if (options.delimiter) { return hex.match(/.{2}/g).join(options.delimiter); } return hex; } else if (options.encoding === "binary") { return digest.getBytes(); } else if (options.encoding) { throw new Error("Unknown encoding \"" + options.encoding + "\"."); } return digest; }; /** * Converts a PKCS#10 certification request (CSR) from PEM format. * * Note: If the certification request is to be verified then compute hash * should be set to true. This will scan the CertificationRequestInfo part of * the ASN.1 object while it is converted so it doesn't need to be converted * back to ASN.1-DER-encoding later. * * @param pem the PEM-formatted certificate. * @param computeHash true to compute the hash for verification. * @param strict true to be strict when checking ASN.1 value lengths, false to * allow truncated values (default: true). * * @return the certification request (CSR). */ pki.certificationRequestFromPem = function(pem, computeHash, strict) { var msg = forge.pem.decode(pem)[0]; if (msg.type !== "CERTIFICATE REQUEST") { var error = new Error("Could not convert certification request from PEM; " + "PEM header type is not \"CERTIFICATE REQUEST\"."); error.headerType = msg.type; throw error; } if (msg.procType && msg.procType.type === "ENCRYPTED") { throw new Error("Could not convert certification request from PEM; " + "PEM is encrypted."); } var obj = asn1.fromDer(msg.body, strict); return pki.certificationRequestFromAsn1(obj, computeHash); }; /** * Converts a PKCS#10 certification request (CSR) to PEM format. * * @param csr the certification request. * @param maxline the maximum characters per line, defaults to 64. * * @return the PEM-formatted certification request. */ pki.certificationRequestToPem = function(csr, maxline) { var msg = { type: "CERTIFICATE REQUEST", body: asn1.toDer(pki.certificationRequestToAsn1(csr)).getBytes() }; return forge.pem.encode(msg, { maxline }); }; /** * Creates an empty X.509v3 RSA certificate. * * @return the certificate. */ pki.createCertificate = function() { var cert = {}; cert.version = 2; cert.serialNumber = "00"; cert.signatureOid = null; cert.signature = null; cert.siginfo = {}; cert.siginfo.algorithmOid = null; cert.validity = {}; cert.validity.notBefore = new Date(); cert.validity.notAfter = new Date(); cert.issuer = {}; cert.issuer.getField = function(sn) { return _getAttribute(cert.issuer, sn); }; cert.issuer.addField = function(attr) { _fillMissingFields([attr]); cert.issuer.attributes.push(attr); }; cert.issuer.attributes = []; cert.issuer.hash = null; cert.subject = {}; cert.subject.getField = function(sn) { return _getAttribute(cert.subject, sn); }; cert.subject.addField = function(attr) { _fillMissingFields([attr]); cert.subject.attributes.push(attr); }; cert.subject.attributes = []; cert.subject.hash = null; cert.extensions = []; cert.publicKey = null; cert.md = null; /** * Sets the subject of this certificate. * * @param attrs the array of subject attributes to use. * @param uniqueId an optional a unique ID to use. */ cert.setSubject = function(attrs, uniqueId) { _fillMissingFields(attrs); cert.subject.attributes = attrs; delete cert.subject.uniqueId; if (uniqueId) { cert.subject.uniqueId = uniqueId; } cert.subject.hash = null; }; /** * Sets the issuer of this certificate. * * @param attrs the array of issuer attributes to use. * @param uniqueId an optional a unique ID to use. */ cert.setIssuer = function(attrs, uniqueId) { _fillMissingFields(attrs); cert.issuer.attributes = attrs; delete cert.issuer.uniqueId; if (uniqueId) { cert.issuer.uniqueId = uniqueId; } cert.issuer.hash = null; }; /** * Sets the extensions of this certificate. * * @param exts the array of extensions to use. */ cert.setExtensions = function(exts) { for (var i = 0; i < exts.length; ++i) { _fillMissingExtensionFields(exts[i], { cert }); } cert.extensions = exts; }; /** * Gets an extension by its name or id. * * @param options the name to use or an object with: * name the name to use. * id the id to use. * * @return the extension or null if not found. */ cert.getExtension = function(options) { if (typeof options === "string") { options = { name: options }; } var rval = null; var ext; for (var i = 0; rval === null && i < cert.extensions.length; ++i) { ext = cert.extensions[i]; if (options.id && ext.id === options.id) { rval = ext; } else if (options.name && ext.name === options.name) { rval = ext; } } return rval; }; /** * Signs this certificate using the given private key. * * @param key the private key to sign with. * @param md the message digest object to use (defaults to forge.md.sha1). */ cert.sign = function(key, md) { cert.md = md || forge.md.sha1.create(); var algorithmOid = oids[cert.md.algorithm + "WithRSAEncryption"]; if (!algorithmOid) { var error = new Error("Could not compute certificate digest. " + "Unknown message digest algorithm OID."); error.algorithm = cert.md.algorithm; throw error; } cert.signatureOid = cert.siginfo.algorithmOid = algorithmOid; cert.tbsCertificate = pki.getTBSCertificate(cert); var bytes = asn1.toDer(cert.tbsCertificate); cert.md.update(bytes.getBytes()); cert.signature = key.sign(cert.md); }; /** * Attempts verify the signature on the passed certificate using this * certificate's public key. * * @param child the certificate to verify. * * @return true if verified, false if not. */ cert.verify = function(child) { var rval = false; if (!cert.issued(child)) { var issuer = child.issuer; var subject = cert.subject; var error = new Error("The parent certificate did not issue the given child " + "certificate; the child certificate's issuer does not match the " + "parent's subject."); error.expectedIssuer = subject.attributes; error.actualIssuer = issuer.attributes; throw error; } var md = child.md; if (md === null) { md = _createSignatureDigest({ signatureOid: child.signatureOid, type: "certificate" }); var tbsCertificate = child.tbsCertificate || pki.getTBSCertificate(child); var bytes = asn1.toDer(tbsCertificate); md.update(bytes.getBytes()); } if (md !== null) { rval = _verifySignature({ certificate: cert, md, signature: child.signature }); } return rval; }; /** * Returns true if this certificate's issuer matches the passed * certificate's subject. Note that no signature check is performed. * * @param parent the certificate to check. * * @return true if this certificate's issuer matches the passed certificate's * subject. */ cert.isIssuer = function(parent) { var rval = false; var i = cert.issuer; var s = parent.subject; if (i.hash && s.hash) { rval = i.hash === s.hash; } else if (i.attributes.length === s.attributes.length) { rval = true; var iattr, sattr; for (var n = 0; rval && n < i.attributes.length; ++n) { iattr = i.attributes[n]; sattr = s.attributes[n]; if (iattr.type !== sattr.type || iattr.value !== sattr.value) { rval = false; } } } return rval; }; /** * Returns true if this certificate's subject matches the issuer of the * given certificate). Note that not signature check is performed. * * @param child the certificate to check. * * @return true if this certificate's subject matches the passed * certificate's issuer. */ cert.issued = function(child) { return child.isIssuer(cert); }; /** * Generates the subjectKeyIdentifier for this certificate as byte buffer. * * @return the subjectKeyIdentifier for this certificate as byte buffer. */ cert.generateSubjectKeyIdentifier = function() { return pki.getPublicKeyFingerprint(cert.publicKey, { type: "RSAPublicKey" }); }; /** * Verifies the subjectKeyIdentifier extension value for this certificate * against its public key. If no extension is found, false will be * returned. * * @return true if verified, false if not. */ cert.verifySubjectKeyIdentifier = function() { var oid = oids["subjectKeyIdentifier"]; for (var i = 0; i < cert.extensions.length; ++i) { var ext = cert.extensions[i]; if (ext.id === oid) { var ski = cert.generateSubjectKeyIdentifier().getBytes(); return forge.util.hexToBytes(ext.subjectKeyIdentifier) === ski; } } return false; }; return cert; }; /** * Converts an X.509v3 RSA certificate from an ASN.1 object. * * Note: If the certificate is to be verified then compute hash should * be set to true. There is currently no implementation for converting * a certificate back to ASN.1 so the TBSCertificate part of the ASN.1 * object needs to be scanned before the cert object is created. * * @param obj the asn1 representation of an X.509v3 RSA certificate. * @param computeHash true to compute the hash for verification. * * @return the certificate. */ pki.certificateFromAsn1 = function(obj, computeHash) { var capture = {}; var errors = []; if (!asn1.validate(obj, x509CertificateValidator, capture, errors)) { var error = new Error("Cannot read X.509 certificate. " + "ASN.1 object is not an X509v3 Certificate."); error.errors = errors; throw error; } var oid = asn1.derToOid(capture.publicKeyOid); if (oid !== pki.oids.rsaEncryption) { throw new Error("Cannot read public key. OID is not RSA."); } var cert = pki.createCertificate(); cert.version = capture.certVersion ? capture.certVersion.charCodeAt(0) : 0; var serial = forge.util.createBuffer(capture.certSerialNumber); cert.serialNumber = serial.toHex(); cert.signatureOid = forge.asn1.derToOid(capture.certSignatureOid); cert.signatureParameters = _readSignatureParameters(cert.signatureOid, capture.certSignatureParams, true); cert.siginfo.algorithmOid = forge.asn1.derToOid(capture.certinfoSignatureOid); cert.siginfo.parameters = _readSignatureParameters(cert.siginfo.algorithmOid, capture.certinfoSignatureParams, false); cert.signature = capture.certSignature; var validity = []; if (capture.certValidity1UTCTime !== undefined) { validity.push(asn1.utcTimeToDate(capture.certValidity1UTCTime)); } if (capture.certValidity2GeneralizedTime !== undefined) { validity.push(asn1.generalizedTimeToDate(capture.certValidity2GeneralizedTime)); } if (capture.certValidity3UTCTime !== undefined) { validity.push(asn1.utcTimeToDate(capture.certValidity3UTCTime)); } if (capture.certValidity4GeneralizedTime !== undefined) { validity.push(asn1.generalizedTimeToDate(capture.certValidity4GeneralizedTime)); } if (validity.length > 2) { throw new Error("Cannot read notBefore/notAfter validity times; more " + "than two times were provided in the certificate."); } if (validity.length < 2) { throw new Error("Cannot read notBefore/notAfter validity times; they " + "were not provided as either UTCTime or GeneralizedTime."); } cert.validity.notBefore = validity[0]; cert.validity.notAfter = validity[1]; cert.tbsCertificate = capture.tbsCertificate; if (computeHash) { cert.md = _createSignatureDigest({ signatureOid: cert.signatureOid, type: "certificate" }); var bytes = asn1.toDer(cert.tbsCertificate); cert.md.update(bytes.getBytes()); } var imd = forge.md.sha1.create(); var ibytes = asn1.toDer(capture.certIssuer); imd.update(ibytes.getBytes()); cert.issuer.getField = function(sn) { return _getAttribute(cert.issuer, sn); }; cert.issuer.addField = function(attr) { _fillMissingFields([attr]); cert.issuer.attributes.push(attr); }; cert.issuer.attributes = pki.RDNAttributesAsArray(capture.certIssuer); if (capture.certIssuerUniqueId) { cert.issuer.uniqueId = capture.certIssuerUniqueId; } cert.issuer.hash = imd.digest().toHex(); var smd = forge.md.sha1.create(); var sbytes = asn1.toDer(capture.certSubject); smd.update(sbytes.getBytes()); cert.subject.getField = function(sn) { return _getAttribute(cert.subject, sn); }; cert.subject.addField = function(attr) { _fillMissingFields([attr]); cert.subject.attributes.push(attr); }; cert.subject.attributes = pki.RDNAttributesAsArray(capture.certSubject); if (capture.certSubjectUniqueId) { cert.subject.uniqueId = capture.certSubjectUniqueId; } cert.subject.hash = smd.digest().toHex(); if (capture.certExtensions) { cert.extensions = pki.certificateExtensionsFromAsn1(capture.certExtensions); } else { cert.extensions = []; } cert.publicKey = pki.publicKeyFromAsn1(capture.subjectPublicKeyInfo); return cert; }; /** * Converts an ASN.1 extensions object (with extension sequences as its * values) into an array of extension objects with types and values. * * Supported extensions: * * id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 } * KeyUsage ::= BIT STRING { * digitalSignature (0), * nonRepudiation (1), * keyEncipherment (2), * dataEncipherment (3), * keyAgreement (4), * keyCertSign (5), * cRLSign (6), * encipherOnly (7), * decipherOnly (8) * } * * id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 } * BasicConstraints ::= SEQUENCE { * cA BOOLEAN DEFAULT FALSE, * pathLenConstraint INTEGER (0..MAX) OPTIONAL * } * * subjectAltName EXTENSION ::= { * SYNTAX GeneralNames * IDENTIFIED BY id-ce-subjectAltName * } * * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName * * GeneralName ::= CHOICE { * otherName [0] INSTANCE OF OTHER-NAME, * rfc822Name [1] IA5String, * dNSName [2] IA5String, * x400Address [3] ORAddress, * directoryName [4] Name, * ediPartyName [5] EDIPartyName, * uniformResourceIdentifier [6] IA5String, * IPAddress [7] OCTET STRING, * registeredID [8] OBJECT IDENTIFIER * } * * OTHER-NAME ::= TYPE-IDENTIFIER * * EDIPartyName ::= SEQUENCE { * nameAssigner [0] DirectoryString {ub-name} OPTIONAL, * partyName [1] DirectoryString {ub-name} * } * * @param exts the extensions ASN.1 with extension sequences to parse. * * @return the array. */ pki.certificateExtensionsFromAsn1 = function(exts) { var rval = []; for (var i = 0; i < exts.value.length; ++i) { var extseq = exts.value[i]; for (var ei = 0; ei < extseq.value.length; ++ei) { rval.push(pki.certificateExtensionFromAsn1(extseq.value[ei])); } } return rval; }; /** * Parses a single certificate extension from ASN.1. * * @param ext the extension in ASN.1 format. * * @return the parsed extension as an object. */ pki.certificateExtensionFromAsn1 = function(ext) { var e = {}; e.id = asn1.derToOid(ext.value[0].value); e.critical = false; if (ext.value[1].type === asn1.Type.BOOLEAN) { e.critical = ext.value[1].value.charCodeAt(0) !== 0; e.value = ext.value[2].value; } else { e.value = ext.value[1].value; } if (e.id in oids) { e.name = oids[e.id]; if (e.name === "keyUsage") { var ev = asn1.fromDer(e.value); var b2 = 0; var b3 = 0; if (ev.value.length > 1) { b2 = ev.value.charCodeAt(1); b3 = ev.value.length > 2 ? ev.value.charCodeAt(2) : 0; } e.digitalSignature = (b2 & 128) === 128; e.nonRepudiation = (b2 & 64) === 64; e.keyEncipherment = (b2 & 32) === 32; e.dataEncipherment = (b2 & 16) === 16; e.keyAgreement = (b2 & 8) === 8; e.keyCertSign = (b2 & 4) === 4; e.cRLSign = (b2 & 2) === 2; e.encipherOnly = (b2 & 1) === 1; e.decipherOnly = (b3 & 128) === 128; } else if (e.name === "basicConstraints") { var ev = asn1.fromDer(e.value); if (ev.value.length > 0 && ev.value[0].type === asn1.Type.BOOLEAN) { e.cA = ev.value[0].value.charCodeAt(0) !== 0; } else { e.cA = false; } var value = null; if (ev.value.length > 0 && ev.value[0].type === asn1.Type.INTEGER) { value = ev.value[0].value; } else if (ev.value.length > 1) { value = ev.value[1].value; } if (value !== null) { e.pathLenConstraint = asn1.derToInteger(value); } } else if (e.name === "extKeyUsage") { var ev = asn1.fromDer(e.value); for (var vi = 0; vi < ev.value.length; ++vi) { var oid = asn1.derToOid(ev.value[vi].value); if (oid in oids) { e[oids[oid]] = true; } else { e[oid] = true; } } } else if (e.name === "nsCertType") { var ev = asn1.fromDer(e.value); var b2 = 0; if (ev.value.length > 1) { b2 = ev.value.charCodeAt(1); } e.client = (b2 & 128) === 128; e.server = (b2 & 64) === 64; e.email = (b2 & 32) === 32; e.objsign = (b2 & 16) === 16; e.reserved = (b2 & 8) === 8; e.sslCA = (b2 & 4) === 4; e.emailCA = (b2 & 2) === 2; e.objCA = (b2 & 1) === 1; } else if (e.name === "subjectAltName" || e.name === "issuerAltName") { e.altNames = []; var gn; var ev = asn1.fromDer(e.value); for (var n = 0; n < ev.value.length; ++n) { gn = ev.value[n]; var altName = { type: gn.type, value: gn.value }; e.altNames.push(altName); switch (gn.type) { case 1: case 2: case 6: break; case 7: altName.ip = forge.util.bytesToIP(gn.value); break; case 8: altName.oid = asn1.derToOid(gn.value); break; default: } } } else if (e.name === "subjectKeyIdentifier") { var ev = asn1.fromDer(e.value); e.subjectKeyIdentifier = forge.util.bytesToHex(ev.value); } } return e; }; /** * Converts a PKCS#10 certification request (CSR) from an ASN.1 object. * * Note: If the certification request is to be verified then compute hash * should be set to true. There is currently no implementation for converting * a certificate back to ASN.1 so the CertificationRequestInfo part of the * ASN.1 object needs to be scanned before the csr object is created. * * @param obj the asn1 representation of a PKCS#10 certification request (CSR). * @param computeHash true to compute the hash for verification. * * @return the certification request (CSR). */ pki.certificationRequestFromAsn1 = function(obj, computeHash) { var capture = {}; var errors = []; if (!asn1.validate(obj, certificationRequestValidator, capture, errors)) { var error = new Error("Cannot read PKCS#10 certificate request. " + "ASN.1 object is not a PKCS#10 CertificationRequest."); error.errors = errors; throw error; } var oid = asn1.derToOid(capture.publicKeyOid); if (oid !== pki.oids.rsaEncryption) { throw new Error("Cannot read public key. OID is not RSA."); } var csr = pki.createCertificationRequest(); csr.version = capture.csrVersion ? capture.csrVersion.charCodeAt(0) : 0; csr.signatureOid = forge.asn1.derToOid(capture.csrSignatureOid); csr.signatureParameters = _readSignatureParameters(csr.signatureOid, capture.csrSignatureParams, true); csr.siginfo.algorithmOid = forge.asn1.derToOid(capture.csrSignatureOid); csr.siginfo.parameters = _readSignatureParameters(csr.siginfo.algorithmOid, capture.csrSignatureParams, false); csr.signature = capture.csrSignature; csr.certificationRequestInfo = capture.certificationRequestInfo; if (computeHash) { csr.md = _createSignatureDigest({ signatureOid: csr.signatureOid, type: "certification request" }); var bytes = asn1.toDer(csr.certificationRequestInfo); csr.md.update(bytes.getBytes()); } var smd = forge.md.sha1.create(); csr.subject.getField = function(sn) { return _getAttribute(csr.subject, sn); }; csr.subject.addField = function(attr) { _fillMissingFields([attr]); csr.subject.attributes.push(attr); }; csr.subject.attributes = pki.RDNAttributesAsArray(capture.certificationRequestInfoSubject, smd); csr.subject.hash = smd.digest().toHex(); csr.publicKey = pki.publicKeyFromAsn1(capture.subjectPublicKeyInfo); csr.getAttribute = function(sn) { return _getAttribute(csr, sn); }; csr.addAttribute = function(attr) { _fillMissingFields([attr]); csr.attributes.push(attr); }; csr.attributes = pki.CRIAttributesAsArray(capture.certificationRequestInfoAttributes || []); return csr; }; /** * Creates an empty certification request (a CSR or certificate signing * request). Once created, its public key and attributes can be set and then * it can be signed. * * @return the empty certification request. */ pki.createCertificationRequest = function() { var csr = {}; csr.version = 0; csr.signatureOid = null; csr.signature = null; csr.siginfo = {}; csr.siginfo.algorithmOid = null; csr.subject = {}; csr.subject.getField = function(sn) { return _getAttribute(csr.subject, sn); }; csr.subject.addField = function(attr) { _fillMissingFields([attr]); csr.subject.attributes.push(attr); }; csr.subject.attributes = []; csr.subject.hash = null; csr.publicKey = null; csr.attributes = []; csr.getAttribute = function(sn) { return _getAttribute(csr, sn); }; csr.addAttribute = function(attr) { _fillMissingFields([attr]); csr.attributes.push(attr); }; csr.md = null; /** * Sets the subject of this certification request. * * @param attrs the array of subject attributes to use. */ csr.setSubject = function(attrs) { _fillMissingFields(attrs); csr.subject.attributes = attrs; csr.subject.hash = null; }; /** * Sets the attributes of this certification request. * * @param attrs the array of attributes to use. */ csr.setAttributes = function(attrs) { _fillMissingFields(attrs); csr.attributes = attrs; }; /** * Signs this certification request using the given private key. * * @param key the private key to sign with. * @param md the message digest object to use (defaults to forge.md.sha1). */ csr.sign = function(key, md) { csr.md = md || forge.md.sha1.create(); var algorithmOid = oids[csr.md.algorithm + "WithRSAEncryption"]; if (!algorithmOid) { var error = new Error("Could not compute certification request digest. " + "Unknown message digest algorithm OID."); error.algorithm = csr.md.algorithm; throw error; } csr.signatureOid = csr.siginfo.algorithmOid = algorithmOid; csr.certificationRequestInfo = pki.getCertificationRequestInfo(csr); var bytes = asn1.toDer(csr.certificationRequestInfo); csr.md.update(bytes.getBytes()); csr.signature = key.sign(csr.md); }; /** * Attempts verify the signature on the passed certification request using * its public key. * * A CSR that has been exported to a file in PEM format can be verified using * OpenSSL using this command: * * openssl req -in -verify -noout -text * * @return true if verified, false if not. */ csr.verify = function() { var rval = false; var md = csr.md; if (md === null) { md = _createSignatureDigest({ signatureOid: csr.signatureOid, type: "certification request" }); var cri = csr.certificationRequestInfo || pki.getCertificationRequestInfo(csr); var bytes = asn1.toDer(cri); md.update(bytes.getBytes()); } if (md !== null) { rval = _verifySignature({ certificate: csr, md, signature: csr.signature }); } return rval; }; return csr; }; /** * Converts an X.509 subject or issuer to an ASN.1 RDNSequence. * * @param obj the subject or issuer (distinguished name). * * @return the ASN.1 RDNSequence. */ function _dnToAsn1(obj) { var rval = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []); var attr, set; var attrs = obj.attributes; for (var i = 0; i < attrs.length; ++i) { attr = attrs[i]; var value = attr.value; var valueTagClass = asn1.Type.PRINTABLESTRING; if ("valueTagClass" in attr) { valueTagClass = attr.valueTagClass; if (valueTagClass === asn1.Type.UTF8) { value = forge.util.encodeUtf8(value); } } set = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(attr.type).getBytes()), asn1.create(asn1.Class.UNIVERSAL, valueTagClass, false, value)])]); rval.value.push(set); } return rval; } /** * Gets all printable attributes (typically of an issuer or subject) in a * simplified JSON format for display. * * @param attrs the attributes. * * @return the JSON for display. */ function _getAttributesAsJson(attrs) { var rval = {}; for (var i = 0; i < attrs.length; ++i) { var attr = attrs[i]; if (attr.shortName && (attr.valueTagClass === asn1.Type.UTF8 || attr.valueTagClass === asn1.Type.PRINTABLESTRING || attr.valueTagClass === asn1.Type.IA5STRING)) { var value = attr.value; if (attr.valueTagClass === asn1.Type.UTF8) { value = forge.util.encodeUtf8(attr.value); } if (!(attr.shortName in rval)) { rval[attr.shortName] = value; } else if (forge.util.isArray(rval[attr.shortName])) { rval[attr.shortName].push(value); } else { rval[attr.shortName] = [rval[attr.shortName], value]; } } } return rval; } /** * Fills in missing fields in attributes. * * @param attrs the attributes to fill missing fields in. */ function _fillMissingFields(attrs) { var attr; for (var i = 0; i < attrs.length; ++i) { attr = attrs[i]; if (typeof attr.name === "undefined") { if (attr.type && attr.type in pki.oids) { attr.name = pki.oids[attr.type]; } else if (attr.shortName && attr.shortName in _shortNames) { attr.name = pki.oids[_shortNames[attr.shortName]]; } } if (typeof attr.type === "undefined") { if (attr.name && attr.name in pki.oids) { attr.type = pki.oids[attr.name]; } else { var error = new Error("Attribute type not specified."); error.attribute = attr; throw error; } } if (typeof attr.shortName === "undefined") { if (attr.name && attr.name in _shortNames) { attr.shortName = _shortNames[attr.name]; } } if (attr.type === oids.extensionRequest) { attr.valueConstructed = true; attr.valueTagClass = asn1.Type.SEQUENCE; if (!attr.value && attr.extensions) { attr.value = []; for (var ei = 0; ei < attr.extensions.length; ++ei) { attr.value.push(pki.certificateExtensionToAsn1(_fillMissingExtensionFields(attr.extensions[ei]))); } } } if (typeof attr.value === "undefined") { var error = new Error("Attribute value not specified."); error.attribute = attr; throw error; } } } /** * Fills in missing fields in certificate extensions. * * @param e the extension. * @param [options] the options to use. * [cert] the certificate the extensions are for. * * @return the extension. */ function _fillMissingExtensionFields(e, options) { options = options || {}; if (typeof e.name === "undefined") { if (e.id && e.id in pki.oids) { e.name = pki.oids[e.id]; } } if (typeof e.id === "undefined") { if (e.name && e.name in pki.oids) { e.id = pki.oids[e.name]; } else { var error = new Error("Extension ID not specified."); error.extension = e; throw error; } } if (typeof e.value !== "undefined") { return e; } if (e.name === "keyUsage") { var unused = 0; var b2 = 0; var b3 = 0; if (e.digitalSignature) { b2 |= 128; unused = 7; } if (e.nonRepudiation) { b2 |= 64; unused = 6; } if (e.keyEncipherment) { b2 |= 32; unused = 5; } if (e.dataEncipherment) { b2 |= 16; unused = 4; } if (e.keyAgreement) { b2 |= 8; unused = 3; } if (e.keyCertSign) { b2 |= 4; unused = 2; } if (e.cRLSign) { b2 |= 2; unused = 1; } if (e.encipherOnly) { b2 |= 1; unused = 0; } if (e.decipherOnly) { b3 |= 128; unused = 7; } var value = String.fromCharCode(unused); if (b3 !== 0) { value += String.fromCharCode(b2) + String.fromCharCode(b3); } else if (b2 !== 0) { value += String.fromCharCode(b2); } e.value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false, value); } else if (e.name === "basicConstraints") { e.value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []); if (e.cA) { e.value.value.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BOOLEAN, false, String.fromCharCode(255))); } if ("pathLenConstraint" in e) { e.value.value.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, asn1.integerToDer(e.pathLenConstraint).getBytes())); } } else if (e.name === "extKeyUsage") { e.value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []); var seq = e.value.value; for (var key in e) { if (e[key] !== true) { continue; } if (key in oids) { seq.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(oids[key]).getBytes())); } else if (key.indexOf(".") !== -1) { seq.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(key).getBytes())); } } } else if (e.name === "nsCertType") { var unused = 0; var b2 = 0; if (e.client) { b2 |= 128; unused = 7; } if (e.server) { b2 |= 64; unused = 6; } if (e.email) { b2 |= 32; unused = 5; } if (e.objsign) { b2 |= 16; unused = 4; } if (e.reserved) { b2 |= 8; unused = 3; } if (e.sslCA) { b2 |= 4; unused = 2; } if (e.emailCA) { b2 |= 2; unused = 1; } if (e.objCA) { b2 |= 1; unused = 0; } var value = String.fromCharCode(unused); if (b2 !== 0) { value += String.fromCharCode(b2); } e.value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false, value); } else if (e.name === "subjectAltName" || e.name === "issuerAltName") { e.value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []); var altName; for (var n = 0; n < e.altNames.length; ++n) { altName = e.altNames[n]; var value = altName.value; if (altName.type === 7 && altName.ip) { value = forge.util.bytesFromIP(altName.ip); if (value === null) { var error = new Error("Extension \"ip\" value is not a valid IPv4 or IPv6 address."); error.extension = e; throw error; } } else if (altName.type === 8) { if (altName.oid) { value = asn1.oidToDer(asn1.oidToDer(altName.oid)); } else { value = asn1.oidToDer(value); } } e.value.value.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, altName.type, false, value)); } } else if (e.name === "nsComment" && options.cert) { if (!/^[\x00-\x7F]*$/.test(e.comment) || e.comment.length < 1 || e.comment.length > 128) { throw new Error("Invalid \"nsComment\" content."); } e.value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.IA5STRING, false, e.comment); } else if (e.name === "subjectKeyIdentifier" && options.cert) { var ski = options.cert.generateSubjectKeyIdentifier(); e.subjectKeyIdentifier = ski.toHex(); e.value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, ski.getBytes()); } else if (e.name === "authorityKeyIdentifier" && options.cert) { e.value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []); var seq = e.value.value; if (e.keyIdentifier) { var keyIdentifier = e.keyIdentifier === true ? options.cert.generateSubjectKeyIdentifier().getBytes() : e.keyIdentifier; seq.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, false, keyIdentifier)); } if (e.authorityCertIssuer) { var authorityCertIssuer = [asn1.create(asn1.Class.CONTEXT_SPECIFIC, 4, true, [_dnToAsn1(e.authorityCertIssuer === true ? options.cert.issuer : e.authorityCertIssuer)])]; seq.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 1, true, authorityCertIssuer)); } if (e.serialNumber) { var serialNumber = forge.util.hexToBytes(e.serialNumber === true ? options.cert.serialNumber : e.serialNumber); seq.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 2, false, serialNumber)); } } else if (e.name === "cRLDistributionPoints") { e.value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []); var seq = e.value.value; var subSeq = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []); var fullNameGeneralNames = asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, []); var altName; for (var n = 0; n < e.altNames.length; ++n) { altName = e.altNames[n]; var value = altName.value; if (altName.type === 7 && altName.ip) { value = forge.util.bytesFromIP(altName.ip); if (value === null) { var error = new Error("Extension \"ip\" value is not a valid IPv4 or IPv6 address."); error.extension = e; throw error; } } else if (altName.type === 8) { if (altName.oid) { value = asn1.oidToDer(asn1.oidToDer(altName.oid)); } else { value = asn1.oidToDer(value); } } fullNameGeneralNames.value.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, altName.type, false, value)); } subSeq.value.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [fullNameGeneralNames])); seq.push(subSeq); } if (typeof e.value === "undefined") { var error = new Error("Extension value not specified."); error.extension = e; throw error; } return e; } /** * Convert signature parameters object to ASN.1 * * @param {String} oid Signature algorithm OID * @param params The signature parametrs object * @return ASN.1 object representing signature parameters */ function _signatureParametersToAsn1(oid, params) { switch (oid) { case oids["RSASSA-PSS"]: var parts = []; if (params.hash.algorithmOid !== undefined) { parts.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(params.hash.algorithmOid).getBytes()), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, "")])])); } if (params.mgf.algorithmOid !== undefined) { parts.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 1, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(params.mgf.algorithmOid).getBytes()), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(params.mgf.hash.algorithmOid).getBytes()), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, "")])])])); } if (params.saltLength !== undefined) { parts.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 2, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, asn1.integerToDer(params.saltLength).getBytes())])); } return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, parts); default: return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, ""); } } /** * Converts a certification request's attributes to an ASN.1 set of * CRIAttributes. * * @param csr certification request. * * @return the ASN.1 set of CRIAttributes. */ function _CRIAttributesToAsn1(csr) { var rval = asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, []); if (csr.attributes.length === 0) { return rval; } var attrs = csr.attributes; for (var i = 0; i < attrs.length; ++i) { var attr = attrs[i]; var value = attr.value; var valueTagClass = asn1.Type.UTF8; if ("valueTagClass" in attr) { valueTagClass = attr.valueTagClass; } if (valueTagClass === asn1.Type.UTF8) { value = forge.util.encodeUtf8(value); } var valueConstructed = false; if ("valueConstructed" in attr) { valueConstructed = attr.valueConstructed; } var seq = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(attr.type).getBytes()), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, [asn1.create(asn1.Class.UNIVERSAL, valueTagClass, valueConstructed, value)])]); rval.value.push(seq); } return rval; } var jan_1_1950 = new Date("1950-01-01T00:00:00Z"); var jan_1_2050 = new Date("2050-01-01T00:00:00Z"); /** * Converts a Date object to ASN.1 * Handles the different format before and after 1st January 2050 * * @param date date object. * * @return the ASN.1 object representing the date. */ function _dateToAsn1(date) { if (date >= jan_1_1950 && date < jan_1_2050) { return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.UTCTIME, false, asn1.dateToUtcTime(date)); } else { return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.GENERALIZEDTIME, false, asn1.dateToGeneralizedTime(date)); } } /** * Gets the ASN.1 TBSCertificate part of an X.509v3 certificate. * * @param cert the certificate. * * @return the asn1 TBSCertificate. */ pki.getTBSCertificate = function(cert) { var notBefore = _dateToAsn1(cert.validity.notBefore); var notAfter = _dateToAsn1(cert.validity.notAfter); var tbs = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, asn1.integerToDer(cert.version).getBytes())]), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, forge.util.hexToBytes(cert.serialNumber)), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(cert.siginfo.algorithmOid).getBytes()), _signatureParametersToAsn1(cert.siginfo.algorithmOid, cert.siginfo.parameters)]), _dnToAsn1(cert.issuer), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [notBefore, notAfter]), _dnToAsn1(cert.subject), pki.publicKeyToAsn1(cert.publicKey) ]); if (cert.issuer.uniqueId) { tbs.value.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 1, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false, String.fromCharCode(0) + cert.issuer.uniqueId)])); } if (cert.subject.uniqueId) { tbs.value.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 2, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false, String.fromCharCode(0) + cert.subject.uniqueId)])); } if (cert.extensions.length > 0) { tbs.value.push(pki.certificateExtensionsToAsn1(cert.extensions)); } return tbs; }; /** * Gets the ASN.1 CertificationRequestInfo part of a * PKCS#10 CertificationRequest. * * @param csr the certification request. * * @return the asn1 CertificationRequestInfo. */ pki.getCertificationRequestInfo = function(csr) { var cri = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, asn1.integerToDer(csr.version).getBytes()), _dnToAsn1(csr.subject), pki.publicKeyToAsn1(csr.publicKey), _CRIAttributesToAsn1(csr) ]); return cri; }; /** * Converts a DistinguishedName (subject or issuer) to an ASN.1 object. * * @param dn the DistinguishedName. * * @return the asn1 representation of a DistinguishedName. */ pki.distinguishedNameToAsn1 = function(dn) { return _dnToAsn1(dn); }; /** * Converts an X.509v3 RSA certificate to an ASN.1 object. * * @param cert the certificate. * * @return the asn1 representation of an X.509v3 RSA certificate. */ pki.certificateToAsn1 = function(cert) { var tbsCertificate = cert.tbsCertificate || pki.getTBSCertificate(cert); return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ tbsCertificate, asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(cert.signatureOid).getBytes()), _signatureParametersToAsn1(cert.signatureOid, cert.signatureParameters)]), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false, String.fromCharCode(0) + cert.signature) ]); }; /** * Converts X.509v3 certificate extensions to ASN.1. * * @param exts the extensions to convert. * * @return the extensions in ASN.1 format. */ pki.certificateExtensionsToAsn1 = function(exts) { var rval = asn1.create(asn1.Class.CONTEXT_SPECIFIC, 3, true, []); var seq = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []); rval.value.push(seq); for (var i = 0; i < exts.length; ++i) { seq.value.push(pki.certificateExtensionToAsn1(exts[i])); } return rval; }; /** * Converts a single certificate extension to ASN.1. * * @param ext the extension to convert. * * @return the extension in ASN.1 format. */ pki.certificateExtensionToAsn1 = function(ext) { var extseq = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []); extseq.value.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(ext.id).getBytes())); if (ext.critical) { extseq.value.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BOOLEAN, false, String.fromCharCode(255))); } var value = ext.value; if (typeof ext.value !== "string") { value = asn1.toDer(value).getBytes(); } extseq.value.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, value)); return extseq; }; /** * Converts a PKCS#10 certification request to an ASN.1 object. * * @param csr the certification request. * * @return the asn1 representation of a certification request. */ pki.certificationRequestToAsn1 = function(csr) { var cri = csr.certificationRequestInfo || pki.getCertificationRequestInfo(csr); return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ cri, asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(csr.signatureOid).getBytes()), _signatureParametersToAsn1(csr.signatureOid, csr.signatureParameters)]), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false, String.fromCharCode(0) + csr.signature) ]); }; /** * Creates a CA store. * * @param certs an optional array of certificate objects or PEM-formatted * certificate strings to add to the CA store. * * @return the CA store. */ pki.createCaStore = function(certs) { var caStore = { certs: {} }; /** * Gets the certificate that issued the passed certificate or its * 'parent'. * * @param cert the certificate to get the parent for. * * @return the parent certificate or null if none was found. */ caStore.getIssuer = function(cert) { var rval = getBySubject(cert.issuer); return rval; }; /** * Adds a trusted certificate to the store. * * @param cert the certificate to add as a trusted certificate (either a * pki.certificate object or a PEM-formatted certificate). */ caStore.addCertificate = function(cert) { if (typeof cert === "string") { cert = forge.pki.certificateFromPem(cert); } ensureSubjectHasHash(cert.subject); if (!caStore.hasCertificate(cert)) { if (cert.subject.hash in caStore.certs) { var tmp = caStore.certs[cert.subject.hash]; if (!forge.util.isArray(tmp)) { tmp = [tmp]; } tmp.push(cert); caStore.certs[cert.subject.hash] = tmp; } else { caStore.certs[cert.subject.hash] = cert; } } }; /** * Checks to see if the given certificate is in the store. * * @param cert the certificate to check (either a pki.certificate or a * PEM-formatted certificate). * * @return true if the certificate is in the store, false if not. */ caStore.hasCertificate = function(cert) { if (typeof cert === "string") { cert = forge.pki.certificateFromPem(cert); } var match = getBySubject(cert.subject); if (!match) { return false; } if (!forge.util.isArray(match)) { match = [match]; } var der1 = asn1.toDer(pki.certificateToAsn1(cert)).getBytes(); for (var i = 0; i < match.length; ++i) { var der2 = asn1.toDer(pki.certificateToAsn1(match[i])).getBytes(); if (der1 === der2) { return true; } } return false; }; /** * Lists all of the certificates kept in the store. * * @return an array of all of the pki.certificate objects in the store. */ caStore.listAllCertificates = function() { var certList = []; for (var hash in caStore.certs) { if (caStore.certs.hasOwnProperty(hash)) { var value = caStore.certs[hash]; if (!forge.util.isArray(value)) { certList.push(value); } else { for (var i = 0; i < value.length; ++i) { certList.push(value[i]); } } } } return certList; }; /** * Removes a certificate from the store. * * @param cert the certificate to remove (either a pki.certificate or a * PEM-formatted certificate). * * @return the certificate that was removed or null if the certificate * wasn't in store. */ caStore.removeCertificate = function(cert) { var result; if (typeof cert === "string") { cert = forge.pki.certificateFromPem(cert); } ensureSubjectHasHash(cert.subject); if (!caStore.hasCertificate(cert)) { return null; } var match = getBySubject(cert.subject); if (!forge.util.isArray(match)) { result = caStore.certs[cert.subject.hash]; delete caStore.certs[cert.subject.hash]; return result; } var der1 = asn1.toDer(pki.certificateToAsn1(cert)).getBytes(); for (var i = 0; i < match.length; ++i) { var der2 = asn1.toDer(pki.certificateToAsn1(match[i])).getBytes(); if (der1 === der2) { result = match[i]; match.splice(i, 1); } } if (match.length === 0) { delete caStore.certs[cert.subject.hash]; } return result; }; function getBySubject(subject) { ensureSubjectHasHash(subject); return caStore.certs[subject.hash] || null; } function ensureSubjectHasHash(subject) { if (!subject.hash) { var md = forge.md.sha1.create(); subject.attributes = pki.RDNAttributesAsArray(_dnToAsn1(subject), md); subject.hash = md.digest().toHex(); } } if (certs) { for (var i = 0; i < certs.length; ++i) { var cert = certs[i]; caStore.addCertificate(cert); } } return caStore; }; /** * Certificate verification errors, based on TLS. */ pki.certificateError = { bad_certificate: "forge.pki.BadCertificate", unsupported_certificate: "forge.pki.UnsupportedCertificate", certificate_revoked: "forge.pki.CertificateRevoked", certificate_expired: "forge.pki.CertificateExpired", certificate_unknown: "forge.pki.CertificateUnknown", unknown_ca: "forge.pki.UnknownCertificateAuthority" }; /** * Verifies a certificate chain against the given Certificate Authority store * with an optional custom verify callback. * * @param caStore a certificate store to verify against. * @param chain the certificate chain to verify, with the root or highest * authority at the end (an array of certificates). * @param options a callback to be called for every certificate in the chain or * an object with: * verify a callback to be called for every certificate in the * chain * validityCheckDate the date against which the certificate * validity period should be checked. Pass null to not check * the validity period. By default, the current date is used. * * The verify callback has the following signature: * * verified - Set to true if certificate was verified, otherwise the * pki.certificateError for why the certificate failed. * depth - The current index in the chain, where 0 is the end point's cert. * certs - The certificate chain, *NOTE* an empty chain indicates an anonymous * end point. * * The function returns true on success and on failure either the appropriate * pki.certificateError or an object with 'error' set to the appropriate * pki.certificateError and 'message' set to a custom error message. * * @return true if successful, error thrown if not. */ pki.verifyCertificateChain = function(caStore, chain, options) { if (typeof options === "function") { options = { verify: options }; } options = options || {}; chain = chain.slice(0); var certs = chain.slice(0); var validityCheckDate = options.validityCheckDate; if (typeof validityCheckDate === "undefined") { validityCheckDate = new Date(); } var first = true; var error = null; var depth = 0; do { var cert = chain.shift(); var parent = null; var selfSigned = false; if (validityCheckDate) { if (validityCheckDate < cert.validity.notBefore || validityCheckDate > cert.validity.notAfter) { error = { message: "Certificate is not valid yet or has expired.", error: pki.certificateError.certificate_expired, notBefore: cert.validity.notBefore, notAfter: cert.validity.notAfter, now: validityCheckDate }; } } if (error === null) { parent = chain[0] || caStore.getIssuer(cert); if (parent === null) { if (cert.isIssuer(cert)) { selfSigned = true; parent = cert; } } if (parent) { var parents = parent; if (!forge.util.isArray(parents)) { parents = [parents]; } var verified = false; while (!verified && parents.length > 0) { parent = parents.shift(); try { verified = parent.verify(cert); } catch (ex) {} } if (!verified) { error = { message: "Certificate signature is invalid.", error: pki.certificateError.bad_certificate }; } } if (error === null && (!parent || selfSigned) && !caStore.hasCertificate(cert)) { error = { message: "Certificate is not trusted.", error: pki.certificateError.unknown_ca }; } } if (error === null && parent && !cert.isIssuer(parent)) { error = { message: "Certificate issuer is invalid.", error: pki.certificateError.bad_certificate }; } if (error === null) { var se = { keyUsage: true, basicConstraints: true }; for (var i = 0; error === null && i < cert.extensions.length; ++i) { var ext = cert.extensions[i]; if (ext.critical && !(ext.name in se)) { error = { message: "Certificate has an unsupported critical extension.", error: pki.certificateError.unsupported_certificate }; } } } if (error === null && (!first || chain.length === 0 && (!parent || selfSigned))) { var bcExt = cert.getExtension("basicConstraints"); var keyUsageExt = cert.getExtension("keyUsage"); if (keyUsageExt !== null) { if (!keyUsageExt.keyCertSign || bcExt === null) { error = { message: "Certificate keyUsage or basicConstraints conflict " + "or indicate that the certificate is not a CA. " + "If the certificate is the only one in the chain or " + "isn't the first then the certificate must be a " + "valid CA.", error: pki.certificateError.bad_certificate }; } } if (error === null && bcExt !== null && !bcExt.cA) { error = { message: "Certificate basicConstraints indicates the certificate " + "is not a CA.", error: pki.certificateError.bad_certificate }; } if (error === null && keyUsageExt !== null && "pathLenConstraint" in bcExt) { var pathLen = depth - 1; if (pathLen > bcExt.pathLenConstraint) { error = { message: "Certificate basicConstraints pathLenConstraint violated.", error: pki.certificateError.bad_certificate }; } } } var vfd = error === null ? true : error.error; var ret = options.verify ? options.verify(vfd, depth, certs) : vfd; if (ret === true) { error = null; } else { if (vfd === true) { error = { message: "The application rejected the certificate.", error: pki.certificateError.bad_certificate }; } if (ret || ret === 0) { if (typeof ret === "object" && !forge.util.isArray(ret)) { if (ret.message) { error.message = ret.message; } if (ret.error) { error.error = ret.error; } } else if (typeof ret === "string") { error.error = ret; } } throw error; } first = false; ++depth; } while (chain.length > 0); return true; }; })); //#endregion //#region ../node_modules/node-forge/lib/pkcs12.js var require_pkcs12 = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Javascript implementation of PKCS#12. * * @author Dave Longley * @author Stefan Siegl * * Copyright (c) 2010-2014 Digital Bazaar, Inc. * Copyright (c) 2012 Stefan Siegl * * The ASN.1 representation of PKCS#12 is as follows * (see ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12-tc1.pdf for details) * * PFX ::= SEQUENCE { * version INTEGER {v3(3)}(v3,...), * authSafe ContentInfo, * macData MacData OPTIONAL * } * * MacData ::= SEQUENCE { * mac DigestInfo, * macSalt OCTET STRING, * iterations INTEGER DEFAULT 1 * } * Note: The iterations default is for historical reasons and its use is * deprecated. A higher value, like 1024, is recommended. * * DigestInfo is defined in PKCS#7 as follows: * * DigestInfo ::= SEQUENCE { * digestAlgorithm DigestAlgorithmIdentifier, * digest Digest * } * * DigestAlgorithmIdentifier ::= AlgorithmIdentifier * * The AlgorithmIdentifier contains an Object Identifier (OID) and parameters * for the algorithm, if any. In the case of SHA1 there is none. * * AlgorithmIdentifer ::= SEQUENCE { * algorithm OBJECT IDENTIFIER, * parameters ANY DEFINED BY algorithm OPTIONAL * } * * Digest ::= OCTET STRING * * * ContentInfo ::= SEQUENCE { * contentType ContentType, * content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL * } * * ContentType ::= OBJECT IDENTIFIER * * AuthenticatedSafe ::= SEQUENCE OF ContentInfo * -- Data if unencrypted * -- EncryptedData if password-encrypted * -- EnvelopedData if public key-encrypted * * * SafeContents ::= SEQUENCE OF SafeBag * * SafeBag ::= SEQUENCE { * bagId BAG-TYPE.&id ({PKCS12BagSet}) * bagValue [0] EXPLICIT BAG-TYPE.&Type({PKCS12BagSet}{@bagId}), * bagAttributes SET OF PKCS12Attribute OPTIONAL * } * * PKCS12Attribute ::= SEQUENCE { * attrId ATTRIBUTE.&id ({PKCS12AttrSet}), * attrValues SET OF ATTRIBUTE.&Type ({PKCS12AttrSet}{@attrId}) * } -- This type is compatible with the X.500 type 'Attribute' * * PKCS12AttrSet ATTRIBUTE ::= { * friendlyName | -- from PKCS #9 * localKeyId, -- from PKCS #9 * ... -- Other attributes are allowed * } * * CertBag ::= SEQUENCE { * certId BAG-TYPE.&id ({CertTypes}), * certValue [0] EXPLICIT BAG-TYPE.&Type ({CertTypes}{@certId}) * } * * x509Certificate BAG-TYPE ::= {OCTET STRING IDENTIFIED BY {certTypes 1}} * -- DER-encoded X.509 certificate stored in OCTET STRING * * sdsiCertificate BAG-TYPE ::= {IA5String IDENTIFIED BY {certTypes 2}} * -- Base64-encoded SDSI certificate stored in IA5String * * CertTypes BAG-TYPE ::= { * x509Certificate | * sdsiCertificate, * ... -- For future extensions * } */ var forge = require_forge(); require_asn1(); require_hmac$1(); require_oids(); require_pkcs7asn1(); require_pbe(); require_random(); require_rsa(); require_sha1$1(); require_util$8(); require_x509(); var asn1 = forge.asn1; var pki = forge.pki; var p12 = module.exports = forge.pkcs12 = forge.pkcs12 || {}; var contentInfoValidator = { name: "ContentInfo", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "ContentInfo.contentType", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OID, constructed: false, capture: "contentType" }, { name: "ContentInfo.content", tagClass: asn1.Class.CONTEXT_SPECIFIC, constructed: true, captureAsn1: "content" }] }; var pfxValidator = { name: "PFX", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [ { name: "PFX.version", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.INTEGER, constructed: false, capture: "version" }, contentInfoValidator, { name: "PFX.macData", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, optional: true, captureAsn1: "mac", value: [ { name: "PFX.macData.mac", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "PFX.macData.mac.digestAlgorithm", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "PFX.macData.mac.digestAlgorithm.algorithm", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OID, constructed: false, capture: "macAlgorithm" }, { name: "PFX.macData.mac.digestAlgorithm.parameters", tagClass: asn1.Class.UNIVERSAL, captureAsn1: "macAlgorithmParameters" }] }, { name: "PFX.macData.mac.digest", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OCTETSTRING, constructed: false, capture: "macDigest" }] }, { name: "PFX.macData.macSalt", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OCTETSTRING, constructed: false, capture: "macSalt" }, { name: "PFX.macData.iterations", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.INTEGER, constructed: false, optional: true, capture: "macIterations" } ] } ] }; var safeBagValidator = { name: "SafeBag", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [ { name: "SafeBag.bagId", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OID, constructed: false, capture: "bagId" }, { name: "SafeBag.bagValue", tagClass: asn1.Class.CONTEXT_SPECIFIC, constructed: true, captureAsn1: "bagValue" }, { name: "SafeBag.bagAttributes", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SET, constructed: true, optional: true, capture: "bagAttributes" } ] }; var attributeValidator = { name: "Attribute", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "Attribute.attrId", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OID, constructed: false, capture: "oid" }, { name: "Attribute.attrValues", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SET, constructed: true, capture: "values" }] }; var certBagValidator = { name: "CertBag", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "CertBag.certId", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OID, constructed: false, capture: "certId" }, { name: "CertBag.certValue", tagClass: asn1.Class.CONTEXT_SPECIFIC, constructed: true, value: [{ name: "CertBag.certValue[0]", tagClass: asn1.Class.UNIVERSAL, type: asn1.Class.OCTETSTRING, constructed: false, capture: "cert" }] }] }; /** * Search SafeContents structure for bags with matching attributes. * * The search can optionally be narrowed by a certain bag type. * * @param safeContents the SafeContents structure to search in. * @param attrName the name of the attribute to compare against. * @param attrValue the attribute value to search for. * @param [bagType] bag type to narrow search by. * * @return an array of matching bags. */ function _getBagsByAttribute(safeContents, attrName, attrValue, bagType) { var result = []; for (var i = 0; i < safeContents.length; i++) { for (var j = 0; j < safeContents[i].safeBags.length; j++) { var bag = safeContents[i].safeBags[j]; if (bagType !== undefined && bag.type !== bagType) { continue; } if (attrName === null) { result.push(bag); continue; } if (bag.attributes[attrName] !== undefined && bag.attributes[attrName].indexOf(attrValue) >= 0) { result.push(bag); } } } return result; } /** * Converts a PKCS#12 PFX in ASN.1 notation into a PFX object. * * @param obj The PKCS#12 PFX in ASN.1 notation. * @param strict true to use strict DER decoding, false not to (default: true). * @param {String} password Password to decrypt with (optional). * * @return PKCS#12 PFX object. */ p12.pkcs12FromAsn1 = function(obj, strict, password) { if (typeof strict === "string") { password = strict; strict = true; } else if (strict === undefined) { strict = true; } var capture = {}; var errors = []; if (!asn1.validate(obj, pfxValidator, capture, errors)) { var error = new Error("Cannot read PKCS#12 PFX. " + "ASN.1 object is not an PKCS#12 PFX."); error.errors = error; throw error; } var pfx = { version: capture.version.charCodeAt(0), safeContents: [], getBags: function(filter) { var rval = {}; var localKeyId; if ("localKeyId" in filter) { localKeyId = filter.localKeyId; } else if ("localKeyIdHex" in filter) { localKeyId = forge.util.hexToBytes(filter.localKeyIdHex); } if (localKeyId === undefined && !("friendlyName" in filter) && "bagType" in filter) { rval[filter.bagType] = _getBagsByAttribute(pfx.safeContents, null, null, filter.bagType); } if (localKeyId !== undefined) { rval.localKeyId = _getBagsByAttribute(pfx.safeContents, "localKeyId", localKeyId, filter.bagType); } if ("friendlyName" in filter) { rval.friendlyName = _getBagsByAttribute(pfx.safeContents, "friendlyName", filter.friendlyName, filter.bagType); } return rval; }, getBagsByFriendlyName: function(friendlyName, bagType) { return _getBagsByAttribute(pfx.safeContents, "friendlyName", friendlyName, bagType); }, getBagsByLocalKeyId: function(localKeyId, bagType) { return _getBagsByAttribute(pfx.safeContents, "localKeyId", localKeyId, bagType); } }; if (capture.version.charCodeAt(0) !== 3) { var error = new Error("PKCS#12 PFX of version other than 3 not supported."); error.version = capture.version.charCodeAt(0); throw error; } if (asn1.derToOid(capture.contentType) !== pki.oids.data) { var error = new Error("Only PKCS#12 PFX in password integrity mode supported."); error.oid = asn1.derToOid(capture.contentType); throw error; } var data = capture.content.value[0]; if (data.tagClass !== asn1.Class.UNIVERSAL || data.type !== asn1.Type.OCTETSTRING) { throw new Error("PKCS#12 authSafe content data is not an OCTET STRING."); } data = _decodePkcs7Data(data); if (capture.mac) { var md = null; var macKeyBytes = 0; var macAlgorithm = asn1.derToOid(capture.macAlgorithm); switch (macAlgorithm) { case pki.oids.sha1: md = forge.md.sha1.create(); macKeyBytes = 20; break; case pki.oids.sha256: md = forge.md.sha256.create(); macKeyBytes = 32; break; case pki.oids.sha384: md = forge.md.sha384.create(); macKeyBytes = 48; break; case pki.oids.sha512: md = forge.md.sha512.create(); macKeyBytes = 64; break; case pki.oids.md5: md = forge.md.md5.create(); macKeyBytes = 16; break; } if (md === null) { throw new Error("PKCS#12 uses unsupported MAC algorithm: " + macAlgorithm); } var macSalt = new forge.util.ByteBuffer(capture.macSalt); var macIterations = "macIterations" in capture ? parseInt(forge.util.bytesToHex(capture.macIterations), 16) : 1; var macKey = p12.generateKey(password, macSalt, 3, macIterations, macKeyBytes, md); var mac = forge.hmac.create(); mac.start(md, macKey); mac.update(data.value); var macValue = mac.getMac(); if (macValue.getBytes() !== capture.macDigest) { throw new Error("PKCS#12 MAC could not be verified. Invalid password?"); } } _decodeAuthenticatedSafe(pfx, data.value, strict, password); return pfx; }; /** * Decodes PKCS#7 Data. PKCS#7 (RFC 2315) defines "Data" as an OCTET STRING, * but it is sometimes an OCTET STRING that is composed/constructed of chunks, * each its own OCTET STRING. This is BER-encoding vs. DER-encoding. This * function transforms this corner-case into the usual simple, * non-composed/constructed OCTET STRING. * * This function may be moved to ASN.1 at some point to better deal with * more BER-encoding issues, should they arise. * * @param data the ASN.1 Data object to transform. */ function _decodePkcs7Data(data) { if (data.composed || data.constructed) { var value = forge.util.createBuffer(); for (var i = 0; i < data.value.length; ++i) { value.putBytes(data.value[i].value); } data.composed = data.constructed = false; data.value = value.getBytes(); } return data; } /** * Decode PKCS#12 AuthenticatedSafe (BER encoded) into PFX object. * * The AuthenticatedSafe is a BER-encoded SEQUENCE OF ContentInfo. * * @param pfx The PKCS#12 PFX object to fill. * @param {String} authSafe BER-encoded AuthenticatedSafe. * @param strict true to use strict DER decoding, false not to. * @param {String} password Password to decrypt with (optional). */ function _decodeAuthenticatedSafe(pfx, authSafe, strict, password) { authSafe = asn1.fromDer(authSafe, strict); if (authSafe.tagClass !== asn1.Class.UNIVERSAL || authSafe.type !== asn1.Type.SEQUENCE || authSafe.constructed !== true) { throw new Error("PKCS#12 AuthenticatedSafe expected to be a " + "SEQUENCE OF ContentInfo"); } for (var i = 0; i < authSafe.value.length; i++) { var contentInfo = authSafe.value[i]; var capture = {}; var errors = []; if (!asn1.validate(contentInfo, contentInfoValidator, capture, errors)) { var error = new Error("Cannot read ContentInfo."); error.errors = errors; throw error; } var obj = { encrypted: false }; var safeContents = null; var data = capture.content.value[0]; switch (asn1.derToOid(capture.contentType)) { case pki.oids.data: if (data.tagClass !== asn1.Class.UNIVERSAL || data.type !== asn1.Type.OCTETSTRING) { throw new Error("PKCS#12 SafeContents Data is not an OCTET STRING."); } safeContents = _decodePkcs7Data(data).value; break; case pki.oids.encryptedData: safeContents = _decryptSafeContents(data, password); obj.encrypted = true; break; default: var error = new Error("Unsupported PKCS#12 contentType."); error.contentType = asn1.derToOid(capture.contentType); throw error; } obj.safeBags = _decodeSafeContents(safeContents, strict, password); pfx.safeContents.push(obj); } } /** * Decrypt PKCS#7 EncryptedData structure. * * @param data ASN.1 encoded EncryptedContentInfo object. * @param password The user-provided password. * * @return The decrypted SafeContents (ASN.1 object). */ function _decryptSafeContents(data, password) { var capture = {}; var errors = []; if (!asn1.validate(data, forge.pkcs7.asn1.encryptedDataValidator, capture, errors)) { var error = new Error("Cannot read EncryptedContentInfo."); error.errors = errors; throw error; } var oid = asn1.derToOid(capture.contentType); if (oid !== pki.oids.data) { var error = new Error("PKCS#12 EncryptedContentInfo ContentType is not Data."); error.oid = oid; throw error; } oid = asn1.derToOid(capture.encAlgorithm); var cipher = pki.pbe.getCipher(oid, capture.encParameter, password); var encryptedContentAsn1 = _decodePkcs7Data(capture.encryptedContentAsn1); var encrypted = forge.util.createBuffer(encryptedContentAsn1.value); cipher.update(encrypted); if (!cipher.finish()) { throw new Error("Failed to decrypt PKCS#12 SafeContents."); } return cipher.output.getBytes(); } /** * Decode PKCS#12 SafeContents (BER-encoded) into array of Bag objects. * * The safeContents is a BER-encoded SEQUENCE OF SafeBag. * * @param {String} safeContents BER-encoded safeContents. * @param strict true to use strict DER decoding, false not to. * @param {String} password Password to decrypt with (optional). * * @return {Array} Array of Bag objects. */ function _decodeSafeContents(safeContents, strict, password) { if (!strict && safeContents.length === 0) { return []; } safeContents = asn1.fromDer(safeContents, strict); if (safeContents.tagClass !== asn1.Class.UNIVERSAL || safeContents.type !== asn1.Type.SEQUENCE || safeContents.constructed !== true) { throw new Error("PKCS#12 SafeContents expected to be a SEQUENCE OF SafeBag."); } var res = []; for (var i = 0; i < safeContents.value.length; i++) { var safeBag = safeContents.value[i]; var capture = {}; var errors = []; if (!asn1.validate(safeBag, safeBagValidator, capture, errors)) { var error = new Error("Cannot read SafeBag."); error.errors = errors; throw error; } var bag = { type: asn1.derToOid(capture.bagId), attributes: _decodeBagAttributes(capture.bagAttributes) }; res.push(bag); var validator, decoder; var bagAsn1 = capture.bagValue.value[0]; switch (bag.type) { case pki.oids.pkcs8ShroudedKeyBag: bagAsn1 = pki.decryptPrivateKeyInfo(bagAsn1, password); if (bagAsn1 === null) { throw new Error("Unable to decrypt PKCS#8 ShroudedKeyBag, wrong password?"); } case pki.oids.keyBag: try { bag.key = pki.privateKeyFromAsn1(bagAsn1); } catch (e) { bag.key = null; bag.asn1 = bagAsn1; } continue; case pki.oids.certBag: validator = certBagValidator; decoder = function() { if (asn1.derToOid(capture.certId) !== pki.oids.x509Certificate) { var error = new Error("Unsupported certificate type, only X.509 supported."); error.oid = asn1.derToOid(capture.certId); throw error; } var certAsn1 = asn1.fromDer(capture.cert, strict); try { bag.cert = pki.certificateFromAsn1(certAsn1, true); } catch (e) { bag.cert = null; bag.asn1 = certAsn1; } }; break; default: var error = new Error("Unsupported PKCS#12 SafeBag type."); error.oid = bag.type; throw error; } if (validator !== undefined && !asn1.validate(bagAsn1, validator, capture, errors)) { var error = new Error("Cannot read PKCS#12 " + validator.name); error.errors = errors; throw error; } decoder(); } return res; } /** * Decode PKCS#12 SET OF PKCS12Attribute into JavaScript object. * * @param attributes SET OF PKCS12Attribute (ASN.1 object). * * @return the decoded attributes. */ function _decodeBagAttributes(attributes) { var decodedAttrs = {}; if (attributes !== undefined) { for (var i = 0; i < attributes.length; ++i) { var capture = {}; var errors = []; if (!asn1.validate(attributes[i], attributeValidator, capture, errors)) { var error = new Error("Cannot read PKCS#12 BagAttribute."); error.errors = errors; throw error; } var oid = asn1.derToOid(capture.oid); if (pki.oids[oid] === undefined) { continue; } decodedAttrs[pki.oids[oid]] = []; for (var j = 0; j < capture.values.length; ++j) { decodedAttrs[pki.oids[oid]].push(capture.values[j].value); } } } return decodedAttrs; } /** * Wraps a private key and certificate in a PKCS#12 PFX wrapper. If a * password is provided then the private key will be encrypted. * * An entire certificate chain may also be included. To do this, pass * an array for the "cert" parameter where the first certificate is * the one that is paired with the private key and each subsequent one * verifies the previous one. The certificates may be in PEM format or * have been already parsed by Forge. * * @todo implement password-based-encryption for the whole package * * @param key the private key. * @param cert the certificate (may be an array of certificates in order * to specify a certificate chain). * @param password the password to use, null for none. * @param options: * algorithm the encryption algorithm to use * ('aes128', 'aes192', 'aes256', '3des'), defaults to 'aes128'. * count the iteration count to use. * saltSize the salt size to use. * useMac true to include a MAC, false not to, defaults to true. * localKeyId the local key ID to use, in hex. * friendlyName the friendly name to use. * generateLocalKeyId true to generate a random local key ID, * false not to, defaults to true. * * @return the PKCS#12 PFX ASN.1 object. */ p12.toPkcs12Asn1 = function(key, cert, password, options) { options = options || {}; options.saltSize = options.saltSize || 8; options.count = options.count || 2048; options.algorithm = options.algorithm || options.encAlgorithm || "aes128"; if (!("useMac" in options)) { options.useMac = true; } if (!("localKeyId" in options)) { options.localKeyId = null; } if (!("generateLocalKeyId" in options)) { options.generateLocalKeyId = true; } var localKeyId = options.localKeyId; var bagAttrs; if (localKeyId !== null) { localKeyId = forge.util.hexToBytes(localKeyId); } else if (options.generateLocalKeyId) { if (cert) { var pairedCert = forge.util.isArray(cert) ? cert[0] : cert; if (typeof pairedCert === "string") { pairedCert = pki.certificateFromPem(pairedCert); } var sha1 = forge.md.sha1.create(); sha1.update(asn1.toDer(pki.certificateToAsn1(pairedCert)).getBytes()); localKeyId = sha1.digest().getBytes(); } else { localKeyId = forge.random.getBytes(20); } } var attrs = []; if (localKeyId !== null) { attrs.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(pki.oids.localKeyId).getBytes()), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, localKeyId)])])); } if ("friendlyName" in options) { attrs.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(pki.oids.friendlyName).getBytes()), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BMPSTRING, false, options.friendlyName)])])); } if (attrs.length > 0) { bagAttrs = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, attrs); } var contents = []; var chain = []; if (cert !== null) { if (forge.util.isArray(cert)) { chain = cert; } else { chain = [cert]; } } var certSafeBags = []; for (var i = 0; i < chain.length; ++i) { cert = chain[i]; if (typeof cert === "string") { cert = pki.certificateFromPem(cert); } var certBagAttrs = i === 0 ? bagAttrs : undefined; var certAsn1 = pki.certificateToAsn1(cert); var certSafeBag = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(pki.oids.certBag).getBytes()), asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(pki.oids.x509Certificate).getBytes()), asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, asn1.toDer(certAsn1).getBytes())])])]), certBagAttrs ]); certSafeBags.push(certSafeBag); } if (certSafeBags.length > 0) { var certSafeContents = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, certSafeBags); var certCI = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(pki.oids.data).getBytes()), asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, asn1.toDer(certSafeContents).getBytes())])]); contents.push(certCI); } var keyBag = null; if (key !== null) { var pkAsn1 = pki.wrapRsaPrivateKey(pki.privateKeyToAsn1(key)); if (password === null) { keyBag = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(pki.oids.keyBag).getBytes()), asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [pkAsn1]), bagAttrs ]); } else { keyBag = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(pki.oids.pkcs8ShroudedKeyBag).getBytes()), asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [pki.encryptPrivateKeyInfo(pkAsn1, password, options)]), bagAttrs ]); } var keySafeContents = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [keyBag]); var keyCI = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(pki.oids.data).getBytes()), asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, asn1.toDer(keySafeContents).getBytes())])]); contents.push(keyCI); } var safe = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, contents); var macData; if (options.useMac) { var sha1 = forge.md.sha1.create(); var macSalt = new forge.util.ByteBuffer(forge.random.getBytes(options.saltSize)); var count = options.count; var key = p12.generateKey(password, macSalt, 3, count, 20); var mac = forge.hmac.create(); mac.start(sha1, key); mac.update(asn1.toDer(safe).getBytes()); var macValue = mac.getMac(); macData = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(pki.oids.sha1).getBytes()), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, "")]), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, macValue.getBytes())]), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, macSalt.getBytes()), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, asn1.integerToDer(count).getBytes()) ]); } return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, asn1.integerToDer(3).getBytes()), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(pki.oids.data).getBytes()), asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, asn1.toDer(safe).getBytes())])]), macData ]); }; /** * Derives a PKCS#12 key. * * @param password the password to derive the key material from, null or * undefined for none. * @param salt the salt, as a ByteBuffer, to use. * @param id the PKCS#12 ID byte (1 = key material, 2 = IV, 3 = MAC). * @param iter the iteration count. * @param n the number of bytes to derive from the password. * @param md the message digest to use, defaults to SHA-1. * * @return a ByteBuffer with the bytes derived from the password. */ p12.generateKey = forge.pbe.generatePkcs12Key; })); //#endregion //#region ../node_modules/node-forge/lib/pki.js var require_pki = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Javascript implementation of a basic Public Key Infrastructure, including * support for RSA public and private keys. * * @author Dave Longley * * Copyright (c) 2010-2013 Digital Bazaar, Inc. */ var forge = require_forge(); require_asn1(); require_oids(); require_pbe(); require_pem(); require_pbkdf2$1(); require_pkcs12(); require_pss(); require_rsa(); require_util$8(); require_x509(); var asn1 = forge.asn1; var pki = module.exports = forge.pki = forge.pki || {}; /** * NOTE: THIS METHOD IS DEPRECATED. Use pem.decode() instead. * * Converts PEM-formatted data to DER. * * @param pem the PEM-formatted data. * * @return the DER-formatted data. */ pki.pemToDer = function(pem) { var msg = forge.pem.decode(pem)[0]; if (msg.procType && msg.procType.type === "ENCRYPTED") { throw new Error("Could not convert PEM to DER; PEM is encrypted."); } return forge.util.createBuffer(msg.body); }; /** * Converts an RSA private key from PEM format. * * @param pem the PEM-formatted private key. * * @return the private key. */ pki.privateKeyFromPem = function(pem) { var msg = forge.pem.decode(pem)[0]; if (msg.type !== "PRIVATE KEY" && msg.type !== "RSA PRIVATE KEY") { var error = new Error("Could not convert private key from PEM; PEM " + "header type is not \"PRIVATE KEY\" or \"RSA PRIVATE KEY\"."); error.headerType = msg.type; throw error; } if (msg.procType && msg.procType.type === "ENCRYPTED") { throw new Error("Could not convert private key from PEM; PEM is encrypted."); } var obj = asn1.fromDer(msg.body); return pki.privateKeyFromAsn1(obj); }; /** * Converts an RSA private key to PEM format. * * @param key the private key. * @param maxline the maximum characters per line, defaults to 64. * * @return the PEM-formatted private key. */ pki.privateKeyToPem = function(key, maxline) { var msg = { type: "RSA PRIVATE KEY", body: asn1.toDer(pki.privateKeyToAsn1(key)).getBytes() }; return forge.pem.encode(msg, { maxline }); }; /** * Converts a PrivateKeyInfo to PEM format. * * @param pki the PrivateKeyInfo. * @param maxline the maximum characters per line, defaults to 64. * * @return the PEM-formatted private key. */ pki.privateKeyInfoToPem = function(pki, maxline) { var msg = { type: "PRIVATE KEY", body: asn1.toDer(pki).getBytes() }; return forge.pem.encode(msg, { maxline }); }; })); //#endregion //#region ../node_modules/node-forge/lib/tls.js var require_tls = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * A Javascript implementation of Transport Layer Security (TLS). * * @author Dave Longley * * Copyright (c) 2009-2014 Digital Bazaar, Inc. * * The TLS Handshake Protocol involves the following steps: * * - Exchange hello messages to agree on algorithms, exchange random values, * and check for session resumption. * * - Exchange the necessary cryptographic parameters to allow the client and * server to agree on a premaster secret. * * - Exchange certificates and cryptographic information to allow the client * and server to authenticate themselves. * * - Generate a master secret from the premaster secret and exchanged random * values. * * - Provide security parameters to the record layer. * * - Allow the client and server to verify that their peer has calculated the * same security parameters and that the handshake occurred without tampering * by an attacker. * * Up to 4 different messages may be sent during a key exchange. The server * certificate, the server key exchange, the client certificate, and the * client key exchange. * * A typical handshake (from the client's perspective). * * 1. Client sends ClientHello. * 2. Client receives ServerHello. * 3. Client receives optional Certificate. * 4. Client receives optional ServerKeyExchange. * 5. Client receives ServerHelloDone. * 6. Client sends optional Certificate. * 7. Client sends ClientKeyExchange. * 8. Client sends optional CertificateVerify. * 9. Client sends ChangeCipherSpec. * 10. Client sends Finished. * 11. Client receives ChangeCipherSpec. * 12. Client receives Finished. * 13. Client sends/receives application data. * * To reuse an existing session: * * 1. Client sends ClientHello with session ID for reuse. * 2. Client receives ServerHello with same session ID if reusing. * 3. Client receives ChangeCipherSpec message if reusing. * 4. Client receives Finished. * 5. Client sends ChangeCipherSpec. * 6. Client sends Finished. * * Note: Client ignores HelloRequest if in the middle of a handshake. * * Record Layer: * * The record layer fragments information blocks into TLSPlaintext records * carrying data in chunks of 2^14 bytes or less. Client message boundaries are * not preserved in the record layer (i.e., multiple client messages of the * same ContentType MAY be coalesced into a single TLSPlaintext record, or a * single message MAY be fragmented across several records). * * struct { * uint8 major; * uint8 minor; * } ProtocolVersion; * * struct { * ContentType type; * ProtocolVersion version; * uint16 length; * opaque fragment[TLSPlaintext.length]; * } TLSPlaintext; * * type: * The higher-level protocol used to process the enclosed fragment. * * version: * The version of the protocol being employed. TLS Version 1.2 uses version * {3, 3}. TLS Version 1.0 uses version {3, 1}. Note that a client that * supports multiple versions of TLS may not know what version will be * employed before it receives the ServerHello. * * length: * The length (in bytes) of the following TLSPlaintext.fragment. The length * MUST NOT exceed 2^14 = 16384 bytes. * * fragment: * The application data. This data is transparent and treated as an * independent block to be dealt with by the higher-level protocol specified * by the type field. * * Implementations MUST NOT send zero-length fragments of Handshake, Alert, or * ChangeCipherSpec content types. Zero-length fragments of Application data * MAY be sent as they are potentially useful as a traffic analysis * countermeasure. * * Note: Data of different TLS record layer content types MAY be interleaved. * Application data is generally of lower precedence for transmission than * other content types. However, records MUST be delivered to the network in * the same order as they are protected by the record layer. Recipients MUST * receive and process interleaved application layer traffic during handshakes * subsequent to the first one on a connection. * * struct { * ContentType type; // same as TLSPlaintext.type * ProtocolVersion version;// same as TLSPlaintext.version * uint16 length; * opaque fragment[TLSCompressed.length]; * } TLSCompressed; * * length: * The length (in bytes) of the following TLSCompressed.fragment. * The length MUST NOT exceed 2^14 + 1024. * * fragment: * The compressed form of TLSPlaintext.fragment. * * Note: A CompressionMethod.null operation is an identity operation; no fields * are altered. In this implementation, since no compression is supported, * uncompressed records are always the same as compressed records. * * Encryption Information: * * The encryption and MAC functions translate a TLSCompressed structure into a * TLSCiphertext. The decryption functions reverse the process. The MAC of the * record also includes a sequence number so that missing, extra, or repeated * messages are detectable. * * struct { * ContentType type; * ProtocolVersion version; * uint16 length; * select (SecurityParameters.cipher_type) { * case stream: GenericStreamCipher; * case block: GenericBlockCipher; * case aead: GenericAEADCipher; * } fragment; * } TLSCiphertext; * * type: * The type field is identical to TLSCompressed.type. * * version: * The version field is identical to TLSCompressed.version. * * length: * The length (in bytes) of the following TLSCiphertext.fragment. * The length MUST NOT exceed 2^14 + 2048. * * fragment: * The encrypted form of TLSCompressed.fragment, with the MAC. * * Note: Only CBC Block Ciphers are supported by this implementation. * * The TLSCompressed.fragment structures are converted to/from block * TLSCiphertext.fragment structures. * * struct { * opaque IV[SecurityParameters.record_iv_length]; * block-ciphered struct { * opaque content[TLSCompressed.length]; * opaque MAC[SecurityParameters.mac_length]; * uint8 padding[GenericBlockCipher.padding_length]; * uint8 padding_length; * }; * } GenericBlockCipher; * * The MAC is generated as described in Section 6.2.3.1. * * IV: * The Initialization Vector (IV) SHOULD be chosen at random, and MUST be * unpredictable. Note that in versions of TLS prior to 1.1, there was no * IV field, and the last ciphertext block of the previous record (the "CBC * residue") was used as the IV. This was changed to prevent the attacks * described in [CBCATT]. For block ciphers, the IV length is of length * SecurityParameters.record_iv_length, which is equal to the * SecurityParameters.block_size. * * padding: * Padding that is added to force the length of the plaintext to be an * integral multiple of the block cipher's block length. The padding MAY be * any length up to 255 bytes, as long as it results in the * TLSCiphertext.length being an integral multiple of the block length. * Lengths longer than necessary might be desirable to frustrate attacks on * a protocol that are based on analysis of the lengths of exchanged * messages. Each uint8 in the padding data vector MUST be filled with the * padding length value. The receiver MUST check this padding and MUST use * the bad_record_mac alert to indicate padding errors. * * padding_length: * The padding length MUST be such that the total size of the * GenericBlockCipher structure is a multiple of the cipher's block length. * Legal values range from zero to 255, inclusive. This length specifies the * length of the padding field exclusive of the padding_length field itself. * * The encrypted data length (TLSCiphertext.length) is one more than the sum of * SecurityParameters.block_length, TLSCompressed.length, * SecurityParameters.mac_length, and padding_length. * * Example: If the block length is 8 bytes, the content length * (TLSCompressed.length) is 61 bytes, and the MAC length is 20 bytes, then the * length before padding is 82 bytes (this does not include the IV. Thus, the * padding length modulo 8 must be equal to 6 in order to make the total length * an even multiple of 8 bytes (the block length). The padding length can be * 6, 14, 22, and so on, through 254. If the padding length were the minimum * necessary, 6, the padding would be 6 bytes, each containing the value 6. * Thus, the last 8 octets of the GenericBlockCipher before block encryption * would be xx 06 06 06 06 06 06 06, where xx is the last octet of the MAC. * * Note: With block ciphers in CBC mode (Cipher Block Chaining), it is critical * that the entire plaintext of the record be known before any ciphertext is * transmitted. Otherwise, it is possible for the attacker to mount the attack * described in [CBCATT]. * * Implementation note: Canvel et al. [CBCTIME] have demonstrated a timing * attack on CBC padding based on the time required to compute the MAC. In * order to defend against this attack, implementations MUST ensure that * record processing time is essentially the same whether or not the padding * is correct. In general, the best way to do this is to compute the MAC even * if the padding is incorrect, and only then reject the packet. For instance, * if the pad appears to be incorrect, the implementation might assume a * zero-length pad and then compute the MAC. This leaves a small timing * channel, since MAC performance depends, to some extent, on the size of the * data fragment, but it is not believed to be large enough to be exploitable, * due to the large block size of existing MACs and the small size of the * timing signal. */ var forge = require_forge(); require_asn1(); require_hmac$1(); require_md5$1(); require_pem(); require_pki(); require_random(); require_sha1$1(); require_util$8(); /** * Generates pseudo random bytes by mixing the result of two hash functions, * MD5 and SHA-1. * * prf_TLS1(secret, label, seed) = * P_MD5(S1, label + seed) XOR P_SHA-1(S2, label + seed); * * Each P_hash function functions as follows: * * P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) + * HMAC_hash(secret, A(2) + seed) + * HMAC_hash(secret, A(3) + seed) + ... * A() is defined as: * A(0) = seed * A(i) = HMAC_hash(secret, A(i-1)) * * The '+' operator denotes concatenation. * * As many iterations A(N) as are needed are performed to generate enough * pseudo random byte output. If an iteration creates more data than is * necessary, then it is truncated. * * Therefore: * A(1) = HMAC_hash(secret, A(0)) * = HMAC_hash(secret, seed) * A(2) = HMAC_hash(secret, A(1)) * = HMAC_hash(secret, HMAC_hash(secret, seed)) * * Therefore: * P_hash(secret, seed) = * HMAC_hash(secret, HMAC_hash(secret, A(0)) + seed) + * HMAC_hash(secret, HMAC_hash(secret, A(1)) + seed) + * ... * * Therefore: * P_hash(secret, seed) = * HMAC_hash(secret, HMAC_hash(secret, seed) + seed) + * HMAC_hash(secret, HMAC_hash(secret, HMAC_hash(secret, seed)) + seed) + * ... * * @param secret the secret to use. * @param label the label to use. * @param seed the seed value to use. * @param length the number of bytes to generate. * * @return the pseudo random bytes in a byte buffer. */ var prf_TLS1 = function(secret, label, seed, length) { var rval = forge.util.createBuffer(); var idx = secret.length >> 1; var slen = idx + (secret.length & 1); var s1 = secret.substr(0, slen); var s2 = secret.substr(idx, slen); var ai = forge.util.createBuffer(); var hmac = forge.hmac.create(); seed = label + seed; var md5itr = Math.ceil(length / 16); var sha1itr = Math.ceil(length / 20); hmac.start("MD5", s1); var md5bytes = forge.util.createBuffer(); ai.putBytes(seed); for (var i = 0; i < md5itr; ++i) { hmac.start(null, null); hmac.update(ai.getBytes()); ai.putBuffer(hmac.digest()); hmac.start(null, null); hmac.update(ai.bytes() + seed); md5bytes.putBuffer(hmac.digest()); } hmac.start("SHA1", s2); var sha1bytes = forge.util.createBuffer(); ai.clear(); ai.putBytes(seed); for (var i = 0; i < sha1itr; ++i) { hmac.start(null, null); hmac.update(ai.getBytes()); ai.putBuffer(hmac.digest()); hmac.start(null, null); hmac.update(ai.bytes() + seed); sha1bytes.putBuffer(hmac.digest()); } rval.putBytes(forge.util.xorBytes(md5bytes.getBytes(), sha1bytes.getBytes(), length)); return rval; }; /** * Generates pseudo random bytes using a SHA256 algorithm. For TLS 1.2. * * @param secret the secret to use. * @param label the label to use. * @param seed the seed value to use. * @param length the number of bytes to generate. * * @return the pseudo random bytes in a byte buffer. */ var prf_sha256 = function(secret, label, seed, length) {}; /** * Gets a MAC for a record using the SHA-1 hash algorithm. * * @param key the mac key. * @param state the sequence number (array of two 32-bit integers). * @param record the record. * * @return the sha-1 hash (20 bytes) for the given record. */ var hmac_sha1 = function(key, seqNum, record) { var hmac = forge.hmac.create(); hmac.start("SHA1", key); var b = forge.util.createBuffer(); b.putInt32(seqNum[0]); b.putInt32(seqNum[1]); b.putByte(record.type); b.putByte(record.version.major); b.putByte(record.version.minor); b.putInt16(record.length); b.putBytes(record.fragment.bytes()); hmac.update(b.getBytes()); return hmac.digest().getBytes(); }; /** * Compresses the TLSPlaintext record into a TLSCompressed record using the * deflate algorithm. * * @param c the TLS connection. * @param record the TLSPlaintext record to compress. * @param s the ConnectionState to use. * * @return true on success, false on failure. */ var deflate = function(c, record, s) { var rval = false; try { var bytes = c.deflate(record.fragment.getBytes()); record.fragment = forge.util.createBuffer(bytes); record.length = bytes.length; rval = true; } catch (ex) {} return rval; }; /** * Decompresses the TLSCompressed record into a TLSPlaintext record using the * deflate algorithm. * * @param c the TLS connection. * @param record the TLSCompressed record to decompress. * @param s the ConnectionState to use. * * @return true on success, false on failure. */ var inflate = function(c, record, s) { var rval = false; try { var bytes = c.inflate(record.fragment.getBytes()); record.fragment = forge.util.createBuffer(bytes); record.length = bytes.length; rval = true; } catch (ex) {} return rval; }; /** * Reads a TLS variable-length vector from a byte buffer. * * Variable-length vectors are defined by specifying a subrange of legal * lengths, inclusively, using the notation . When these are * encoded, the actual length precedes the vector's contents in the byte * stream. The length will be in the form of a number consuming as many bytes * as required to hold the vector's specified maximum (ceiling) length. A * variable-length vector with an actual length field of zero is referred to * as an empty vector. * * @param b the byte buffer. * @param lenBytes the number of bytes required to store the length. * * @return the resulting byte buffer. */ var readVector = function(b, lenBytes) { var len = 0; switch (lenBytes) { case 1: len = b.getByte(); break; case 2: len = b.getInt16(); break; case 3: len = b.getInt24(); break; case 4: len = b.getInt32(); break; } return forge.util.createBuffer(b.getBytes(len)); }; /** * Writes a TLS variable-length vector to a byte buffer. * * @param b the byte buffer. * @param lenBytes the number of bytes required to store the length. * @param v the byte buffer vector. */ var writeVector = function(b, lenBytes, v) { b.putInt(v.length(), lenBytes << 3); b.putBuffer(v); }; /** * The tls implementation. */ var tls = {}; /** * Version: TLS 1.2 = 3.3, TLS 1.1 = 3.2, TLS 1.0 = 3.1. Both TLS 1.1 and * TLS 1.2 were still too new (ie: openSSL didn't implement them) at the time * of this implementation so TLS 1.0 was implemented instead. */ tls.Versions = { TLS_1_0: { major: 3, minor: 1 }, TLS_1_1: { major: 3, minor: 2 }, TLS_1_2: { major: 3, minor: 3 } }; tls.SupportedVersions = [tls.Versions.TLS_1_1, tls.Versions.TLS_1_0]; tls.Version = tls.SupportedVersions[0]; /** * Maximum fragment size. True maximum is 16384, but we fragment before that * to allow for unusual small increases during compression. */ tls.MaxFragment = 16384 - 1024; /** * Whether this entity is considered the "client" or "server". * enum { server, client } ConnectionEnd; */ tls.ConnectionEnd = { server: 0, client: 1 }; /** * Pseudo-random function algorithm used to generate keys from the master * secret. * enum { tls_prf_sha256 } PRFAlgorithm; */ tls.PRFAlgorithm = { tls_prf_sha256: 0 }; /** * Bulk encryption algorithms. * enum { null, rc4, des3, aes } BulkCipherAlgorithm; */ tls.BulkCipherAlgorithm = { none: null, rc4: 0, des3: 1, aes: 2 }; /** * Cipher types. * enum { stream, block, aead } CipherType; */ tls.CipherType = { stream: 0, block: 1, aead: 2 }; /** * MAC (Message Authentication Code) algorithms. * enum { null, hmac_md5, hmac_sha1, hmac_sha256, * hmac_sha384, hmac_sha512} MACAlgorithm; */ tls.MACAlgorithm = { none: null, hmac_md5: 0, hmac_sha1: 1, hmac_sha256: 2, hmac_sha384: 3, hmac_sha512: 4 }; /** * Compression algorithms. * enum { null(0), deflate(1), (255) } CompressionMethod; */ tls.CompressionMethod = { none: 0, deflate: 1 }; /** * TLS record content types. * enum { * change_cipher_spec(20), alert(21), handshake(22), * application_data(23), (255) * } ContentType; */ tls.ContentType = { change_cipher_spec: 20, alert: 21, handshake: 22, application_data: 23, heartbeat: 24 }; /** * TLS handshake types. * enum { * hello_request(0), client_hello(1), server_hello(2), * certificate(11), server_key_exchange (12), * certificate_request(13), server_hello_done(14), * certificate_verify(15), client_key_exchange(16), * finished(20), (255) * } HandshakeType; */ tls.HandshakeType = { hello_request: 0, client_hello: 1, server_hello: 2, certificate: 11, server_key_exchange: 12, certificate_request: 13, server_hello_done: 14, certificate_verify: 15, client_key_exchange: 16, finished: 20 }; /** * TLS Alert Protocol. * * enum { warning(1), fatal(2), (255) } AlertLevel; * * enum { * close_notify(0), * unexpected_message(10), * bad_record_mac(20), * decryption_failed(21), * record_overflow(22), * decompression_failure(30), * handshake_failure(40), * bad_certificate(42), * unsupported_certificate(43), * certificate_revoked(44), * certificate_expired(45), * certificate_unknown(46), * illegal_parameter(47), * unknown_ca(48), * access_denied(49), * decode_error(50), * decrypt_error(51), * export_restriction(60), * protocol_version(70), * insufficient_security(71), * internal_error(80), * user_canceled(90), * no_renegotiation(100), * (255) * } AlertDescription; * * struct { * AlertLevel level; * AlertDescription description; * } Alert; */ tls.Alert = {}; tls.Alert.Level = { warning: 1, fatal: 2 }; tls.Alert.Description = { close_notify: 0, unexpected_message: 10, bad_record_mac: 20, decryption_failed: 21, record_overflow: 22, decompression_failure: 30, handshake_failure: 40, bad_certificate: 42, unsupported_certificate: 43, certificate_revoked: 44, certificate_expired: 45, certificate_unknown: 46, illegal_parameter: 47, unknown_ca: 48, access_denied: 49, decode_error: 50, decrypt_error: 51, export_restriction: 60, protocol_version: 70, insufficient_security: 71, internal_error: 80, user_canceled: 90, no_renegotiation: 100 }; /** * TLS Heartbeat Message types. * enum { * heartbeat_request(1), * heartbeat_response(2), * (255) * } HeartbeatMessageType; */ tls.HeartbeatMessageType = { heartbeat_request: 1, heartbeat_response: 2 }; /** * Supported cipher suites. */ tls.CipherSuites = {}; /** * Gets a supported cipher suite from its 2 byte ID. * * @param twoBytes two bytes in a string. * * @return the matching supported cipher suite or null. */ tls.getCipherSuite = function(twoBytes) { var rval = null; for (var key in tls.CipherSuites) { var cs = tls.CipherSuites[key]; if (cs.id[0] === twoBytes.charCodeAt(0) && cs.id[1] === twoBytes.charCodeAt(1)) { rval = cs; break; } } return rval; }; /** * Called when an unexpected record is encountered. * * @param c the connection. * @param record the record. */ tls.handleUnexpected = function(c, record) { var ignore = !c.open && c.entity === tls.ConnectionEnd.client; if (!ignore) { c.error(c, { message: "Unexpected message. Received TLS record out of order.", send: true, alert: { level: tls.Alert.Level.fatal, description: tls.Alert.Description.unexpected_message } }); } }; /** * Called when a client receives a HelloRequest record. * * @param c the connection. * @param record the record. * @param length the length of the handshake message. */ tls.handleHelloRequest = function(c, record, length) { if (!c.handshaking && c.handshakes > 0) { tls.queue(c, tls.createAlert(c, { level: tls.Alert.Level.warning, description: tls.Alert.Description.no_renegotiation })); tls.flush(c); } c.process(); }; /** * Parses a hello message from a ClientHello or ServerHello record. * * @param record the record to parse. * * @return the parsed message. */ tls.parseHelloMessage = function(c, record, length) { var msg = null; var client = c.entity === tls.ConnectionEnd.client; if (length < 38) { c.error(c, { message: client ? "Invalid ServerHello message. Message too short." : "Invalid ClientHello message. Message too short.", send: true, alert: { level: tls.Alert.Level.fatal, description: tls.Alert.Description.illegal_parameter } }); } else { var b = record.fragment; var remaining = b.length(); msg = { version: { major: b.getByte(), minor: b.getByte() }, random: forge.util.createBuffer(b.getBytes(32)), session_id: readVector(b, 1), extensions: [] }; if (client) { msg.cipher_suite = b.getBytes(2); msg.compression_method = b.getByte(); } else { msg.cipher_suites = readVector(b, 2); msg.compression_methods = readVector(b, 1); } remaining = length - (remaining - b.length()); if (remaining > 0) { var exts = readVector(b, 2); while (exts.length() > 0) { msg.extensions.push({ type: [exts.getByte(), exts.getByte()], data: readVector(exts, 2) }); } if (!client) { for (var i = 0; i < msg.extensions.length; ++i) { var ext = msg.extensions[i]; if (ext.type[0] === 0 && ext.type[1] === 0) { var snl = readVector(ext.data, 2); while (snl.length() > 0) { var snType = snl.getByte(); if (snType !== 0) { break; } c.session.extensions.server_name.serverNameList.push(readVector(snl, 2).getBytes()); } } } } } if (c.session.version) { if (msg.version.major !== c.session.version.major || msg.version.minor !== c.session.version.minor) { return c.error(c, { message: "TLS version change is disallowed during renegotiation.", send: true, alert: { level: tls.Alert.Level.fatal, description: tls.Alert.Description.protocol_version } }); } } if (client) { c.session.cipherSuite = tls.getCipherSuite(msg.cipher_suite); } else { var tmp = forge.util.createBuffer(msg.cipher_suites.bytes()); while (tmp.length() > 0) { c.session.cipherSuite = tls.getCipherSuite(tmp.getBytes(2)); if (c.session.cipherSuite !== null) { break; } } } if (c.session.cipherSuite === null) { return c.error(c, { message: "No cipher suites in common.", send: true, alert: { level: tls.Alert.Level.fatal, description: tls.Alert.Description.handshake_failure }, cipherSuite: forge.util.bytesToHex(msg.cipher_suite) }); } if (client) { c.session.compressionMethod = msg.compression_method; } else { c.session.compressionMethod = tls.CompressionMethod.none; } } return msg; }; /** * Creates security parameters for the given connection based on the given * hello message. * * @param c the TLS connection. * @param msg the hello message. */ tls.createSecurityParameters = function(c, msg) { var client = c.entity === tls.ConnectionEnd.client; var msgRandom = msg.random.bytes(); var cRandom = client ? c.session.sp.client_random : msgRandom; var sRandom = client ? msgRandom : tls.createRandom().getBytes(); c.session.sp = { entity: c.entity, prf_algorithm: tls.PRFAlgorithm.tls_prf_sha256, bulk_cipher_algorithm: null, cipher_type: null, enc_key_length: null, block_length: null, fixed_iv_length: null, record_iv_length: null, mac_algorithm: null, mac_length: null, mac_key_length: null, compression_algorithm: c.session.compressionMethod, pre_master_secret: null, master_secret: null, client_random: cRandom, server_random: sRandom }; }; /** * Called when a client receives a ServerHello record. * * When a ServerHello message will be sent: * The server will send this message in response to a client hello message * when it was able to find an acceptable set of algorithms. If it cannot * find such a match, it will respond with a handshake failure alert. * * uint24 length; * struct { * ProtocolVersion server_version; * Random random; * SessionID session_id; * CipherSuite cipher_suite; * CompressionMethod compression_method; * select(extensions_present) { * case false: * struct {}; * case true: * Extension extensions<0..2^16-1>; * }; * } ServerHello; * * @param c the connection. * @param record the record. * @param length the length of the handshake message. */ tls.handleServerHello = function(c, record, length) { var msg = tls.parseHelloMessage(c, record, length); if (c.fail) { return; } if (msg.version.minor <= c.version.minor) { c.version.minor = msg.version.minor; } else { return c.error(c, { message: "Incompatible TLS version.", send: true, alert: { level: tls.Alert.Level.fatal, description: tls.Alert.Description.protocol_version } }); } c.session.version = c.version; var sessionId = msg.session_id.bytes(); if (sessionId.length > 0 && sessionId === c.session.id) { c.expect = SCC; c.session.resuming = true; c.session.sp.server_random = msg.random.bytes(); } else { c.expect = SCE; c.session.resuming = false; tls.createSecurityParameters(c, msg); } c.session.id = sessionId; c.process(); }; /** * Called when a server receives a ClientHello record. * * When a ClientHello message will be sent: * When a client first connects to a server it is required to send the * client hello as its first message. The client can also send a client * hello in response to a hello request or on its own initiative in order * to renegotiate the security parameters in an existing connection. * * @param c the connection. * @param record the record. * @param length the length of the handshake message. */ tls.handleClientHello = function(c, record, length) { var msg = tls.parseHelloMessage(c, record, length); if (c.fail) { return; } var sessionId = msg.session_id.bytes(); var session = null; if (c.sessionCache) { session = c.sessionCache.getSession(sessionId); if (session === null) { sessionId = ""; } else if (session.version.major !== msg.version.major || session.version.minor > msg.version.minor) { session = null; sessionId = ""; } } if (sessionId.length === 0) { sessionId = forge.random.getBytes(32); } c.session.id = sessionId; c.session.clientHelloVersion = msg.version; c.session.sp = {}; if (session) { c.version = c.session.version = session.version; c.session.sp = session.sp; } else { var version; for (var i = 1; i < tls.SupportedVersions.length; ++i) { version = tls.SupportedVersions[i]; if (version.minor <= msg.version.minor) { break; } } c.version = { major: version.major, minor: version.minor }; c.session.version = c.version; } if (session !== null) { c.expect = CCC; c.session.resuming = true; c.session.sp.client_random = msg.random.bytes(); } else { c.expect = c.verifyClient !== false ? CCE : CKE; c.session.resuming = false; tls.createSecurityParameters(c, msg); } c.open = true; tls.queue(c, tls.createRecord(c, { type: tls.ContentType.handshake, data: tls.createServerHello(c) })); if (c.session.resuming) { tls.queue(c, tls.createRecord(c, { type: tls.ContentType.change_cipher_spec, data: tls.createChangeCipherSpec() })); c.state.pending = tls.createConnectionState(c); c.state.current.write = c.state.pending.write; tls.queue(c, tls.createRecord(c, { type: tls.ContentType.handshake, data: tls.createFinished(c) })); } else { tls.queue(c, tls.createRecord(c, { type: tls.ContentType.handshake, data: tls.createCertificate(c) })); if (!c.fail) { tls.queue(c, tls.createRecord(c, { type: tls.ContentType.handshake, data: tls.createServerKeyExchange(c) })); if (c.verifyClient !== false) { tls.queue(c, tls.createRecord(c, { type: tls.ContentType.handshake, data: tls.createCertificateRequest(c) })); } tls.queue(c, tls.createRecord(c, { type: tls.ContentType.handshake, data: tls.createServerHelloDone(c) })); } } tls.flush(c); c.process(); }; /** * Called when a client receives a Certificate record. * * When this message will be sent: * The server must send a certificate whenever the agreed-upon key exchange * method is not an anonymous one. This message will always immediately * follow the server hello message. * * Meaning of this message: * The certificate type must be appropriate for the selected cipher suite's * key exchange algorithm, and is generally an X.509v3 certificate. It must * contain a key which matches the key exchange method, as follows. Unless * otherwise specified, the signing algorithm for the certificate must be * the same as the algorithm for the certificate key. Unless otherwise * specified, the public key may be of any length. * * opaque ASN.1Cert<1..2^24-1>; * struct { * ASN.1Cert certificate_list<1..2^24-1>; * } Certificate; * * @param c the connection. * @param record the record. * @param length the length of the handshake message. */ tls.handleCertificate = function(c, record, length) { if (length < 3) { return c.error(c, { message: "Invalid Certificate message. Message too short.", send: true, alert: { level: tls.Alert.Level.fatal, description: tls.Alert.Description.illegal_parameter } }); } var b = record.fragment; var msg = { certificate_list: readVector(b, 3) }; var cert, asn1; var certs = []; try { while (msg.certificate_list.length() > 0) { cert = readVector(msg.certificate_list, 3); asn1 = forge.asn1.fromDer(cert); cert = forge.pki.certificateFromAsn1(asn1, true); certs.push(cert); } } catch (ex) { return c.error(c, { message: "Could not parse certificate list.", cause: ex, send: true, alert: { level: tls.Alert.Level.fatal, description: tls.Alert.Description.bad_certificate } }); } var client = c.entity === tls.ConnectionEnd.client; if ((client || c.verifyClient === true) && certs.length === 0) { c.error(c, { message: client ? "No server certificate provided." : "No client certificate provided.", send: true, alert: { level: tls.Alert.Level.fatal, description: tls.Alert.Description.illegal_parameter } }); } else if (certs.length === 0) { c.expect = client ? SKE : CKE; } else { if (client) { c.session.serverCertificate = certs[0]; } else { c.session.clientCertificate = certs[0]; } if (tls.verifyCertificateChain(c, certs)) { c.expect = client ? SKE : CKE; } } c.process(); }; /** * Called when a client receives a ServerKeyExchange record. * * When this message will be sent: * This message will be sent immediately after the server certificate * message (or the server hello message, if this is an anonymous * negotiation). * * The server key exchange message is sent by the server only when the * server certificate message (if sent) does not contain enough data to * allow the client to exchange a premaster secret. * * Meaning of this message: * This message conveys cryptographic information to allow the client to * communicate the premaster secret: either an RSA public key to encrypt * the premaster secret with, or a Diffie-Hellman public key with which the * client can complete a key exchange (with the result being the premaster * secret.) * * enum { * dhe_dss, dhe_rsa, dh_anon, rsa, dh_dss, dh_rsa * } KeyExchangeAlgorithm; * * struct { * opaque dh_p<1..2^16-1>; * opaque dh_g<1..2^16-1>; * opaque dh_Ys<1..2^16-1>; * } ServerDHParams; * * struct { * select(KeyExchangeAlgorithm) { * case dh_anon: * ServerDHParams params; * case dhe_dss: * case dhe_rsa: * ServerDHParams params; * digitally-signed struct { * opaque client_random[32]; * opaque server_random[32]; * ServerDHParams params; * } signed_params; * case rsa: * case dh_dss: * case dh_rsa: * struct {}; * }; * } ServerKeyExchange; * * @param c the connection. * @param record the record. * @param length the length of the handshake message. */ tls.handleServerKeyExchange = function(c, record, length) { if (length > 0) { return c.error(c, { message: "Invalid key parameters. Only RSA is supported.", send: true, alert: { level: tls.Alert.Level.fatal, description: tls.Alert.Description.unsupported_certificate } }); } c.expect = SCR; c.process(); }; /** * Called when a client receives a ClientKeyExchange record. * * @param c the connection. * @param record the record. * @param length the length of the handshake message. */ tls.handleClientKeyExchange = function(c, record, length) { if (length < 48) { return c.error(c, { message: "Invalid key parameters. Only RSA is supported.", send: true, alert: { level: tls.Alert.Level.fatal, description: tls.Alert.Description.unsupported_certificate } }); } var b = record.fragment; var msg = { enc_pre_master_secret: readVector(b, 2).getBytes() }; var privateKey = null; if (c.getPrivateKey) { try { privateKey = c.getPrivateKey(c, c.session.serverCertificate); privateKey = forge.pki.privateKeyFromPem(privateKey); } catch (ex) { c.error(c, { message: "Could not get private key.", cause: ex, send: true, alert: { level: tls.Alert.Level.fatal, description: tls.Alert.Description.internal_error } }); } } if (privateKey === null) { return c.error(c, { message: "No private key set.", send: true, alert: { level: tls.Alert.Level.fatal, description: tls.Alert.Description.internal_error } }); } try { var sp = c.session.sp; sp.pre_master_secret = privateKey.decrypt(msg.enc_pre_master_secret); var version = c.session.clientHelloVersion; if (version.major !== sp.pre_master_secret.charCodeAt(0) || version.minor !== sp.pre_master_secret.charCodeAt(1)) { throw new Error("TLS version rollback attack detected."); } } catch (ex) { sp.pre_master_secret = forge.random.getBytes(48); } c.expect = CCC; if (c.session.clientCertificate !== null) { c.expect = CCV; } c.process(); }; /** * Called when a client receives a CertificateRequest record. * * When this message will be sent: * A non-anonymous server can optionally request a certificate from the * client, if appropriate for the selected cipher suite. This message, if * sent, will immediately follow the Server Key Exchange message (if it is * sent; otherwise, the Server Certificate message). * * enum { * rsa_sign(1), dss_sign(2), rsa_fixed_dh(3), dss_fixed_dh(4), * rsa_ephemeral_dh_RESERVED(5), dss_ephemeral_dh_RESERVED(6), * fortezza_dms_RESERVED(20), (255) * } ClientCertificateType; * * opaque DistinguishedName<1..2^16-1>; * * struct { * ClientCertificateType certificate_types<1..2^8-1>; * SignatureAndHashAlgorithm supported_signature_algorithms<2^16-1>; * DistinguishedName certificate_authorities<0..2^16-1>; * } CertificateRequest; * * @param c the connection. * @param record the record. * @param length the length of the handshake message. */ tls.handleCertificateRequest = function(c, record, length) { if (length < 3) { return c.error(c, { message: "Invalid CertificateRequest. Message too short.", send: true, alert: { level: tls.Alert.Level.fatal, description: tls.Alert.Description.illegal_parameter } }); } var b = record.fragment; var msg = { certificate_types: readVector(b, 1), certificate_authorities: readVector(b, 2) }; c.session.certificateRequest = msg; c.expect = SHD; c.process(); }; /** * Called when a server receives a CertificateVerify record. * * @param c the connection. * @param record the record. * @param length the length of the handshake message. */ tls.handleCertificateVerify = function(c, record, length) { if (length < 2) { return c.error(c, { message: "Invalid CertificateVerify. Message too short.", send: true, alert: { level: tls.Alert.Level.fatal, description: tls.Alert.Description.illegal_parameter } }); } var b = record.fragment; b.read -= 4; var msgBytes = b.bytes(); b.read += 4; var msg = { signature: readVector(b, 2).getBytes() }; var verify = forge.util.createBuffer(); verify.putBuffer(c.session.md5.digest()); verify.putBuffer(c.session.sha1.digest()); verify = verify.getBytes(); try { var cert = c.session.clientCertificate; if (!cert.publicKey.verify(verify, msg.signature, "NONE")) { throw new Error("CertificateVerify signature does not match."); } c.session.md5.update(msgBytes); c.session.sha1.update(msgBytes); } catch (ex) { return c.error(c, { message: "Bad signature in CertificateVerify.", send: true, alert: { level: tls.Alert.Level.fatal, description: tls.Alert.Description.handshake_failure } }); } c.expect = CCC; c.process(); }; /** * Called when a client receives a ServerHelloDone record. * * When this message will be sent: * The server hello done message is sent by the server to indicate the end * of the server hello and associated messages. After sending this message * the server will wait for a client response. * * Meaning of this message: * This message means that the server is done sending messages to support * the key exchange, and the client can proceed with its phase of the key * exchange. * * Upon receipt of the server hello done message the client should verify * that the server provided a valid certificate if required and check that * the server hello parameters are acceptable. * * struct {} ServerHelloDone; * * @param c the connection. * @param record the record. * @param length the length of the handshake message. */ tls.handleServerHelloDone = function(c, record, length) { if (length > 0) { return c.error(c, { message: "Invalid ServerHelloDone message. Invalid length.", send: true, alert: { level: tls.Alert.Level.fatal, description: tls.Alert.Description.record_overflow } }); } if (c.serverCertificate === null) { var error = { message: "No server certificate provided. Not enough security.", send: true, alert: { level: tls.Alert.Level.fatal, description: tls.Alert.Description.insufficient_security } }; var depth = 0; var ret = c.verify(c, error.alert.description, depth, []); if (ret !== true) { if (ret || ret === 0) { if (typeof ret === "object" && !forge.util.isArray(ret)) { if (ret.message) { error.message = ret.message; } if (ret.alert) { error.alert.description = ret.alert; } } else if (typeof ret === "number") { error.alert.description = ret; } } return c.error(c, error); } } if (c.session.certificateRequest !== null) { record = tls.createRecord(c, { type: tls.ContentType.handshake, data: tls.createCertificate(c) }); tls.queue(c, record); } record = tls.createRecord(c, { type: tls.ContentType.handshake, data: tls.createClientKeyExchange(c) }); tls.queue(c, record); c.expect = SER; var callback = function(c, signature) { if (c.session.certificateRequest !== null && c.session.clientCertificate !== null) { tls.queue(c, tls.createRecord(c, { type: tls.ContentType.handshake, data: tls.createCertificateVerify(c, signature) })); } tls.queue(c, tls.createRecord(c, { type: tls.ContentType.change_cipher_spec, data: tls.createChangeCipherSpec() })); c.state.pending = tls.createConnectionState(c); c.state.current.write = c.state.pending.write; tls.queue(c, tls.createRecord(c, { type: tls.ContentType.handshake, data: tls.createFinished(c) })); c.expect = SCC; tls.flush(c); c.process(); }; if (c.session.certificateRequest === null || c.session.clientCertificate === null) { return callback(c, null); } tls.getClientSignature(c, callback); }; /** * Called when a ChangeCipherSpec record is received. * * @param c the connection. * @param record the record. */ tls.handleChangeCipherSpec = function(c, record) { if (record.fragment.getByte() !== 1) { return c.error(c, { message: "Invalid ChangeCipherSpec message received.", send: true, alert: { level: tls.Alert.Level.fatal, description: tls.Alert.Description.illegal_parameter } }); } var client = c.entity === tls.ConnectionEnd.client; if (c.session.resuming && client || !c.session.resuming && !client) { c.state.pending = tls.createConnectionState(c); } c.state.current.read = c.state.pending.read; if (!c.session.resuming && client || c.session.resuming && !client) { c.state.pending = null; } c.expect = client ? SFI : CFI; c.process(); }; /** * Called when a Finished record is received. * * When this message will be sent: * A finished message is always sent immediately after a change * cipher spec message to verify that the key exchange and * authentication processes were successful. It is essential that a * change cipher spec message be received between the other * handshake messages and the Finished message. * * Meaning of this message: * The finished message is the first protected with the just- * negotiated algorithms, keys, and secrets. Recipients of finished * messages must verify that the contents are correct. Once a side * has sent its Finished message and received and validated the * Finished message from its peer, it may begin to send and receive * application data over the connection. * * struct { * opaque verify_data[verify_data_length]; * } Finished; * * verify_data * PRF(master_secret, finished_label, Hash(handshake_messages)) * [0..verify_data_length-1]; * * finished_label * For Finished messages sent by the client, the string * "client finished". For Finished messages sent by the server, the * string "server finished". * * verify_data_length depends on the cipher suite. If it is not specified * by the cipher suite, then it is 12. Versions of TLS < 1.2 always used * 12 bytes. * * @param c the connection. * @param record the record. * @param length the length of the handshake message. */ tls.handleFinished = function(c, record, length) { var b = record.fragment; b.read -= 4; var msgBytes = b.bytes(); b.read += 4; var vd = record.fragment.getBytes(); b = forge.util.createBuffer(); b.putBuffer(c.session.md5.digest()); b.putBuffer(c.session.sha1.digest()); var client = c.entity === tls.ConnectionEnd.client; var label = client ? "server finished" : "client finished"; var sp = c.session.sp; var vdl = 12; var prf = prf_TLS1; b = prf(sp.master_secret, label, b.getBytes(), vdl); if (b.getBytes() !== vd) { return c.error(c, { message: "Invalid verify_data in Finished message.", send: true, alert: { level: tls.Alert.Level.fatal, description: tls.Alert.Description.decrypt_error } }); } c.session.md5.update(msgBytes); c.session.sha1.update(msgBytes); if (c.session.resuming && client || !c.session.resuming && !client) { tls.queue(c, tls.createRecord(c, { type: tls.ContentType.change_cipher_spec, data: tls.createChangeCipherSpec() })); c.state.current.write = c.state.pending.write; c.state.pending = null; tls.queue(c, tls.createRecord(c, { type: tls.ContentType.handshake, data: tls.createFinished(c) })); } c.expect = client ? SAD : CAD; c.handshaking = false; ++c.handshakes; c.peerCertificate = client ? c.session.serverCertificate : c.session.clientCertificate; tls.flush(c); c.isConnected = true; c.connected(c); c.process(); }; /** * Called when an Alert record is received. * * @param c the connection. * @param record the record. */ tls.handleAlert = function(c, record) { var b = record.fragment; var alert = { level: b.getByte(), description: b.getByte() }; var msg; switch (alert.description) { case tls.Alert.Description.close_notify: msg = "Connection closed."; break; case tls.Alert.Description.unexpected_message: msg = "Unexpected message."; break; case tls.Alert.Description.bad_record_mac: msg = "Bad record MAC."; break; case tls.Alert.Description.decryption_failed: msg = "Decryption failed."; break; case tls.Alert.Description.record_overflow: msg = "Record overflow."; break; case tls.Alert.Description.decompression_failure: msg = "Decompression failed."; break; case tls.Alert.Description.handshake_failure: msg = "Handshake failure."; break; case tls.Alert.Description.bad_certificate: msg = "Bad certificate."; break; case tls.Alert.Description.unsupported_certificate: msg = "Unsupported certificate."; break; case tls.Alert.Description.certificate_revoked: msg = "Certificate revoked."; break; case tls.Alert.Description.certificate_expired: msg = "Certificate expired."; break; case tls.Alert.Description.certificate_unknown: msg = "Certificate unknown."; break; case tls.Alert.Description.illegal_parameter: msg = "Illegal parameter."; break; case tls.Alert.Description.unknown_ca: msg = "Unknown certificate authority."; break; case tls.Alert.Description.access_denied: msg = "Access denied."; break; case tls.Alert.Description.decode_error: msg = "Decode error."; break; case tls.Alert.Description.decrypt_error: msg = "Decrypt error."; break; case tls.Alert.Description.export_restriction: msg = "Export restriction."; break; case tls.Alert.Description.protocol_version: msg = "Unsupported protocol version."; break; case tls.Alert.Description.insufficient_security: msg = "Insufficient security."; break; case tls.Alert.Description.internal_error: msg = "Internal error."; break; case tls.Alert.Description.user_canceled: msg = "User canceled."; break; case tls.Alert.Description.no_renegotiation: msg = "Renegotiation not supported."; break; default: msg = "Unknown error."; break; } if (alert.description === tls.Alert.Description.close_notify) { return c.close(); } c.error(c, { message: msg, send: false, origin: c.entity === tls.ConnectionEnd.client ? "server" : "client", alert }); c.process(); }; /** * Called when a Handshake record is received. * * @param c the connection. * @param record the record. */ tls.handleHandshake = function(c, record) { var b = record.fragment; var type = b.getByte(); var length = b.getInt24(); if (length > b.length()) { c.fragmented = record; record.fragment = forge.util.createBuffer(); b.read -= 4; return c.process(); } c.fragmented = null; b.read -= 4; var bytes = b.bytes(length + 4); b.read += 4; if (type in hsTable[c.entity][c.expect]) { if (c.entity === tls.ConnectionEnd.server && !c.open && !c.fail) { c.handshaking = true; c.session = { version: null, extensions: { server_name: { serverNameList: [] } }, cipherSuite: null, compressionMethod: null, serverCertificate: null, clientCertificate: null, md5: forge.md.md5.create(), sha1: forge.md.sha1.create() }; } if (type !== tls.HandshakeType.hello_request && type !== tls.HandshakeType.certificate_verify && type !== tls.HandshakeType.finished) { c.session.md5.update(bytes); c.session.sha1.update(bytes); } hsTable[c.entity][c.expect][type](c, record, length); } else { tls.handleUnexpected(c, record); } }; /** * Called when an ApplicationData record is received. * * @param c the connection. * @param record the record. */ tls.handleApplicationData = function(c, record) { c.data.putBuffer(record.fragment); c.dataReady(c); c.process(); }; /** * Called when a Heartbeat record is received. * * @param c the connection. * @param record the record. */ tls.handleHeartbeat = function(c, record) { var b = record.fragment; var type = b.getByte(); var length = b.getInt16(); var payload = b.getBytes(length); if (type === tls.HeartbeatMessageType.heartbeat_request) { if (c.handshaking || length > payload.length) { return c.process(); } tls.queue(c, tls.createRecord(c, { type: tls.ContentType.heartbeat, data: tls.createHeartbeat(tls.HeartbeatMessageType.heartbeat_response, payload) })); tls.flush(c); } else if (type === tls.HeartbeatMessageType.heartbeat_response) { if (payload !== c.expectedHeartbeatPayload) { return c.process(); } if (c.heartbeatReceived) { c.heartbeatReceived(c, forge.util.createBuffer(payload)); } } c.process(); }; /** * The transistional state tables for receiving TLS records. It maps the * current TLS engine state and a received record to a function to handle the * record and update the state. * * For instance, if the current state is SHE, then the TLS engine is expecting * a ServerHello record. Once a record is received, the handler function is * looked up using the state SHE and the record's content type. * * The resulting function will either be an error handler or a record handler. * The function will take whatever action is appropriate and update the state * for the next record. * * The states are all based on possible server record types. Note that the * client will never specifically expect to receive a HelloRequest or an alert * from the server so there is no state that reflects this. These messages may * occur at any time. * * There are two tables for mapping states because there is a second tier of * types for handshake messages. Once a record with a content type of handshake * is received, the handshake record handler will look up the handshake type in * the secondary map to get its appropriate handler. * * Valid message orders are as follows: * * =======================FULL HANDSHAKE====================== * Client Server * * ClientHello --------> * ServerHello * Certificate* * ServerKeyExchange* * CertificateRequest* * <-------- ServerHelloDone * Certificate* * ClientKeyExchange * CertificateVerify* * [ChangeCipherSpec] * Finished --------> * [ChangeCipherSpec] * <-------- Finished * Application Data <-------> Application Data * * =====================SESSION RESUMPTION===================== * Client Server * * ClientHello --------> * ServerHello * [ChangeCipherSpec] * <-------- Finished * [ChangeCipherSpec] * Finished --------> * Application Data <-------> Application Data */ var SHE = 0; var SCE = 1; var SKE = 2; var SCR = 3; var SHD = 4; var SCC = 5; var SFI = 6; var SAD = 7; var SER = 8; var CHE = 0; var CCE = 1; var CKE = 2; var CCV = 3; var CCC = 4; var CFI = 5; var CAD = 6; var CER = 7; var __ = tls.handleUnexpected; var R0 = tls.handleChangeCipherSpec; var R1 = tls.handleAlert; var R2 = tls.handleHandshake; var R3 = tls.handleApplicationData; var R4 = tls.handleHeartbeat; var ctTable = []; ctTable[tls.ConnectionEnd.client] = [ [ __, R1, R2, __, R4 ], [ __, R1, R2, __, R4 ], [ __, R1, R2, __, R4 ], [ __, R1, R2, __, R4 ], [ __, R1, R2, __, R4 ], [ R0, R1, __, __, R4 ], [ __, R1, R2, __, R4 ], [ __, R1, R2, R3, R4 ], [ __, R1, R2, __, R4 ] ]; ctTable[tls.ConnectionEnd.server] = [ [ __, R1, R2, __, R4 ], [ __, R1, R2, __, R4 ], [ __, R1, R2, __, R4 ], [ __, R1, R2, __, R4 ], [ R0, R1, __, __, R4 ], [ __, R1, R2, __, R4 ], [ __, R1, R2, R3, R4 ], [ __, R1, R2, __, R4 ] ]; var H0 = tls.handleHelloRequest; var H1 = tls.handleServerHello; var H2 = tls.handleCertificate; var H3 = tls.handleServerKeyExchange; var H4 = tls.handleCertificateRequest; var H5 = tls.handleServerHelloDone; var H6 = tls.handleFinished; var hsTable = []; hsTable[tls.ConnectionEnd.client] = [ [ __, __, H1, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __ ], [ H0, __, __, __, __, __, __, __, __, __, __, H2, H3, H4, H5, __, __, __, __, __, __ ], [ H0, __, __, __, __, __, __, __, __, __, __, __, H3, H4, H5, __, __, __, __, __, __ ], [ H0, __, __, __, __, __, __, __, __, __, __, __, __, H4, H5, __, __, __, __, __, __ ], [ H0, __, __, __, __, __, __, __, __, __, __, __, __, __, H5, __, __, __, __, __, __ ], [ H0, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __ ], [ H0, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, H6 ], [ H0, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __ ], [ H0, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __ ] ]; var H7 = tls.handleClientHello; var H8 = tls.handleClientKeyExchange; var H9 = tls.handleCertificateVerify; hsTable[tls.ConnectionEnd.server] = [ [ __, H7, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __ ], [ __, __, __, __, __, __, __, __, __, __, __, H2, __, __, __, __, __, __, __, __, __ ], [ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, H8, __, __, __, __ ], [ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, H9, __, __, __, __, __ ], [ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __ ], [ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, H6 ], [ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __ ], [ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __ ] ]; /** * Generates the master_secret and keys using the given security parameters. * * The security parameters for a TLS connection state are defined as such: * * struct { * ConnectionEnd entity; * PRFAlgorithm prf_algorithm; * BulkCipherAlgorithm bulk_cipher_algorithm; * CipherType cipher_type; * uint8 enc_key_length; * uint8 block_length; * uint8 fixed_iv_length; * uint8 record_iv_length; * MACAlgorithm mac_algorithm; * uint8 mac_length; * uint8 mac_key_length; * CompressionMethod compression_algorithm; * opaque master_secret[48]; * opaque client_random[32]; * opaque server_random[32]; * } SecurityParameters; * * Note that this definition is from TLS 1.2. In TLS 1.0 some of these * parameters are ignored because, for instance, the PRFAlgorithm is a * builtin-fixed algorithm combining iterations of MD5 and SHA-1 in TLS 1.0. * * The Record Protocol requires an algorithm to generate keys required by the * current connection state. * * The master secret is expanded into a sequence of secure bytes, which is then * split to a client write MAC key, a server write MAC key, a client write * encryption key, and a server write encryption key. In TLS 1.0 a client write * IV and server write IV are also generated. Each of these is generated from * the byte sequence in that order. Unused values are empty. In TLS 1.2, some * AEAD ciphers may additionally require a client write IV and a server write * IV (see Section 6.2.3.3). * * When keys, MAC keys, and IVs are generated, the master secret is used as an * entropy source. * * To generate the key material, compute: * * master_secret = PRF(pre_master_secret, "master secret", * ClientHello.random + ServerHello.random) * * key_block = PRF(SecurityParameters.master_secret, * "key expansion", * SecurityParameters.server_random + * SecurityParameters.client_random); * * until enough output has been generated. Then, the key_block is * partitioned as follows: * * client_write_MAC_key[SecurityParameters.mac_key_length] * server_write_MAC_key[SecurityParameters.mac_key_length] * client_write_key[SecurityParameters.enc_key_length] * server_write_key[SecurityParameters.enc_key_length] * client_write_IV[SecurityParameters.fixed_iv_length] * server_write_IV[SecurityParameters.fixed_iv_length] * * In TLS 1.2, the client_write_IV and server_write_IV are only generated for * implicit nonce techniques as described in Section 3.2.1 of [AEAD]. This * implementation uses TLS 1.0 so IVs are generated. * * Implementation note: The currently defined cipher suite which requires the * most material is AES_256_CBC_SHA256. It requires 2 x 32 byte keys and 2 x 32 * byte MAC keys, for a total 128 bytes of key material. In TLS 1.0 it also * requires 2 x 16 byte IVs, so it actually takes 160 bytes of key material. * * @param c the connection. * @param sp the security parameters to use. * * @return the security keys. */ tls.generateKeys = function(c, sp) { var prf = prf_TLS1; var random = sp.client_random + sp.server_random; if (!c.session.resuming) { sp.master_secret = prf(sp.pre_master_secret, "master secret", random, 48).bytes(); sp.pre_master_secret = null; } random = sp.server_random + sp.client_random; var length = 2 * sp.mac_key_length + 2 * sp.enc_key_length; var tls10 = c.version.major === tls.Versions.TLS_1_0.major && c.version.minor === tls.Versions.TLS_1_0.minor; if (tls10) { length += 2 * sp.fixed_iv_length; } var km = prf(sp.master_secret, "key expansion", random, length); var rval = { client_write_MAC_key: km.getBytes(sp.mac_key_length), server_write_MAC_key: km.getBytes(sp.mac_key_length), client_write_key: km.getBytes(sp.enc_key_length), server_write_key: km.getBytes(sp.enc_key_length) }; if (tls10) { rval.client_write_IV = km.getBytes(sp.fixed_iv_length); rval.server_write_IV = km.getBytes(sp.fixed_iv_length); } return rval; }; /** * Creates a new initialized TLS connection state. A connection state has * a read mode and a write mode. * * compression state: * The current state of the compression algorithm. * * cipher state: * The current state of the encryption algorithm. This will consist of the * scheduled key for that connection. For stream ciphers, this will also * contain whatever state information is necessary to allow the stream to * continue to encrypt or decrypt data. * * MAC key: * The MAC key for the connection. * * sequence number: * Each connection state contains a sequence number, which is maintained * separately for read and write states. The sequence number MUST be set to * zero whenever a connection state is made the active state. Sequence * numbers are of type uint64 and may not exceed 2^64-1. Sequence numbers do * not wrap. If a TLS implementation would need to wrap a sequence number, * it must renegotiate instead. A sequence number is incremented after each * record: specifically, the first record transmitted under a particular * connection state MUST use sequence number 0. * * @param c the connection. * * @return the new initialized TLS connection state. */ tls.createConnectionState = function(c) { var client = c.entity === tls.ConnectionEnd.client; var createMode = function() { var mode = { sequenceNumber: [0, 0], macKey: null, macLength: 0, macFunction: null, cipherState: null, cipherFunction: function(record) { return true; }, compressionState: null, compressFunction: function(record) { return true; }, updateSequenceNumber: function() { if (mode.sequenceNumber[1] === 4294967295) { mode.sequenceNumber[1] = 0; ++mode.sequenceNumber[0]; } else { ++mode.sequenceNumber[1]; } } }; return mode; }; var state = { read: createMode(), write: createMode() }; state.read.update = function(c, record) { if (!state.read.cipherFunction(record, state.read)) { c.error(c, { message: "Could not decrypt record or bad MAC.", send: true, alert: { level: tls.Alert.Level.fatal, description: tls.Alert.Description.bad_record_mac } }); } else if (!state.read.compressFunction(c, record, state.read)) { c.error(c, { message: "Could not decompress record.", send: true, alert: { level: tls.Alert.Level.fatal, description: tls.Alert.Description.decompression_failure } }); } return !c.fail; }; state.write.update = function(c, record) { if (!state.write.compressFunction(c, record, state.write)) { c.error(c, { message: "Could not compress record.", send: false, alert: { level: tls.Alert.Level.fatal, description: tls.Alert.Description.internal_error } }); } else if (!state.write.cipherFunction(record, state.write)) { c.error(c, { message: "Could not encrypt record.", send: false, alert: { level: tls.Alert.Level.fatal, description: tls.Alert.Description.internal_error } }); } return !c.fail; }; if (c.session) { var sp = c.session.sp; c.session.cipherSuite.initSecurityParameters(sp); sp.keys = tls.generateKeys(c, sp); state.read.macKey = client ? sp.keys.server_write_MAC_key : sp.keys.client_write_MAC_key; state.write.macKey = client ? sp.keys.client_write_MAC_key : sp.keys.server_write_MAC_key; c.session.cipherSuite.initConnectionState(state, c, sp); switch (sp.compression_algorithm) { case tls.CompressionMethod.none: break; case tls.CompressionMethod.deflate: state.read.compressFunction = inflate; state.write.compressFunction = deflate; break; default: throw new Error("Unsupported compression algorithm."); } } return state; }; /** * Creates a Random structure. * * struct { * uint32 gmt_unix_time; * opaque random_bytes[28]; * } Random; * * gmt_unix_time: * The current time and date in standard UNIX 32-bit format (seconds since * the midnight starting Jan 1, 1970, UTC, ignoring leap seconds) according * to the sender's internal clock. Clocks are not required to be set * correctly by the basic TLS protocol; higher-level or application * protocols may define additional requirements. Note that, for historical * reasons, the data element is named using GMT, the predecessor of the * current worldwide time base, UTC. * random_bytes: * 28 bytes generated by a secure random number generator. * * @return the Random structure as a byte array. */ tls.createRandom = function() { var d = new Date(); var utc = +d + d.getTimezoneOffset() * 6e4; var rval = forge.util.createBuffer(); rval.putInt32(utc); rval.putBytes(forge.random.getBytes(28)); return rval; }; /** * Creates a TLS record with the given type and data. * * @param c the connection. * @param options: * type: the record type. * data: the plain text data in a byte buffer. * * @return the created record. */ tls.createRecord = function(c, options) { if (!options.data) { return null; } var record = { type: options.type, version: { major: c.version.major, minor: c.version.minor }, length: options.data.length(), fragment: options.data }; return record; }; /** * Creates a TLS alert record. * * @param c the connection. * @param alert: * level: the TLS alert level. * description: the TLS alert description. * * @return the created alert record. */ tls.createAlert = function(c, alert) { var b = forge.util.createBuffer(); b.putByte(alert.level); b.putByte(alert.description); return tls.createRecord(c, { type: tls.ContentType.alert, data: b }); }; /** * Creates a ClientHello message. * * opaque SessionID<0..32>; * enum { null(0), deflate(1), (255) } CompressionMethod; * uint8 CipherSuite[2]; * * struct { * ProtocolVersion client_version; * Random random; * SessionID session_id; * CipherSuite cipher_suites<2..2^16-2>; * CompressionMethod compression_methods<1..2^8-1>; * select(extensions_present) { * case false: * struct {}; * case true: * Extension extensions<0..2^16-1>; * }; * } ClientHello; * * The extension format for extended client hellos and server hellos is: * * struct { * ExtensionType extension_type; * opaque extension_data<0..2^16-1>; * } Extension; * * Here: * * - "extension_type" identifies the particular extension type. * - "extension_data" contains information specific to the particular * extension type. * * The extension types defined in this document are: * * enum { * server_name(0), max_fragment_length(1), * client_certificate_url(2), trusted_ca_keys(3), * truncated_hmac(4), status_request(5), (65535) * } ExtensionType; * * @param c the connection. * * @return the ClientHello byte buffer. */ tls.createClientHello = function(c) { c.session.clientHelloVersion = { major: c.version.major, minor: c.version.minor }; var cipherSuites = forge.util.createBuffer(); for (var i = 0; i < c.cipherSuites.length; ++i) { var cs = c.cipherSuites[i]; cipherSuites.putByte(cs.id[0]); cipherSuites.putByte(cs.id[1]); } var cSuites = cipherSuites.length(); var compressionMethods = forge.util.createBuffer(); compressionMethods.putByte(tls.CompressionMethod.none); var cMethods = compressionMethods.length(); var extensions = forge.util.createBuffer(); if (c.virtualHost) { var ext = forge.util.createBuffer(); ext.putByte(0); ext.putByte(0); var serverName = forge.util.createBuffer(); serverName.putByte(0); writeVector(serverName, 2, forge.util.createBuffer(c.virtualHost)); var snList = forge.util.createBuffer(); writeVector(snList, 2, serverName); writeVector(ext, 2, snList); extensions.putBuffer(ext); } var extLength = extensions.length(); if (extLength > 0) { extLength += 2; } var sessionId = c.session.id; var length = sessionId.length + 1 + 2 + 4 + 28 + 2 + cSuites + 1 + cMethods + extLength; var rval = forge.util.createBuffer(); rval.putByte(tls.HandshakeType.client_hello); rval.putInt24(length); rval.putByte(c.version.major); rval.putByte(c.version.minor); rval.putBytes(c.session.sp.client_random); writeVector(rval, 1, forge.util.createBuffer(sessionId)); writeVector(rval, 2, cipherSuites); writeVector(rval, 1, compressionMethods); if (extLength > 0) { writeVector(rval, 2, extensions); } return rval; }; /** * Creates a ServerHello message. * * @param c the connection. * * @return the ServerHello byte buffer. */ tls.createServerHello = function(c) { var sessionId = c.session.id; var length = sessionId.length + 1 + 2 + 4 + 28 + 2 + 1; var rval = forge.util.createBuffer(); rval.putByte(tls.HandshakeType.server_hello); rval.putInt24(length); rval.putByte(c.version.major); rval.putByte(c.version.minor); rval.putBytes(c.session.sp.server_random); writeVector(rval, 1, forge.util.createBuffer(sessionId)); rval.putByte(c.session.cipherSuite.id[0]); rval.putByte(c.session.cipherSuite.id[1]); rval.putByte(c.session.compressionMethod); return rval; }; /** * Creates a Certificate message. * * When this message will be sent: * This is the first message the client can send after receiving a server * hello done message and the first message the server can send after * sending a ServerHello. This client message is only sent if the server * requests a certificate. If no suitable certificate is available, the * client should send a certificate message containing no certificates. If * client authentication is required by the server for the handshake to * continue, it may respond with a fatal handshake failure alert. * * opaque ASN.1Cert<1..2^24-1>; * * struct { * ASN.1Cert certificate_list<0..2^24-1>; * } Certificate; * * @param c the connection. * * @return the Certificate byte buffer. */ tls.createCertificate = function(c) { var client = c.entity === tls.ConnectionEnd.client; var cert = null; if (c.getCertificate) { var hint; if (client) { hint = c.session.certificateRequest; } else { hint = c.session.extensions.server_name.serverNameList; } cert = c.getCertificate(c, hint); } var certList = forge.util.createBuffer(); if (cert !== null) { try { if (!forge.util.isArray(cert)) { cert = [cert]; } var asn1 = null; for (var i = 0; i < cert.length; ++i) { var msg = forge.pem.decode(cert[i])[0]; if (msg.type !== "CERTIFICATE" && msg.type !== "X509 CERTIFICATE" && msg.type !== "TRUSTED CERTIFICATE") { var error = new Error("Could not convert certificate from PEM; PEM " + "header type is not \"CERTIFICATE\", \"X509 CERTIFICATE\", or " + "\"TRUSTED CERTIFICATE\"."); error.headerType = msg.type; throw error; } if (msg.procType && msg.procType.type === "ENCRYPTED") { throw new Error("Could not convert certificate from PEM; PEM is encrypted."); } var der = forge.util.createBuffer(msg.body); if (asn1 === null) { asn1 = forge.asn1.fromDer(der.bytes(), false); } var certBuffer = forge.util.createBuffer(); writeVector(certBuffer, 3, der); certList.putBuffer(certBuffer); } cert = forge.pki.certificateFromAsn1(asn1); if (client) { c.session.clientCertificate = cert; } else { c.session.serverCertificate = cert; } } catch (ex) { return c.error(c, { message: "Could not send certificate list.", cause: ex, send: true, alert: { level: tls.Alert.Level.fatal, description: tls.Alert.Description.bad_certificate } }); } } var length = 3 + certList.length(); var rval = forge.util.createBuffer(); rval.putByte(tls.HandshakeType.certificate); rval.putInt24(length); writeVector(rval, 3, certList); return rval; }; /** * Creates a ClientKeyExchange message. * * When this message will be sent: * This message is always sent by the client. It will immediately follow the * client certificate message, if it is sent. Otherwise it will be the first * message sent by the client after it receives the server hello done * message. * * Meaning of this message: * With this message, the premaster secret is set, either though direct * transmission of the RSA-encrypted secret, or by the transmission of * Diffie-Hellman parameters which will allow each side to agree upon the * same premaster secret. When the key exchange method is DH_RSA or DH_DSS, * client certification has been requested, and the client was able to * respond with a certificate which contained a Diffie-Hellman public key * whose parameters (group and generator) matched those specified by the * server in its certificate, this message will not contain any data. * * Meaning of this message: * If RSA is being used for key agreement and authentication, the client * generates a 48-byte premaster secret, encrypts it using the public key * from the server's certificate or the temporary RSA key provided in a * server key exchange message, and sends the result in an encrypted * premaster secret message. This structure is a variant of the client * key exchange message, not a message in itself. * * struct { * select(KeyExchangeAlgorithm) { * case rsa: EncryptedPreMasterSecret; * case diffie_hellman: ClientDiffieHellmanPublic; * } exchange_keys; * } ClientKeyExchange; * * struct { * ProtocolVersion client_version; * opaque random[46]; * } PreMasterSecret; * * struct { * public-key-encrypted PreMasterSecret pre_master_secret; * } EncryptedPreMasterSecret; * * A public-key-encrypted element is encoded as a vector <0..2^16-1>. * * @param c the connection. * * @return the ClientKeyExchange byte buffer. */ tls.createClientKeyExchange = function(c) { var b = forge.util.createBuffer(); b.putByte(c.session.clientHelloVersion.major); b.putByte(c.session.clientHelloVersion.minor); b.putBytes(forge.random.getBytes(46)); var sp = c.session.sp; sp.pre_master_secret = b.getBytes(); var key = c.session.serverCertificate.publicKey; b = key.encrypt(sp.pre_master_secret); var length = b.length + 2; var rval = forge.util.createBuffer(); rval.putByte(tls.HandshakeType.client_key_exchange); rval.putInt24(length); rval.putInt16(b.length); rval.putBytes(b); return rval; }; /** * Creates a ServerKeyExchange message. * * @param c the connection. * * @return the ServerKeyExchange byte buffer. */ tls.createServerKeyExchange = function(c) { var length = 0; var rval = forge.util.createBuffer(); if (length > 0) { rval.putByte(tls.HandshakeType.server_key_exchange); rval.putInt24(length); } return rval; }; /** * Gets the signed data used to verify a client-side certificate. See * tls.createCertificateVerify() for details. * * @param c the connection. * @param callback the callback to call once the signed data is ready. */ tls.getClientSignature = function(c, callback) { var b = forge.util.createBuffer(); b.putBuffer(c.session.md5.digest()); b.putBuffer(c.session.sha1.digest()); b = b.getBytes(); c.getSignature = c.getSignature || function(c, b, callback) { var privateKey = null; if (c.getPrivateKey) { try { privateKey = c.getPrivateKey(c, c.session.clientCertificate); privateKey = forge.pki.privateKeyFromPem(privateKey); } catch (ex) { c.error(c, { message: "Could not get private key.", cause: ex, send: true, alert: { level: tls.Alert.Level.fatal, description: tls.Alert.Description.internal_error } }); } } if (privateKey === null) { c.error(c, { message: "No private key set.", send: true, alert: { level: tls.Alert.Level.fatal, description: tls.Alert.Description.internal_error } }); } else { b = privateKey.sign(b, null); } callback(c, b); }; c.getSignature(c, b, callback); }; /** * Creates a CertificateVerify message. * * Meaning of this message: * This structure conveys the client's Diffie-Hellman public value * (Yc) if it was not already included in the client's certificate. * The encoding used for Yc is determined by the enumerated * PublicValueEncoding. This structure is a variant of the client * key exchange message, not a message in itself. * * When this message will be sent: * This message is used to provide explicit verification of a client * certificate. This message is only sent following a client * certificate that has signing capability (i.e. all certificates * except those containing fixed Diffie-Hellman parameters). When * sent, it will immediately follow the client key exchange message. * * struct { * Signature signature; * } CertificateVerify; * * CertificateVerify.signature.md5_hash * MD5(handshake_messages); * * Certificate.signature.sha_hash * SHA(handshake_messages); * * Here handshake_messages refers to all handshake messages sent or * received starting at client hello up to but not including this * message, including the type and length fields of the handshake * messages. * * select(SignatureAlgorithm) { * case anonymous: struct { }; * case rsa: * digitally-signed struct { * opaque md5_hash[16]; * opaque sha_hash[20]; * }; * case dsa: * digitally-signed struct { * opaque sha_hash[20]; * }; * } Signature; * * In digital signing, one-way hash functions are used as input for a * signing algorithm. A digitally-signed element is encoded as an opaque * vector <0..2^16-1>, where the length is specified by the signing * algorithm and key. * * In RSA signing, a 36-byte structure of two hashes (one SHA and one * MD5) is signed (encrypted with the private key). It is encoded with * PKCS #1 block type 0 or type 1 as described in [PKCS1]. * * In DSS, the 20 bytes of the SHA hash are run directly through the * Digital Signing Algorithm with no additional hashing. * * @param c the connection. * @param signature the signature to include in the message. * * @return the CertificateVerify byte buffer. */ tls.createCertificateVerify = function(c, signature) { var length = signature.length + 2; var rval = forge.util.createBuffer(); rval.putByte(tls.HandshakeType.certificate_verify); rval.putInt24(length); rval.putInt16(signature.length); rval.putBytes(signature); return rval; }; /** * Creates a CertificateRequest message. * * @param c the connection. * * @return the CertificateRequest byte buffer. */ tls.createCertificateRequest = function(c) { var certTypes = forge.util.createBuffer(); certTypes.putByte(1); var cAs = forge.util.createBuffer(); for (var key in c.caStore.certs) { var cert = c.caStore.certs[key]; var dn = forge.pki.distinguishedNameToAsn1(cert.subject); var byteBuffer = forge.asn1.toDer(dn); cAs.putInt16(byteBuffer.length()); cAs.putBuffer(byteBuffer); } var length = 1 + certTypes.length() + 2 + cAs.length(); var rval = forge.util.createBuffer(); rval.putByte(tls.HandshakeType.certificate_request); rval.putInt24(length); writeVector(rval, 1, certTypes); writeVector(rval, 2, cAs); return rval; }; /** * Creates a ServerHelloDone message. * * @param c the connection. * * @return the ServerHelloDone byte buffer. */ tls.createServerHelloDone = function(c) { var rval = forge.util.createBuffer(); rval.putByte(tls.HandshakeType.server_hello_done); rval.putInt24(0); return rval; }; /** * Creates a ChangeCipherSpec message. * * The change cipher spec protocol exists to signal transitions in * ciphering strategies. The protocol consists of a single message, * which is encrypted and compressed under the current (not the pending) * connection state. The message consists of a single byte of value 1. * * struct { * enum { change_cipher_spec(1), (255) } type; * } ChangeCipherSpec; * * @return the ChangeCipherSpec byte buffer. */ tls.createChangeCipherSpec = function() { var rval = forge.util.createBuffer(); rval.putByte(1); return rval; }; /** * Creates a Finished message. * * struct { * opaque verify_data[12]; * } Finished; * * verify_data * PRF(master_secret, finished_label, MD5(handshake_messages) + * SHA-1(handshake_messages)) [0..11]; * * finished_label * For Finished messages sent by the client, the string "client * finished". For Finished messages sent by the server, the * string "server finished". * * handshake_messages * All of the data from all handshake messages up to but not * including this message. This is only data visible at the * handshake layer and does not include record layer headers. * This is the concatenation of all the Handshake structures as * defined in 7.4 exchanged thus far. * * @param c the connection. * * @return the Finished byte buffer. */ tls.createFinished = function(c) { var b = forge.util.createBuffer(); b.putBuffer(c.session.md5.digest()); b.putBuffer(c.session.sha1.digest()); var client = c.entity === tls.ConnectionEnd.client; var sp = c.session.sp; var vdl = 12; var prf = prf_TLS1; var label = client ? "client finished" : "server finished"; b = prf(sp.master_secret, label, b.getBytes(), vdl); var rval = forge.util.createBuffer(); rval.putByte(tls.HandshakeType.finished); rval.putInt24(b.length()); rval.putBuffer(b); return rval; }; /** * Creates a HeartbeatMessage (See RFC 6520). * * struct { * HeartbeatMessageType type; * uint16 payload_length; * opaque payload[HeartbeatMessage.payload_length]; * opaque padding[padding_length]; * } HeartbeatMessage; * * The total length of a HeartbeatMessage MUST NOT exceed 2^14 or * max_fragment_length when negotiated as defined in [RFC6066]. * * type: The message type, either heartbeat_request or heartbeat_response. * * payload_length: The length of the payload. * * payload: The payload consists of arbitrary content. * * padding: The padding is random content that MUST be ignored by the * receiver. The length of a HeartbeatMessage is TLSPlaintext.length * for TLS and DTLSPlaintext.length for DTLS. Furthermore, the * length of the type field is 1 byte, and the length of the * payload_length is 2. Therefore, the padding_length is * TLSPlaintext.length - payload_length - 3 for TLS and * DTLSPlaintext.length - payload_length - 3 for DTLS. The * padding_length MUST be at least 16. * * The sender of a HeartbeatMessage MUST use a random padding of at * least 16 bytes. The padding of a received HeartbeatMessage message * MUST be ignored. * * If the payload_length of a received HeartbeatMessage is too large, * the received HeartbeatMessage MUST be discarded silently. * * @param c the connection. * @param type the tls.HeartbeatMessageType. * @param payload the heartbeat data to send as the payload. * @param [payloadLength] the payload length to use, defaults to the * actual payload length. * * @return the HeartbeatRequest byte buffer. */ tls.createHeartbeat = function(type, payload, payloadLength) { if (typeof payloadLength === "undefined") { payloadLength = payload.length; } var rval = forge.util.createBuffer(); rval.putByte(type); rval.putInt16(payloadLength); rval.putBytes(payload); var plaintextLength = rval.length(); var paddingLength = Math.max(16, plaintextLength - payloadLength - 3); rval.putBytes(forge.random.getBytes(paddingLength)); return rval; }; /** * Fragments, compresses, encrypts, and queues a record for delivery. * * @param c the connection. * @param record the record to queue. */ tls.queue = function(c, record) { if (!record) { return; } if (record.fragment.length() === 0) { if (record.type === tls.ContentType.handshake || record.type === tls.ContentType.alert || record.type === tls.ContentType.change_cipher_spec) { return; } } if (record.type === tls.ContentType.handshake) { var bytes = record.fragment.bytes(); c.session.md5.update(bytes); c.session.sha1.update(bytes); bytes = null; } var records; if (record.fragment.length() <= tls.MaxFragment) { records = [record]; } else { records = []; var data = record.fragment.bytes(); while (data.length > tls.MaxFragment) { records.push(tls.createRecord(c, { type: record.type, data: forge.util.createBuffer(data.slice(0, tls.MaxFragment)) })); data = data.slice(tls.MaxFragment); } if (data.length > 0) { records.push(tls.createRecord(c, { type: record.type, data: forge.util.createBuffer(data) })); } } for (var i = 0; i < records.length && !c.fail; ++i) { var rec = records[i]; var s = c.state.current.write; if (s.update(c, rec)) { c.records.push(rec); } } }; /** * Flushes all queued records to the output buffer and calls the * tlsDataReady() handler on the given connection. * * @param c the connection. * * @return true on success, false on failure. */ tls.flush = function(c) { for (var i = 0; i < c.records.length; ++i) { var record = c.records[i]; c.tlsData.putByte(record.type); c.tlsData.putByte(record.version.major); c.tlsData.putByte(record.version.minor); c.tlsData.putInt16(record.fragment.length()); c.tlsData.putBuffer(c.records[i].fragment); } c.records = []; return c.tlsDataReady(c); }; /** * Maps a pki.certificateError to a tls.Alert.Description. * * @param error the error to map. * * @return the alert description. */ var _certErrorToAlertDesc = function(error) { switch (error) { case true: return true; case forge.pki.certificateError.bad_certificate: return tls.Alert.Description.bad_certificate; case forge.pki.certificateError.unsupported_certificate: return tls.Alert.Description.unsupported_certificate; case forge.pki.certificateError.certificate_revoked: return tls.Alert.Description.certificate_revoked; case forge.pki.certificateError.certificate_expired: return tls.Alert.Description.certificate_expired; case forge.pki.certificateError.certificate_unknown: return tls.Alert.Description.certificate_unknown; case forge.pki.certificateError.unknown_ca: return tls.Alert.Description.unknown_ca; default: return tls.Alert.Description.bad_certificate; } }; /** * Maps a tls.Alert.Description to a pki.certificateError. * * @param desc the alert description. * * @return the certificate error. */ var _alertDescToCertError = function(desc) { switch (desc) { case true: return true; case tls.Alert.Description.bad_certificate: return forge.pki.certificateError.bad_certificate; case tls.Alert.Description.unsupported_certificate: return forge.pki.certificateError.unsupported_certificate; case tls.Alert.Description.certificate_revoked: return forge.pki.certificateError.certificate_revoked; case tls.Alert.Description.certificate_expired: return forge.pki.certificateError.certificate_expired; case tls.Alert.Description.certificate_unknown: return forge.pki.certificateError.certificate_unknown; case tls.Alert.Description.unknown_ca: return forge.pki.certificateError.unknown_ca; default: return forge.pki.certificateError.bad_certificate; } }; /** * Verifies a certificate chain against the given connection's * Certificate Authority store. * * @param c the TLS connection. * @param chain the certificate chain to verify, with the root or highest * authority at the end. * * @return true if successful, false if not. */ tls.verifyCertificateChain = function(c, chain) { try { var options = {}; for (var key in c.verifyOptions) { options[key] = c.verifyOptions[key]; } options.verify = function(vfd, depth, chain) { var desc = _certErrorToAlertDesc(vfd); var ret = c.verify(c, vfd, depth, chain); if (ret !== true) { if (typeof ret === "object" && !forge.util.isArray(ret)) { var error = new Error("The application rejected the certificate."); error.send = true; error.alert = { level: tls.Alert.Level.fatal, description: tls.Alert.Description.bad_certificate }; if (ret.message) { error.message = ret.message; } if (ret.alert) { error.alert.description = ret.alert; } throw error; } if (ret !== vfd) { ret = _alertDescToCertError(ret); } } return ret; }; forge.pki.verifyCertificateChain(c.caStore, chain, options); } catch (ex) { var err = ex; if (typeof err !== "object" || forge.util.isArray(err)) { err = { send: true, alert: { level: tls.Alert.Level.fatal, description: _certErrorToAlertDesc(ex) } }; } if (!("send" in err)) { err.send = true; } if (!("alert" in err)) { err.alert = { level: tls.Alert.Level.fatal, description: _certErrorToAlertDesc(err.error) }; } c.error(c, err); } return !c.fail; }; /** * Creates a new TLS session cache. * * @param cache optional map of session ID to cached session. * @param capacity the maximum size for the cache (default: 100). * * @return the new TLS session cache. */ tls.createSessionCache = function(cache, capacity) { var rval = null; if (cache && cache.getSession && cache.setSession && cache.order) { rval = cache; } else { rval = {}; rval.cache = cache || {}; rval.capacity = Math.max(capacity || 100, 1); rval.order = []; for (var key in cache) { if (rval.order.length <= capacity) { rval.order.push(key); } else { delete cache[key]; } } rval.getSession = function(sessionId) { var session = null; var key = null; if (sessionId) { key = forge.util.bytesToHex(sessionId); } else if (rval.order.length > 0) { key = rval.order[0]; } if (key !== null && key in rval.cache) { session = rval.cache[key]; delete rval.cache[key]; for (var i in rval.order) { if (rval.order[i] === key) { rval.order.splice(i, 1); break; } } } return session; }; rval.setSession = function(sessionId, session) { if (rval.order.length === rval.capacity) { var key = rval.order.shift(); delete rval.cache[key]; } var key = forge.util.bytesToHex(sessionId); rval.order.push(key); rval.cache[key] = session; }; } return rval; }; /** * Creates a new TLS connection. * * See public createConnection() docs for more details. * * @param options the options for this connection. * * @return the new TLS connection. */ tls.createConnection = function(options) { var caStore = null; if (options.caStore) { if (forge.util.isArray(options.caStore)) { caStore = forge.pki.createCaStore(options.caStore); } else { caStore = options.caStore; } } else { caStore = forge.pki.createCaStore(); } var cipherSuites = options.cipherSuites || null; if (cipherSuites === null) { cipherSuites = []; for (var key in tls.CipherSuites) { cipherSuites.push(tls.CipherSuites[key]); } } var entity = options.server || false ? tls.ConnectionEnd.server : tls.ConnectionEnd.client; var sessionCache = options.sessionCache ? tls.createSessionCache(options.sessionCache) : null; var c = { version: { major: tls.Version.major, minor: tls.Version.minor }, entity, sessionId: options.sessionId, caStore, sessionCache, cipherSuites, connected: options.connected, virtualHost: options.virtualHost || null, verifyClient: options.verifyClient || false, verify: options.verify || function(cn, vfd, dpth, cts) { return vfd; }, verifyOptions: options.verifyOptions || {}, getCertificate: options.getCertificate || null, getPrivateKey: options.getPrivateKey || null, getSignature: options.getSignature || null, input: forge.util.createBuffer(), tlsData: forge.util.createBuffer(), data: forge.util.createBuffer(), tlsDataReady: options.tlsDataReady, dataReady: options.dataReady, heartbeatReceived: options.heartbeatReceived, closed: options.closed, error: function(c, ex) { ex.origin = ex.origin || (c.entity === tls.ConnectionEnd.client ? "client" : "server"); if (ex.send) { tls.queue(c, tls.createAlert(c, ex.alert)); tls.flush(c); } var fatal = ex.fatal !== false; if (fatal) { c.fail = true; } options.error(c, ex); if (fatal) { c.close(false); } }, deflate: options.deflate || null, inflate: options.inflate || null }; /** * Resets a closed TLS connection for reuse. Called in c.close(). * * @param clearFail true to clear the fail flag (default: true). */ c.reset = function(clearFail) { c.version = { major: tls.Version.major, minor: tls.Version.minor }; c.record = null; c.session = null; c.peerCertificate = null; c.state = { pending: null, current: null }; c.expect = c.entity === tls.ConnectionEnd.client ? SHE : CHE; c.fragmented = null; c.records = []; c.open = false; c.handshakes = 0; c.handshaking = false; c.isConnected = false; c.fail = !(clearFail || typeof clearFail === "undefined"); c.input.clear(); c.tlsData.clear(); c.data.clear(); c.state.current = tls.createConnectionState(c); }; c.reset(); /** * Updates the current TLS engine state based on the given record. * * @param c the TLS connection. * @param record the TLS record to act on. */ var _update = function(c, record) { var aligned = record.type - tls.ContentType.change_cipher_spec; var handlers = ctTable[c.entity][c.expect]; if (aligned in handlers) { handlers[aligned](c, record); } else { tls.handleUnexpected(c, record); } }; /** * Reads the record header and initializes the next record on the given * connection. * * @param c the TLS connection with the next record. * * @return 0 if the input data could be processed, otherwise the * number of bytes required for data to be processed. */ var _readRecordHeader = function(c) { var rval = 0; var b = c.input; var len = b.length(); if (len < 5) { rval = 5 - len; } else { c.record = { type: b.getByte(), version: { major: b.getByte(), minor: b.getByte() }, length: b.getInt16(), fragment: forge.util.createBuffer(), ready: false }; var compatibleVersion = c.record.version.major === c.version.major; if (compatibleVersion && c.session && c.session.version) { compatibleVersion = c.record.version.minor === c.version.minor; } if (!compatibleVersion) { c.error(c, { message: "Incompatible TLS version.", send: true, alert: { level: tls.Alert.Level.fatal, description: tls.Alert.Description.protocol_version } }); } } return rval; }; /** * Reads the next record's contents and appends its message to any * previously fragmented message. * * @param c the TLS connection with the next record. * * @return 0 if the input data could be processed, otherwise the * number of bytes required for data to be processed. */ var _readRecord = function(c) { var rval = 0; var b = c.input; var len = b.length(); if (len < c.record.length) { rval = c.record.length - len; } else { c.record.fragment.putBytes(b.getBytes(c.record.length)); b.compact(); var s = c.state.current.read; if (s.update(c, c.record)) { if (c.fragmented !== null) { if (c.fragmented.type === c.record.type) { c.fragmented.fragment.putBuffer(c.record.fragment); c.record = c.fragmented; } else { c.error(c, { message: "Invalid fragmented record.", send: true, alert: { level: tls.Alert.Level.fatal, description: tls.Alert.Description.unexpected_message } }); } } c.record.ready = true; } } return rval; }; /** * Performs a handshake using the TLS Handshake Protocol, as a client. * * This method should only be called if the connection is in client mode. * * @param sessionId the session ID to use, null to start a new one. */ c.handshake = function(sessionId) { if (c.entity !== tls.ConnectionEnd.client) { c.error(c, { message: "Cannot initiate handshake as a server.", fatal: false }); } else if (c.handshaking) { c.error(c, { message: "Handshake already in progress.", fatal: false }); } else { if (c.fail && !c.open && c.handshakes === 0) { c.fail = false; } c.handshaking = true; sessionId = sessionId || ""; var session = null; if (sessionId.length > 0) { if (c.sessionCache) { session = c.sessionCache.getSession(sessionId); } if (session === null) { sessionId = ""; } } if (sessionId.length === 0 && c.sessionCache) { session = c.sessionCache.getSession(); if (session !== null) { sessionId = session.id; } } c.session = { id: sessionId, version: null, cipherSuite: null, compressionMethod: null, serverCertificate: null, certificateRequest: null, clientCertificate: null, sp: {}, md5: forge.md.md5.create(), sha1: forge.md.sha1.create() }; if (session) { c.version = session.version; c.session.sp = session.sp; } c.session.sp.client_random = tls.createRandom().getBytes(); c.open = true; tls.queue(c, tls.createRecord(c, { type: tls.ContentType.handshake, data: tls.createClientHello(c) })); tls.flush(c); } }; /** * Called when TLS protocol data has been received from somewhere and should * be processed by the TLS engine. * * @param data the TLS protocol data, as a string, to process. * * @return 0 if the data could be processed, otherwise the number of bytes * required for data to be processed. */ c.process = function(data) { var rval = 0; if (data) { c.input.putBytes(data); } if (!c.fail) { if (c.record !== null && c.record.ready && c.record.fragment.isEmpty()) { c.record = null; } if (c.record === null) { rval = _readRecordHeader(c); } if (!c.fail && c.record !== null && !c.record.ready) { rval = _readRecord(c); } if (!c.fail && c.record !== null && c.record.ready) { _update(c, c.record); } } return rval; }; /** * Requests that application data be packaged into a TLS record. The * tlsDataReady handler will be called when the TLS record(s) have been * prepared. * * @param data the application data, as a raw 'binary' encoded string, to * be sent; to send utf-16/utf-8 string data, use the return value * of util.encodeUtf8(str). * * @return true on success, false on failure. */ c.prepare = function(data) { tls.queue(c, tls.createRecord(c, { type: tls.ContentType.application_data, data: forge.util.createBuffer(data) })); return tls.flush(c); }; /** * Requests that a heartbeat request be packaged into a TLS record for * transmission. The tlsDataReady handler will be called when TLS record(s) * have been prepared. * * When a heartbeat response has been received, the heartbeatReceived * handler will be called with the matching payload. This handler can * be used to clear a retransmission timer, etc. * * @param payload the heartbeat data to send as the payload in the message. * @param [payloadLength] the payload length to use, defaults to the * actual payload length. * * @return true on success, false on failure. */ c.prepareHeartbeatRequest = function(payload, payloadLength) { if (payload instanceof forge.util.ByteBuffer) { payload = payload.bytes(); } if (typeof payloadLength === "undefined") { payloadLength = payload.length; } c.expectedHeartbeatPayload = payload; tls.queue(c, tls.createRecord(c, { type: tls.ContentType.heartbeat, data: tls.createHeartbeat(tls.HeartbeatMessageType.heartbeat_request, payload, payloadLength) })); return tls.flush(c); }; /** * Closes the connection (sends a close_notify alert). * * @param clearFail true to clear the fail flag (default: true). */ c.close = function(clearFail) { if (!c.fail && c.sessionCache && c.session) { var session = { id: c.session.id, version: c.session.version, sp: c.session.sp }; session.sp.keys = null; c.sessionCache.setSession(session.id, session); } if (c.open) { c.open = false; c.input.clear(); if (c.isConnected || c.handshaking) { c.isConnected = c.handshaking = false; tls.queue(c, tls.createAlert(c, { level: tls.Alert.Level.warning, description: tls.Alert.Description.close_notify })); tls.flush(c); } c.closed(c); } c.reset(clearFail); }; return c; }; module.exports = forge.tls = forge.tls || {}; for (var key in tls) { if (typeof tls[key] !== "function") { forge.tls[key] = tls[key]; } } forge.tls.prf_tls1 = prf_TLS1; forge.tls.hmac_sha1 = hmac_sha1; forge.tls.createSessionCache = tls.createSessionCache; /** * Creates a new TLS connection. This does not make any assumptions about the * transport layer that TLS is working on top of, ie: it does not assume there * is a TCP/IP connection or establish one. A TLS connection is totally * abstracted away from the layer is runs on top of, it merely establishes a * secure channel between a client" and a "server". * * A TLS connection contains 4 connection states: pending read and write, and * current read and write. * * At initialization, the current read and write states will be null. Only once * the security parameters have been set and the keys have been generated can * the pending states be converted into current states. Current states will be * updated for each record processed. * * A custom certificate verify callback may be provided to check information * like the common name on the server's certificate. It will be called for * every certificate in the chain. It has the following signature: * * variable func(c, certs, index, preVerify) * Where: * c The TLS connection * verified Set to true if certificate was verified, otherwise the alert * tls.Alert.Description for why the certificate failed. * depth The current index in the chain, where 0 is the server's cert. * certs The certificate chain, *NOTE* if the server was anonymous then * the chain will be empty. * * The function returns true on success and on failure either the appropriate * tls.Alert.Description or an object with 'alert' set to the appropriate * tls.Alert.Description and 'message' set to a custom error message. If true * is not returned then the connection will abort using, in order of * availability, first the returned alert description, second the preVerify * alert description, and lastly the default 'bad_certificate'. * * There are three callbacks that can be used to make use of client-side * certificates where each takes the TLS connection as the first parameter: * * getCertificate(conn, hint) * The second parameter is a hint as to which certificate should be * returned. If the connection entity is a client, then the hint will be * the CertificateRequest message from the server that is part of the * TLS protocol. If the connection entity is a server, then it will be * the servername list provided via an SNI extension the ClientHello, if * one was provided (empty array if not). The hint can be examined to * determine which certificate to use (advanced). Most implementations * will just return a certificate. The return value must be a * PEM-formatted certificate or an array of PEM-formatted certificates * that constitute a certificate chain, with the first in the array/chain * being the client's certificate. * getPrivateKey(conn, certificate) * The second parameter is an forge.pki X.509 certificate object that * is associated with the requested private key. The return value must * be a PEM-formatted private key. * getSignature(conn, bytes, callback) * This callback can be used instead of getPrivateKey if the private key * is not directly accessible in javascript or should not be. For * instance, a secure external web service could provide the signature * in exchange for appropriate credentials. The second parameter is a * string of bytes to be signed that are part of the TLS protocol. These * bytes are used to verify that the private key for the previously * provided client-side certificate is accessible to the client. The * callback is a function that takes 2 parameters, the TLS connection * and the RSA encrypted (signed) bytes as a string. This callback must * be called once the signature is ready. * * @param options the options for this connection: * server: true if the connection is server-side, false for client. * sessionId: a session ID to reuse, null for a new connection. * caStore: an array of certificates to trust. * sessionCache: a session cache to use. * cipherSuites: an optional array of cipher suites to use, * see tls.CipherSuites. * connected: function(conn) called when the first handshake completes. * virtualHost: the virtual server name to use in a TLS SNI extension. * verifyClient: true to require a client certificate in server mode, * 'optional' to request one, false not to (default: false). * verify: a handler used to custom verify certificates in the chain. * verifyOptions: an object with options for the certificate chain validation. * See documentation of pki.verifyCertificateChain for possible options. * verifyOptions.verify is ignored. If you wish to specify a verify handler * use the verify key. * getCertificate: an optional callback used to get a certificate or * a chain of certificates (as an array). * getPrivateKey: an optional callback used to get a private key. * getSignature: an optional callback used to get a signature. * tlsDataReady: function(conn) called when TLS protocol data has been * prepared and is ready to be used (typically sent over a socket * connection to its destination), read from conn.tlsData buffer. * dataReady: function(conn) called when application data has * been parsed from a TLS record and should be consumed by the * application, read from conn.data buffer. * closed: function(conn) called when the connection has been closed. * error: function(conn, error) called when there was an error. * deflate: function(inBytes) if provided, will deflate TLS records using * the deflate algorithm if the server supports it. * inflate: function(inBytes) if provided, will inflate TLS records using * the deflate algorithm if the server supports it. * * @return the new TLS connection. */ forge.tls.createConnection = tls.createConnection; })); //#endregion //#region ../node_modules/node-forge/lib/aesCipherSuites.js var require_aesCipherSuites = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * A Javascript implementation of AES Cipher Suites for TLS. * * @author Dave Longley * * Copyright (c) 2009-2015 Digital Bazaar, Inc. * */ var forge = require_forge(); require_aes$1(); require_tls(); var tls = module.exports = forge.tls; /** * Supported cipher suites. */ tls.CipherSuites["TLS_RSA_WITH_AES_128_CBC_SHA"] = { id: [0, 47], name: "TLS_RSA_WITH_AES_128_CBC_SHA", initSecurityParameters: function(sp) { sp.bulk_cipher_algorithm = tls.BulkCipherAlgorithm.aes; sp.cipher_type = tls.CipherType.block; sp.enc_key_length = 16; sp.block_length = 16; sp.fixed_iv_length = 16; sp.record_iv_length = 16; sp.mac_algorithm = tls.MACAlgorithm.hmac_sha1; sp.mac_length = 20; sp.mac_key_length = 20; }, initConnectionState }; tls.CipherSuites["TLS_RSA_WITH_AES_256_CBC_SHA"] = { id: [0, 53], name: "TLS_RSA_WITH_AES_256_CBC_SHA", initSecurityParameters: function(sp) { sp.bulk_cipher_algorithm = tls.BulkCipherAlgorithm.aes; sp.cipher_type = tls.CipherType.block; sp.enc_key_length = 32; sp.block_length = 16; sp.fixed_iv_length = 16; sp.record_iv_length = 16; sp.mac_algorithm = tls.MACAlgorithm.hmac_sha1; sp.mac_length = 20; sp.mac_key_length = 20; }, initConnectionState }; function initConnectionState(state, c, sp) { var client = c.entity === forge.tls.ConnectionEnd.client; state.read.cipherState = { init: false, cipher: forge.cipher.createDecipher("AES-CBC", client ? sp.keys.server_write_key : sp.keys.client_write_key), iv: client ? sp.keys.server_write_IV : sp.keys.client_write_IV }; state.write.cipherState = { init: false, cipher: forge.cipher.createCipher("AES-CBC", client ? sp.keys.client_write_key : sp.keys.server_write_key), iv: client ? sp.keys.client_write_IV : sp.keys.server_write_IV }; state.read.cipherFunction = decrypt_aes_cbc_sha1; state.write.cipherFunction = encrypt_aes_cbc_sha1; state.read.macLength = state.write.macLength = sp.mac_length; state.read.macFunction = state.write.macFunction = tls.hmac_sha1; } /** * Encrypts the TLSCompressed record into a TLSCipherText record using AES * in CBC mode. * * @param record the TLSCompressed record to encrypt. * @param s the ConnectionState to use. * * @return true on success, false on failure. */ function encrypt_aes_cbc_sha1(record, s) { var rval = false; var mac = s.macFunction(s.macKey, s.sequenceNumber, record); record.fragment.putBytes(mac); s.updateSequenceNumber(); var iv; if (record.version.minor === tls.Versions.TLS_1_0.minor) { iv = s.cipherState.init ? null : s.cipherState.iv; } else { iv = forge.random.getBytesSync(16); } s.cipherState.init = true; var cipher = s.cipherState.cipher; cipher.start({ iv }); if (record.version.minor >= tls.Versions.TLS_1_1.minor) { cipher.output.putBytes(iv); } cipher.update(record.fragment); if (cipher.finish(encrypt_aes_cbc_sha1_padding)) { record.fragment = cipher.output; record.length = record.fragment.length(); rval = true; } return rval; } /** * Handles padding for aes_cbc_sha1 in encrypt mode. * * @param blockSize the block size. * @param input the input buffer. * @param decrypt true in decrypt mode, false in encrypt mode. * * @return true on success, false on failure. */ function encrypt_aes_cbc_sha1_padding(blockSize, input, decrypt) { if (!decrypt) { var padding = blockSize - input.length() % blockSize; input.fillWithByte(padding - 1, padding); } return true; } /** * Handles padding for aes_cbc_sha1 in decrypt mode. * * @param blockSize the block size. * @param output the output buffer. * @param decrypt true in decrypt mode, false in encrypt mode. * * @return true on success, false on failure. */ function decrypt_aes_cbc_sha1_padding(blockSize, output, decrypt) { var rval = true; if (decrypt) { var len = output.length(); var paddingLength = output.last(); for (var i = len - 1 - paddingLength; i < len - 1; ++i) { rval = rval && output.at(i) == paddingLength; } if (rval) { output.truncate(paddingLength + 1); } } return rval; } /** * Decrypts a TLSCipherText record into a TLSCompressed record using * AES in CBC mode. * * @param record the TLSCipherText record to decrypt. * @param s the ConnectionState to use. * * @return true on success, false on failure. */ function decrypt_aes_cbc_sha1(record, s) { var rval = false; var iv; if (record.version.minor === tls.Versions.TLS_1_0.minor) { iv = s.cipherState.init ? null : s.cipherState.iv; } else { iv = record.fragment.getBytes(16); } s.cipherState.init = true; var cipher = s.cipherState.cipher; cipher.start({ iv }); cipher.update(record.fragment); rval = cipher.finish(decrypt_aes_cbc_sha1_padding); var macLen = s.macLength; var mac = forge.random.getBytesSync(macLen); var len = cipher.output.length(); if (len >= macLen) { record.fragment = cipher.output.getBytes(len - macLen); mac = cipher.output.getBytes(macLen); } else { record.fragment = cipher.output.getBytes(); } record.fragment = forge.util.createBuffer(record.fragment); record.length = record.fragment.length(); var mac2 = s.macFunction(s.macKey, s.sequenceNumber, record); s.updateSequenceNumber(); rval = compareMacs(s.macKey, mac, mac2) && rval; return rval; } /** * Safely compare two MACs. This function will compare two MACs in a way * that protects against timing attacks. * * TODO: Expose elsewhere as a utility API. * * See: https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/february/double-hmac-verification/ * * @param key the MAC key to use. * @param mac1 as a binary-encoded string of bytes. * @param mac2 as a binary-encoded string of bytes. * * @return true if the MACs are the same, false if not. */ function compareMacs(key, mac1, mac2) { var hmac = forge.hmac.create(); hmac.start("SHA1", key); hmac.update(mac1); mac1 = hmac.digest().getBytes(); hmac.start(null, null); hmac.update(mac2); mac2 = hmac.digest().getBytes(); return mac1 === mac2; } })); //#endregion //#region ../node_modules/node-forge/lib/sha512.js var require_sha512$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Secure Hash Algorithm with a 1024-bit block size implementation. * * This includes: SHA-512, SHA-384, SHA-512/224, and SHA-512/256. For * SHA-256 (block size 512 bits), see sha256.js. * * See FIPS 180-4 for details. * * @author Dave Longley * * Copyright (c) 2014-2015 Digital Bazaar, Inc. */ var forge = require_forge(); require_md(); require_util$8(); var sha512 = module.exports = forge.sha512 = forge.sha512 || {}; forge.md.sha512 = forge.md.algorithms.sha512 = sha512; var sha384 = forge.sha384 = forge.sha512.sha384 = forge.sha512.sha384 || {}; sha384.create = function() { return sha512.create("SHA-384"); }; forge.md.sha384 = forge.md.algorithms.sha384 = sha384; forge.sha512.sha256 = forge.sha512.sha256 || { create: function() { return sha512.create("SHA-512/256"); } }; forge.md["sha512/256"] = forge.md.algorithms["sha512/256"] = forge.sha512.sha256; forge.sha512.sha224 = forge.sha512.sha224 || { create: function() { return sha512.create("SHA-512/224"); } }; forge.md["sha512/224"] = forge.md.algorithms["sha512/224"] = forge.sha512.sha224; /** * Creates a SHA-2 message digest object. * * @param algorithm the algorithm to use (SHA-512, SHA-384, SHA-512/224, * SHA-512/256). * * @return a message digest object. */ sha512.create = function(algorithm) { if (!_initialized) { _init(); } if (typeof algorithm === "undefined") { algorithm = "SHA-512"; } if (!(algorithm in _states)) { throw new Error("Invalid SHA-512 algorithm: " + algorithm); } var _state = _states[algorithm]; var _h = null; var _input = forge.util.createBuffer(); var _w = new Array(80); for (var wi = 0; wi < 80; ++wi) { _w[wi] = new Array(2); } var digestLength = 64; switch (algorithm) { case "SHA-384": digestLength = 48; break; case "SHA-512/256": digestLength = 32; break; case "SHA-512/224": digestLength = 28; break; } var md = { algorithm: algorithm.replace("-", "").toLowerCase(), blockLength: 128, digestLength, messageLength: 0, fullMessageLength: null, messageLengthSize: 16 }; /** * Starts the digest. * * @return this digest object. */ md.start = function() { md.messageLength = 0; md.fullMessageLength = md.messageLength128 = []; var int32s = md.messageLengthSize / 4; for (var i = 0; i < int32s; ++i) { md.fullMessageLength.push(0); } _input = forge.util.createBuffer(); _h = new Array(_state.length); for (var i = 0; i < _state.length; ++i) { _h[i] = _state[i].slice(0); } return md; }; md.start(); /** * Updates the digest with the given message input. The given input can * treated as raw input (no encoding will be applied) or an encoding of * 'utf8' maybe given to encode the input using UTF-8. * * @param msg the message input to update with. * @param encoding the encoding to use (default: 'raw', other: 'utf8'). * * @return this digest object. */ md.update = function(msg, encoding) { if (encoding === "utf8") { msg = forge.util.encodeUtf8(msg); } var len = msg.length; md.messageLength += len; len = [len / 4294967296 >>> 0, len >>> 0]; for (var i = md.fullMessageLength.length - 1; i >= 0; --i) { md.fullMessageLength[i] += len[1]; len[1] = len[0] + (md.fullMessageLength[i] / 4294967296 >>> 0); md.fullMessageLength[i] = md.fullMessageLength[i] >>> 0; len[0] = len[1] / 4294967296 >>> 0; } _input.putBytes(msg); _update(_h, _w, _input); if (_input.read > 2048 || _input.length() === 0) { _input.compact(); } return md; }; /** * Produces the digest. * * @return a byte buffer containing the digest value. */ md.digest = function() { var finalBlock = forge.util.createBuffer(); finalBlock.putBytes(_input.bytes()); var remaining = md.fullMessageLength[md.fullMessageLength.length - 1] + md.messageLengthSize; var overflow = remaining & md.blockLength - 1; finalBlock.putBytes(_padding.substr(0, md.blockLength - overflow)); var next, carry; var bits = md.fullMessageLength[0] * 8; for (var i = 0; i < md.fullMessageLength.length - 1; ++i) { next = md.fullMessageLength[i + 1] * 8; carry = next / 4294967296 >>> 0; bits += carry; finalBlock.putInt32(bits >>> 0); bits = next >>> 0; } finalBlock.putInt32(bits); var h = new Array(_h.length); for (var i = 0; i < _h.length; ++i) { h[i] = _h[i].slice(0); } _update(h, _w, finalBlock); var rval = forge.util.createBuffer(); var hlen; if (algorithm === "SHA-512") { hlen = h.length; } else if (algorithm === "SHA-384") { hlen = h.length - 2; } else { hlen = h.length - 4; } for (var i = 0; i < hlen; ++i) { rval.putInt32(h[i][0]); if (i !== hlen - 1 || algorithm !== "SHA-512/224") { rval.putInt32(h[i][1]); } } return rval; }; return md; }; var _padding = null; var _initialized = false; var _k = null; var _states = null; /** * Initializes the constant tables. */ function _init() { _padding = String.fromCharCode(128); _padding += forge.util.fillString(String.fromCharCode(0), 128); _k = [ [1116352408, 3609767458], [1899447441, 602891725], [3049323471, 3964484399], [3921009573, 2173295548], [961987163, 4081628472], [1508970993, 3053834265], [2453635748, 2937671579], [2870763221, 3664609560], [3624381080, 2734883394], [310598401, 1164996542], [607225278, 1323610764], [1426881987, 3590304994], [1925078388, 4068182383], [2162078206, 991336113], [2614888103, 633803317], [3248222580, 3479774868], [3835390401, 2666613458], [4022224774, 944711139], [264347078, 2341262773], [604807628, 2007800933], [770255983, 1495990901], [1249150122, 1856431235], [1555081692, 3175218132], [1996064986, 2198950837], [2554220882, 3999719339], [2821834349, 766784016], [2952996808, 2566594879], [3210313671, 3203337956], [3336571891, 1034457026], [3584528711, 2466948901], [113926993, 3758326383], [338241895, 168717936], [666307205, 1188179964], [773529912, 1546045734], [1294757372, 1522805485], [1396182291, 2643833823], [1695183700, 2343527390], [1986661051, 1014477480], [2177026350, 1206759142], [2456956037, 344077627], [2730485921, 1290863460], [2820302411, 3158454273], [3259730800, 3505952657], [3345764771, 106217008], [3516065817, 3606008344], [3600352804, 1432725776], [4094571909, 1467031594], [275423344, 851169720], [430227734, 3100823752], [506948616, 1363258195], [659060556, 3750685593], [883997877, 3785050280], [958139571, 3318307427], [1322822218, 3812723403], [1537002063, 2003034995], [1747873779, 3602036899], [1955562222, 1575990012], [2024104815, 1125592928], [2227730452, 2716904306], [2361852424, 442776044], [2428436474, 593698344], [2756734187, 3733110249], [3204031479, 2999351573], [3329325298, 3815920427], [3391569614, 3928383900], [3515267271, 566280711], [3940187606, 3454069534], [4118630271, 4000239992], [116418474, 1914138554], [174292421, 2731055270], [289380356, 3203993006], [460393269, 320620315], [685471733, 587496836], [852142971, 1086792851], [1017036298, 365543100], [1126000580, 2618297676], [1288033470, 3409855158], [1501505948, 4234509866], [1607167915, 987167468], [1816402316, 1246189591] ]; _states = {}; _states["SHA-512"] = [ [1779033703, 4089235720], [3144134277, 2227873595], [1013904242, 4271175723], [2773480762, 1595750129], [1359893119, 2917565137], [2600822924, 725511199], [528734635, 4215389547], [1541459225, 327033209] ]; _states["SHA-384"] = [ [3418070365, 3238371032], [1654270250, 914150663], [2438529370, 812702999], [355462360, 4144912697], [1731405415, 4290775857], [2394180231, 1750603025], [3675008525, 1694076839], [1203062813, 3204075428] ]; _states["SHA-512/256"] = [ [573645204, 4230739756], [2673172387, 3360449730], [596883563, 1867755857], [2520282905, 1497426621], [2519219938, 2827943907], [3193839141, 1401305490], [721525244, 746961066], [246885852, 2177182882] ]; _states["SHA-512/224"] = [ [2352822216, 424955298], [1944164710, 2312950998], [502970286, 855612546], [1738396948, 1479516111], [258812777, 2077511080], [2011393907, 79989058], [1067287976, 1780299464], [286451373, 2446758561] ]; _initialized = true; } /** * Updates a SHA-512 state with the given byte buffer. * * @param s the SHA-512 state to update. * @param w the array to use to store words. * @param bytes the byte buffer to update with. */ function _update(s, w, bytes) { var t1_hi, t1_lo; var t2_hi, t2_lo; var s0_hi, s0_lo; var s1_hi, s1_lo; var ch_hi, ch_lo; var maj_hi, maj_lo; var a_hi, a_lo; var b_hi, b_lo; var c_hi, c_lo; var d_hi, d_lo; var e_hi, e_lo; var f_hi, f_lo; var g_hi, g_lo; var h_hi, h_lo; var i, hi, lo, w2, w7, w15, w16; var len = bytes.length(); while (len >= 128) { for (i = 0; i < 16; ++i) { w[i][0] = bytes.getInt32() >>> 0; w[i][1] = bytes.getInt32() >>> 0; } for (; i < 80; ++i) { w2 = w[i - 2]; hi = w2[0]; lo = w2[1]; t1_hi = ((hi >>> 19 | lo << 13) ^ (lo >>> 29 | hi << 3) ^ hi >>> 6) >>> 0; t1_lo = ((hi << 13 | lo >>> 19) ^ (lo << 3 | hi >>> 29) ^ (hi << 26 | lo >>> 6)) >>> 0; w15 = w[i - 15]; hi = w15[0]; lo = w15[1]; t2_hi = ((hi >>> 1 | lo << 31) ^ (hi >>> 8 | lo << 24) ^ hi >>> 7) >>> 0; t2_lo = ((hi << 31 | lo >>> 1) ^ (hi << 24 | lo >>> 8) ^ (hi << 25 | lo >>> 7)) >>> 0; w7 = w[i - 7]; w16 = w[i - 16]; lo = t1_lo + w7[1] + t2_lo + w16[1]; w[i][0] = t1_hi + w7[0] + t2_hi + w16[0] + (lo / 4294967296 >>> 0) >>> 0; w[i][1] = lo >>> 0; } a_hi = s[0][0]; a_lo = s[0][1]; b_hi = s[1][0]; b_lo = s[1][1]; c_hi = s[2][0]; c_lo = s[2][1]; d_hi = s[3][0]; d_lo = s[3][1]; e_hi = s[4][0]; e_lo = s[4][1]; f_hi = s[5][0]; f_lo = s[5][1]; g_hi = s[6][0]; g_lo = s[6][1]; h_hi = s[7][0]; h_lo = s[7][1]; for (i = 0; i < 80; ++i) { s1_hi = ((e_hi >>> 14 | e_lo << 18) ^ (e_hi >>> 18 | e_lo << 14) ^ (e_lo >>> 9 | e_hi << 23)) >>> 0; s1_lo = ((e_hi << 18 | e_lo >>> 14) ^ (e_hi << 14 | e_lo >>> 18) ^ (e_lo << 23 | e_hi >>> 9)) >>> 0; ch_hi = (g_hi ^ e_hi & (f_hi ^ g_hi)) >>> 0; ch_lo = (g_lo ^ e_lo & (f_lo ^ g_lo)) >>> 0; s0_hi = ((a_hi >>> 28 | a_lo << 4) ^ (a_lo >>> 2 | a_hi << 30) ^ (a_lo >>> 7 | a_hi << 25)) >>> 0; s0_lo = ((a_hi << 4 | a_lo >>> 28) ^ (a_lo << 30 | a_hi >>> 2) ^ (a_lo << 25 | a_hi >>> 7)) >>> 0; maj_hi = (a_hi & b_hi | c_hi & (a_hi ^ b_hi)) >>> 0; maj_lo = (a_lo & b_lo | c_lo & (a_lo ^ b_lo)) >>> 0; lo = h_lo + s1_lo + ch_lo + _k[i][1] + w[i][1]; t1_hi = h_hi + s1_hi + ch_hi + _k[i][0] + w[i][0] + (lo / 4294967296 >>> 0) >>> 0; t1_lo = lo >>> 0; lo = s0_lo + maj_lo; t2_hi = s0_hi + maj_hi + (lo / 4294967296 >>> 0) >>> 0; t2_lo = lo >>> 0; h_hi = g_hi; h_lo = g_lo; g_hi = f_hi; g_lo = f_lo; f_hi = e_hi; f_lo = e_lo; lo = d_lo + t1_lo; e_hi = d_hi + t1_hi + (lo / 4294967296 >>> 0) >>> 0; e_lo = lo >>> 0; d_hi = c_hi; d_lo = c_lo; c_hi = b_hi; c_lo = b_lo; b_hi = a_hi; b_lo = a_lo; lo = t1_lo + t2_lo; a_hi = t1_hi + t2_hi + (lo / 4294967296 >>> 0) >>> 0; a_lo = lo >>> 0; } lo = s[0][1] + a_lo; s[0][0] = s[0][0] + a_hi + (lo / 4294967296 >>> 0) >>> 0; s[0][1] = lo >>> 0; lo = s[1][1] + b_lo; s[1][0] = s[1][0] + b_hi + (lo / 4294967296 >>> 0) >>> 0; s[1][1] = lo >>> 0; lo = s[2][1] + c_lo; s[2][0] = s[2][0] + c_hi + (lo / 4294967296 >>> 0) >>> 0; s[2][1] = lo >>> 0; lo = s[3][1] + d_lo; s[3][0] = s[3][0] + d_hi + (lo / 4294967296 >>> 0) >>> 0; s[3][1] = lo >>> 0; lo = s[4][1] + e_lo; s[4][0] = s[4][0] + e_hi + (lo / 4294967296 >>> 0) >>> 0; s[4][1] = lo >>> 0; lo = s[5][1] + f_lo; s[5][0] = s[5][0] + f_hi + (lo / 4294967296 >>> 0) >>> 0; s[5][1] = lo >>> 0; lo = s[6][1] + g_lo; s[6][0] = s[6][0] + g_hi + (lo / 4294967296 >>> 0) >>> 0; s[6][1] = lo >>> 0; lo = s[7][1] + h_lo; s[7][0] = s[7][0] + h_hi + (lo / 4294967296 >>> 0) >>> 0; s[7][1] = lo >>> 0; len -= 128; } } })); //#endregion //#region ../node_modules/node-forge/lib/asn1-validator.js var require_asn1_validator = /* @__PURE__ */ __commonJSMin(((exports) => { /** * Copyright (c) 2019 Digital Bazaar, Inc. */ var forge = require_forge(); require_asn1(); var asn1 = forge.asn1; exports.privateKeyValidator = { name: "PrivateKeyInfo", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [ { name: "PrivateKeyInfo.version", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.INTEGER, constructed: false, capture: "privateKeyVersion" }, { name: "PrivateKeyInfo.privateKeyAlgorithm", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "AlgorithmIdentifier.algorithm", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OID, constructed: false, capture: "privateKeyOid" }] }, { name: "PrivateKeyInfo", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OCTETSTRING, constructed: false, capture: "privateKey" } ] }; exports.publicKeyValidator = { name: "SubjectPublicKeyInfo", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, captureAsn1: "subjectPublicKeyInfo", value: [{ name: "SubjectPublicKeyInfo.AlgorithmIdentifier", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.SEQUENCE, constructed: true, value: [{ name: "AlgorithmIdentifier.algorithm", tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.OID, constructed: false, capture: "publicKeyOid" }] }, { tagClass: asn1.Class.UNIVERSAL, type: asn1.Type.BITSTRING, constructed: false, composed: true, captureBitStringValue: "ed25519PublicKey" }] }; })); //#endregion //#region ../node_modules/node-forge/lib/ed25519.js var require_ed25519 = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * JavaScript implementation of Ed25519. * * Copyright (c) 2017-2019 Digital Bazaar, Inc. * * This implementation is based on the most excellent TweetNaCl which is * in the public domain. Many thanks to its contributors: * * https://github.com/dchest/tweetnacl-js */ var forge = require_forge(); require_jsbn(); require_random(); require_sha512$1(); require_util$8(); var asn1Validator = require_asn1_validator(); var publicKeyValidator = asn1Validator.publicKeyValidator; var privateKeyValidator = asn1Validator.privateKeyValidator; if (typeof BigInteger === "undefined") { var BigInteger = forge.jsbn.BigInteger; } var ByteBuffer = forge.util.ByteBuffer; var NativeBuffer = typeof Buffer === "undefined" ? Uint8Array : Buffer; forge.pki = forge.pki || {}; module.exports = forge.pki.ed25519 = forge.ed25519 = forge.ed25519 || {}; var ed25519 = forge.ed25519; ed25519.constants = {}; ed25519.constants.PUBLIC_KEY_BYTE_LENGTH = 32; ed25519.constants.PRIVATE_KEY_BYTE_LENGTH = 64; ed25519.constants.SEED_BYTE_LENGTH = 32; ed25519.constants.SIGN_BYTE_LENGTH = 64; ed25519.constants.HASH_BYTE_LENGTH = 64; ed25519.generateKeyPair = function(options) { options = options || {}; var seed = options.seed; if (seed === undefined) { seed = forge.random.getBytesSync(ed25519.constants.SEED_BYTE_LENGTH); } else if (typeof seed === "string") { if (seed.length !== ed25519.constants.SEED_BYTE_LENGTH) { throw new TypeError("\"seed\" must be " + ed25519.constants.SEED_BYTE_LENGTH + " bytes in length."); } } else if (!(seed instanceof Uint8Array)) { throw new TypeError("\"seed\" must be a node.js Buffer, Uint8Array, or a binary string."); } seed = messageToNativeBuffer({ message: seed, encoding: "binary" }); var pk = new NativeBuffer(ed25519.constants.PUBLIC_KEY_BYTE_LENGTH); var sk = new NativeBuffer(ed25519.constants.PRIVATE_KEY_BYTE_LENGTH); for (var i = 0; i < 32; ++i) { sk[i] = seed[i]; } crypto_sign_keypair(pk, sk); return { publicKey: pk, privateKey: sk }; }; /** * Converts a private key from a RFC8410 ASN.1 encoding. * * @param obj - The asn1 representation of a private key. * * @returns {Object} keyInfo - The key information. * @returns {Buffer|Uint8Array} keyInfo.privateKeyBytes - 32 private key bytes. */ ed25519.privateKeyFromAsn1 = function(obj) { var capture = {}; var errors = []; var valid = forge.asn1.validate(obj, privateKeyValidator, capture, errors); if (!valid) { var error = new Error("Invalid Key."); error.errors = errors; throw error; } var oid = forge.asn1.derToOid(capture.privateKeyOid); var ed25519Oid = forge.oids.EdDSA25519; if (oid !== ed25519Oid) { throw new Error("Invalid OID \"" + oid + "\"; OID must be \"" + ed25519Oid + "\"."); } var privateKey = capture.privateKey; var privateKeyBytes = messageToNativeBuffer({ message: forge.asn1.fromDer(privateKey).value, encoding: "binary" }); return { privateKeyBytes }; }; /** * Converts a public key from a RFC8410 ASN.1 encoding. * * @param obj - The asn1 representation of a public key. * * @return {Buffer|Uint8Array} - 32 public key bytes. */ ed25519.publicKeyFromAsn1 = function(obj) { var capture = {}; var errors = []; var valid = forge.asn1.validate(obj, publicKeyValidator, capture, errors); if (!valid) { var error = new Error("Invalid Key."); error.errors = errors; throw error; } var oid = forge.asn1.derToOid(capture.publicKeyOid); var ed25519Oid = forge.oids.EdDSA25519; if (oid !== ed25519Oid) { throw new Error("Invalid OID \"" + oid + "\"; OID must be \"" + ed25519Oid + "\"."); } var publicKeyBytes = capture.ed25519PublicKey; if (publicKeyBytes.length !== ed25519.constants.PUBLIC_KEY_BYTE_LENGTH) { throw new Error("Key length is invalid."); } return messageToNativeBuffer({ message: publicKeyBytes, encoding: "binary" }); }; ed25519.publicKeyFromPrivateKey = function(options) { options = options || {}; var privateKey = messageToNativeBuffer({ message: options.privateKey, encoding: "binary" }); if (privateKey.length !== ed25519.constants.PRIVATE_KEY_BYTE_LENGTH) { throw new TypeError("\"options.privateKey\" must have a byte length of " + ed25519.constants.PRIVATE_KEY_BYTE_LENGTH); } var pk = new NativeBuffer(ed25519.constants.PUBLIC_KEY_BYTE_LENGTH); for (var i = 0; i < pk.length; ++i) { pk[i] = privateKey[32 + i]; } return pk; }; ed25519.sign = function(options) { options = options || {}; var msg = messageToNativeBuffer(options); var privateKey = messageToNativeBuffer({ message: options.privateKey, encoding: "binary" }); if (privateKey.length === ed25519.constants.SEED_BYTE_LENGTH) { var keyPair = ed25519.generateKeyPair({ seed: privateKey }); privateKey = keyPair.privateKey; } else if (privateKey.length !== ed25519.constants.PRIVATE_KEY_BYTE_LENGTH) { throw new TypeError("\"options.privateKey\" must have a byte length of " + ed25519.constants.SEED_BYTE_LENGTH + " or " + ed25519.constants.PRIVATE_KEY_BYTE_LENGTH); } var signedMsg = new NativeBuffer(ed25519.constants.SIGN_BYTE_LENGTH + msg.length); crypto_sign(signedMsg, msg, msg.length, privateKey); var sig = new NativeBuffer(ed25519.constants.SIGN_BYTE_LENGTH); for (var i = 0; i < sig.length; ++i) { sig[i] = signedMsg[i]; } return sig; }; ed25519.verify = function(options) { options = options || {}; var msg = messageToNativeBuffer(options); if (options.signature === undefined) { throw new TypeError("\"options.signature\" must be a node.js Buffer, a Uint8Array, a forge " + "ByteBuffer, or a binary string."); } var sig = messageToNativeBuffer({ message: options.signature, encoding: "binary" }); if (sig.length !== ed25519.constants.SIGN_BYTE_LENGTH) { throw new TypeError("\"options.signature\" must have a byte length of " + ed25519.constants.SIGN_BYTE_LENGTH); } var publicKey = messageToNativeBuffer({ message: options.publicKey, encoding: "binary" }); if (publicKey.length !== ed25519.constants.PUBLIC_KEY_BYTE_LENGTH) { throw new TypeError("\"options.publicKey\" must have a byte length of " + ed25519.constants.PUBLIC_KEY_BYTE_LENGTH); } var sm = new NativeBuffer(ed25519.constants.SIGN_BYTE_LENGTH + msg.length); var m = new NativeBuffer(ed25519.constants.SIGN_BYTE_LENGTH + msg.length); var i; for (i = 0; i < ed25519.constants.SIGN_BYTE_LENGTH; ++i) { sm[i] = sig[i]; } for (i = 0; i < msg.length; ++i) { sm[i + ed25519.constants.SIGN_BYTE_LENGTH] = msg[i]; } return crypto_sign_open(m, sm, sm.length, publicKey) >= 0; }; function messageToNativeBuffer(options) { var message = options.message; if (message instanceof Uint8Array || message instanceof NativeBuffer) { return message; } var encoding = options.encoding; if (message === undefined) { if (options.md) { message = options.md.digest().getBytes(); encoding = "binary"; } else { throw new TypeError("\"options.message\" or \"options.md\" not specified."); } } if (typeof message === "string" && !encoding) { throw new TypeError("\"options.encoding\" must be \"binary\" or \"utf8\"."); } if (typeof message === "string") { if (typeof Buffer !== "undefined") { return Buffer.from(message, encoding); } message = new ByteBuffer(message, encoding); } else if (!(message instanceof ByteBuffer)) { throw new TypeError("\"options.message\" must be a node.js Buffer, a Uint8Array, a forge " + "ByteBuffer, or a string with \"options.encoding\" specifying its " + "encoding."); } var buffer = new NativeBuffer(message.length()); for (var i = 0; i < buffer.length; ++i) { buffer[i] = message.at(i); } return buffer; } var gf0 = gf(); var gf1 = gf([1]); var D = gf([ 30883, 4953, 19914, 30187, 55467, 16705, 2637, 112, 59544, 30585, 16505, 36039, 65139, 11119, 27886, 20995 ]); var D2 = gf([ 61785, 9906, 39828, 60374, 45398, 33411, 5274, 224, 53552, 61171, 33010, 6542, 64743, 22239, 55772, 9222 ]); var X = gf([ 54554, 36645, 11616, 51542, 42930, 38181, 51040, 26924, 56412, 64982, 57905, 49316, 21502, 52590, 14035, 8553 ]); var Y = gf([ 26200, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214 ]); var L = new Float64Array([ 237, 211, 245, 92, 26, 99, 18, 88, 214, 156, 247, 162, 222, 249, 222, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16 ]); var I = gf([ 41136, 18958, 6951, 50414, 58488, 44335, 6150, 12099, 55207, 15867, 153, 11085, 57099, 20417, 9344, 11139 ]); function sha512(msg, msgLen) { var md = forge.md.sha512.create(); var buffer = new ByteBuffer(msg); md.update(buffer.getBytes(msgLen), "binary"); var hash = md.digest().getBytes(); if (typeof Buffer !== "undefined") { return Buffer.from(hash, "binary"); } var out = new NativeBuffer(ed25519.constants.HASH_BYTE_LENGTH); for (var i = 0; i < 64; ++i) { out[i] = hash.charCodeAt(i); } return out; } function crypto_sign_keypair(pk, sk) { var p = [ gf(), gf(), gf(), gf() ]; var i; var d = sha512(sk, 32); d[0] &= 248; d[31] &= 127; d[31] |= 64; scalarbase(p, d); pack(pk, p); for (i = 0; i < 32; ++i) { sk[i + 32] = pk[i]; } return 0; } function crypto_sign(sm, m, n, sk) { var i, j, x = new Float64Array(64); var p = [ gf(), gf(), gf(), gf() ]; var d = sha512(sk, 32); 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]; } var r = sha512(sm.subarray(32), n + 32); reduce(r); scalarbase(p, r); pack(sm, p); for (i = 32; i < 64; ++i) { sm[i] = sk[i]; } var h = sha512(sm, n + 64); reduce(h); for (i = 32; 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 crypto_sign_open(m, sm, n, pk) { var i, mlen; var t = new NativeBuffer(32); 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]; } var h = sha512(m, n); 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; } 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); for (var i = 0; i < 64; ++i) { x[i] = r[i]; r[i] = 0; } modL(r, x); } 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) { for (var 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 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] - 65517; for (i = 1; i < 15; ++i) { m[i] = t[i] - 65535 - (m[i - 1] >> 16 & 1); m[i - 1] &= 65535; } m[15] = t[15] - 32767 - (m[14] >> 16 & 1); b = m[15] >> 16 & 1; m[14] &= 65535; sel25519(t, m, 1 - b); } for (i = 0; i < 16; i++) { o[2 * i] = t[i] & 255; o[2 * i + 1] = t[i] >> 8; } } 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 unpack25519(o, n) { var i; for (i = 0; i < 16; ++i) { o[i] = n[2 * i] + (n[2 * i + 1] << 8); } o[15] &= 32767; } 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 neq25519(a, b) { var c = new NativeBuffer(32); var d = new NativeBuffer(32); pack25519(c, a); pack25519(d, b); return crypto_verify_32(c, 0, d, 0); } function crypto_verify_32(x, xi, y, yi) { return vn(x, xi, y, yi, 32); } 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 par25519(a) { var d = new NativeBuffer(32); pack25519(d, a); return d[0] & 1; } 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 set25519(r, a) { var i; for (i = 0; i < 16; i++) { r[i] = a[i] | 0; } } 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 car25519(o) { var i, v, c = 1; for (i = 0; i < 16; ++i) { v = o[i] + c + 65535; c = Math.floor(v / 65536); o[i] = v - c * 65536; } o[0] += c - 1 + 37 * (c - 1); } 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 gf(init) { var i, r = new Float64Array(16); if (init) { for (i = 0; i < init.length; ++i) { r[i] = init[i]; } } return r; } function A(o, a, b) { for (var i = 0; i < 16; ++i) { o[i] = a[i] + b[i]; } } function Z(o, a, b) { for (var i = 0; i < 16; ++i) { o[i] = a[i] - b[i]; } } function S(o, a) { M(o, a, a); } function M(o, a, b) { var v, c, t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0, t8 = 0, t9 = 0, t10 = 0, t11 = 0, t12 = 0, t13 = 0, t14 = 0, t15 = 0, t16 = 0, t17 = 0, t18 = 0, t19 = 0, t20 = 0, t21 = 0, t22 = 0, t23 = 0, t24 = 0, t25 = 0, t26 = 0, t27 = 0, t28 = 0, t29 = 0, t30 = 0, b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4], b5 = b[5], b6 = b[6], b7 = b[7], b8 = b[8], b9 = b[9], b10 = b[10], b11 = b[11], b12 = b[12], b13 = b[13], b14 = b[14], b15 = b[15]; v = a[0]; t0 += v * b0; t1 += v * b1; t2 += v * b2; t3 += v * b3; t4 += v * b4; t5 += v * b5; t6 += v * b6; t7 += v * b7; t8 += v * b8; t9 += v * b9; t10 += v * b10; t11 += v * b11; t12 += v * b12; t13 += v * b13; t14 += v * b14; t15 += v * b15; v = a[1]; t1 += v * b0; t2 += v * b1; t3 += v * b2; t4 += v * b3; t5 += v * b4; t6 += v * b5; t7 += v * b6; t8 += v * b7; t9 += v * b8; t10 += v * b9; t11 += v * b10; t12 += v * b11; t13 += v * b12; t14 += v * b13; t15 += v * b14; t16 += v * b15; v = a[2]; t2 += v * b0; t3 += v * b1; t4 += v * b2; t5 += v * b3; t6 += v * b4; t7 += v * b5; t8 += v * b6; t9 += v * b7; t10 += v * b8; t11 += v * b9; t12 += v * b10; t13 += v * b11; t14 += v * b12; t15 += v * b13; t16 += v * b14; t17 += v * b15; v = a[3]; t3 += v * b0; t4 += v * b1; t5 += v * b2; t6 += v * b3; t7 += v * b4; t8 += v * b5; t9 += v * b6; t10 += v * b7; t11 += v * b8; t12 += v * b9; t13 += v * b10; t14 += v * b11; t15 += v * b12; t16 += v * b13; t17 += v * b14; t18 += v * b15; v = a[4]; t4 += v * b0; t5 += v * b1; t6 += v * b2; t7 += v * b3; t8 += v * b4; t9 += v * b5; t10 += v * b6; t11 += v * b7; t12 += v * b8; t13 += v * b9; t14 += v * b10; t15 += v * b11; t16 += v * b12; t17 += v * b13; t18 += v * b14; t19 += v * b15; v = a[5]; t5 += v * b0; t6 += v * b1; t7 += v * b2; t8 += v * b3; t9 += v * b4; t10 += v * b5; t11 += v * b6; t12 += v * b7; t13 += v * b8; t14 += v * b9; t15 += v * b10; t16 += v * b11; t17 += v * b12; t18 += v * b13; t19 += v * b14; t20 += v * b15; v = a[6]; t6 += v * b0; t7 += v * b1; t8 += v * b2; t9 += v * b3; t10 += v * b4; t11 += v * b5; t12 += v * b6; t13 += v * b7; t14 += v * b8; t15 += v * b9; t16 += v * b10; t17 += v * b11; t18 += v * b12; t19 += v * b13; t20 += v * b14; t21 += v * b15; v = a[7]; t7 += v * b0; t8 += v * b1; t9 += v * b2; t10 += v * b3; t11 += v * b4; t12 += v * b5; t13 += v * b6; t14 += v * b7; t15 += v * b8; t16 += v * b9; t17 += v * b10; t18 += v * b11; t19 += v * b12; t20 += v * b13; t21 += v * b14; t22 += v * b15; v = a[8]; t8 += v * b0; t9 += v * b1; t10 += v * b2; t11 += v * b3; t12 += v * b4; t13 += v * b5; t14 += v * b6; t15 += v * b7; t16 += v * b8; t17 += v * b9; t18 += v * b10; t19 += v * b11; t20 += v * b12; t21 += v * b13; t22 += v * b14; t23 += v * b15; v = a[9]; t9 += v * b0; t10 += v * b1; t11 += v * b2; t12 += v * b3; t13 += v * b4; t14 += v * b5; t15 += v * b6; t16 += v * b7; t17 += v * b8; t18 += v * b9; t19 += v * b10; t20 += v * b11; t21 += v * b12; t22 += v * b13; t23 += v * b14; t24 += v * b15; v = a[10]; t10 += v * b0; t11 += v * b1; t12 += v * b2; t13 += v * b3; t14 += v * b4; t15 += v * b5; t16 += v * b6; t17 += v * b7; t18 += v * b8; t19 += v * b9; t20 += v * b10; t21 += v * b11; t22 += v * b12; t23 += v * b13; t24 += v * b14; t25 += v * b15; v = a[11]; t11 += v * b0; t12 += v * b1; t13 += v * b2; t14 += v * b3; t15 += v * b4; t16 += v * b5; t17 += v * b6; t18 += v * b7; t19 += v * b8; t20 += v * b9; t21 += v * b10; t22 += v * b11; t23 += v * b12; t24 += v * b13; t25 += v * b14; t26 += v * b15; v = a[12]; t12 += v * b0; t13 += v * b1; t14 += v * b2; t15 += v * b3; t16 += v * b4; t17 += v * b5; t18 += v * b6; t19 += v * b7; t20 += v * b8; t21 += v * b9; t22 += v * b10; t23 += v * b11; t24 += v * b12; t25 += v * b13; t26 += v * b14; t27 += v * b15; v = a[13]; t13 += v * b0; t14 += v * b1; t15 += v * b2; t16 += v * b3; t17 += v * b4; t18 += v * b5; t19 += v * b6; t20 += v * b7; t21 += v * b8; t22 += v * b9; t23 += v * b10; t24 += v * b11; t25 += v * b12; t26 += v * b13; t27 += v * b14; t28 += v * b15; v = a[14]; t14 += v * b0; t15 += v * b1; t16 += v * b2; t17 += v * b3; t18 += v * b4; t19 += v * b5; t20 += v * b6; t21 += v * b7; t22 += v * b8; t23 += v * b9; t24 += v * b10; t25 += v * b11; t26 += v * b12; t27 += v * b13; t28 += v * b14; t29 += v * b15; v = a[15]; t15 += v * b0; t16 += v * b1; t17 += v * b2; t18 += v * b3; t19 += v * b4; t20 += v * b5; t21 += v * b6; t22 += v * b7; t23 += v * b8; t24 += v * b9; t25 += v * b10; t26 += v * b11; t27 += v * b12; t28 += v * b13; t29 += v * b14; t30 += v * b15; t0 += 38 * t16; t1 += 38 * t17; t2 += 38 * t18; t3 += 38 * t19; t4 += 38 * t20; t5 += 38 * t21; t6 += 38 * t22; t7 += 38 * t23; t8 += 38 * t24; t9 += 38 * t25; t10 += 38 * t26; t11 += 38 * t27; t12 += 38 * t28; t13 += 38 * t29; t14 += 38 * t30; c = 1; v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536; v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536; v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536; v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536; v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536; v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536; v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536; v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536; v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536; v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536; v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536; v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536; v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536; v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536; v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536; v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536; t0 += c - 1 + 37 * (c - 1); c = 1; v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536; v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536; v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536; v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536; v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536; v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536; v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536; v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536; v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536; v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536; v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536; v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536; v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536; v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536; v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536; v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536; t0 += c - 1 + 37 * (c - 1); o[0] = t0; o[1] = t1; o[2] = t2; o[3] = t3; o[4] = t4; o[5] = t5; o[6] = t6; o[7] = t7; o[8] = t8; o[9] = t9; o[10] = t10; o[11] = t11; o[12] = t12; o[13] = t13; o[14] = t14; o[15] = t15; } })); //#endregion //#region ../node_modules/node-forge/lib/kem.js var require_kem = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Javascript implementation of RSA-KEM. * * @author Lautaro Cozzani Rodriguez * @author Dave Longley * * Copyright (c) 2014 Lautaro Cozzani * Copyright (c) 2014 Digital Bazaar, Inc. */ var forge = require_forge(); require_util$8(); require_random(); require_jsbn(); module.exports = forge.kem = forge.kem || {}; var BigInteger = forge.jsbn.BigInteger; /** * The API for the RSA Key Encapsulation Mechanism (RSA-KEM) from ISO 18033-2. */ forge.kem.rsa = {}; /** * Creates an RSA KEM API object for generating a secret asymmetric key. * * The symmetric key may be generated via a call to 'encrypt', which will * produce a ciphertext to be transmitted to the recipient and a key to be * kept secret. The ciphertext is a parameter to be passed to 'decrypt' which * will produce the same secret key for the recipient to use to decrypt a * message that was encrypted with the secret key. * * @param kdf the KDF API to use (eg: new forge.kem.kdf1()). * @param options the options to use. * [prng] a custom crypto-secure pseudo-random number generator to use, * that must define "getBytesSync". */ forge.kem.rsa.create = function(kdf, options) { options = options || {}; var prng = options.prng || forge.random; var kem = {}; /** * Generates a secret key and its encapsulation. * * @param publicKey the RSA public key to encrypt with. * @param keyLength the length, in bytes, of the secret key to generate. * * @return an object with: * encapsulation: the ciphertext for generating the secret key, as a * binary-encoded string of bytes. * key: the secret key to use for encrypting a message. */ kem.encrypt = function(publicKey, keyLength) { var byteLength = Math.ceil(publicKey.n.bitLength() / 8); var r; do { r = new BigInteger(forge.util.bytesToHex(prng.getBytesSync(byteLength)), 16).mod(publicKey.n); } while (r.compareTo(BigInteger.ONE) <= 0); r = forge.util.hexToBytes(r.toString(16)); var zeros = byteLength - r.length; if (zeros > 0) { r = forge.util.fillString(String.fromCharCode(0), zeros) + r; } var encapsulation = publicKey.encrypt(r, "NONE"); var key = kdf.generate(r, keyLength); return { encapsulation, key }; }; /** * Decrypts an encapsulated secret key. * * @param privateKey the RSA private key to decrypt with. * @param encapsulation the ciphertext for generating the secret key, as * a binary-encoded string of bytes. * @param keyLength the length, in bytes, of the secret key to generate. * * @return the secret key as a binary-encoded string of bytes. */ kem.decrypt = function(privateKey, encapsulation, keyLength) { var r = privateKey.decrypt(encapsulation, "NONE"); return kdf.generate(r, keyLength); }; return kem; }; /** * Creates a key derivation API object that implements KDF1 per ISO 18033-2. * * @param md the hash API to use. * @param [digestLength] an optional digest length that must be positive and * less than or equal to md.digestLength. * * @return a KDF1 API object. */ forge.kem.kdf1 = function(md, digestLength) { _createKDF(this, md, 0, digestLength || md.digestLength); }; /** * Creates a key derivation API object that implements KDF2 per ISO 18033-2. * * @param md the hash API to use. * @param [digestLength] an optional digest length that must be positive and * less than or equal to md.digestLength. * * @return a KDF2 API object. */ forge.kem.kdf2 = function(md, digestLength) { _createKDF(this, md, 1, digestLength || md.digestLength); }; /** * Creates a KDF1 or KDF2 API object. * * @param md the hash API to use. * @param counterStart the starting index for the counter. * @param digestLength the digest length to use. * * @return the KDF API object. */ function _createKDF(kdf, md, counterStart, digestLength) { /** * Generate a key of the specified length. * * @param x the binary-encoded byte string to generate a key from. * @param length the number of bytes to generate (the size of the key). * * @return the key as a binary-encoded string. */ kdf.generate = function(x, length) { var key = new forge.util.ByteBuffer(); var k = Math.ceil(length / digestLength) + counterStart; var c = new forge.util.ByteBuffer(); for (var i = counterStart; i < k; ++i) { c.putInt32(i); md.start(); md.update(x + c.getBytes()); var hash = md.digest(); key.putBytes(hash.getBytes(digestLength)); } key.truncate(key.length() - length); return key.getBytes(); }; } })); //#endregion //#region ../node_modules/node-forge/lib/log.js var require_log = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Cross-browser support for logging in a web application. * * @author David I. Lehn * * Copyright (c) 2008-2013 Digital Bazaar, Inc. */ var forge = require_forge(); require_util$8(); module.exports = forge.log = forge.log || {}; /** * Application logging system. * * Each logger level available as it's own function of the form: * forge.log.level(category, args...) * The category is an arbitrary string, and the args are the same as * Firebug's console.log API. By default the call will be output as: * 'LEVEL [category] , args[1], ...' * This enables proper % formatting via the first argument. * Each category is enabled by default but can be enabled or disabled with * the setCategoryEnabled() function. */ forge.log.levels = [ "none", "error", "warning", "info", "debug", "verbose", "max" ]; var sLevelInfo = {}; var sLoggers = []; /** * Standard console logger. If no console support is enabled this will * remain null. Check before using. */ var sConsoleLogger = null; /** * Lock the level at the current value. Used in cases where user config may * set the level such that only critical messages are seen but more verbose * messages are needed for debugging or other purposes. */ forge.log.LEVEL_LOCKED = 1 << 1; /** * Always call log function. By default, the logging system will check the * message level against logger.level before calling the log function. This * flag allows the function to do its own check. */ forge.log.NO_LEVEL_CHECK = 1 << 2; /** * Perform message interpolation with the passed arguments. "%" style * fields in log messages will be replaced by arguments as needed. Some * loggers, such as Firebug, may do this automatically. The original log * message will be available as 'message' and the interpolated version will * be available as 'fullMessage'. */ forge.log.INTERPOLATE = 1 << 3; for (var i = 0; i < forge.log.levels.length; ++i) { var level = forge.log.levels[i]; sLevelInfo[level] = { index: i, name: level.toUpperCase() }; } /** * Message logger. Will dispatch a message to registered loggers as needed. * * @param message message object */ forge.log.logMessage = function(message) { var messageLevelIndex = sLevelInfo[message.level].index; for (var i = 0; i < sLoggers.length; ++i) { var logger = sLoggers[i]; if (logger.flags & forge.log.NO_LEVEL_CHECK) { logger.f(message); } else { var loggerLevelIndex = sLevelInfo[logger.level].index; if (messageLevelIndex <= loggerLevelIndex) { logger.f(logger, message); } } } }; /** * Sets the 'standard' key on a message object to: * "LEVEL [category] " + message * * @param message a message log object */ forge.log.prepareStandard = function(message) { if (!("standard" in message)) { message.standard = sLevelInfo[message.level].name + " [" + message.category + "] " + message.message; } }; /** * Sets the 'full' key on a message object to the original message * interpolated via % formatting with the message arguments. * * @param message a message log object. */ forge.log.prepareFull = function(message) { if (!("full" in message)) { var args = [message.message]; args = args.concat([] || message["arguments"]); message.full = forge.util.format.apply(this, args); } }; /** * Applies both preparseStandard() and prepareFull() to a message object and * store result in 'standardFull'. * * @param message a message log object. */ forge.log.prepareStandardFull = function(message) { if (!("standardFull" in message)) { forge.log.prepareStandard(message); message.standardFull = message.standard; } }; if (true) { var levels = [ "error", "warning", "info", "debug", "verbose" ]; for (var i = 0; i < levels.length; ++i) { (function(level) { forge.log[level] = function(category, message) { var args = Array.prototype.slice.call(arguments).slice(2); var msg = { timestamp: new Date(), level, category, message, "arguments": args }; forge.log.logMessage(msg); }; })(levels[i]); } } /** * Creates a new logger with specified custom logging function. * * The logging function has a signature of: * function(logger, message) * logger: current logger * message: object: * level: level id * category: category * message: string message * arguments: Array of extra arguments * fullMessage: interpolated message and arguments if INTERPOLATE flag set * * @param logFunction a logging function which takes a log message object * as a parameter. * * @return a logger object. */ forge.log.makeLogger = function(logFunction) { var logger = { flags: 0, f: logFunction }; forge.log.setLevel(logger, "none"); return logger; }; /** * Sets the current log level on a logger. * * @param logger the target logger. * @param level the new maximum log level as a string. * * @return true if set, false if not. */ forge.log.setLevel = function(logger, level) { var rval = false; if (logger && !(logger.flags & forge.log.LEVEL_LOCKED)) { for (var i = 0; i < forge.log.levels.length; ++i) { var aValidLevel = forge.log.levels[i]; if (level == aValidLevel) { logger.level = level; rval = true; break; } } } return rval; }; /** * Locks the log level at its current value. * * @param logger the target logger. * @param lock boolean lock value, default to true. */ forge.log.lock = function(logger, lock) { if (typeof lock === "undefined" || lock) { logger.flags |= forge.log.LEVEL_LOCKED; } else { logger.flags &= ~forge.log.LEVEL_LOCKED; } }; /** * Adds a logger. * * @param logger the logger object. */ forge.log.addLogger = function(logger) { sLoggers.push(logger); }; if (typeof console !== "undefined" && "log" in console) { var logger; if (console.error && console.warn && console.info && console.debug) { var levelHandlers = { error: console.error, warning: console.warn, info: console.info, debug: console.debug, verbose: console.debug }; var f = function(logger, message) { forge.log.prepareStandard(message); var handler = levelHandlers[message.level]; var args = [message.standard]; args = args.concat(message["arguments"].slice()); handler.apply(console, args); }; logger = forge.log.makeLogger(f); } else { var f = function(logger, message) { forge.log.prepareStandardFull(message); console.log(message.standardFull); }; logger = forge.log.makeLogger(f); } forge.log.setLevel(logger, "debug"); forge.log.addLogger(logger); sConsoleLogger = logger; } else { console = { log: function() {} }; } if (sConsoleLogger !== null && typeof window !== "undefined" && window.location) { var query = new URL(window.location.href).searchParams; if (query.has("console.level")) { forge.log.setLevel(sConsoleLogger, query.get("console.level").slice(-1)[0]); } if (query.has("console.lock")) { var lock = query.get("console.lock").slice(-1)[0]; if (lock == "true") { forge.log.lock(sConsoleLogger); } } } forge.log.consoleLogger = sConsoleLogger; })); //#endregion //#region ../node_modules/node-forge/lib/md.all.js var require_md_all = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Node.js module for all known Forge message digests. * * @author Dave Longley * * Copyright 2011-2017 Digital Bazaar, Inc. */ module.exports = require_md(); require_md5$1(); require_sha1$1(); require_sha256$1(); require_sha512$1(); })); //#endregion //#region ../node_modules/node-forge/lib/pkcs7.js var require_pkcs7 = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Javascript implementation of PKCS#7 v1.5. * * @author Stefan Siegl * @author Dave Longley * * Copyright (c) 2012 Stefan Siegl * Copyright (c) 2012-2015 Digital Bazaar, Inc. * * Currently this implementation only supports ContentType of EnvelopedData, * EncryptedData, or SignedData at the root level. The top level elements may * contain only a ContentInfo of ContentType Data, i.e. plain data. Further * nesting is not (yet) supported. * * The Forge validators for PKCS #7's ASN.1 structures are available from * a separate file pkcs7asn1.js, since those are referenced from other * PKCS standards like PKCS #12. */ var forge = require_forge(); require_aes$1(); require_asn1(); require_des(); require_oids(); require_pem(); require_pkcs7asn1(); require_random(); require_util$8(); require_x509(); var asn1 = forge.asn1; var p7 = module.exports = forge.pkcs7 = forge.pkcs7 || {}; /** * Converts a PKCS#7 message from PEM format. * * @param pem the PEM-formatted PKCS#7 message. * * @return the PKCS#7 message. */ p7.messageFromPem = function(pem) { var msg = forge.pem.decode(pem)[0]; if (msg.type !== "PKCS7") { var error = new Error("Could not convert PKCS#7 message from PEM; PEM " + "header type is not \"PKCS#7\"."); error.headerType = msg.type; throw error; } if (msg.procType && msg.procType.type === "ENCRYPTED") { throw new Error("Could not convert PKCS#7 message from PEM; PEM is encrypted."); } var obj = asn1.fromDer(msg.body); return p7.messageFromAsn1(obj); }; /** * Converts a PKCS#7 message to PEM format. * * @param msg The PKCS#7 message object * @param maxline The maximum characters per line, defaults to 64. * * @return The PEM-formatted PKCS#7 message. */ p7.messageToPem = function(msg, maxline) { var pemObj = { type: "PKCS7", body: asn1.toDer(msg.toAsn1()).getBytes() }; return forge.pem.encode(pemObj, { maxline }); }; /** * Converts a PKCS#7 message from an ASN.1 object. * * @param obj the ASN.1 representation of a ContentInfo. * * @return the PKCS#7 message. */ p7.messageFromAsn1 = function(obj) { var capture = {}; var errors = []; if (!asn1.validate(obj, p7.asn1.contentInfoValidator, capture, errors)) { var error = new Error("Cannot read PKCS#7 message. " + "ASN.1 object is not an PKCS#7 ContentInfo."); error.errors = errors; throw error; } var contentType = asn1.derToOid(capture.contentType); var msg; switch (contentType) { case forge.pki.oids.envelopedData: msg = p7.createEnvelopedData(); break; case forge.pki.oids.encryptedData: msg = p7.createEncryptedData(); break; case forge.pki.oids.signedData: msg = p7.createSignedData(); break; default: throw new Error("Cannot read PKCS#7 message. ContentType with OID " + contentType + " is not (yet) supported."); } msg.fromAsn1(capture.content.value[0]); return msg; }; p7.createSignedData = function() { var msg = null; msg = { type: forge.pki.oids.signedData, version: 1, certificates: [], crls: [], signers: [], digestAlgorithmIdentifiers: [], contentInfo: null, signerInfos: [], fromAsn1: function(obj) { _fromAsn1(msg, obj, p7.asn1.signedDataValidator); msg.certificates = []; msg.crls = []; msg.digestAlgorithmIdentifiers = []; msg.contentInfo = null; msg.signerInfos = []; if (msg.rawCapture.certificates) { var certs = msg.rawCapture.certificates.value; for (var i = 0; i < certs.length; ++i) { msg.certificates.push(forge.pki.certificateFromAsn1(certs[i])); } } }, toAsn1: function() { if (!msg.contentInfo) { msg.sign(); } var certs = []; for (var i = 0; i < msg.certificates.length; ++i) { certs.push(forge.pki.certificateToAsn1(msg.certificates[i])); } var crls = []; var signedData = asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, asn1.integerToDer(msg.version).getBytes()), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, msg.digestAlgorithmIdentifiers), msg.contentInfo ])]); if (certs.length > 0) { signedData.value[0].value.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, certs)); } if (crls.length > 0) { signedData.value[0].value.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 1, true, crls)); } signedData.value[0].value.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, msg.signerInfos)); return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(msg.type).getBytes()), signedData]); }, addSigner: function(signer) { var issuer = signer.issuer; var serialNumber = signer.serialNumber; if (signer.certificate) { var cert = signer.certificate; if (typeof cert === "string") { cert = forge.pki.certificateFromPem(cert); } issuer = cert.issuer.attributes; serialNumber = cert.serialNumber; } var key = signer.key; if (!key) { throw new Error("Could not add PKCS#7 signer; no private key specified."); } if (typeof key === "string") { key = forge.pki.privateKeyFromPem(key); } var digestAlgorithm = signer.digestAlgorithm || forge.pki.oids.sha1; switch (digestAlgorithm) { case forge.pki.oids.sha1: case forge.pki.oids.sha256: case forge.pki.oids.sha384: case forge.pki.oids.sha512: case forge.pki.oids.md5: break; default: throw new Error("Could not add PKCS#7 signer; unknown message digest algorithm: " + digestAlgorithm); } var authenticatedAttributes = signer.authenticatedAttributes || []; if (authenticatedAttributes.length > 0) { var contentType = false; var messageDigest = false; for (var i = 0; i < authenticatedAttributes.length; ++i) { var attr = authenticatedAttributes[i]; if (!contentType && attr.type === forge.pki.oids.contentType) { contentType = true; if (messageDigest) { break; } continue; } if (!messageDigest && attr.type === forge.pki.oids.messageDigest) { messageDigest = true; if (contentType) { break; } continue; } } if (!contentType || !messageDigest) { throw new Error("Invalid signer.authenticatedAttributes. If " + "signer.authenticatedAttributes is specified, then it must " + "contain at least two attributes, PKCS #9 content-type and " + "PKCS #9 message-digest."); } } msg.signers.push({ key, version: 1, issuer, serialNumber, digestAlgorithm, signatureAlgorithm: forge.pki.oids.rsaEncryption, signature: null, authenticatedAttributes, unauthenticatedAttributes: [] }); }, sign: function(options) { options = options || {}; if (typeof msg.content !== "object" || msg.contentInfo === null) { msg.contentInfo = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(forge.pki.oids.data).getBytes())]); if ("content" in msg) { var content; if (msg.content instanceof forge.util.ByteBuffer) { content = msg.content.bytes(); } else if (typeof msg.content === "string") { content = forge.util.encodeUtf8(msg.content); } if (options.detached) { msg.detachedContent = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, content); } else { msg.contentInfo.value.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, content)])); } } } if (msg.signers.length === 0) { return; } var mds = addDigestAlgorithmIds(); addSignerInfos(mds); }, verify: function() { throw new Error("PKCS#7 signature verification not yet implemented."); }, addCertificate: function(cert) { if (typeof cert === "string") { cert = forge.pki.certificateFromPem(cert); } msg.certificates.push(cert); }, addCertificateRevokationList: function(crl) { throw new Error("PKCS#7 CRL support not yet implemented."); } }; return msg; function addDigestAlgorithmIds() { var mds = {}; for (var i = 0; i < msg.signers.length; ++i) { var signer = msg.signers[i]; var oid = signer.digestAlgorithm; if (!(oid in mds)) { mds[oid] = forge.md[forge.pki.oids[oid]].create(); } if (signer.authenticatedAttributes.length === 0) { signer.md = mds[oid]; } else { signer.md = forge.md[forge.pki.oids[oid]].create(); } } msg.digestAlgorithmIdentifiers = []; for (var oid in mds) { msg.digestAlgorithmIdentifiers.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(oid).getBytes()), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, "")])); } return mds; } function addSignerInfos(mds) { var content; if (msg.detachedContent) { content = msg.detachedContent; } else { content = msg.contentInfo.value[1]; content = content.value[0]; } if (!content) { throw new Error("Could not sign PKCS#7 message; there is no content to sign."); } var contentType = asn1.derToOid(msg.contentInfo.value[0].value); var bytes = asn1.toDer(content); bytes.getByte(); asn1.getBerValueLength(bytes); bytes = bytes.getBytes(); for (var oid in mds) { mds[oid].start().update(bytes); } var signingTime = new Date(); for (var i = 0; i < msg.signers.length; ++i) { var signer = msg.signers[i]; if (signer.authenticatedAttributes.length === 0) { if (contentType !== forge.pki.oids.data) { throw new Error("Invalid signer; authenticatedAttributes must be present " + "when the ContentInfo content type is not PKCS#7 Data."); } } else { signer.authenticatedAttributesAsn1 = asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, []); var attrsAsn1 = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, []); for (var ai = 0; ai < signer.authenticatedAttributes.length; ++ai) { var attr = signer.authenticatedAttributes[ai]; if (attr.type === forge.pki.oids.messageDigest) { attr.value = mds[signer.digestAlgorithm].digest(); } else if (attr.type === forge.pki.oids.signingTime) { if (!attr.value) { attr.value = signingTime; } } attrsAsn1.value.push(_attributeToAsn1(attr)); signer.authenticatedAttributesAsn1.value.push(_attributeToAsn1(attr)); } bytes = asn1.toDer(attrsAsn1).getBytes(); signer.md.start().update(bytes); } signer.signature = signer.key.sign(signer.md, "RSASSA-PKCS1-V1_5"); } msg.signerInfos = _signersToAsn1(msg.signers); } }; /** * Creates an empty PKCS#7 message of type EncryptedData. * * @return the message. */ p7.createEncryptedData = function() { var msg = null; msg = { type: forge.pki.oids.encryptedData, version: 0, encryptedContent: { algorithm: forge.pki.oids["aes256-CBC"] }, fromAsn1: function(obj) { _fromAsn1(msg, obj, p7.asn1.encryptedDataValidator); }, decrypt: function(key) { if (key !== undefined) { msg.encryptedContent.key = key; } _decryptContent(msg); } }; return msg; }; /** * Creates an empty PKCS#7 message of type EnvelopedData. * * @return the message. */ p7.createEnvelopedData = function() { var msg = null; msg = { type: forge.pki.oids.envelopedData, version: 0, recipients: [], encryptedContent: { algorithm: forge.pki.oids["aes256-CBC"] }, fromAsn1: function(obj) { var capture = _fromAsn1(msg, obj, p7.asn1.envelopedDataValidator); msg.recipients = _recipientsFromAsn1(capture.recipientInfos.value); }, toAsn1: function() { return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(msg.type).getBytes()), asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, asn1.integerToDer(msg.version).getBytes()), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, _recipientsToAsn1(msg.recipients)), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, _encryptedContentToAsn1(msg.encryptedContent)) ])])]); }, findRecipient: function(cert) { var sAttr = cert.issuer.attributes; for (var i = 0; i < msg.recipients.length; ++i) { var r = msg.recipients[i]; var rAttr = r.issuer; if (r.serialNumber !== cert.serialNumber) { continue; } if (rAttr.length !== sAttr.length) { continue; } var match = true; for (var j = 0; j < sAttr.length; ++j) { if (rAttr[j].type !== sAttr[j].type || rAttr[j].value !== sAttr[j].value) { match = false; break; } } if (match) { return r; } } return null; }, decrypt: function(recipient, privKey) { if (msg.encryptedContent.key === undefined && recipient !== undefined && privKey !== undefined) { switch (recipient.encryptedContent.algorithm) { case forge.pki.oids.rsaEncryption: case forge.pki.oids.desCBC: var key = privKey.decrypt(recipient.encryptedContent.content); msg.encryptedContent.key = forge.util.createBuffer(key); break; default: throw new Error("Unsupported asymmetric cipher, " + "OID " + recipient.encryptedContent.algorithm); } } _decryptContent(msg); }, addRecipient: function(cert) { msg.recipients.push({ version: 0, issuer: cert.issuer.attributes, serialNumber: cert.serialNumber, encryptedContent: { algorithm: forge.pki.oids.rsaEncryption, key: cert.publicKey } }); }, encrypt: function(key, cipher) { if (msg.encryptedContent.content === undefined) { cipher = cipher || msg.encryptedContent.algorithm; key = key || msg.encryptedContent.key; var keyLen, ivLen, ciphFn; switch (cipher) { case forge.pki.oids["aes128-CBC"]: keyLen = 16; ivLen = 16; ciphFn = forge.aes.createEncryptionCipher; break; case forge.pki.oids["aes192-CBC"]: keyLen = 24; ivLen = 16; ciphFn = forge.aes.createEncryptionCipher; break; case forge.pki.oids["aes256-CBC"]: keyLen = 32; ivLen = 16; ciphFn = forge.aes.createEncryptionCipher; break; case forge.pki.oids["des-EDE3-CBC"]: keyLen = 24; ivLen = 8; ciphFn = forge.des.createEncryptionCipher; break; default: throw new Error("Unsupported symmetric cipher, OID " + cipher); } if (key === undefined) { key = forge.util.createBuffer(forge.random.getBytes(keyLen)); } else if (key.length() != keyLen) { throw new Error("Symmetric key has wrong length; " + "got " + key.length() + " bytes, expected " + keyLen + "."); } msg.encryptedContent.algorithm = cipher; msg.encryptedContent.key = key; msg.encryptedContent.parameter = forge.util.createBuffer(forge.random.getBytes(ivLen)); var ciph = ciphFn(key); ciph.start(msg.encryptedContent.parameter.copy()); ciph.update(msg.content); if (!ciph.finish()) { throw new Error("Symmetric encryption failed."); } msg.encryptedContent.content = ciph.output; } for (var i = 0; i < msg.recipients.length; ++i) { var recipient = msg.recipients[i]; if (recipient.encryptedContent.content !== undefined) { continue; } switch (recipient.encryptedContent.algorithm) { case forge.pki.oids.rsaEncryption: recipient.encryptedContent.content = recipient.encryptedContent.key.encrypt(msg.encryptedContent.key.data); break; default: throw new Error("Unsupported asymmetric cipher, OID " + recipient.encryptedContent.algorithm); } } } }; return msg; }; /** * Converts a single recipient from an ASN.1 object. * * @param obj the ASN.1 RecipientInfo. * * @return the recipient object. */ function _recipientFromAsn1(obj) { var capture = {}; var errors = []; if (!asn1.validate(obj, p7.asn1.recipientInfoValidator, capture, errors)) { var error = new Error("Cannot read PKCS#7 RecipientInfo. " + "ASN.1 object is not an PKCS#7 RecipientInfo."); error.errors = errors; throw error; } return { version: capture.version.charCodeAt(0), issuer: forge.pki.RDNAttributesAsArray(capture.issuer), serialNumber: forge.util.createBuffer(capture.serial).toHex(), encryptedContent: { algorithm: asn1.derToOid(capture.encAlgorithm), parameter: capture.encParameter ? capture.encParameter.value : undefined, content: capture.encKey } }; } /** * Converts a single recipient object to an ASN.1 object. * * @param obj the recipient object. * * @return the ASN.1 RecipientInfo. */ function _recipientToAsn1(obj) { return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, asn1.integerToDer(obj.version).getBytes()), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [forge.pki.distinguishedNameToAsn1({ attributes: obj.issuer }), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, forge.util.hexToBytes(obj.serialNumber))]), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(obj.encryptedContent.algorithm).getBytes()), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, "")]), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, obj.encryptedContent.content) ]); } /** * Map a set of RecipientInfo ASN.1 objects to recipient objects. * * @param infos an array of ASN.1 representations RecipientInfo (i.e. SET OF). * * @return an array of recipient objects. */ function _recipientsFromAsn1(infos) { var ret = []; for (var i = 0; i < infos.length; ++i) { ret.push(_recipientFromAsn1(infos[i])); } return ret; } /** * Map an array of recipient objects to ASN.1 RecipientInfo objects. * * @param recipients an array of recipientInfo objects. * * @return an array of ASN.1 RecipientInfos. */ function _recipientsToAsn1(recipients) { var ret = []; for (var i = 0; i < recipients.length; ++i) { ret.push(_recipientToAsn1(recipients[i])); } return ret; } /** * Converts a single signer from an ASN.1 object. * * @param obj the ASN.1 representation of a SignerInfo. * * @return the signer object. */ function _signerFromAsn1(obj) { var capture = {}; var errors = []; if (!asn1.validate(obj, p7.asn1.signerInfoValidator, capture, errors)) { var error = new Error("Cannot read PKCS#7 SignerInfo. " + "ASN.1 object is not an PKCS#7 SignerInfo."); error.errors = errors; throw error; } var rval = { version: capture.version.charCodeAt(0), issuer: forge.pki.RDNAttributesAsArray(capture.issuer), serialNumber: forge.util.createBuffer(capture.serial).toHex(), digestAlgorithm: asn1.derToOid(capture.digestAlgorithm), signatureAlgorithm: asn1.derToOid(capture.signatureAlgorithm), signature: capture.signature, authenticatedAttributes: [], unauthenticatedAttributes: [] }; var authenticatedAttributes = capture.authenticatedAttributes || []; var unauthenticatedAttributes = capture.unauthenticatedAttributes || []; return rval; } /** * Converts a single signerInfo object to an ASN.1 object. * * @param obj the signerInfo object. * * @return the ASN.1 representation of a SignerInfo. */ function _signerToAsn1(obj) { var rval = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, asn1.integerToDer(obj.version).getBytes()), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [forge.pki.distinguishedNameToAsn1({ attributes: obj.issuer }), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, forge.util.hexToBytes(obj.serialNumber))]), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(obj.digestAlgorithm).getBytes()), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, "")]) ]); if (obj.authenticatedAttributesAsn1) { rval.value.push(obj.authenticatedAttributesAsn1); } rval.value.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(obj.signatureAlgorithm).getBytes()), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, "")])); rval.value.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, obj.signature)); if (obj.unauthenticatedAttributes.length > 0) { var attrsAsn1 = asn1.create(asn1.Class.CONTEXT_SPECIFIC, 1, true, []); for (var i = 0; i < obj.unauthenticatedAttributes.length; ++i) { var attr = obj.unauthenticatedAttributes[i]; attrsAsn1.values.push(_attributeToAsn1(attr)); } rval.value.push(attrsAsn1); } return rval; } /** * Map a set of SignerInfo ASN.1 objects to an array of signer objects. * * @param signerInfoAsn1s an array of ASN.1 SignerInfos (i.e. SET OF). * * @return an array of signers objects. */ function _signersFromAsn1(signerInfoAsn1s) { var ret = []; for (var i = 0; i < signerInfoAsn1s.length; ++i) { ret.push(_signerFromAsn1(signerInfoAsn1s[i])); } return ret; } /** * Map an array of signer objects to ASN.1 objects. * * @param signers an array of signer objects. * * @return an array of ASN.1 SignerInfos. */ function _signersToAsn1(signers) { var ret = []; for (var i = 0; i < signers.length; ++i) { ret.push(_signerToAsn1(signers[i])); } return ret; } /** * Convert an attribute object to an ASN.1 Attribute. * * @param attr the attribute object. * * @return the ASN.1 Attribute. */ function _attributeToAsn1(attr) { var value; if (attr.type === forge.pki.oids.contentType) { value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(attr.value).getBytes()); } else if (attr.type === forge.pki.oids.messageDigest) { value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, attr.value.bytes()); } else if (attr.type === forge.pki.oids.signingTime) { var jan_1_1950 = new Date("1950-01-01T00:00:00Z"); var jan_1_2050 = new Date("2050-01-01T00:00:00Z"); var date = attr.value; if (typeof date === "string") { var timestamp = Date.parse(date); if (!isNaN(timestamp)) { date = new Date(timestamp); } else if (date.length === 13) { date = asn1.utcTimeToDate(date); } else { date = asn1.generalizedTimeToDate(date); } } if (date >= jan_1_1950 && date < jan_1_2050) { value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.UTCTIME, false, asn1.dateToUtcTime(date)); } else { value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.GENERALIZEDTIME, false, asn1.dateToGeneralizedTime(date)); } } return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(attr.type).getBytes()), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, [value])]); } /** * Map messages encrypted content to ASN.1 objects. * * @param ec The encryptedContent object of the message. * * @return ASN.1 representation of the encryptedContent object (SEQUENCE). */ function _encryptedContentToAsn1(ec) { return [ asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(forge.pki.oids.data).getBytes()), asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(ec.algorithm).getBytes()), !ec.parameter ? undefined : asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, ec.parameter.getBytes())]), asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, ec.content.getBytes())]) ]; } /** * Reads the "common part" of an PKCS#7 content block (in ASN.1 format) * * This function reads the "common part" of the PKCS#7 content blocks * EncryptedData and EnvelopedData, i.e. version number and symmetrically * encrypted content block. * * The result of the ASN.1 validate and capture process is returned * to allow the caller to extract further data, e.g. the list of recipients * in case of a EnvelopedData object. * * @param msg the PKCS#7 object to read the data to. * @param obj the ASN.1 representation of the content block. * @param validator the ASN.1 structure validator object to use. * * @return the value map captured by validator object. */ function _fromAsn1(msg, obj, validator) { var capture = {}; var errors = []; if (!asn1.validate(obj, validator, capture, errors)) { var error = new Error("Cannot read PKCS#7 message. " + "ASN.1 object is not a supported PKCS#7 message."); error.errors = error; throw error; } var contentType = asn1.derToOid(capture.contentType); if (contentType !== forge.pki.oids.data) { throw new Error("Unsupported PKCS#7 message. " + "Only wrapped ContentType Data supported."); } if (capture.encryptedContent) { var content = ""; if (forge.util.isArray(capture.encryptedContent)) { for (var i = 0; i < capture.encryptedContent.length; ++i) { if (capture.encryptedContent[i].type !== asn1.Type.OCTETSTRING) { throw new Error("Malformed PKCS#7 message, expecting encrypted " + "content constructed of only OCTET STRING objects."); } content += capture.encryptedContent[i].value; } } else { content = capture.encryptedContent; } msg.encryptedContent = { algorithm: asn1.derToOid(capture.encAlgorithm), parameter: forge.util.createBuffer(capture.encParameter.value), content: forge.util.createBuffer(content) }; } if (capture.content) { var content = ""; if (forge.util.isArray(capture.content)) { for (var i = 0; i < capture.content.length; ++i) { if (capture.content[i].type !== asn1.Type.OCTETSTRING) { throw new Error("Malformed PKCS#7 message, expecting " + "content constructed of only OCTET STRING objects."); } content += capture.content[i].value; } } else { content = capture.content; } msg.content = forge.util.createBuffer(content); } msg.version = capture.version.charCodeAt(0); msg.rawCapture = capture; return capture; } /** * Decrypt the symmetrically encrypted content block of the PKCS#7 message. * * Decryption is skipped in case the PKCS#7 message object already has a * (decrypted) content attribute. The algorithm, key and cipher parameters * (probably the iv) are taken from the encryptedContent attribute of the * message object. * * @param The PKCS#7 message object. */ function _decryptContent(msg) { if (msg.encryptedContent.key === undefined) { throw new Error("Symmetric key not available."); } if (msg.content === undefined) { var ciph; switch (msg.encryptedContent.algorithm) { case forge.pki.oids["aes128-CBC"]: case forge.pki.oids["aes192-CBC"]: case forge.pki.oids["aes256-CBC"]: ciph = forge.aes.createDecryptionCipher(msg.encryptedContent.key); break; case forge.pki.oids["desCBC"]: case forge.pki.oids["des-EDE3-CBC"]: ciph = forge.des.createDecryptionCipher(msg.encryptedContent.key); break; default: throw new Error("Unsupported symmetric cipher, OID " + msg.encryptedContent.algorithm); } ciph.start(msg.encryptedContent.parameter); ciph.update(msg.encryptedContent.content); if (!ciph.finish()) { throw new Error("Symmetric decryption failed."); } msg.content = ciph.output; } } })); //#endregion //#region ../node_modules/node-forge/lib/ssh.js var require_ssh = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Functions to output keys in SSH-friendly formats. * * This is part of the Forge project which may be used under the terms of * either the BSD License or the GNU General Public License (GPL) Version 2. * * See: https://github.com/digitalbazaar/forge/blob/cbebca3780658703d925b61b2caffb1d263a6c1d/LICENSE * * @author https://github.com/shellac */ var forge = require_forge(); require_aes$1(); require_hmac$1(); require_md5$1(); require_sha1$1(); require_util$8(); var ssh = module.exports = forge.ssh = forge.ssh || {}; /** * Encodes (and optionally encrypts) a private RSA key as a Putty PPK file. * * @param privateKey the key. * @param passphrase a passphrase to protect the key (falsy for no encryption). * @param comment a comment to include in the key file. * * @return the PPK file as a string. */ ssh.privateKeyToPutty = function(privateKey, passphrase, comment) { comment = comment || ""; passphrase = passphrase || ""; var algorithm = "ssh-rsa"; var encryptionAlgorithm = passphrase === "" ? "none" : "aes256-cbc"; var ppk = "PuTTY-User-Key-File-2: " + algorithm + "\r\n"; ppk += "Encryption: " + encryptionAlgorithm + "\r\n"; ppk += "Comment: " + comment + "\r\n"; var pubbuffer = forge.util.createBuffer(); _addStringToBuffer(pubbuffer, algorithm); _addBigIntegerToBuffer(pubbuffer, privateKey.e); _addBigIntegerToBuffer(pubbuffer, privateKey.n); var pub = forge.util.encode64(pubbuffer.bytes(), 64); var length = Math.floor(pub.length / 66) + 1; ppk += "Public-Lines: " + length + "\r\n"; ppk += pub; var privbuffer = forge.util.createBuffer(); _addBigIntegerToBuffer(privbuffer, privateKey.d); _addBigIntegerToBuffer(privbuffer, privateKey.p); _addBigIntegerToBuffer(privbuffer, privateKey.q); _addBigIntegerToBuffer(privbuffer, privateKey.qInv); var priv; if (!passphrase) { priv = forge.util.encode64(privbuffer.bytes(), 64); } else { var encLen = privbuffer.length() + 16 - 1; encLen -= encLen % 16; var padding = _sha1(privbuffer.bytes()); padding.truncate(padding.length() - encLen + privbuffer.length()); privbuffer.putBuffer(padding); var aeskey = forge.util.createBuffer(); aeskey.putBuffer(_sha1("\0\0\0\0", passphrase)); aeskey.putBuffer(_sha1("\0\0\0", passphrase)); var cipher = forge.aes.createEncryptionCipher(aeskey.truncate(8), "CBC"); cipher.start(forge.util.createBuffer().fillWithByte(0, 16)); cipher.update(privbuffer.copy()); cipher.finish(); var encrypted = cipher.output; encrypted.truncate(16); priv = forge.util.encode64(encrypted.bytes(), 64); } length = Math.floor(priv.length / 66) + 1; ppk += "\r\nPrivate-Lines: " + length + "\r\n"; ppk += priv; var mackey = _sha1("putty-private-key-file-mac-key", passphrase); var macbuffer = forge.util.createBuffer(); _addStringToBuffer(macbuffer, algorithm); _addStringToBuffer(macbuffer, encryptionAlgorithm); _addStringToBuffer(macbuffer, comment); macbuffer.putInt32(pubbuffer.length()); macbuffer.putBuffer(pubbuffer); macbuffer.putInt32(privbuffer.length()); macbuffer.putBuffer(privbuffer); var hmac = forge.hmac.create(); hmac.start("sha1", mackey); hmac.update(macbuffer.bytes()); ppk += "\r\nPrivate-MAC: " + hmac.digest().toHex() + "\r\n"; return ppk; }; /** * Encodes a public RSA key as an OpenSSH file. * * @param key the key. * @param comment a comment. * * @return the public key in OpenSSH format. */ ssh.publicKeyToOpenSSH = function(key, comment) { var type = "ssh-rsa"; comment = comment || ""; var buffer = forge.util.createBuffer(); _addStringToBuffer(buffer, type); _addBigIntegerToBuffer(buffer, key.e); _addBigIntegerToBuffer(buffer, key.n); return type + " " + forge.util.encode64(buffer.bytes()) + " " + comment; }; /** * Encodes a private RSA key as an OpenSSH file. * * @param key the key. * @param passphrase a passphrase to protect the key (falsy for no encryption). * * @return the public key in OpenSSH format. */ ssh.privateKeyToOpenSSH = function(privateKey, passphrase) { if (!passphrase) { return forge.pki.privateKeyToPem(privateKey); } return forge.pki.encryptRsaPrivateKey(privateKey, passphrase, { legacy: true, algorithm: "aes128" }); }; /** * Gets the SSH fingerprint for the given public key. * * @param options the options to use. * [md] the message digest object to use (defaults to forge.md.md5). * [encoding] an alternative output encoding, such as 'hex' * (defaults to none, outputs a byte buffer). * [delimiter] the delimiter to use between bytes for 'hex' encoded * output, eg: ':' (defaults to none). * * @return the fingerprint as a byte buffer or other encoding based on options. */ ssh.getPublicKeyFingerprint = function(key, options) { options = options || {}; var md = options.md || forge.md.md5.create(); var type = "ssh-rsa"; var buffer = forge.util.createBuffer(); _addStringToBuffer(buffer, type); _addBigIntegerToBuffer(buffer, key.e); _addBigIntegerToBuffer(buffer, key.n); md.start(); md.update(buffer.getBytes()); var digest = md.digest(); if (options.encoding === "hex") { var hex = digest.toHex(); if (options.delimiter) { return hex.match(/.{2}/g).join(options.delimiter); } return hex; } else if (options.encoding === "binary") { return digest.getBytes(); } else if (options.encoding) { throw new Error("Unknown encoding \"" + options.encoding + "\"."); } return digest; }; /** * Adds len(val) then val to a buffer. * * @param buffer the buffer to add to. * @param val a big integer. */ function _addBigIntegerToBuffer(buffer, val) { var hexVal = val.toString(16); if (hexVal[0] >= "8") { hexVal = "00" + hexVal; } var bytes = forge.util.hexToBytes(hexVal); buffer.putInt32(bytes.length); buffer.putBytes(bytes); } /** * Adds len(val) then val to a buffer. * * @param buffer the buffer to add to. * @param val a string. */ function _addStringToBuffer(buffer, val) { buffer.putInt32(val.length); buffer.putString(val); } /** * Hashes the arguments into one value using SHA-1. * * @return the sha1 hash of the provided arguments. */ function _sha1() { var sha = forge.md.sha1.create(); var num = arguments.length; for (var i = 0; i < num; ++i) { sha.update(arguments[i]); } return sha.digest(); } })); //#endregion //#region ../node_modules/node-forge/lib/index.js var require_lib$3 = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Node.js module for Forge. * * @author Dave Longley * * Copyright 2011-2016 Digital Bazaar, Inc. */ module.exports = require_forge(); require_aes$1(); require_aesCipherSuites(); require_asn1(); require_cipher(); require_des(); require_ed25519(); require_hmac$1(); require_kem(); require_log(); require_md_all(); require_mgf1(); require_pbkdf2$1(); require_pem(); require_pkcs1(); require_pkcs12(); require_pkcs7(); require_pki(); require_prime(); require_prng(); require_pss(); require_random(); require_rc2(); require_ssh(); require_tls(); require_util$8(); })); //#endregion //#region ../node_modules/minipass/dist/esm/index.js var import_lib = /* @__PURE__ */ __toESM(require_lib$3(), 1); var import_json_bigint = /* @__PURE__ */ __toESM(require_json_bigint(), 1); const proc = typeof process === "object" && process ? process : { stdout: null, stderr: null }; /** * Return true if the argument is a Minipass stream, Node stream, or something * else that Minipass can interact with. */ const isStream$1 = (s) => !!s && typeof s === "object" && (s instanceof Minipass || s instanceof Stream || isReadable$1(s) || isWritable(s)); /** * Return true if the argument is a valid {@link Minipass.Readable} */ const isReadable$1 = (s) => !!s && typeof s === "object" && s instanceof EventEmitter$1 && typeof s.pipe === "function" && s.pipe !== Stream.Writable.prototype.pipe; /** * Return true if the argument is a valid {@link Minipass.Writable} */ const isWritable = (s) => !!s && typeof s === "object" && s instanceof EventEmitter$1 && typeof s.write === "function" && typeof s.end === "function"; const EOF = Symbol("EOF"); const MAYBE_EMIT_END = Symbol("maybeEmitEnd"); const EMITTED_END = Symbol("emittedEnd"); const EMITTING_END = Symbol("emittingEnd"); const EMITTED_ERROR = Symbol("emittedError"); const CLOSED = Symbol("closed"); const READ = Symbol("read"); const FLUSH = Symbol("flush"); const FLUSHCHUNK = Symbol("flushChunk"); const ENCODING = Symbol("encoding"); const DECODER = Symbol("decoder"); const FLOWING = Symbol("flowing"); const PAUSED = Symbol("paused"); const RESUME = Symbol("resume"); const BUFFER = Symbol("buffer"); const PIPES = Symbol("pipes"); const BUFFERLENGTH = Symbol("bufferLength"); const BUFFERPUSH = Symbol("bufferPush"); const BUFFERSHIFT = Symbol("bufferShift"); const OBJECTMODE = Symbol("objectMode"); const DESTROYED = Symbol("destroyed"); const ERROR = Symbol("error"); const EMITDATA = Symbol("emitData"); const EMITEND = Symbol("emitEnd"); const EMITEND2 = Symbol("emitEnd2"); const ASYNC = Symbol("async"); const ABORT = Symbol("abort"); const ABORTED = Symbol("aborted"); const SIGNAL = Symbol("signal"); const DATALISTENERS = Symbol("dataListeners"); const DISCARDED = Symbol("discarded"); const defer$1 = (fn) => Promise.resolve().then(fn); const nodefer = (fn) => fn(); const isEndish = (ev) => ev === "end" || ev === "finish" || ev === "prefinish"; const isArrayBufferLike = (b) => b instanceof ArrayBuffer || !!b && typeof b === "object" && b.constructor && b.constructor.name === "ArrayBuffer" && b.byteLength >= 0; const isArrayBufferView$1 = (b) => !Buffer.isBuffer(b) && ArrayBuffer.isView(b); /** * Internal class representing a pipe to a destination stream. * * @internal */ var Pipe = class { src; dest; opts; ondrain; constructor(src, dest, opts) { this.src = src; this.dest = dest; this.opts = opts; this.ondrain = () => src[RESUME](); this.dest.on("drain", this.ondrain); } unpipe() { this.dest.removeListener("drain", this.ondrain); } /* c8 ignore start */ proxyErrors(_er) {} /* c8 ignore stop */ end() { this.unpipe(); if (this.opts.end) this.dest.end(); } }; /** * Internal class representing a pipe to a destination stream where * errors are proxied. * * @internal */ var PipeProxyErrors = class extends Pipe { unpipe() { this.src.removeListener("error", this.proxyErrors); super.unpipe(); } constructor(src, dest, opts) { super(src, dest, opts); this.proxyErrors = (er) => dest.emit("error", er); src.on("error", this.proxyErrors); } }; const isObjectModeOptions = (o) => !!o.objectMode; const isEncodingOptions = (o) => !o.objectMode && !!o.encoding && o.encoding !== "buffer"; /** * Main export, the Minipass class * * `RType` is the type of data emitted, defaults to Buffer * * `WType` is the type of data to be written, if RType is buffer or string, * then any {@link Minipass.ContiguousData} is allowed. * * `Events` is the set of event handler signatures that this object * will emit, see {@link Minipass.Events} */ var Minipass = class extends EventEmitter$1 { [FLOWING] = false; [PAUSED] = false; [PIPES] = []; [BUFFER] = []; [OBJECTMODE]; [ENCODING]; [ASYNC]; [DECODER]; [EOF] = false; [EMITTED_END] = false; [EMITTING_END] = false; [CLOSED] = false; [EMITTED_ERROR] = null; [BUFFERLENGTH] = 0; [DESTROYED] = false; [SIGNAL]; [ABORTED] = false; [DATALISTENERS] = 0; [DISCARDED] = false; /** * true if the stream can be written */ writable = true; /** * true if the stream can be read */ readable = true; /** * If `RType` is Buffer, then options do not need to be provided. * Otherwise, an options object must be provided to specify either * {@link Minipass.SharedOptions.objectMode} or * {@link Minipass.SharedOptions.encoding}, as appropriate. */ constructor(...args) { const options = args[0] || {}; super(); if (options.objectMode && typeof options.encoding === "string") { throw new TypeError("Encoding and objectMode may not be used together"); } if (isObjectModeOptions(options)) { this[OBJECTMODE] = true; this[ENCODING] = null; } else if (isEncodingOptions(options)) { this[ENCODING] = options.encoding; this[OBJECTMODE] = false; } else { this[OBJECTMODE] = false; this[ENCODING] = null; } this[ASYNC] = !!options.async; this[DECODER] = this[ENCODING] ? new StringDecoder(this[ENCODING]) : null; if (options && options.debugExposeBuffer === true) { Object.defineProperty(this, "buffer", { get: () => this[BUFFER] }); } if (options && options.debugExposePipes === true) { Object.defineProperty(this, "pipes", { get: () => this[PIPES] }); } const { signal } = options; if (signal) { this[SIGNAL] = signal; if (signal.aborted) { this[ABORT](); } else { signal.addEventListener("abort", () => this[ABORT]()); } } } /** * The amount of data stored in the buffer waiting to be read. * * For Buffer strings, this will be the total byte length. * For string encoding streams, this will be the string character length, * according to JavaScript's `string.length` logic. * For objectMode streams, this is a count of the items waiting to be * emitted. */ get bufferLength() { return this[BUFFERLENGTH]; } /** * The `BufferEncoding` currently in use, or `null` */ get encoding() { return this[ENCODING]; } /** * @deprecated - This is a read only property */ set encoding(_enc) { throw new Error("Encoding must be set at instantiation time"); } /** * @deprecated - Encoding may only be set at instantiation time */ setEncoding(_enc) { throw new Error("Encoding must be set at instantiation time"); } /** * True if this is an objectMode stream */ get objectMode() { return this[OBJECTMODE]; } /** * @deprecated - This is a read-only property */ set objectMode(_om) { throw new Error("objectMode must be set at instantiation time"); } /** * true if this is an async stream */ get ["async"]() { return this[ASYNC]; } /** * Set to true to make this stream async. * * Once set, it cannot be unset, as this would potentially cause incorrect * behavior. Ie, a sync stream can be made async, but an async stream * cannot be safely made sync. */ set ["async"](a) { this[ASYNC] = this[ASYNC] || !!a; } [ABORT]() { this[ABORTED] = true; this.emit("abort", this[SIGNAL]?.reason); this.destroy(this[SIGNAL]?.reason); } /** * True if the stream has been aborted. */ get aborted() { return this[ABORTED]; } /** * No-op setter. Stream aborted status is set via the AbortSignal provided * in the constructor options. */ set aborted(_) {} write(chunk, encoding, cb) { if (this[ABORTED]) return false; if (this[EOF]) throw new Error("write after end"); if (this[DESTROYED]) { this.emit("error", Object.assign(new Error("Cannot call write after a stream was destroyed"), { code: "ERR_STREAM_DESTROYED" })); return true; } if (typeof encoding === "function") { cb = encoding; encoding = "utf8"; } if (!encoding) encoding = "utf8"; const fn = this[ASYNC] ? defer$1 : nodefer; if (!this[OBJECTMODE] && !Buffer.isBuffer(chunk)) { if (isArrayBufferView$1(chunk)) { chunk = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength); } else if (isArrayBufferLike(chunk)) { chunk = Buffer.from(chunk); } else if (typeof chunk !== "string") { throw new Error("Non-contiguous data written to non-objectMode stream"); } } if (this[OBJECTMODE]) { /* c8 ignore start */ if (this[FLOWING] && this[BUFFERLENGTH] !== 0) this[FLUSH](true); /* c8 ignore stop */ if (this[FLOWING]) this.emit("data", chunk); else this[BUFFERPUSH](chunk); if (this[BUFFERLENGTH] !== 0) this.emit("readable"); if (cb) fn(cb); return this[FLOWING]; } if (!chunk.length) { if (this[BUFFERLENGTH] !== 0) this.emit("readable"); if (cb) fn(cb); return this[FLOWING]; } if (typeof chunk === "string" && !(encoding === this[ENCODING] && !this[DECODER]?.lastNeed)) { chunk = Buffer.from(chunk, encoding); } if (Buffer.isBuffer(chunk) && this[ENCODING]) { chunk = this[DECODER].write(chunk); } if (this[FLOWING] && this[BUFFERLENGTH] !== 0) this[FLUSH](true); if (this[FLOWING]) this.emit("data", chunk); else this[BUFFERPUSH](chunk); if (this[BUFFERLENGTH] !== 0) this.emit("readable"); if (cb) fn(cb); return this[FLOWING]; } /** * Low-level explicit read method. * * In objectMode, the argument is ignored, and one item is returned if * available. * * `n` is the number of bytes (or in the case of encoding streams, * characters) to consume. If `n` is not provided, then the entire buffer * is returned, or `null` is returned if no data is available. * * If `n` is greater that the amount of data in the internal buffer, * then `null` is returned. */ read(n) { if (this[DESTROYED]) return null; this[DISCARDED] = false; if (this[BUFFERLENGTH] === 0 || n === 0 || n && n > this[BUFFERLENGTH]) { this[MAYBE_EMIT_END](); return null; } if (this[OBJECTMODE]) n = null; if (this[BUFFER].length > 1 && !this[OBJECTMODE]) { this[BUFFER] = [this[ENCODING] ? this[BUFFER].join("") : Buffer.concat(this[BUFFER], this[BUFFERLENGTH])]; } const ret = this[READ](n || null, this[BUFFER][0]); this[MAYBE_EMIT_END](); return ret; } [READ](n, chunk) { if (this[OBJECTMODE]) this[BUFFERSHIFT](); else { const c = chunk; if (n === c.length || n === null) this[BUFFERSHIFT](); else if (typeof c === "string") { this[BUFFER][0] = c.slice(n); chunk = c.slice(0, n); this[BUFFERLENGTH] -= n; } else { this[BUFFER][0] = c.subarray(n); chunk = c.subarray(0, n); this[BUFFERLENGTH] -= n; } } this.emit("data", chunk); if (!this[BUFFER].length && !this[EOF]) this.emit("drain"); return chunk; } end(chunk, encoding, cb) { if (typeof chunk === "function") { cb = chunk; chunk = undefined; } if (typeof encoding === "function") { cb = encoding; encoding = "utf8"; } if (chunk !== undefined) this.write(chunk, encoding); if (cb) this.once("end", cb); this[EOF] = true; this.writable = false; if (this[FLOWING] || !this[PAUSED]) this[MAYBE_EMIT_END](); return this; } [RESUME]() { if (this[DESTROYED]) return; if (!this[DATALISTENERS] && !this[PIPES].length) { this[DISCARDED] = true; } this[PAUSED] = false; this[FLOWING] = true; this.emit("resume"); if (this[BUFFER].length) this[FLUSH](); else if (this[EOF]) this[MAYBE_EMIT_END](); else this.emit("drain"); } /** * Resume the stream if it is currently in a paused state * * If called when there are no pipe destinations or `data` event listeners, * this will place the stream in a "discarded" state, where all data will * be thrown away. The discarded state is removed if a pipe destination or * data handler is added, if pause() is called, or if any synchronous or * asynchronous iteration is started. */ resume() { return this[RESUME](); } /** * Pause the stream */ pause() { this[FLOWING] = false; this[PAUSED] = true; this[DISCARDED] = false; } /** * true if the stream has been forcibly destroyed */ get destroyed() { return this[DESTROYED]; } /** * true if the stream is currently in a flowing state, meaning that * any writes will be immediately emitted. */ get flowing() { return this[FLOWING]; } /** * true if the stream is currently in a paused state */ get paused() { return this[PAUSED]; } [BUFFERPUSH](chunk) { if (this[OBJECTMODE]) this[BUFFERLENGTH] += 1; else this[BUFFERLENGTH] += chunk.length; this[BUFFER].push(chunk); } [BUFFERSHIFT]() { if (this[OBJECTMODE]) this[BUFFERLENGTH] -= 1; else this[BUFFERLENGTH] -= this[BUFFER][0].length; return this[BUFFER].shift(); } [FLUSH](noDrain = false) { do {} while (this[FLUSHCHUNK](this[BUFFERSHIFT]()) && this[BUFFER].length); if (!noDrain && !this[BUFFER].length && !this[EOF]) this.emit("drain"); } [FLUSHCHUNK](chunk) { this.emit("data", chunk); return this[FLOWING]; } /** * Pipe all data emitted by this stream into the destination provided. * * Triggers the flow of data. */ pipe(dest, opts) { if (this[DESTROYED]) return dest; this[DISCARDED] = false; const ended = this[EMITTED_END]; opts = opts || {}; if (dest === proc.stdout || dest === proc.stderr) opts.end = false; else opts.end = opts.end !== false; opts.proxyErrors = !!opts.proxyErrors; if (ended) { if (opts.end) dest.end(); } else { this[PIPES].push(!opts.proxyErrors ? new Pipe(this, dest, opts) : new PipeProxyErrors(this, dest, opts)); if (this[ASYNC]) defer$1(() => this[RESUME]()); else this[RESUME](); } return dest; } /** * Fully unhook a piped destination stream. * * If the destination stream was the only consumer of this stream (ie, * there are no other piped destinations or `'data'` event listeners) * then the flow of data will stop until there is another consumer or * {@link Minipass#resume} is explicitly called. */ unpipe(dest) { const p = this[PIPES].find((p) => p.dest === dest); if (p) { if (this[PIPES].length === 1) { if (this[FLOWING] && this[DATALISTENERS] === 0) { this[FLOWING] = false; } this[PIPES] = []; } else this[PIPES].splice(this[PIPES].indexOf(p), 1); p.unpipe(); } } /** * Alias for {@link Minipass#on} */ addListener(ev, handler) { return this.on(ev, handler); } /** * Mostly identical to `EventEmitter.on`, with the following * behavior differences to prevent data loss and unnecessary hangs: * * - Adding a 'data' event handler will trigger the flow of data * * - Adding a 'readable' event handler when there is data waiting to be read * will cause 'readable' to be emitted immediately. * * - Adding an 'endish' event handler ('end', 'finish', etc.) which has * already passed will cause the event to be emitted immediately and all * handlers removed. * * - Adding an 'error' event handler after an error has been emitted will * cause the event to be re-emitted immediately with the error previously * raised. */ on(ev, handler) { const ret = super.on(ev, handler); if (ev === "data") { this[DISCARDED] = false; this[DATALISTENERS]++; if (!this[PIPES].length && !this[FLOWING]) { this[RESUME](); } } else if (ev === "readable" && this[BUFFERLENGTH] !== 0) { super.emit("readable"); } else if (isEndish(ev) && this[EMITTED_END]) { super.emit(ev); this.removeAllListeners(ev); } else if (ev === "error" && this[EMITTED_ERROR]) { const h = handler; if (this[ASYNC]) defer$1(() => h.call(this, this[EMITTED_ERROR])); else h.call(this, this[EMITTED_ERROR]); } return ret; } /** * Alias for {@link Minipass#off} */ removeListener(ev, handler) { return this.off(ev, handler); } /** * Mostly identical to `EventEmitter.off` * * If a 'data' event handler is removed, and it was the last consumer * (ie, there are no pipe destinations or other 'data' event listeners), * then the flow of data will stop until there is another consumer or * {@link Minipass#resume} is explicitly called. */ off(ev, handler) { const ret = super.off(ev, handler); if (ev === "data") { this[DATALISTENERS] = this.listeners("data").length; if (this[DATALISTENERS] === 0 && !this[DISCARDED] && !this[PIPES].length) { this[FLOWING] = false; } } return ret; } /** * Mostly identical to `EventEmitter.removeAllListeners` * * If all 'data' event handlers are removed, and they were the last consumer * (ie, there are no pipe destinations), then the flow of data will stop * until there is another consumer or {@link Minipass#resume} is explicitly * called. */ removeAllListeners(ev) { const ret = super.removeAllListeners(ev); if (ev === "data" || ev === undefined) { this[DATALISTENERS] = 0; if (!this[DISCARDED] && !this[PIPES].length) { this[FLOWING] = false; } } return ret; } /** * true if the 'end' event has been emitted */ get emittedEnd() { return this[EMITTED_END]; } [MAYBE_EMIT_END]() { if (!this[EMITTING_END] && !this[EMITTED_END] && !this[DESTROYED] && this[BUFFER].length === 0 && this[EOF]) { this[EMITTING_END] = true; this.emit("end"); this.emit("prefinish"); this.emit("finish"); if (this[CLOSED]) this.emit("close"); this[EMITTING_END] = false; } } /** * Mostly identical to `EventEmitter.emit`, with the following * behavior differences to prevent data loss and unnecessary hangs: * * If the stream has been destroyed, and the event is something other * than 'close' or 'error', then `false` is returned and no handlers * are called. * * If the event is 'end', and has already been emitted, then the event * is ignored. If the stream is in a paused or non-flowing state, then * the event will be deferred until data flow resumes. If the stream is * async, then handlers will be called on the next tick rather than * immediately. * * If the event is 'close', and 'end' has not yet been emitted, then * the event will be deferred until after 'end' is emitted. * * If the event is 'error', and an AbortSignal was provided for the stream, * and there are no listeners, then the event is ignored, matching the * behavior of node core streams in the presense of an AbortSignal. * * If the event is 'finish' or 'prefinish', then all listeners will be * removed after emitting the event, to prevent double-firing. */ emit(ev, ...args) { const data = args[0]; if (ev !== "error" && ev !== "close" && ev !== DESTROYED && this[DESTROYED]) { return false; } else if (ev === "data") { return !this[OBJECTMODE] && !data ? false : this[ASYNC] ? (defer$1(() => this[EMITDATA](data)), true) : this[EMITDATA](data); } else if (ev === "end") { return this[EMITEND](); } else if (ev === "close") { this[CLOSED] = true; if (!this[EMITTED_END] && !this[DESTROYED]) return false; const ret = super.emit("close"); this.removeAllListeners("close"); return ret; } else if (ev === "error") { this[EMITTED_ERROR] = data; super.emit(ERROR, data); const ret = !this[SIGNAL] || this.listeners("error").length ? super.emit("error", data) : false; this[MAYBE_EMIT_END](); return ret; } else if (ev === "resume") { const ret = super.emit("resume"); this[MAYBE_EMIT_END](); return ret; } else if (ev === "finish" || ev === "prefinish") { const ret = super.emit(ev); this.removeAllListeners(ev); return ret; } const ret = super.emit(ev, ...args); this[MAYBE_EMIT_END](); return ret; } [EMITDATA](data) { for (const p of this[PIPES]) { if (p.dest.write(data) === false) this.pause(); } const ret = this[DISCARDED] ? false : super.emit("data", data); this[MAYBE_EMIT_END](); return ret; } [EMITEND]() { if (this[EMITTED_END]) return false; this[EMITTED_END] = true; this.readable = false; return this[ASYNC] ? (defer$1(() => this[EMITEND2]()), true) : this[EMITEND2](); } [EMITEND2]() { if (this[DECODER]) { const data = this[DECODER].end(); if (data) { for (const p of this[PIPES]) { p.dest.write(data); } if (!this[DISCARDED]) super.emit("data", data); } } for (const p of this[PIPES]) { p.end(); } const ret = super.emit("end"); this.removeAllListeners("end"); return ret; } /** * Return a Promise that resolves to an array of all emitted data once * the stream ends. */ async collect() { const buf = Object.assign([], { dataLength: 0 }); if (!this[OBJECTMODE]) buf.dataLength = 0; const p = this.promise(); this.on("data", (c) => { buf.push(c); if (!this[OBJECTMODE]) buf.dataLength += c.length; }); await p; return buf; } /** * Return a Promise that resolves to the concatenation of all emitted data * once the stream ends. * * Not allowed on objectMode streams. */ async concat() { if (this[OBJECTMODE]) { throw new Error("cannot concat in objectMode"); } const buf = await this.collect(); return this[ENCODING] ? buf.join("") : Buffer.concat(buf, buf.dataLength); } /** * Return a void Promise that resolves once the stream ends. */ async promise() { return new Promise((resolve, reject) => { this.on(DESTROYED, () => reject(new Error("stream destroyed"))); this.on("error", (er) => reject(er)); this.on("end", () => resolve()); }); } /** * Asynchronous `for await of` iteration. * * This will continue emitting all chunks until the stream terminates. */ [Symbol.asyncIterator]() { this[DISCARDED] = false; let stopped = false; const stop = async () => { this.pause(); stopped = true; return { value: undefined, done: true }; }; const next = () => { if (stopped) return stop(); const res = this.read(); if (res !== null) return Promise.resolve({ done: false, value: res }); if (this[EOF]) return stop(); let resolve; let reject; const onerr = (er) => { this.off("data", ondata); this.off("end", onend); this.off(DESTROYED, ondestroy); stop(); reject(er); }; const ondata = (value) => { this.off("error", onerr); this.off("end", onend); this.off(DESTROYED, ondestroy); this.pause(); resolve({ value, done: !!this[EOF] }); }; const onend = () => { this.off("error", onerr); this.off("data", ondata); this.off(DESTROYED, ondestroy); stop(); resolve({ done: true, value: undefined }); }; const ondestroy = () => onerr(new Error("stream destroyed")); return new Promise((res, rej) => { reject = rej; resolve = res; this.once(DESTROYED, ondestroy); this.once("error", onerr); this.once("end", onend); this.once("data", ondata); }); }; return { next, throw: stop, return: stop, [Symbol.asyncIterator]() { return this; } }; } /** * Synchronous `for of` iteration. * * The iteration will terminate when the internal buffer runs out, even * if the stream has not yet terminated. */ [Symbol.iterator]() { this[DISCARDED] = false; let stopped = false; const stop = () => { this.pause(); this.off(ERROR, stop); this.off(DESTROYED, stop); this.off("end", stop); stopped = true; return { done: true, value: undefined }; }; const next = () => { if (stopped) return stop(); const value = this.read(); return value === null ? stop() : { done: false, value }; }; this.once("end", stop); this.once(ERROR, stop); this.once(DESTROYED, stop); return { next, throw: stop, return: stop, [Symbol.iterator]() { return this; } }; } /** * Destroy a stream, preventing it from being used for any further purpose. * * If the stream has a `close()` method, then it will be called on * destruction. * * After destruction, any attempt to write data, read data, or emit most * events will be ignored. * * If an error argument is provided, then it will be emitted in an * 'error' event. */ destroy(er) { if (this[DESTROYED]) { if (er) this.emit("error", er); else this.emit(DESTROYED); return this; } this[DESTROYED] = true; this[DISCARDED] = true; this[BUFFER].length = 0; this[BUFFERLENGTH] = 0; const wc = this; if (typeof wc.close === "function" && !this[CLOSED]) wc.close(); if (er) this.emit("error", er); else this.emit(DESTROYED); return this; } /** * Alias for {@link isStream} * * Former export location, maintained for backwards compatibility. * * @deprecated */ static get isStream() { return isStream$1; } }; //#endregion //#region ../node_modules/minizlib/dist/esm/constants.js /* c8 ignore start */ const realZlibConstants = zlib.constants || { ZLIB_VERNUM: 4736 }; /* c8 ignore stop */ const constants$1 = Object.freeze(Object.assign(Object.create(null), { Z_NO_FLUSH: 0, Z_PARTIAL_FLUSH: 1, Z_SYNC_FLUSH: 2, Z_FULL_FLUSH: 3, Z_FINISH: 4, Z_BLOCK: 5, Z_OK: 0, Z_STREAM_END: 1, Z_NEED_DICT: 2, Z_ERRNO: -1, Z_STREAM_ERROR: -2, Z_DATA_ERROR: -3, Z_MEM_ERROR: -4, Z_BUF_ERROR: -5, Z_VERSION_ERROR: -6, Z_NO_COMPRESSION: 0, Z_BEST_SPEED: 1, Z_BEST_COMPRESSION: 9, Z_DEFAULT_COMPRESSION: -1, Z_FILTERED: 1, Z_HUFFMAN_ONLY: 2, Z_RLE: 3, Z_FIXED: 4, Z_DEFAULT_STRATEGY: 0, DEFLATE: 1, INFLATE: 2, GZIP: 3, GUNZIP: 4, DEFLATERAW: 5, INFLATERAW: 6, UNZIP: 7, BROTLI_DECODE: 8, BROTLI_ENCODE: 9, Z_MIN_WINDOWBITS: 8, Z_MAX_WINDOWBITS: 15, Z_DEFAULT_WINDOWBITS: 15, Z_MIN_CHUNK: 64, Z_MAX_CHUNK: Infinity, Z_DEFAULT_CHUNK: 16384, Z_MIN_MEMLEVEL: 1, Z_MAX_MEMLEVEL: 9, Z_DEFAULT_MEMLEVEL: 8, Z_MIN_LEVEL: -1, Z_MAX_LEVEL: 9, Z_DEFAULT_LEVEL: -1, BROTLI_OPERATION_PROCESS: 0, BROTLI_OPERATION_FLUSH: 1, BROTLI_OPERATION_FINISH: 2, BROTLI_OPERATION_EMIT_METADATA: 3, BROTLI_MODE_GENERIC: 0, BROTLI_MODE_TEXT: 1, BROTLI_MODE_FONT: 2, BROTLI_DEFAULT_MODE: 0, BROTLI_MIN_QUALITY: 0, BROTLI_MAX_QUALITY: 11, BROTLI_DEFAULT_QUALITY: 11, BROTLI_MIN_WINDOW_BITS: 10, BROTLI_MAX_WINDOW_BITS: 24, BROTLI_LARGE_MAX_WINDOW_BITS: 30, BROTLI_DEFAULT_WINDOW: 22, BROTLI_MIN_INPUT_BLOCK_BITS: 16, BROTLI_MAX_INPUT_BLOCK_BITS: 24, BROTLI_PARAM_MODE: 0, BROTLI_PARAM_QUALITY: 1, BROTLI_PARAM_LGWIN: 2, BROTLI_PARAM_LGBLOCK: 3, BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING: 4, BROTLI_PARAM_SIZE_HINT: 5, BROTLI_PARAM_LARGE_WINDOW: 6, BROTLI_PARAM_NPOSTFIX: 7, BROTLI_PARAM_NDIRECT: 8, BROTLI_DECODER_RESULT_ERROR: 0, BROTLI_DECODER_RESULT_SUCCESS: 1, BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT: 2, BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT: 3, BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION: 0, BROTLI_DECODER_PARAM_LARGE_WINDOW: 1, BROTLI_DECODER_NO_ERROR: 0, BROTLI_DECODER_SUCCESS: 1, BROTLI_DECODER_NEEDS_MORE_INPUT: 2, BROTLI_DECODER_NEEDS_MORE_OUTPUT: 3, BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE: -1, BROTLI_DECODER_ERROR_FORMAT_RESERVED: -2, BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE: -3, BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET: -4, BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME: -5, BROTLI_DECODER_ERROR_FORMAT_CL_SPACE: -6, BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE: -7, BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT: -8, BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1: -9, BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2: -10, BROTLI_DECODER_ERROR_FORMAT_TRANSFORM: -11, BROTLI_DECODER_ERROR_FORMAT_DICTIONARY: -12, BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS: -13, BROTLI_DECODER_ERROR_FORMAT_PADDING_1: -14, BROTLI_DECODER_ERROR_FORMAT_PADDING_2: -15, BROTLI_DECODER_ERROR_FORMAT_DISTANCE: -16, BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET: -19, BROTLI_DECODER_ERROR_INVALID_ARGUMENTS: -20, BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES: -21, BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS: -22, BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP: -25, BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1: -26, BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2: -27, BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES: -30, BROTLI_DECODER_ERROR_UNREACHABLE: -31 }, realZlibConstants)); //#endregion //#region ../node_modules/minizlib/dist/esm/index.js var esm_exports$1 = /* @__PURE__ */ __exportAll({ BrotliCompress: () => BrotliCompress, BrotliDecompress: () => BrotliDecompress, Deflate: () => Deflate, DeflateRaw: () => DeflateRaw, Gunzip: () => Gunzip, Gzip: () => Gzip, Inflate: () => Inflate, InflateRaw: () => InflateRaw, Unzip: () => Unzip, Zlib: () => Zlib, ZlibError: () => ZlibError, ZstdCompress: () => ZstdCompress, ZstdDecompress: () => ZstdDecompress, constants: () => constants$1 }); const OriginalBufferConcat = Buffer$1.concat; const desc = Object.getOwnPropertyDescriptor(Buffer$1, "concat"); const noop$2 = (args) => args; const passthroughBufferConcat = desc?.writable === true || desc?.set !== undefined ? (makeNoOp) => { Buffer$1.concat = makeNoOp ? noop$2 : OriginalBufferConcat; } : (_) => {}; const _superWrite = Symbol("_superWrite"); var ZlibError = class extends Error { code; errno; constructor(err, origin) { super("zlib: " + err.message, { cause: err }); this.code = err.code; this.errno = err.errno; /* c8 ignore next */ if (!this.code) this.code = "ZLIB_ERROR"; this.message = "zlib: " + err.message; Error.captureStackTrace(this, origin ?? this.constructor); } get name() { return "ZlibError"; } }; const _flushFlag = Symbol("flushFlag"); var ZlibBase = class extends Minipass { #sawError = false; #ended = false; #flushFlag; #finishFlushFlag; #fullFlushFlag; #handle; #onError; get sawError() { return this.#sawError; } get handle() { return this.#handle; } /* c8 ignore start */ get flushFlag() { return this.#flushFlag; } /* c8 ignore stop */ constructor(opts, mode) { if (!opts || typeof opts !== "object") throw new TypeError("invalid options for ZlibBase constructor"); super(opts); /* c8 ignore start */ this.#flushFlag = opts.flush ?? 0; this.#finishFlushFlag = opts.finishFlush ?? 0; this.#fullFlushFlag = opts.fullFlushFlag ?? 0; /* c8 ignore stop */ if (typeof realZlib[mode] !== "function") { throw new TypeError("Compression method not supported: " + mode); } try { this.#handle = new realZlib[mode](opts); } catch (er) { throw new ZlibError(er, this.constructor); } this.#onError = (err) => { if (this.#sawError) return; this.#sawError = true; this.close(); this.emit("error", err); }; this.#handle?.on("error", (er) => this.#onError(new ZlibError(er))); this.once("end", () => this.close); } close() { if (this.#handle) { this.#handle.close(); this.#handle = undefined; this.emit("close"); } } reset() { if (!this.#sawError) { assert(this.#handle, "zlib binding closed"); return this.#handle.reset?.(); } } flush(flushFlag) { if (this.ended) return; if (typeof flushFlag !== "number") flushFlag = this.#fullFlushFlag; this.write(Object.assign(Buffer$1.alloc(0), { [_flushFlag]: flushFlag })); } end(chunk, encoding, cb) { /* c8 ignore start */ if (typeof chunk === "function") { cb = chunk; encoding = undefined; chunk = undefined; } if (typeof encoding === "function") { cb = encoding; encoding = undefined; } /* c8 ignore stop */ if (chunk) { if (encoding) this.write(chunk, encoding); else this.write(chunk); } this.flush(this.#finishFlushFlag); this.#ended = true; return super.end(cb); } get ended() { return this.#ended; } [_superWrite](data) { return super.write(data); } write(chunk, encoding, cb) { if (typeof encoding === "function") cb = encoding, encoding = "utf8"; if (typeof chunk === "string") chunk = Buffer$1.from(chunk, encoding); if (this.#sawError) return; assert(this.#handle, "zlib binding closed"); const nativeHandle = this.#handle._handle; const originalNativeClose = nativeHandle.close; nativeHandle.close = () => {}; const originalClose = this.#handle.close; this.#handle.close = () => {}; passthroughBufferConcat(true); let result = undefined; try { const flushFlag = typeof chunk[_flushFlag] === "number" ? chunk[_flushFlag] : this.#flushFlag; result = this.#handle._processChunk(chunk, flushFlag); passthroughBufferConcat(false); } catch (err) { passthroughBufferConcat(false); this.#onError(new ZlibError(err, this.write)); } finally { if (this.#handle) { ; this.#handle._handle = nativeHandle; nativeHandle.close = originalNativeClose; this.#handle.close = originalClose; this.#handle.removeAllListeners("error"); } } if (this.#handle) this.#handle.on("error", (er) => this.#onError(new ZlibError(er, this.write))); let writeReturn; if (result) { if (Array.isArray(result) && result.length > 0) { const r = result[0]; writeReturn = this[_superWrite](Buffer$1.from(r)); for (let i = 1; i < result.length; i++) { writeReturn = this[_superWrite](result[i]); } } else { writeReturn = this[_superWrite](Buffer$1.from(result)); } } if (cb) cb(); return writeReturn; } }; var Zlib = class extends ZlibBase { #level; #strategy; constructor(opts, mode) { opts = opts || {}; opts.flush = opts.flush || constants$1.Z_NO_FLUSH; opts.finishFlush = opts.finishFlush || constants$1.Z_FINISH; opts.fullFlushFlag = constants$1.Z_FULL_FLUSH; super(opts, mode); this.#level = opts.level; this.#strategy = opts.strategy; } params(level, strategy) { if (this.sawError) return; if (!this.handle) throw new Error("cannot switch params when binding is closed"); /* c8 ignore start */ if (!this.handle.params) throw new Error("not supported in this implementation"); /* c8 ignore stop */ if (this.#level !== level || this.#strategy !== strategy) { this.flush(constants$1.Z_SYNC_FLUSH); assert(this.handle, "zlib binding closed"); const origFlush = this.handle.flush; this.handle.flush = (flushFlag, cb) => { /* c8 ignore start */ if (typeof flushFlag === "function") { cb = flushFlag; flushFlag = this.flushFlag; } /* c8 ignore stop */ this.flush(flushFlag); cb?.(); }; try { ; this.handle.params(level, strategy); } finally { this.handle.flush = origFlush; } /* c8 ignore start */ if (this.handle) { this.#level = level; this.#strategy = strategy; } } } }; var Deflate = class extends Zlib { constructor(opts) { super(opts, "Deflate"); } }; var Inflate = class extends Zlib { constructor(opts) { super(opts, "Inflate"); } }; var Gzip = class extends Zlib { #portable; constructor(opts) { super(opts, "Gzip"); this.#portable = opts && !!opts.portable; } [_superWrite](data) { if (!this.#portable) return super[_superWrite](data); this.#portable = false; data[9] = 255; return super[_superWrite](data); } }; var Gunzip = class extends Zlib { constructor(opts) { super(opts, "Gunzip"); } }; var DeflateRaw = class extends Zlib { constructor(opts) { super(opts, "DeflateRaw"); } }; var InflateRaw = class extends Zlib { constructor(opts) { super(opts, "InflateRaw"); } }; var Unzip = class extends Zlib { constructor(opts) { super(opts, "Unzip"); } }; var Brotli = class extends ZlibBase { constructor(opts, mode) { opts = opts || {}; opts.flush = opts.flush || constants$1.BROTLI_OPERATION_PROCESS; opts.finishFlush = opts.finishFlush || constants$1.BROTLI_OPERATION_FINISH; opts.fullFlushFlag = constants$1.BROTLI_OPERATION_FLUSH; super(opts, mode); } }; var BrotliCompress = class extends Brotli { constructor(opts) { super(opts, "BrotliCompress"); } }; var BrotliDecompress = class extends Brotli { constructor(opts) { super(opts, "BrotliDecompress"); } }; var Zstd = class extends ZlibBase { constructor(opts, mode) { opts = opts || {}; opts.flush = opts.flush || constants$1.ZSTD_e_continue; opts.finishFlush = opts.finishFlush || constants$1.ZSTD_e_end; opts.fullFlushFlag = constants$1.ZSTD_e_flush; super(opts, mode); } }; var ZstdCompress = class extends Zstd { constructor(opts) { super(opts, "ZstdCompress"); } }; var ZstdDecompress = class extends Zstd { constructor(opts) { super(opts, "ZstdDecompress"); } }; //#endregion //#region ../node_modules/lodash/lodash.js var require_lodash = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * @license * Lodash * Copyright OpenJS Foundation and other contributors * Released under MIT license * Based on Underscore.js 1.8.3 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors */ ; (function() { /** Used as a safe reference for `undefined` in pre-ES5 environments. */ var undefined; /** Used as the semantic version number. */ var VERSION = "4.17.21"; /** Used as the size to enable large array optimizations. */ var LARGE_ARRAY_SIZE = 200; /** Error message constants. */ var CORE_ERROR_TEXT = "Unsupported core-js use. Try https://npms.io/search?q=ponyfill.", FUNC_ERROR_TEXT = "Expected a function", INVALID_TEMPL_VAR_ERROR_TEXT = "Invalid `variable` option passed into `_.template`"; /** Used to stand-in for `undefined` hash values. */ var HASH_UNDEFINED = "__lodash_hash_undefined__"; /** Used as the maximum memoize cache size. */ var MAX_MEMOIZE_SIZE = 500; /** Used as the internal argument placeholder. */ var PLACEHOLDER = "__lodash_placeholder__"; /** Used to compose bitmasks for cloning. */ var CLONE_DEEP_FLAG = 1, CLONE_FLAT_FLAG = 2, CLONE_SYMBOLS_FLAG = 4; /** Used to compose bitmasks for value comparisons. */ var COMPARE_PARTIAL_FLAG = 1, COMPARE_UNORDERED_FLAG = 2; /** Used to compose bitmasks for function metadata. */ var WRAP_BIND_FLAG = 1, WRAP_BIND_KEY_FLAG = 2, WRAP_CURRY_BOUND_FLAG = 4, WRAP_CURRY_FLAG = 8, WRAP_CURRY_RIGHT_FLAG = 16, WRAP_PARTIAL_FLAG = 32, WRAP_PARTIAL_RIGHT_FLAG = 64, WRAP_ARY_FLAG = 128, WRAP_REARG_FLAG = 256, WRAP_FLIP_FLAG = 512; /** Used as default options for `_.truncate`. */ var DEFAULT_TRUNC_LENGTH = 30, DEFAULT_TRUNC_OMISSION = "..."; /** Used to detect hot functions by number of calls within a span of milliseconds. */ var HOT_COUNT = 800, HOT_SPAN = 16; /** Used to indicate the type of lazy iteratees. */ var LAZY_FILTER_FLAG = 1, LAZY_MAP_FLAG = 2, LAZY_WHILE_FLAG = 3; /** Used as references for various `Number` constants. */ var INFINITY = 1 / 0, MAX_SAFE_INTEGER = 9007199254740991, MAX_INTEGER = 17976931348623157e292, NAN = 0 / 0; /** Used as references for the maximum length and index of an array. */ var MAX_ARRAY_LENGTH = 4294967295, MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; /** Used to associate wrap methods with their bit flags. */ var wrapFlags = [ ["ary", WRAP_ARY_FLAG], ["bind", WRAP_BIND_FLAG], ["bindKey", WRAP_BIND_KEY_FLAG], ["curry", WRAP_CURRY_FLAG], ["curryRight", WRAP_CURRY_RIGHT_FLAG], ["flip", WRAP_FLIP_FLAG], ["partial", WRAP_PARTIAL_FLAG], ["partialRight", WRAP_PARTIAL_RIGHT_FLAG], ["rearg", WRAP_REARG_FLAG] ]; /** `Object#toString` result references. */ var argsTag = "[object Arguments]", arrayTag = "[object Array]", asyncTag = "[object AsyncFunction]", boolTag = "[object Boolean]", dateTag = "[object Date]", domExcTag = "[object DOMException]", errorTag = "[object Error]", funcTag = "[object Function]", genTag = "[object GeneratorFunction]", mapTag = "[object Map]", numberTag = "[object Number]", nullTag = "[object Null]", objectTag = "[object Object]", promiseTag = "[object Promise]", proxyTag = "[object Proxy]", regexpTag = "[object RegExp]", setTag = "[object Set]", stringTag = "[object String]", symbolTag = "[object Symbol]", undefinedTag = "[object Undefined]", weakMapTag = "[object WeakMap]", weakSetTag = "[object WeakSet]"; var arrayBufferTag = "[object ArrayBuffer]", dataViewTag = "[object DataView]", float32Tag = "[object Float32Array]", float64Tag = "[object Float64Array]", int8Tag = "[object Int8Array]", int16Tag = "[object Int16Array]", int32Tag = "[object Int32Array]", uint8Tag = "[object Uint8Array]", uint8ClampedTag = "[object Uint8ClampedArray]", uint16Tag = "[object Uint16Array]", uint32Tag = "[object Uint32Array]"; /** Used to match empty string literals in compiled template source. */ var reEmptyStringLeading = /\b__p \+= '';/g, reEmptyStringMiddle = /\b(__p \+=) '' \+/g, reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; /** Used to match HTML entities and HTML characters. */ var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g, reUnescapedHtml = /[&<>"']/g, reHasEscapedHtml = RegExp(reEscapedHtml.source), reHasUnescapedHtml = RegExp(reUnescapedHtml.source); /** Used to match template delimiters. */ var reEscape = /<%-([\s\S]+?)%>/g, reEvaluate = /<%([\s\S]+?)%>/g, reInterpolate = /<%=([\s\S]+?)%>/g; /** Used to match property names within property paths. */ var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, reIsPlainProp = /^\w*$/, rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; /** * Used to match `RegExp` * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). */ var reRegExpChar = /[\\^$.*+?()[\]{}|]/g, reHasRegExpChar = RegExp(reRegExpChar.source); /** Used to match leading whitespace. */ var reTrimStart = /^\s+/; /** Used to match a single whitespace character. */ var reWhitespace = /\s/; /** Used to match wrap detail comments. */ var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/, reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/, reSplitDetails = /,? & /; /** Used to match words composed of alphanumeric characters. */ var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g; /** * Used to validate the `validate` option in `_.template` variable. * * Forbids characters which could potentially change the meaning of the function argument definition: * - "()," (modification of function parameters) * - "=" (default value) * - "[]{}" (destructuring of function parameters) * - "/" (beginning of a comment) * - whitespace */ var reForbiddenIdentifierChars = /[()=,{}\[\]\/\s]/; /** Used to match backslashes in property paths. */ var reEscapeChar = /\\(\\)?/g; /** * Used to match * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components). */ var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; /** Used to match `RegExp` flags from their coerced string values. */ var reFlags = /\w*$/; /** Used to detect bad signed hexadecimal string values. */ var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; /** Used to detect binary string values. */ var reIsBinary = /^0b[01]+$/i; /** Used to detect host constructors (Safari). */ var reIsHostCtor = /^\[object .+?Constructor\]$/; /** Used to detect octal string values. */ var reIsOctal = /^0o[0-7]+$/i; /** Used to detect unsigned integer values. */ var reIsUint = /^(?:0|[1-9]\d*)$/; /** Used to match Latin Unicode letters (excluding mathematical operators). */ var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g; /** Used to ensure capturing order of template delimiters. */ var reNoMatch = /($^)/; /** Used to match unescaped characters in compiled string literals. */ var reUnescapedString = /['\n\r\u2028\u2029\\]/g; /** Used to compose unicode character classes. */ var rsAstralRange = "\\ud800-\\udfff", rsComboMarksRange = "\\u0300-\\u036f", reComboHalfMarksRange = "\\ufe20-\\ufe2f", rsComboSymbolsRange = "\\u20d0-\\u20ff", rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, rsDingbatRange = "\\u2700-\\u27bf", rsLowerRange = "a-z\\xdf-\\xf6\\xf8-\\xff", rsMathOpRange = "\\xac\\xb1\\xd7\\xf7", rsNonCharRange = "\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf", rsPunctuationRange = "\\u2000-\\u206f", rsSpaceRange = " \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000", rsUpperRange = "A-Z\\xc0-\\xd6\\xd8-\\xde", rsVarRange = "\\ufe0e\\ufe0f", rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange; /** Used to compose unicode capture groups. */ var rsApos = "['’]", rsAstral = "[" + rsAstralRange + "]", rsBreak = "[" + rsBreakRange + "]", rsCombo = "[" + rsComboRange + "]", rsDigits = "\\d+", rsDingbat = "[" + rsDingbatRange + "]", rsLower = "[" + rsLowerRange + "]", rsMisc = "[^" + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + "]", rsFitz = "\\ud83c[\\udffb-\\udfff]", rsModifier = "(?:" + rsCombo + "|" + rsFitz + ")", rsNonAstral = "[^" + rsAstralRange + "]", rsRegional = "(?:\\ud83c[\\udde6-\\uddff]){2}", rsSurrPair = "[\\ud800-\\udbff][\\udc00-\\udfff]", rsUpper = "[" + rsUpperRange + "]", rsZWJ = "\\u200d"; /** Used to compose unicode regexes. */ var rsMiscLower = "(?:" + rsLower + "|" + rsMisc + ")", rsMiscUpper = "(?:" + rsUpper + "|" + rsMisc + ")", rsOptContrLower = "(?:" + rsApos + "(?:d|ll|m|re|s|t|ve))?", rsOptContrUpper = "(?:" + rsApos + "(?:D|LL|M|RE|S|T|VE))?", reOptMod = rsModifier + "?", rsOptVar = "[" + rsVarRange + "]?", rsOptJoin = "(?:" + rsZWJ + "(?:" + [ rsNonAstral, rsRegional, rsSurrPair ].join("|") + ")" + rsOptVar + reOptMod + ")*", rsOrdLower = "\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])", rsOrdUpper = "\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])", rsSeq = rsOptVar + reOptMod + rsOptJoin, rsEmoji = "(?:" + [ rsDingbat, rsRegional, rsSurrPair ].join("|") + ")" + rsSeq, rsSymbol = "(?:" + [ rsNonAstral + rsCombo + "?", rsCombo, rsRegional, rsSurrPair, rsAstral ].join("|") + ")"; /** Used to match apostrophes. */ var reApos = RegExp(rsApos, "g"); /** * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols). */ var reComboMark = RegExp(rsCombo, "g"); /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ var reUnicode = RegExp(rsFitz + "(?=" + rsFitz + ")|" + rsSymbol + rsSeq, "g"); /** Used to match complex or compound words. */ var reUnicodeWord = RegExp([ rsUpper + "?" + rsLower + "+" + rsOptContrLower + "(?=" + [ rsBreak, rsUpper, "$" ].join("|") + ")", rsMiscUpper + "+" + rsOptContrUpper + "(?=" + [ rsBreak, rsUpper + rsMiscLower, "$" ].join("|") + ")", rsUpper + "?" + rsMiscLower + "+" + rsOptContrLower, rsUpper + "+" + rsOptContrUpper, rsOrdUpper, rsOrdLower, rsDigits, rsEmoji ].join("|"), "g"); /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ var reHasUnicode = RegExp("[" + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + "]"); /** Used to detect strings that need a more robust regexp to match words. */ var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/; /** Used to assign default `context` object properties. */ var contextProps = [ "Array", "Buffer", "DataView", "Date", "Error", "Float32Array", "Float64Array", "Function", "Int8Array", "Int16Array", "Int32Array", "Map", "Math", "Object", "Promise", "RegExp", "Set", "String", "Symbol", "TypeError", "Uint8Array", "Uint8ClampedArray", "Uint16Array", "Uint32Array", "WeakMap", "_", "clearTimeout", "isFinite", "parseInt", "setTimeout" ]; /** Used to make template sourceURLs easier to identify. */ var templateCounter = -1; /** Used to identify `toStringTag` values of typed arrays. */ var typedArrayTags = {}; typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = typedArrayTags[uint32Tag] = true; typedArrayTags[argsTag] = typedArrayTags[arrayTag] = typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = typedArrayTags[errorTag] = typedArrayTags[funcTag] = typedArrayTags[mapTag] = typedArrayTags[numberTag] = typedArrayTags[objectTag] = typedArrayTags[regexpTag] = typedArrayTags[setTag] = typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; /** Used to identify `toStringTag` values supported by `_.clone`. */ var cloneableTags = {}; cloneableTags[argsTag] = cloneableTags[arrayTag] = cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = cloneableTags[boolTag] = cloneableTags[dateTag] = cloneableTags[float32Tag] = cloneableTags[float64Tag] = cloneableTags[int8Tag] = cloneableTags[int16Tag] = cloneableTags[int32Tag] = cloneableTags[mapTag] = cloneableTags[numberTag] = cloneableTags[objectTag] = cloneableTags[regexpTag] = cloneableTags[setTag] = cloneableTags[stringTag] = cloneableTags[symbolTag] = cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; cloneableTags[errorTag] = cloneableTags[funcTag] = cloneableTags[weakMapTag] = false; /** Used to map Latin Unicode letters to basic Latin letters. */ var deburredLetters = { "À": "A", "Á": "A", "Â": "A", "Ã": "A", "Ä": "A", "Å": "A", "à": "a", "á": "a", "â": "a", "ã": "a", "ä": "a", "å": "a", "Ç": "C", "ç": "c", "Ð": "D", "ð": "d", "È": "E", "É": "E", "Ê": "E", "Ë": "E", "è": "e", "é": "e", "ê": "e", "ë": "e", "Ì": "I", "Í": "I", "Î": "I", "Ï": "I", "ì": "i", "í": "i", "î": "i", "ï": "i", "Ñ": "N", "ñ": "n", "Ò": "O", "Ó": "O", "Ô": "O", "Õ": "O", "Ö": "O", "Ø": "O", "ò": "o", "ó": "o", "ô": "o", "õ": "o", "ö": "o", "ø": "o", "Ù": "U", "Ú": "U", "Û": "U", "Ü": "U", "ù": "u", "ú": "u", "û": "u", "ü": "u", "Ý": "Y", "ý": "y", "ÿ": "y", "Æ": "Ae", "æ": "ae", "Þ": "Th", "þ": "th", "ß": "ss", "Ā": "A", "Ă": "A", "Ą": "A", "ā": "a", "ă": "a", "ą": "a", "Ć": "C", "Ĉ": "C", "Ċ": "C", "Č": "C", "ć": "c", "ĉ": "c", "ċ": "c", "č": "c", "Ď": "D", "Đ": "D", "ď": "d", "đ": "d", "Ē": "E", "Ĕ": "E", "Ė": "E", "Ę": "E", "Ě": "E", "ē": "e", "ĕ": "e", "ė": "e", "ę": "e", "ě": "e", "Ĝ": "G", "Ğ": "G", "Ġ": "G", "Ģ": "G", "ĝ": "g", "ğ": "g", "ġ": "g", "ģ": "g", "Ĥ": "H", "Ħ": "H", "ĥ": "h", "ħ": "h", "Ĩ": "I", "Ī": "I", "Ĭ": "I", "Į": "I", "İ": "I", "ĩ": "i", "ī": "i", "ĭ": "i", "į": "i", "ı": "i", "Ĵ": "J", "ĵ": "j", "Ķ": "K", "ķ": "k", "ĸ": "k", "Ĺ": "L", "Ļ": "L", "Ľ": "L", "Ŀ": "L", "Ł": "L", "ĺ": "l", "ļ": "l", "ľ": "l", "ŀ": "l", "ł": "l", "Ń": "N", "Ņ": "N", "Ň": "N", "Ŋ": "N", "ń": "n", "ņ": "n", "ň": "n", "ŋ": "n", "Ō": "O", "Ŏ": "O", "Ő": "O", "ō": "o", "ŏ": "o", "ő": "o", "Ŕ": "R", "Ŗ": "R", "Ř": "R", "ŕ": "r", "ŗ": "r", "ř": "r", "Ś": "S", "Ŝ": "S", "Ş": "S", "Š": "S", "ś": "s", "ŝ": "s", "ş": "s", "š": "s", "Ţ": "T", "Ť": "T", "Ŧ": "T", "ţ": "t", "ť": "t", "ŧ": "t", "Ũ": "U", "Ū": "U", "Ŭ": "U", "Ů": "U", "Ű": "U", "Ų": "U", "ũ": "u", "ū": "u", "ŭ": "u", "ů": "u", "ű": "u", "ų": "u", "Ŵ": "W", "ŵ": "w", "Ŷ": "Y", "ŷ": "y", "Ÿ": "Y", "Ź": "Z", "Ż": "Z", "Ž": "Z", "ź": "z", "ż": "z", "ž": "z", "IJ": "IJ", "ij": "ij", "Œ": "Oe", "œ": "oe", "ʼn": "'n", "ſ": "s" }; /** Used to map characters to HTML entities. */ var htmlEscapes = { "&": "&", "<": "<", ">": ">", "\"": """, "'": "'" }; /** Used to map HTML entities to characters. */ var htmlUnescapes = { "&": "&", "<": "<", ">": ">", """: "\"", "'": "'" }; /** Used to escape characters for inclusion in compiled string literals. */ var stringEscapes = { "\\": "\\", "'": "'", "\n": "n", "\r": "r", "\u2028": "u2028", "\u2029": "u2029" }; /** Built-in method references without a dependency on `root`. */ var freeParseFloat = parseFloat, freeParseInt = parseInt; /** Detect free variable `global` from Node.js. */ var freeGlobal = typeof global == "object" && global && global.Object === Object && global; /** Detect free variable `self`. */ var freeSelf = typeof self == "object" && self && self.Object === Object && self; /** Used as a reference to the global object. */ var root = freeGlobal || freeSelf || Function("return this")(); /** Detect free variable `exports`. */ var freeExports = typeof exports == "object" && exports && !exports.nodeType && exports; /** Detect free variable `module`. */ var freeModule = freeExports && typeof module == "object" && module && !module.nodeType && module; /** Detect the popular CommonJS extension `module.exports`. */ var moduleExports = freeModule && freeModule.exports === freeExports; /** Detect free variable `process` from Node.js. */ var freeProcess = moduleExports && freeGlobal.process; /** Used to access faster Node.js helpers. */ var nodeUtil = function() { try { var types = freeModule && freeModule.require && freeModule.require("util").types; if (types) { return types; } return freeProcess && freeProcess.binding && freeProcess.binding("util"); } catch (e) {} }(); var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer, nodeIsDate = nodeUtil && nodeUtil.isDate, nodeIsMap = nodeUtil && nodeUtil.isMap, nodeIsRegExp = nodeUtil && nodeUtil.isRegExp, nodeIsSet = nodeUtil && nodeUtil.isSet, nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; /** * A faster alternative to `Function#apply`, this function invokes `func` * with the `this` binding of `thisArg` and the arguments of `args`. * * @private * @param {Function} func The function to invoke. * @param {*} thisArg The `this` binding of `func`. * @param {Array} args The arguments to invoke `func` with. * @returns {*} Returns the result of `func`. */ function apply(func, thisArg, args) { switch (args.length) { case 0: return func.call(thisArg); case 1: return func.call(thisArg, args[0]); case 2: return func.call(thisArg, args[0], args[1]); case 3: return func.call(thisArg, args[0], args[1], args[2]); } return func.apply(thisArg, args); } /** * A specialized version of `baseAggregator` for arrays. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} setter The function to set `accumulator` values. * @param {Function} iteratee The iteratee to transform keys. * @param {Object} accumulator The initial aggregated object. * @returns {Function} Returns `accumulator`. */ function arrayAggregator(array, setter, iteratee, accumulator) { var index = -1, length = array == null ? 0 : array.length; while (++index < length) { var value = array[index]; setter(accumulator, value, iteratee(value), array); } return accumulator; } /** * A specialized version of `_.forEach` for arrays without support for * iteratee shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns `array`. */ function arrayEach(array, iteratee) { var index = -1, length = array == null ? 0 : array.length; while (++index < length) { if (iteratee(array[index], index, array) === false) { break; } } return array; } /** * A specialized version of `_.forEachRight` for arrays without support for * iteratee shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns `array`. */ function arrayEachRight(array, iteratee) { var length = array == null ? 0 : array.length; while (length--) { if (iteratee(array[length], length, array) === false) { break; } } return array; } /** * A specialized version of `_.every` for arrays without support for * iteratee shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} predicate The function invoked per iteration. * @returns {boolean} Returns `true` if all elements pass the predicate check, * else `false`. */ function arrayEvery(array, predicate) { var index = -1, length = array == null ? 0 : array.length; while (++index < length) { if (!predicate(array[index], index, array)) { return false; } } return true; } /** * A specialized version of `_.filter` for arrays without support for * iteratee shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} predicate The function invoked per iteration. * @returns {Array} Returns the new filtered array. */ function arrayFilter(array, predicate) { var index = -1, length = array == null ? 0 : array.length, resIndex = 0, result = []; while (++index < length) { var value = array[index]; if (predicate(value, index, array)) { result[resIndex++] = value; } } return result; } /** * A specialized version of `_.includes` for arrays without support for * specifying an index to search from. * * @private * @param {Array} [array] The array to inspect. * @param {*} target The value to search for. * @returns {boolean} Returns `true` if `target` is found, else `false`. */ function arrayIncludes(array, value) { var length = array == null ? 0 : array.length; return !!length && baseIndexOf(array, value, 0) > -1; } /** * This function is like `arrayIncludes` except that it accepts a comparator. * * @private * @param {Array} [array] The array to inspect. * @param {*} target The value to search for. * @param {Function} comparator The comparator invoked per element. * @returns {boolean} Returns `true` if `target` is found, else `false`. */ function arrayIncludesWith(array, value, comparator) { var index = -1, length = array == null ? 0 : array.length; while (++index < length) { if (comparator(value, array[index])) { return true; } } return false; } /** * A specialized version of `_.map` for arrays without support for iteratee * shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns the new mapped array. */ function arrayMap(array, iteratee) { var index = -1, length = array == null ? 0 : array.length, result = Array(length); while (++index < length) { result[index] = iteratee(array[index], index, array); } return result; } /** * Appends the elements of `values` to `array`. * * @private * @param {Array} array The array to modify. * @param {Array} values The values to append. * @returns {Array} Returns `array`. */ function arrayPush(array, values) { var index = -1, length = values.length, offset = array.length; while (++index < length) { array[offset + index] = values[index]; } return array; } /** * A specialized version of `_.reduce` for arrays without support for * iteratee shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @param {*} [accumulator] The initial value. * @param {boolean} [initAccum] Specify using the first element of `array` as * the initial value. * @returns {*} Returns the accumulated value. */ function arrayReduce(array, iteratee, accumulator, initAccum) { var index = -1, length = array == null ? 0 : array.length; if (initAccum && length) { accumulator = array[++index]; } while (++index < length) { accumulator = iteratee(accumulator, array[index], index, array); } return accumulator; } /** * A specialized version of `_.reduceRight` for arrays without support for * iteratee shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @param {*} [accumulator] The initial value. * @param {boolean} [initAccum] Specify using the last element of `array` as * the initial value. * @returns {*} Returns the accumulated value. */ function arrayReduceRight(array, iteratee, accumulator, initAccum) { var length = array == null ? 0 : array.length; if (initAccum && length) { accumulator = array[--length]; } while (length--) { accumulator = iteratee(accumulator, array[length], length, array); } return accumulator; } /** * A specialized version of `_.some` for arrays without support for iteratee * shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} predicate The function invoked per iteration. * @returns {boolean} Returns `true` if any element passes the predicate check, * else `false`. */ function arraySome(array, predicate) { var index = -1, length = array == null ? 0 : array.length; while (++index < length) { if (predicate(array[index], index, array)) { return true; } } return false; } /** * Gets the size of an ASCII `string`. * * @private * @param {string} string The string inspect. * @returns {number} Returns the string size. */ var asciiSize = baseProperty("length"); /** * Converts an ASCII `string` to an array. * * @private * @param {string} string The string to convert. * @returns {Array} Returns the converted array. */ function asciiToArray(string) { return string.split(""); } /** * Splits an ASCII `string` into an array of its words. * * @private * @param {string} The string to inspect. * @returns {Array} Returns the words of `string`. */ function asciiWords(string) { return string.match(reAsciiWord) || []; } /** * The base implementation of methods like `_.findKey` and `_.findLastKey`, * without support for iteratee shorthands, which iterates over `collection` * using `eachFunc`. * * @private * @param {Array|Object} collection The collection to inspect. * @param {Function} predicate The function invoked per iteration. * @param {Function} eachFunc The function to iterate over `collection`. * @returns {*} Returns the found element or its key, else `undefined`. */ function baseFindKey(collection, predicate, eachFunc) { var result; eachFunc(collection, function(value, key, collection) { if (predicate(value, key, collection)) { result = key; return false; } }); return result; } /** * The base implementation of `_.findIndex` and `_.findLastIndex` without * support for iteratee shorthands. * * @private * @param {Array} array The array to inspect. * @param {Function} predicate The function invoked per iteration. * @param {number} fromIndex The index to search from. * @param {boolean} [fromRight] Specify iterating from right to left. * @returns {number} Returns the index of the matched value, else `-1`. */ function baseFindIndex(array, predicate, fromIndex, fromRight) { var length = array.length, index = fromIndex + (fromRight ? 1 : -1); while (fromRight ? index-- : ++index < length) { if (predicate(array[index], index, array)) { return index; } } return -1; } /** * The base implementation of `_.indexOf` without `fromIndex` bounds checks. * * @private * @param {Array} array The array to inspect. * @param {*} value The value to search for. * @param {number} fromIndex The index to search from. * @returns {number} Returns the index of the matched value, else `-1`. */ function baseIndexOf(array, value, fromIndex) { return value === value ? strictIndexOf(array, value, fromIndex) : baseFindIndex(array, baseIsNaN, fromIndex); } /** * This function is like `baseIndexOf` except that it accepts a comparator. * * @private * @param {Array} array The array to inspect. * @param {*} value The value to search for. * @param {number} fromIndex The index to search from. * @param {Function} comparator The comparator invoked per element. * @returns {number} Returns the index of the matched value, else `-1`. */ function baseIndexOfWith(array, value, fromIndex, comparator) { var index = fromIndex - 1, length = array.length; while (++index < length) { if (comparator(array[index], value)) { return index; } } return -1; } /** * The base implementation of `_.isNaN` without support for number objects. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. */ function baseIsNaN(value) { return value !== value; } /** * The base implementation of `_.mean` and `_.meanBy` without support for * iteratee shorthands. * * @private * @param {Array} array The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {number} Returns the mean. */ function baseMean(array, iteratee) { var length = array == null ? 0 : array.length; return length ? baseSum(array, iteratee) / length : NAN; } /** * The base implementation of `_.property` without support for deep paths. * * @private * @param {string} key The key of the property to get. * @returns {Function} Returns the new accessor function. */ function baseProperty(key) { return function(object) { return object == null ? undefined : object[key]; }; } /** * The base implementation of `_.propertyOf` without support for deep paths. * * @private * @param {Object} object The object to query. * @returns {Function} Returns the new accessor function. */ function basePropertyOf(object) { return function(key) { return object == null ? undefined : object[key]; }; } /** * The base implementation of `_.reduce` and `_.reduceRight`, without support * for iteratee shorthands, which iterates over `collection` using `eachFunc`. * * @private * @param {Array|Object} collection The collection to iterate over. * @param {Function} iteratee The function invoked per iteration. * @param {*} accumulator The initial value. * @param {boolean} initAccum Specify using the first or last element of * `collection` as the initial value. * @param {Function} eachFunc The function to iterate over `collection`. * @returns {*} Returns the accumulated value. */ function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { eachFunc(collection, function(value, index, collection) { accumulator = initAccum ? (initAccum = false, value) : iteratee(accumulator, value, index, collection); }); return accumulator; } /** * The base implementation of `_.sortBy` which uses `comparer` to define the * sort order of `array` and replaces criteria objects with their corresponding * values. * * @private * @param {Array} array The array to sort. * @param {Function} comparer The function to define sort order. * @returns {Array} Returns `array`. */ function baseSortBy(array, comparer) { var length = array.length; array.sort(comparer); while (length--) { array[length] = array[length].value; } return array; } /** * The base implementation of `_.sum` and `_.sumBy` without support for * iteratee shorthands. * * @private * @param {Array} array The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {number} Returns the sum. */ function baseSum(array, iteratee) { var result, index = -1, length = array.length; while (++index < length) { var current = iteratee(array[index]); if (current !== undefined) { result = result === undefined ? current : result + current; } } return result; } /** * The base implementation of `_.times` without support for iteratee shorthands * or max array length checks. * * @private * @param {number} n The number of times to invoke `iteratee`. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns the array of results. */ function baseTimes(n, iteratee) { var index = -1, result = Array(n); while (++index < n) { result[index] = iteratee(index); } return result; } /** * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array * of key-value pairs for `object` corresponding to the property names of `props`. * * @private * @param {Object} object The object to query. * @param {Array} props The property names to get values for. * @returns {Object} Returns the key-value pairs. */ function baseToPairs(object, props) { return arrayMap(props, function(key) { return [key, object[key]]; }); } /** * The base implementation of `_.trim`. * * @private * @param {string} string The string to trim. * @returns {string} Returns the trimmed string. */ function baseTrim(string) { return string ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, "") : string; } /** * The base implementation of `_.unary` without support for storing metadata. * * @private * @param {Function} func The function to cap arguments for. * @returns {Function} Returns the new capped function. */ function baseUnary(func) { return function(value) { return func(value); }; } /** * The base implementation of `_.values` and `_.valuesIn` which creates an * array of `object` property values corresponding to the property names * of `props`. * * @private * @param {Object} object The object to query. * @param {Array} props The property names to get values for. * @returns {Object} Returns the array of property values. */ function baseValues(object, props) { return arrayMap(props, function(key) { return object[key]; }); } /** * Checks if a `cache` value for `key` exists. * * @private * @param {Object} cache The cache to query. * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function cacheHas(cache, key) { return cache.has(key); } /** * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol * that is not found in the character symbols. * * @private * @param {Array} strSymbols The string symbols to inspect. * @param {Array} chrSymbols The character symbols to find. * @returns {number} Returns the index of the first unmatched string symbol. */ function charsStartIndex(strSymbols, chrSymbols) { var index = -1, length = strSymbols.length; while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} return index; } /** * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol * that is not found in the character symbols. * * @private * @param {Array} strSymbols The string symbols to inspect. * @param {Array} chrSymbols The character symbols to find. * @returns {number} Returns the index of the last unmatched string symbol. */ function charsEndIndex(strSymbols, chrSymbols) { var index = strSymbols.length; while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} return index; } /** * Gets the number of `placeholder` occurrences in `array`. * * @private * @param {Array} array The array to inspect. * @param {*} placeholder The placeholder to search for. * @returns {number} Returns the placeholder count. */ function countHolders(array, placeholder) { var length = array.length, result = 0; while (length--) { if (array[length] === placeholder) { ++result; } } return result; } /** * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A * letters to basic Latin letters. * * @private * @param {string} letter The matched letter to deburr. * @returns {string} Returns the deburred letter. */ var deburrLetter = basePropertyOf(deburredLetters); /** * Used by `_.escape` to convert characters to HTML entities. * * @private * @param {string} chr The matched character to escape. * @returns {string} Returns the escaped character. */ var escapeHtmlChar = basePropertyOf(htmlEscapes); /** * Used by `_.template` to escape characters for inclusion in compiled string literals. * * @private * @param {string} chr The matched character to escape. * @returns {string} Returns the escaped character. */ function escapeStringChar(chr) { return "\\" + stringEscapes[chr]; } /** * Gets the value at `key` of `object`. * * @private * @param {Object} [object] The object to query. * @param {string} key The key of the property to get. * @returns {*} Returns the property value. */ function getValue(object, key) { return object == null ? undefined : object[key]; } /** * Checks if `string` contains Unicode symbols. * * @private * @param {string} string The string to inspect. * @returns {boolean} Returns `true` if a symbol is found, else `false`. */ function hasUnicode(string) { return reHasUnicode.test(string); } /** * Checks if `string` contains a word composed of Unicode symbols. * * @private * @param {string} string The string to inspect. * @returns {boolean} Returns `true` if a word is found, else `false`. */ function hasUnicodeWord(string) { return reHasUnicodeWord.test(string); } /** * Converts `iterator` to an array. * * @private * @param {Object} iterator The iterator to convert. * @returns {Array} Returns the converted array. */ function iteratorToArray(iterator) { var data, result = []; while (!(data = iterator.next()).done) { result.push(data.value); } return result; } /** * Converts `map` to its key-value pairs. * * @private * @param {Object} map The map to convert. * @returns {Array} Returns the key-value pairs. */ function mapToArray(map) { var index = -1, result = Array(map.size); map.forEach(function(value, key) { result[++index] = [key, value]; }); return result; } /** * Creates a unary function that invokes `func` with its argument transformed. * * @private * @param {Function} func The function to wrap. * @param {Function} transform The argument transform. * @returns {Function} Returns the new function. */ function overArg(func, transform) { return function(arg) { return func(transform(arg)); }; } /** * Replaces all `placeholder` elements in `array` with an internal placeholder * and returns an array of their indexes. * * @private * @param {Array} array The array to modify. * @param {*} placeholder The placeholder to replace. * @returns {Array} Returns the new array of placeholder indexes. */ function replaceHolders(array, placeholder) { var index = -1, length = array.length, resIndex = 0, result = []; while (++index < length) { var value = array[index]; if (value === placeholder || value === PLACEHOLDER) { array[index] = PLACEHOLDER; result[resIndex++] = index; } } return result; } /** * Converts `set` to an array of its values. * * @private * @param {Object} set The set to convert. * @returns {Array} Returns the values. */ function setToArray(set) { var index = -1, result = Array(set.size); set.forEach(function(value) { result[++index] = value; }); return result; } /** * Converts `set` to its value-value pairs. * * @private * @param {Object} set The set to convert. * @returns {Array} Returns the value-value pairs. */ function setToPairs(set) { var index = -1, result = Array(set.size); set.forEach(function(value) { result[++index] = [value, value]; }); return result; } /** * A specialized version of `_.indexOf` which performs strict equality * comparisons of values, i.e. `===`. * * @private * @param {Array} array The array to inspect. * @param {*} value The value to search for. * @param {number} fromIndex The index to search from. * @returns {number} Returns the index of the matched value, else `-1`. */ function strictIndexOf(array, value, fromIndex) { var index = fromIndex - 1, length = array.length; while (++index < length) { if (array[index] === value) { return index; } } return -1; } /** * A specialized version of `_.lastIndexOf` which performs strict equality * comparisons of values, i.e. `===`. * * @private * @param {Array} array The array to inspect. * @param {*} value The value to search for. * @param {number} fromIndex The index to search from. * @returns {number} Returns the index of the matched value, else `-1`. */ function strictLastIndexOf(array, value, fromIndex) { var index = fromIndex + 1; while (index--) { if (array[index] === value) { return index; } } return index; } /** * Gets the number of symbols in `string`. * * @private * @param {string} string The string to inspect. * @returns {number} Returns the string size. */ function stringSize(string) { return hasUnicode(string) ? unicodeSize(string) : asciiSize(string); } /** * Converts `string` to an array. * * @private * @param {string} string The string to convert. * @returns {Array} Returns the converted array. */ function stringToArray(string) { return hasUnicode(string) ? unicodeToArray(string) : asciiToArray(string); } /** * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace * character of `string`. * * @private * @param {string} string The string to inspect. * @returns {number} Returns the index of the last non-whitespace character. */ function trimmedEndIndex(string) { var index = string.length; while (index-- && reWhitespace.test(string.charAt(index))) {} return index; } /** * Used by `_.unescape` to convert HTML entities to characters. * * @private * @param {string} chr The matched character to unescape. * @returns {string} Returns the unescaped character. */ var unescapeHtmlChar = basePropertyOf(htmlUnescapes); /** * Gets the size of a Unicode `string`. * * @private * @param {string} string The string inspect. * @returns {number} Returns the string size. */ function unicodeSize(string) { var result = reUnicode.lastIndex = 0; while (reUnicode.test(string)) { ++result; } return result; } /** * Converts a Unicode `string` to an array. * * @private * @param {string} string The string to convert. * @returns {Array} Returns the converted array. */ function unicodeToArray(string) { return string.match(reUnicode) || []; } /** * Splits a Unicode `string` into an array of its words. * * @private * @param {string} The string to inspect. * @returns {Array} Returns the words of `string`. */ function unicodeWords(string) { return string.match(reUnicodeWord) || []; } /** * Create a new pristine `lodash` function using the `context` object. * * @static * @memberOf _ * @since 1.1.0 * @category Util * @param {Object} [context=root] The context object. * @returns {Function} Returns a new `lodash` function. * @example * * _.mixin({ 'foo': _.constant('foo') }); * * var lodash = _.runInContext(); * lodash.mixin({ 'bar': lodash.constant('bar') }); * * _.isFunction(_.foo); * // => true * _.isFunction(_.bar); * // => false * * lodash.isFunction(lodash.foo); * // => false * lodash.isFunction(lodash.bar); * // => true * * // Create a suped-up `defer` in Node.js. * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; */ var runInContext = (function runInContext(context) { context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps)); /** Built-in constructor references. */ var Array = context.Array, Date = context.Date, Error = context.Error, Function = context.Function, Math = context.Math, Object = context.Object, RegExp = context.RegExp, String = context.String, TypeError = context.TypeError; /** Used for built-in method references. */ var arrayProto = Array.prototype, funcProto = Function.prototype, objectProto = Object.prototype; /** Used to detect overreaching core-js shims. */ var coreJsData = context["__core-js_shared__"]; /** Used to resolve the decompiled source of functions. */ var funcToString = funcProto.toString; /** Used to check objects for own properties. */ var hasOwnProperty = objectProto.hasOwnProperty; /** Used to generate unique IDs. */ var idCounter = 0; /** Used to detect methods masquerading as native. */ var maskSrcKey = function() { var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ""); return uid ? "Symbol(src)_1." + uid : ""; }(); /** * Used to resolve the * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) * of values. */ var nativeObjectToString = objectProto.toString; /** Used to infer the `Object` constructor. */ var objectCtorString = funcToString.call(Object); /** Used to restore the original `_` reference in `_.noConflict`. */ var oldDash = root._; /** Used to detect if a method is native. */ var reIsNative = RegExp("^" + funcToString.call(hasOwnProperty).replace(reRegExpChar, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$"); /** Built-in value references. */ var Buffer = moduleExports ? context.Buffer : undefined, Symbol = context.Symbol, Uint8Array = context.Uint8Array, allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined, getPrototype = overArg(Object.getPrototypeOf, Object), objectCreate = Object.create, propertyIsEnumerable = objectProto.propertyIsEnumerable, splice = arrayProto.splice, spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined, symIterator = Symbol ? Symbol.iterator : undefined, symToStringTag = Symbol ? Symbol.toStringTag : undefined; var defineProperty = function() { try { var func = getNative(Object, "defineProperty"); func({}, "", {}); return func; } catch (e) {} }(); /** Mocked built-ins. */ var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout, ctxNow = Date && Date.now !== root.Date.now && Date.now, ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout; var nativeCeil = Math.ceil, nativeFloor = Math.floor, nativeGetSymbols = Object.getOwnPropertySymbols, nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, nativeIsFinite = context.isFinite, nativeJoin = arrayProto.join, nativeKeys = overArg(Object.keys, Object), nativeMax = Math.max, nativeMin = Math.min, nativeNow = Date.now, nativeParseInt = context.parseInt, nativeRandom = Math.random, nativeReverse = arrayProto.reverse; var DataView = getNative(context, "DataView"), Map = getNative(context, "Map"), Promise = getNative(context, "Promise"), Set = getNative(context, "Set"), WeakMap = getNative(context, "WeakMap"), nativeCreate = getNative(Object, "create"); /** Used to store function metadata. */ var metaMap = WeakMap && new WeakMap(); /** Used to lookup unminified function names. */ var realNames = {}; /** Used to detect maps, sets, and weakmaps. */ var dataViewCtorString = toSource(DataView), mapCtorString = toSource(Map), promiseCtorString = toSource(Promise), setCtorString = toSource(Set), weakMapCtorString = toSource(WeakMap); /** Used to convert symbols to primitives and strings. */ var symbolProto = Symbol ? Symbol.prototype : undefined, symbolValueOf = symbolProto ? symbolProto.valueOf : undefined, symbolToString = symbolProto ? symbolProto.toString : undefined; /** * Creates a `lodash` object which wraps `value` to enable implicit method * chain sequences. Methods that operate on and return arrays, collections, * and functions can be chained together. Methods that retrieve a single value * or may return a primitive value will automatically end the chain sequence * and return the unwrapped value. Otherwise, the value must be unwrapped * with `_#value`. * * Explicit chain sequences, which must be unwrapped with `_#value`, may be * enabled using `_.chain`. * * The execution of chained methods is lazy, that is, it's deferred until * `_#value` is implicitly or explicitly called. * * Lazy evaluation allows several methods to support shortcut fusion. * Shortcut fusion is an optimization to merge iteratee calls; this avoids * the creation of intermediate arrays and can greatly reduce the number of * iteratee executions. Sections of a chain sequence qualify for shortcut * fusion if the section is applied to an array and iteratees accept only * one argument. The heuristic for whether a section qualifies for shortcut * fusion is subject to change. * * Chaining is supported in custom builds as long as the `_#value` method is * directly or indirectly included in the build. * * In addition to lodash methods, wrappers have `Array` and `String` methods. * * The wrapper `Array` methods are: * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift` * * The wrapper `String` methods are: * `replace` and `split` * * The wrapper methods that support shortcut fusion are: * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`, * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`, * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray` * * The chainable wrapper methods are: * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`, * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`, * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`, * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`, * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`, * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`, * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`, * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`, * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`, * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`, * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`, * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`, * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`, * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`, * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`, * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`, * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`, * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`, * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`, * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, * `zipObject`, `zipObjectDeep`, and `zipWith` * * The wrapper methods that are **not** chainable by default are: * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`, * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`, * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`, * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`, * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`, * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`, * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`, * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`, * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`, * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`, * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`, * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`, * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`, * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`, * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`, * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`, * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`, * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`, * `upperFirst`, `value`, and `words` * * @name _ * @constructor * @category Seq * @param {*} value The value to wrap in a `lodash` instance. * @returns {Object} Returns the new `lodash` wrapper instance. * @example * * function square(n) { * return n * n; * } * * var wrapped = _([1, 2, 3]); * * // Returns an unwrapped value. * wrapped.reduce(_.add); * // => 6 * * // Returns a wrapped value. * var squares = wrapped.map(square); * * _.isArray(squares); * // => false * * _.isArray(squares.value()); * // => true */ function lodash(value) { if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { if (value instanceof LodashWrapper) { return value; } if (hasOwnProperty.call(value, "__wrapped__")) { return wrapperClone(value); } } return new LodashWrapper(value); } /** * The base implementation of `_.create` without support for assigning * properties to the created object. * * @private * @param {Object} proto The object to inherit from. * @returns {Object} Returns the new object. */ var baseCreate = function() { function object() {} return function(proto) { if (!isObject(proto)) { return {}; } if (objectCreate) { return objectCreate(proto); } object.prototype = proto; var result = new object(); object.prototype = undefined; return result; }; }(); /** * The function whose prototype chain sequence wrappers inherit from. * * @private */ function baseLodash() {} /** * The base constructor for creating `lodash` wrapper objects. * * @private * @param {*} value The value to wrap. * @param {boolean} [chainAll] Enable explicit method chain sequences. */ function LodashWrapper(value, chainAll) { this.__wrapped__ = value; this.__actions__ = []; this.__chain__ = !!chainAll; this.__index__ = 0; this.__values__ = undefined; } /** * By default, the template delimiters used by lodash are like those in * embedded Ruby (ERB) as well as ES2015 template strings. Change the * following template settings to use alternative delimiters. * * @static * @memberOf _ * @type {Object} */ lodash.templateSettings = { "escape": reEscape, "evaluate": reEvaluate, "interpolate": reInterpolate, "variable": "", "imports": { "_": lodash } }; lodash.prototype = baseLodash.prototype; lodash.prototype.constructor = lodash; LodashWrapper.prototype = baseCreate(baseLodash.prototype); LodashWrapper.prototype.constructor = LodashWrapper; /** * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. * * @private * @constructor * @param {*} value The value to wrap. */ function LazyWrapper(value) { this.__wrapped__ = value; this.__actions__ = []; this.__dir__ = 1; this.__filtered__ = false; this.__iteratees__ = []; this.__takeCount__ = MAX_ARRAY_LENGTH; this.__views__ = []; } /** * Creates a clone of the lazy wrapper object. * * @private * @name clone * @memberOf LazyWrapper * @returns {Object} Returns the cloned `LazyWrapper` object. */ function lazyClone() { var result = new LazyWrapper(this.__wrapped__); result.__actions__ = copyArray(this.__actions__); result.__dir__ = this.__dir__; result.__filtered__ = this.__filtered__; result.__iteratees__ = copyArray(this.__iteratees__); result.__takeCount__ = this.__takeCount__; result.__views__ = copyArray(this.__views__); return result; } /** * Reverses the direction of lazy iteration. * * @private * @name reverse * @memberOf LazyWrapper * @returns {Object} Returns the new reversed `LazyWrapper` object. */ function lazyReverse() { if (this.__filtered__) { var result = new LazyWrapper(this); result.__dir__ = -1; result.__filtered__ = true; } else { result = this.clone(); result.__dir__ *= -1; } return result; } /** * Extracts the unwrapped value from its lazy wrapper. * * @private * @name value * @memberOf LazyWrapper * @returns {*} Returns the unwrapped value. */ function lazyValue() { var array = this.__wrapped__.value(), dir = this.__dir__, isArr = isArray(array), isRight = dir < 0, arrLength = isArr ? array.length : 0, view = getView(0, arrLength, this.__views__), start = view.start, end = view.end, length = end - start, index = isRight ? end : start - 1, iteratees = this.__iteratees__, iterLength = iteratees.length, resIndex = 0, takeCount = nativeMin(length, this.__takeCount__); if (!isArr || !isRight && arrLength == length && takeCount == length) { return baseWrapperValue(array, this.__actions__); } var result = []; outer: while (length-- && resIndex < takeCount) { index += dir; var iterIndex = -1, value = array[index]; while (++iterIndex < iterLength) { var data = iteratees[iterIndex], iteratee = data.iteratee, type = data.type, computed = iteratee(value); if (type == LAZY_MAP_FLAG) { value = computed; } else if (!computed) { if (type == LAZY_FILTER_FLAG) { continue outer; } else { break outer; } } } result[resIndex++] = value; } return result; } LazyWrapper.prototype = baseCreate(baseLodash.prototype); LazyWrapper.prototype.constructor = LazyWrapper; /** * Creates a hash object. * * @private * @constructor * @param {Array} [entries] The key-value pairs to cache. */ function Hash(entries) { var index = -1, length = entries == null ? 0 : entries.length; this.clear(); while (++index < length) { var entry = entries[index]; this.set(entry[0], entry[1]); } } /** * Removes all key-value entries from the hash. * * @private * @name clear * @memberOf Hash */ function hashClear() { this.__data__ = nativeCreate ? nativeCreate(null) : {}; this.size = 0; } /** * Removes `key` and its value from the hash. * * @private * @name delete * @memberOf Hash * @param {Object} hash The hash to modify. * @param {string} key The key of the value to remove. * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function hashDelete(key) { var result = this.has(key) && delete this.__data__[key]; this.size -= result ? 1 : 0; return result; } /** * Gets the hash value for `key`. * * @private * @name get * @memberOf Hash * @param {string} key The key of the value to get. * @returns {*} Returns the entry value. */ function hashGet(key) { var data = this.__data__; if (nativeCreate) { var result = data[key]; return result === HASH_UNDEFINED ? undefined : result; } return hasOwnProperty.call(data, key) ? data[key] : undefined; } /** * Checks if a hash value for `key` exists. * * @private * @name has * @memberOf Hash * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function hashHas(key) { var data = this.__data__; return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key); } /** * Sets the hash `key` to `value`. * * @private * @name set * @memberOf Hash * @param {string} key The key of the value to set. * @param {*} value The value to set. * @returns {Object} Returns the hash instance. */ function hashSet(key, value) { var data = this.__data__; this.size += this.has(key) ? 0 : 1; data[key] = nativeCreate && value === undefined ? HASH_UNDEFINED : value; return this; } Hash.prototype.clear = hashClear; Hash.prototype["delete"] = hashDelete; Hash.prototype.get = hashGet; Hash.prototype.has = hashHas; Hash.prototype.set = hashSet; /** * Creates an list cache object. * * @private * @constructor * @param {Array} [entries] The key-value pairs to cache. */ function ListCache(entries) { var index = -1, length = entries == null ? 0 : entries.length; this.clear(); while (++index < length) { var entry = entries[index]; this.set(entry[0], entry[1]); } } /** * Removes all key-value entries from the list cache. * * @private * @name clear * @memberOf ListCache */ function listCacheClear() { this.__data__ = []; this.size = 0; } /** * Removes `key` and its value from the list cache. * * @private * @name delete * @memberOf ListCache * @param {string} key The key of the value to remove. * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function listCacheDelete(key) { var data = this.__data__, index = assocIndexOf(data, key); if (index < 0) { return false; } var lastIndex = data.length - 1; if (index == lastIndex) { data.pop(); } else { splice.call(data, index, 1); } --this.size; return true; } /** * Gets the list cache value for `key`. * * @private * @name get * @memberOf ListCache * @param {string} key The key of the value to get. * @returns {*} Returns the entry value. */ function listCacheGet(key) { var data = this.__data__, index = assocIndexOf(data, key); return index < 0 ? undefined : data[index][1]; } /** * Checks if a list cache value for `key` exists. * * @private * @name has * @memberOf ListCache * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function listCacheHas(key) { return assocIndexOf(this.__data__, key) > -1; } /** * Sets the list cache `key` to `value`. * * @private * @name set * @memberOf ListCache * @param {string} key The key of the value to set. * @param {*} value The value to set. * @returns {Object} Returns the list cache instance. */ function listCacheSet(key, value) { var data = this.__data__, index = assocIndexOf(data, key); if (index < 0) { ++this.size; data.push([key, value]); } else { data[index][1] = value; } return this; } ListCache.prototype.clear = listCacheClear; ListCache.prototype["delete"] = listCacheDelete; ListCache.prototype.get = listCacheGet; ListCache.prototype.has = listCacheHas; ListCache.prototype.set = listCacheSet; /** * Creates a map cache object to store key-value pairs. * * @private * @constructor * @param {Array} [entries] The key-value pairs to cache. */ function MapCache(entries) { var index = -1, length = entries == null ? 0 : entries.length; this.clear(); while (++index < length) { var entry = entries[index]; this.set(entry[0], entry[1]); } } /** * Removes all key-value entries from the map. * * @private * @name clear * @memberOf MapCache */ function mapCacheClear() { this.size = 0; this.__data__ = { "hash": new Hash(), "map": new (Map || ListCache)(), "string": new Hash() }; } /** * Removes `key` and its value from the map. * * @private * @name delete * @memberOf MapCache * @param {string} key The key of the value to remove. * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function mapCacheDelete(key) { var result = getMapData(this, key)["delete"](key); this.size -= result ? 1 : 0; return result; } /** * Gets the map value for `key`. * * @private * @name get * @memberOf MapCache * @param {string} key The key of the value to get. * @returns {*} Returns the entry value. */ function mapCacheGet(key) { return getMapData(this, key).get(key); } /** * Checks if a map value for `key` exists. * * @private * @name has * @memberOf MapCache * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function mapCacheHas(key) { return getMapData(this, key).has(key); } /** * Sets the map `key` to `value`. * * @private * @name set * @memberOf MapCache * @param {string} key The key of the value to set. * @param {*} value The value to set. * @returns {Object} Returns the map cache instance. */ function mapCacheSet(key, value) { var data = getMapData(this, key), size = data.size; data.set(key, value); this.size += data.size == size ? 0 : 1; return this; } MapCache.prototype.clear = mapCacheClear; MapCache.prototype["delete"] = mapCacheDelete; MapCache.prototype.get = mapCacheGet; MapCache.prototype.has = mapCacheHas; MapCache.prototype.set = mapCacheSet; /** * * Creates an array cache object to store unique values. * * @private * @constructor * @param {Array} [values] The values to cache. */ function SetCache(values) { var index = -1, length = values == null ? 0 : values.length; this.__data__ = new MapCache(); while (++index < length) { this.add(values[index]); } } /** * Adds `value` to the array cache. * * @private * @name add * @memberOf SetCache * @alias push * @param {*} value The value to cache. * @returns {Object} Returns the cache instance. */ function setCacheAdd(value) { this.__data__.set(value, HASH_UNDEFINED); return this; } /** * Checks if `value` is in the array cache. * * @private * @name has * @memberOf SetCache * @param {*} value The value to search for. * @returns {number} Returns `true` if `value` is found, else `false`. */ function setCacheHas(value) { return this.__data__.has(value); } SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; SetCache.prototype.has = setCacheHas; /** * Creates a stack cache object to store key-value pairs. * * @private * @constructor * @param {Array} [entries] The key-value pairs to cache. */ function Stack(entries) { var data = this.__data__ = new ListCache(entries); this.size = data.size; } /** * Removes all key-value entries from the stack. * * @private * @name clear * @memberOf Stack */ function stackClear() { this.__data__ = new ListCache(); this.size = 0; } /** * Removes `key` and its value from the stack. * * @private * @name delete * @memberOf Stack * @param {string} key The key of the value to remove. * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function stackDelete(key) { var data = this.__data__, result = data["delete"](key); this.size = data.size; return result; } /** * Gets the stack value for `key`. * * @private * @name get * @memberOf Stack * @param {string} key The key of the value to get. * @returns {*} Returns the entry value. */ function stackGet(key) { return this.__data__.get(key); } /** * Checks if a stack value for `key` exists. * * @private * @name has * @memberOf Stack * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function stackHas(key) { return this.__data__.has(key); } /** * Sets the stack `key` to `value`. * * @private * @name set * @memberOf Stack * @param {string} key The key of the value to set. * @param {*} value The value to set. * @returns {Object} Returns the stack cache instance. */ function stackSet(key, value) { var data = this.__data__; if (data instanceof ListCache) { var pairs = data.__data__; if (!Map || pairs.length < LARGE_ARRAY_SIZE - 1) { pairs.push([key, value]); this.size = ++data.size; return this; } data = this.__data__ = new MapCache(pairs); } data.set(key, value); this.size = data.size; return this; } Stack.prototype.clear = stackClear; Stack.prototype["delete"] = stackDelete; Stack.prototype.get = stackGet; Stack.prototype.has = stackHas; Stack.prototype.set = stackSet; /** * Creates an array of the enumerable property names of the array-like `value`. * * @private * @param {*} value The value to query. * @param {boolean} inherited Specify returning inherited property names. * @returns {Array} Returns the array of property names. */ function arrayLikeKeys(value, inherited) { var isArr = isArray(value), isArg = !isArr && isArguments(value), isBuff = !isArr && !isArg && isBuffer(value), isType = !isArr && !isArg && !isBuff && isTypedArray(value), skipIndexes = isArr || isArg || isBuff || isType, result = skipIndexes ? baseTimes(value.length, String) : [], length = result.length; for (var key in value) { if ((inherited || hasOwnProperty.call(value, key)) && !(skipIndexes && (key == "length" || isBuff && (key == "offset" || key == "parent") || isType && (key == "buffer" || key == "byteLength" || key == "byteOffset") || isIndex(key, length)))) { result.push(key); } } return result; } /** * A specialized version of `_.sample` for arrays. * * @private * @param {Array} array The array to sample. * @returns {*} Returns the random element. */ function arraySample(array) { var length = array.length; return length ? array[baseRandom(0, length - 1)] : undefined; } /** * A specialized version of `_.sampleSize` for arrays. * * @private * @param {Array} array The array to sample. * @param {number} n The number of elements to sample. * @returns {Array} Returns the random elements. */ function arraySampleSize(array, n) { return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length)); } /** * A specialized version of `_.shuffle` for arrays. * * @private * @param {Array} array The array to shuffle. * @returns {Array} Returns the new shuffled array. */ function arrayShuffle(array) { return shuffleSelf(copyArray(array)); } /** * This function is like `assignValue` except that it doesn't assign * `undefined` values. * * @private * @param {Object} object The object to modify. * @param {string} key The key of the property to assign. * @param {*} value The value to assign. */ function assignMergeValue(object, key, value) { if (value !== undefined && !eq(object[key], value) || value === undefined && !(key in object)) { baseAssignValue(object, key, value); } } /** * Assigns `value` to `key` of `object` if the existing value is not equivalent * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * for equality comparisons. * * @private * @param {Object} object The object to modify. * @param {string} key The key of the property to assign. * @param {*} value The value to assign. */ function assignValue(object, key, value) { var objValue = object[key]; if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || value === undefined && !(key in object)) { baseAssignValue(object, key, value); } } /** * Gets the index at which the `key` is found in `array` of key-value pairs. * * @private * @param {Array} array The array to inspect. * @param {*} key The key to search for. * @returns {number} Returns the index of the matched value, else `-1`. */ function assocIndexOf(array, key) { var length = array.length; while (length--) { if (eq(array[length][0], key)) { return length; } } return -1; } /** * Aggregates elements of `collection` on `accumulator` with keys transformed * by `iteratee` and values set by `setter`. * * @private * @param {Array|Object} collection The collection to iterate over. * @param {Function} setter The function to set `accumulator` values. * @param {Function} iteratee The iteratee to transform keys. * @param {Object} accumulator The initial aggregated object. * @returns {Function} Returns `accumulator`. */ function baseAggregator(collection, setter, iteratee, accumulator) { baseEach(collection, function(value, key, collection) { setter(accumulator, value, iteratee(value), collection); }); return accumulator; } /** * The base implementation of `_.assign` without support for multiple sources * or `customizer` functions. * * @private * @param {Object} object The destination object. * @param {Object} source The source object. * @returns {Object} Returns `object`. */ function baseAssign(object, source) { return object && copyObject(source, keys(source), object); } /** * The base implementation of `_.assignIn` without support for multiple sources * or `customizer` functions. * * @private * @param {Object} object The destination object. * @param {Object} source The source object. * @returns {Object} Returns `object`. */ function baseAssignIn(object, source) { return object && copyObject(source, keysIn(source), object); } /** * The base implementation of `assignValue` and `assignMergeValue` without * value checks. * * @private * @param {Object} object The object to modify. * @param {string} key The key of the property to assign. * @param {*} value The value to assign. */ function baseAssignValue(object, key, value) { if (key == "__proto__" && defineProperty) { defineProperty(object, key, { "configurable": true, "enumerable": true, "value": value, "writable": true }); } else { object[key] = value; } } /** * The base implementation of `_.at` without support for individual paths. * * @private * @param {Object} object The object to iterate over. * @param {string[]} paths The property paths to pick. * @returns {Array} Returns the picked elements. */ function baseAt(object, paths) { var index = -1, length = paths.length, result = Array(length), skip = object == null; while (++index < length) { result[index] = skip ? undefined : get(object, paths[index]); } return result; } /** * The base implementation of `_.clamp` which doesn't coerce arguments. * * @private * @param {number} number The number to clamp. * @param {number} [lower] The lower bound. * @param {number} upper The upper bound. * @returns {number} Returns the clamped number. */ function baseClamp(number, lower, upper) { if (number === number) { if (upper !== undefined) { number = number <= upper ? number : upper; } if (lower !== undefined) { number = number >= lower ? number : lower; } } return number; } /** * The base implementation of `_.clone` and `_.cloneDeep` which tracks * traversed objects. * * @private * @param {*} value The value to clone. * @param {boolean} bitmask The bitmask flags. * 1 - Deep clone * 2 - Flatten inherited properties * 4 - Clone symbols * @param {Function} [customizer] The function to customize cloning. * @param {string} [key] The key of `value`. * @param {Object} [object] The parent object of `value`. * @param {Object} [stack] Tracks traversed objects and their clone counterparts. * @returns {*} Returns the cloned value. */ function baseClone(value, bitmask, customizer, key, object, stack) { var result, isDeep = bitmask & CLONE_DEEP_FLAG, isFlat = bitmask & CLONE_FLAT_FLAG, isFull = bitmask & CLONE_SYMBOLS_FLAG; if (customizer) { result = object ? customizer(value, key, object, stack) : customizer(value); } if (result !== undefined) { return result; } if (!isObject(value)) { return value; } var isArr = isArray(value); if (isArr) { result = initCloneArray(value); if (!isDeep) { return copyArray(value, result); } } else { var tag = getTag(value), isFunc = tag == funcTag || tag == genTag; if (isBuffer(value)) { return cloneBuffer(value, isDeep); } if (tag == objectTag || tag == argsTag || isFunc && !object) { result = isFlat || isFunc ? {} : initCloneObject(value); if (!isDeep) { return isFlat ? copySymbolsIn(value, baseAssignIn(result, value)) : copySymbols(value, baseAssign(result, value)); } } else { if (!cloneableTags[tag]) { return object ? value : {}; } result = initCloneByTag(value, tag, isDeep); } } stack || (stack = new Stack()); var stacked = stack.get(value); if (stacked) { return stacked; } stack.set(value, result); if (isSet(value)) { value.forEach(function(subValue) { result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); }); } else if (isMap(value)) { value.forEach(function(subValue, key) { result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); }); } var keysFunc = isFull ? isFlat ? getAllKeysIn : getAllKeys : isFlat ? keysIn : keys; var props = isArr ? undefined : keysFunc(value); arrayEach(props || value, function(subValue, key) { if (props) { key = subValue; subValue = value[key]; } assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); }); return result; } /** * The base implementation of `_.conforms` which doesn't clone `source`. * * @private * @param {Object} source The object of property predicates to conform to. * @returns {Function} Returns the new spec function. */ function baseConforms(source) { var props = keys(source); return function(object) { return baseConformsTo(object, source, props); }; } /** * The base implementation of `_.conformsTo` which accepts `props` to check. * * @private * @param {Object} object The object to inspect. * @param {Object} source The object of property predicates to conform to. * @returns {boolean} Returns `true` if `object` conforms, else `false`. */ function baseConformsTo(object, source, props) { var length = props.length; if (object == null) { return !length; } object = Object(object); while (length--) { var key = props[length], predicate = source[key], value = object[key]; if (value === undefined && !(key in object) || !predicate(value)) { return false; } } return true; } /** * The base implementation of `_.delay` and `_.defer` which accepts `args` * to provide to `func`. * * @private * @param {Function} func The function to delay. * @param {number} wait The number of milliseconds to delay invocation. * @param {Array} args The arguments to provide to `func`. * @returns {number|Object} Returns the timer id or timeout object. */ function baseDelay(func, wait, args) { if (typeof func != "function") { throw new TypeError(FUNC_ERROR_TEXT); } return setTimeout(function() { func.apply(undefined, args); }, wait); } /** * The base implementation of methods like `_.difference` without support * for excluding multiple arrays or iteratee shorthands. * * @private * @param {Array} array The array to inspect. * @param {Array} values The values to exclude. * @param {Function} [iteratee] The iteratee invoked per element. * @param {Function} [comparator] The comparator invoked per element. * @returns {Array} Returns the new array of filtered values. */ function baseDifference(array, values, iteratee, comparator) { var index = -1, includes = arrayIncludes, isCommon = true, length = array.length, result = [], valuesLength = values.length; if (!length) { return result; } if (iteratee) { values = arrayMap(values, baseUnary(iteratee)); } if (comparator) { includes = arrayIncludesWith; isCommon = false; } else if (values.length >= LARGE_ARRAY_SIZE) { includes = cacheHas; isCommon = false; values = new SetCache(values); } outer: while (++index < length) { var value = array[index], computed = iteratee == null ? value : iteratee(value); value = comparator || value !== 0 ? value : 0; if (isCommon && computed === computed) { var valuesIndex = valuesLength; while (valuesIndex--) { if (values[valuesIndex] === computed) { continue outer; } } result.push(value); } else if (!includes(values, computed, comparator)) { result.push(value); } } return result; } /** * The base implementation of `_.forEach` without support for iteratee shorthands. * * @private * @param {Array|Object} collection The collection to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array|Object} Returns `collection`. */ var baseEach = createBaseEach(baseForOwn); /** * The base implementation of `_.forEachRight` without support for iteratee shorthands. * * @private * @param {Array|Object} collection The collection to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array|Object} Returns `collection`. */ var baseEachRight = createBaseEach(baseForOwnRight, true); /** * The base implementation of `_.every` without support for iteratee shorthands. * * @private * @param {Array|Object} collection The collection to iterate over. * @param {Function} predicate The function invoked per iteration. * @returns {boolean} Returns `true` if all elements pass the predicate check, * else `false` */ function baseEvery(collection, predicate) { var result = true; baseEach(collection, function(value, index, collection) { result = !!predicate(value, index, collection); return result; }); return result; } /** * The base implementation of methods like `_.max` and `_.min` which accepts a * `comparator` to determine the extremum value. * * @private * @param {Array} array The array to iterate over. * @param {Function} iteratee The iteratee invoked per iteration. * @param {Function} comparator The comparator used to compare values. * @returns {*} Returns the extremum value. */ function baseExtremum(array, iteratee, comparator) { var index = -1, length = array.length; while (++index < length) { var value = array[index], current = iteratee(value); if (current != null && (computed === undefined ? current === current && !isSymbol(current) : comparator(current, computed))) { var computed = current, result = value; } } return result; } /** * The base implementation of `_.fill` without an iteratee call guard. * * @private * @param {Array} array The array to fill. * @param {*} value The value to fill `array` with. * @param {number} [start=0] The start position. * @param {number} [end=array.length] The end position. * @returns {Array} Returns `array`. */ function baseFill(array, value, start, end) { var length = array.length; start = toInteger(start); if (start < 0) { start = -start > length ? 0 : length + start; } end = end === undefined || end > length ? length : toInteger(end); if (end < 0) { end += length; } end = start > end ? 0 : toLength(end); while (start < end) { array[start++] = value; } return array; } /** * The base implementation of `_.filter` without support for iteratee shorthands. * * @private * @param {Array|Object} collection The collection to iterate over. * @param {Function} predicate The function invoked per iteration. * @returns {Array} Returns the new filtered array. */ function baseFilter(collection, predicate) { var result = []; baseEach(collection, function(value, index, collection) { if (predicate(value, index, collection)) { result.push(value); } }); return result; } /** * The base implementation of `_.flatten` with support for restricting flattening. * * @private * @param {Array} array The array to flatten. * @param {number} depth The maximum recursion depth. * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. * @param {Array} [result=[]] The initial result value. * @returns {Array} Returns the new flattened array. */ function baseFlatten(array, depth, predicate, isStrict, result) { var index = -1, length = array.length; predicate || (predicate = isFlattenable); result || (result = []); while (++index < length) { var value = array[index]; if (depth > 0 && predicate(value)) { if (depth > 1) { baseFlatten(value, depth - 1, predicate, isStrict, result); } else { arrayPush(result, value); } } else if (!isStrict) { result[result.length] = value; } } return result; } /** * The base implementation of `baseForOwn` which iterates over `object` * properties returned by `keysFunc` and invokes `iteratee` for each property. * Iteratee functions may exit iteration early by explicitly returning `false`. * * @private * @param {Object} object The object to iterate over. * @param {Function} iteratee The function invoked per iteration. * @param {Function} keysFunc The function to get the keys of `object`. * @returns {Object} Returns `object`. */ var baseFor = createBaseFor(); /** * This function is like `baseFor` except that it iterates over properties * in the opposite order. * * @private * @param {Object} object The object to iterate over. * @param {Function} iteratee The function invoked per iteration. * @param {Function} keysFunc The function to get the keys of `object`. * @returns {Object} Returns `object`. */ var baseForRight = createBaseFor(true); /** * The base implementation of `_.forOwn` without support for iteratee shorthands. * * @private * @param {Object} object The object to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Object} Returns `object`. */ function baseForOwn(object, iteratee) { return object && baseFor(object, iteratee, keys); } /** * The base implementation of `_.forOwnRight` without support for iteratee shorthands. * * @private * @param {Object} object The object to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Object} Returns `object`. */ function baseForOwnRight(object, iteratee) { return object && baseForRight(object, iteratee, keys); } /** * The base implementation of `_.functions` which creates an array of * `object` function property names filtered from `props`. * * @private * @param {Object} object The object to inspect. * @param {Array} props The property names to filter. * @returns {Array} Returns the function names. */ function baseFunctions(object, props) { return arrayFilter(props, function(key) { return isFunction(object[key]); }); } /** * The base implementation of `_.get` without support for default values. * * @private * @param {Object} object The object to query. * @param {Array|string} path The path of the property to get. * @returns {*} Returns the resolved value. */ function baseGet(object, path) { path = castPath(path, object); var index = 0, length = path.length; while (object != null && index < length) { object = object[toKey(path[index++])]; } return index && index == length ? object : undefined; } /** * The base implementation of `getAllKeys` and `getAllKeysIn` which uses * `keysFunc` and `symbolsFunc` to get the enumerable property names and * symbols of `object`. * * @private * @param {Object} object The object to query. * @param {Function} keysFunc The function to get the keys of `object`. * @param {Function} symbolsFunc The function to get the symbols of `object`. * @returns {Array} Returns the array of property names and symbols. */ function baseGetAllKeys(object, keysFunc, symbolsFunc) { var result = keysFunc(object); return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); } /** * The base implementation of `getTag` without fallbacks for buggy environments. * * @private * @param {*} value The value to query. * @returns {string} Returns the `toStringTag`. */ function baseGetTag(value) { if (value == null) { return value === undefined ? undefinedTag : nullTag; } return symToStringTag && symToStringTag in Object(value) ? getRawTag(value) : objectToString(value); } /** * The base implementation of `_.gt` which doesn't coerce arguments. * * @private * @param {*} value The value to compare. * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if `value` is greater than `other`, * else `false`. */ function baseGt(value, other) { return value > other; } /** * The base implementation of `_.has` without support for deep paths. * * @private * @param {Object} [object] The object to query. * @param {Array|string} key The key to check. * @returns {boolean} Returns `true` if `key` exists, else `false`. */ function baseHas(object, key) { return object != null && hasOwnProperty.call(object, key); } /** * The base implementation of `_.hasIn` without support for deep paths. * * @private * @param {Object} [object] The object to query. * @param {Array|string} key The key to check. * @returns {boolean} Returns `true` if `key` exists, else `false`. */ function baseHasIn(object, key) { return object != null && key in Object(object); } /** * The base implementation of `_.inRange` which doesn't coerce arguments. * * @private * @param {number} number The number to check. * @param {number} start The start of the range. * @param {number} end The end of the range. * @returns {boolean} Returns `true` if `number` is in the range, else `false`. */ function baseInRange(number, start, end) { return number >= nativeMin(start, end) && number < nativeMax(start, end); } /** * The base implementation of methods like `_.intersection`, without support * for iteratee shorthands, that accepts an array of arrays to inspect. * * @private * @param {Array} arrays The arrays to inspect. * @param {Function} [iteratee] The iteratee invoked per element. * @param {Function} [comparator] The comparator invoked per element. * @returns {Array} Returns the new array of shared values. */ function baseIntersection(arrays, iteratee, comparator) { var includes = comparator ? arrayIncludesWith : arrayIncludes, length = arrays[0].length, othLength = arrays.length, othIndex = othLength, caches = Array(othLength), maxLength = Infinity, result = []; while (othIndex--) { var array = arrays[othIndex]; if (othIndex && iteratee) { array = arrayMap(array, baseUnary(iteratee)); } maxLength = nativeMin(array.length, maxLength); caches[othIndex] = !comparator && (iteratee || length >= 120 && array.length >= 120) ? new SetCache(othIndex && array) : undefined; } array = arrays[0]; var index = -1, seen = caches[0]; outer: while (++index < length && result.length < maxLength) { var value = array[index], computed = iteratee ? iteratee(value) : value; value = comparator || value !== 0 ? value : 0; if (!(seen ? cacheHas(seen, computed) : includes(result, computed, comparator))) { othIndex = othLength; while (--othIndex) { var cache = caches[othIndex]; if (!(cache ? cacheHas(cache, computed) : includes(arrays[othIndex], computed, comparator))) { continue outer; } } if (seen) { seen.push(computed); } result.push(value); } } return result; } /** * The base implementation of `_.invert` and `_.invertBy` which inverts * `object` with values transformed by `iteratee` and set by `setter`. * * @private * @param {Object} object The object to iterate over. * @param {Function} setter The function to set `accumulator` values. * @param {Function} iteratee The iteratee to transform values. * @param {Object} accumulator The initial inverted object. * @returns {Function} Returns `accumulator`. */ function baseInverter(object, setter, iteratee, accumulator) { baseForOwn(object, function(value, key, object) { setter(accumulator, iteratee(value), key, object); }); return accumulator; } /** * The base implementation of `_.invoke` without support for individual * method arguments. * * @private * @param {Object} object The object to query. * @param {Array|string} path The path of the method to invoke. * @param {Array} args The arguments to invoke the method with. * @returns {*} Returns the result of the invoked method. */ function baseInvoke(object, path, args) { path = castPath(path, object); object = parent(object, path); var func = object == null ? object : object[toKey(last(path))]; return func == null ? undefined : apply(func, object, args); } /** * The base implementation of `_.isArguments`. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an `arguments` object, */ function baseIsArguments(value) { return isObjectLike(value) && baseGetTag(value) == argsTag; } /** * The base implementation of `_.isArrayBuffer` without Node.js optimizations. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`. */ function baseIsArrayBuffer(value) { return isObjectLike(value) && baseGetTag(value) == arrayBufferTag; } /** * The base implementation of `_.isDate` without Node.js optimizations. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a date object, else `false`. */ function baseIsDate(value) { return isObjectLike(value) && baseGetTag(value) == dateTag; } /** * The base implementation of `_.isEqual` which supports partial comparisons * and tracks traversed objects. * * @private * @param {*} value The value to compare. * @param {*} other The other value to compare. * @param {boolean} bitmask The bitmask flags. * 1 - Unordered comparison * 2 - Partial comparison * @param {Function} [customizer] The function to customize comparisons. * @param {Object} [stack] Tracks traversed `value` and `other` objects. * @returns {boolean} Returns `true` if the values are equivalent, else `false`. */ function baseIsEqual(value, other, bitmask, customizer, stack) { if (value === other) { return true; } if (value == null || other == null || !isObjectLike(value) && !isObjectLike(other)) { return value !== value && other !== other; } return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); } /** * A specialized version of `baseIsEqual` for arrays and objects which performs * deep comparisons and tracks traversed objects enabling objects with circular * references to be compared. * * @private * @param {Object} object The object to compare. * @param {Object} other The other object to compare. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. * @param {Function} customizer The function to customize comparisons. * @param {Function} equalFunc The function to determine equivalents of values. * @param {Object} [stack] Tracks traversed `object` and `other` objects. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. */ function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { var objIsArr = isArray(object), othIsArr = isArray(other), objTag = objIsArr ? arrayTag : getTag(object), othTag = othIsArr ? arrayTag : getTag(other); objTag = objTag == argsTag ? objectTag : objTag; othTag = othTag == argsTag ? objectTag : othTag; var objIsObj = objTag == objectTag, othIsObj = othTag == objectTag, isSameTag = objTag == othTag; if (isSameTag && isBuffer(object)) { if (!isBuffer(other)) { return false; } objIsArr = true; objIsObj = false; } if (isSameTag && !objIsObj) { stack || (stack = new Stack()); return objIsArr || isTypedArray(object) ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); } if (!(bitmask & COMPARE_PARTIAL_FLAG)) { var objIsWrapped = objIsObj && hasOwnProperty.call(object, "__wrapped__"), othIsWrapped = othIsObj && hasOwnProperty.call(other, "__wrapped__"); if (objIsWrapped || othIsWrapped) { var objUnwrapped = objIsWrapped ? object.value() : object, othUnwrapped = othIsWrapped ? other.value() : other; stack || (stack = new Stack()); return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); } } if (!isSameTag) { return false; } stack || (stack = new Stack()); return equalObjects(object, other, bitmask, customizer, equalFunc, stack); } /** * The base implementation of `_.isMap` without Node.js optimizations. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a map, else `false`. */ function baseIsMap(value) { return isObjectLike(value) && getTag(value) == mapTag; } /** * The base implementation of `_.isMatch` without support for iteratee shorthands. * * @private * @param {Object} object The object to inspect. * @param {Object} source The object of property values to match. * @param {Array} matchData The property names, values, and compare flags to match. * @param {Function} [customizer] The function to customize comparisons. * @returns {boolean} Returns `true` if `object` is a match, else `false`. */ function baseIsMatch(object, source, matchData, customizer) { var index = matchData.length, length = index, noCustomizer = !customizer; if (object == null) { return !length; } object = Object(object); while (index--) { var data = matchData[index]; if (noCustomizer && data[2] ? data[1] !== object[data[0]] : !(data[0] in object)) { return false; } } while (++index < length) { data = matchData[index]; var key = data[0], objValue = object[key], srcValue = data[1]; if (noCustomizer && data[2]) { if (objValue === undefined && !(key in object)) { return false; } } else { var stack = new Stack(); if (customizer) { var result = customizer(objValue, srcValue, key, object, source, stack); } if (!(result === undefined ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack) : result)) { return false; } } } return true; } /** * The base implementation of `_.isNative` without bad shim checks. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a native function, * else `false`. */ function baseIsNative(value) { if (!isObject(value) || isMasked(value)) { return false; } var pattern = isFunction(value) ? reIsNative : reIsHostCtor; return pattern.test(toSource(value)); } /** * The base implementation of `_.isRegExp` without Node.js optimizations. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. */ function baseIsRegExp(value) { return isObjectLike(value) && baseGetTag(value) == regexpTag; } /** * The base implementation of `_.isSet` without Node.js optimizations. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a set, else `false`. */ function baseIsSet(value) { return isObjectLike(value) && getTag(value) == setTag; } /** * The base implementation of `_.isTypedArray` without Node.js optimizations. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. */ function baseIsTypedArray(value) { return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; } /** * The base implementation of `_.iteratee`. * * @private * @param {*} [value=_.identity] The value to convert to an iteratee. * @returns {Function} Returns the iteratee. */ function baseIteratee(value) { if (typeof value == "function") { return value; } if (value == null) { return identity; } if (typeof value == "object") { return isArray(value) ? baseMatchesProperty(value[0], value[1]) : baseMatches(value); } return property(value); } /** * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. */ function baseKeys(object) { if (!isPrototype(object)) { return nativeKeys(object); } var result = []; for (var key in Object(object)) { if (hasOwnProperty.call(object, key) && key != "constructor") { result.push(key); } } return result; } /** * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. */ function baseKeysIn(object) { if (!isObject(object)) { return nativeKeysIn(object); } var isProto = isPrototype(object), result = []; for (var key in object) { if (!(key == "constructor" && (isProto || !hasOwnProperty.call(object, key)))) { result.push(key); } } return result; } /** * The base implementation of `_.lt` which doesn't coerce arguments. * * @private * @param {*} value The value to compare. * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if `value` is less than `other`, * else `false`. */ function baseLt(value, other) { return value < other; } /** * The base implementation of `_.map` without support for iteratee shorthands. * * @private * @param {Array|Object} collection The collection to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns the new mapped array. */ function baseMap(collection, iteratee) { var index = -1, result = isArrayLike(collection) ? Array(collection.length) : []; baseEach(collection, function(value, key, collection) { result[++index] = iteratee(value, key, collection); }); return result; } /** * The base implementation of `_.matches` which doesn't clone `source`. * * @private * @param {Object} source The object of property values to match. * @returns {Function} Returns the new spec function. */ function baseMatches(source) { var matchData = getMatchData(source); if (matchData.length == 1 && matchData[0][2]) { return matchesStrictComparable(matchData[0][0], matchData[0][1]); } return function(object) { return object === source || baseIsMatch(object, source, matchData); }; } /** * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. * * @private * @param {string} path The path of the property to get. * @param {*} srcValue The value to match. * @returns {Function} Returns the new spec function. */ function baseMatchesProperty(path, srcValue) { if (isKey(path) && isStrictComparable(srcValue)) { return matchesStrictComparable(toKey(path), srcValue); } return function(object) { var objValue = get(object, path); return objValue === undefined && objValue === srcValue ? hasIn(object, path) : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG); }; } /** * The base implementation of `_.merge` without support for multiple sources. * * @private * @param {Object} object The destination object. * @param {Object} source The source object. * @param {number} srcIndex The index of `source`. * @param {Function} [customizer] The function to customize merged values. * @param {Object} [stack] Tracks traversed source values and their merged * counterparts. */ function baseMerge(object, source, srcIndex, customizer, stack) { if (object === source) { return; } baseFor(source, function(srcValue, key) { stack || (stack = new Stack()); if (isObject(srcValue)) { baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); } else { var newValue = customizer ? customizer(safeGet(object, key), srcValue, key + "", object, source, stack) : undefined; if (newValue === undefined) { newValue = srcValue; } assignMergeValue(object, key, newValue); } }, keysIn); } /** * A specialized version of `baseMerge` for arrays and objects which performs * deep merges and tracks traversed objects enabling objects with circular * references to be merged. * * @private * @param {Object} object The destination object. * @param {Object} source The source object. * @param {string} key The key of the value to merge. * @param {number} srcIndex The index of `source`. * @param {Function} mergeFunc The function to merge values. * @param {Function} [customizer] The function to customize assigned values. * @param {Object} [stack] Tracks traversed source values and their merged * counterparts. */ function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { var objValue = safeGet(object, key), srcValue = safeGet(source, key), stacked = stack.get(srcValue); if (stacked) { assignMergeValue(object, key, stacked); return; } var newValue = customizer ? customizer(objValue, srcValue, key + "", object, source, stack) : undefined; var isCommon = newValue === undefined; if (isCommon) { var isArr = isArray(srcValue), isBuff = !isArr && isBuffer(srcValue), isTyped = !isArr && !isBuff && isTypedArray(srcValue); newValue = srcValue; if (isArr || isBuff || isTyped) { if (isArray(objValue)) { newValue = objValue; } else if (isArrayLikeObject(objValue)) { newValue = copyArray(objValue); } else if (isBuff) { isCommon = false; newValue = cloneBuffer(srcValue, true); } else if (isTyped) { isCommon = false; newValue = cloneTypedArray(srcValue, true); } else { newValue = []; } } else if (isPlainObject(srcValue) || isArguments(srcValue)) { newValue = objValue; if (isArguments(objValue)) { newValue = toPlainObject(objValue); } else if (!isObject(objValue) || isFunction(objValue)) { newValue = initCloneObject(srcValue); } } else { isCommon = false; } } if (isCommon) { stack.set(srcValue, newValue); mergeFunc(newValue, srcValue, srcIndex, customizer, stack); stack["delete"](srcValue); } assignMergeValue(object, key, newValue); } /** * The base implementation of `_.nth` which doesn't coerce arguments. * * @private * @param {Array} array The array to query. * @param {number} n The index of the element to return. * @returns {*} Returns the nth element of `array`. */ function baseNth(array, n) { var length = array.length; if (!length) { return; } n += n < 0 ? length : 0; return isIndex(n, length) ? array[n] : undefined; } /** * The base implementation of `_.orderBy` without param guards. * * @private * @param {Array|Object} collection The collection to iterate over. * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. * @param {string[]} orders The sort orders of `iteratees`. * @returns {Array} Returns the new sorted array. */ function baseOrderBy(collection, iteratees, orders) { if (iteratees.length) { iteratees = arrayMap(iteratees, function(iteratee) { if (isArray(iteratee)) { return function(value) { return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee); }; } return iteratee; }); } else { iteratees = [identity]; } var index = -1; iteratees = arrayMap(iteratees, baseUnary(getIteratee())); var result = baseMap(collection, function(value, key, collection) { var criteria = arrayMap(iteratees, function(iteratee) { return iteratee(value); }); return { "criteria": criteria, "index": ++index, "value": value }; }); return baseSortBy(result, function(object, other) { return compareMultiple(object, other, orders); }); } /** * The base implementation of `_.pick` without support for individual * property identifiers. * * @private * @param {Object} object The source object. * @param {string[]} paths The property paths to pick. * @returns {Object} Returns the new object. */ function basePick(object, paths) { return basePickBy(object, paths, function(value, path) { return hasIn(object, path); }); } /** * The base implementation of `_.pickBy` without support for iteratee shorthands. * * @private * @param {Object} object The source object. * @param {string[]} paths The property paths to pick. * @param {Function} predicate The function invoked per property. * @returns {Object} Returns the new object. */ function basePickBy(object, paths, predicate) { var index = -1, length = paths.length, result = {}; while (++index < length) { var path = paths[index], value = baseGet(object, path); if (predicate(value, path)) { baseSet(result, castPath(path, object), value); } } return result; } /** * A specialized version of `baseProperty` which supports deep paths. * * @private * @param {Array|string} path The path of the property to get. * @returns {Function} Returns the new accessor function. */ function basePropertyDeep(path) { return function(object) { return baseGet(object, path); }; } /** * The base implementation of `_.pullAllBy` without support for iteratee * shorthands. * * @private * @param {Array} array The array to modify. * @param {Array} values The values to remove. * @param {Function} [iteratee] The iteratee invoked per element. * @param {Function} [comparator] The comparator invoked per element. * @returns {Array} Returns `array`. */ function basePullAll(array, values, iteratee, comparator) { var indexOf = comparator ? baseIndexOfWith : baseIndexOf, index = -1, length = values.length, seen = array; if (array === values) { values = copyArray(values); } if (iteratee) { seen = arrayMap(array, baseUnary(iteratee)); } while (++index < length) { var fromIndex = 0, value = values[index], computed = iteratee ? iteratee(value) : value; while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) { if (seen !== array) { splice.call(seen, fromIndex, 1); } splice.call(array, fromIndex, 1); } } return array; } /** * The base implementation of `_.pullAt` without support for individual * indexes or capturing the removed elements. * * @private * @param {Array} array The array to modify. * @param {number[]} indexes The indexes of elements to remove. * @returns {Array} Returns `array`. */ function basePullAt(array, indexes) { var length = array ? indexes.length : 0, lastIndex = length - 1; while (length--) { var index = indexes[length]; if (length == lastIndex || index !== previous) { var previous = index; if (isIndex(index)) { splice.call(array, index, 1); } else { baseUnset(array, index); } } } return array; } /** * The base implementation of `_.random` without support for returning * floating-point numbers. * * @private * @param {number} lower The lower bound. * @param {number} upper The upper bound. * @returns {number} Returns the random number. */ function baseRandom(lower, upper) { return lower + nativeFloor(nativeRandom() * (upper - lower + 1)); } /** * The base implementation of `_.range` and `_.rangeRight` which doesn't * coerce arguments. * * @private * @param {number} start The start of the range. * @param {number} end The end of the range. * @param {number} step The value to increment or decrement by. * @param {boolean} [fromRight] Specify iterating from right to left. * @returns {Array} Returns the range of numbers. */ function baseRange(start, end, step, fromRight) { var index = -1, length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), result = Array(length); while (length--) { result[fromRight ? length : ++index] = start; start += step; } return result; } /** * The base implementation of `_.repeat` which doesn't coerce arguments. * * @private * @param {string} string The string to repeat. * @param {number} n The number of times to repeat the string. * @returns {string} Returns the repeated string. */ function baseRepeat(string, n) { var result = ""; if (!string || n < 1 || n > MAX_SAFE_INTEGER) { return result; } do { if (n % 2) { result += string; } n = nativeFloor(n / 2); if (n) { string += string; } } while (n); return result; } /** * The base implementation of `_.rest` which doesn't validate or coerce arguments. * * @private * @param {Function} func The function to apply a rest parameter to. * @param {number} [start=func.length-1] The start position of the rest parameter. * @returns {Function} Returns the new function. */ function baseRest(func, start) { return setToString(overRest(func, start, identity), func + ""); } /** * The base implementation of `_.sample`. * * @private * @param {Array|Object} collection The collection to sample. * @returns {*} Returns the random element. */ function baseSample(collection) { return arraySample(values(collection)); } /** * The base implementation of `_.sampleSize` without param guards. * * @private * @param {Array|Object} collection The collection to sample. * @param {number} n The number of elements to sample. * @returns {Array} Returns the random elements. */ function baseSampleSize(collection, n) { var array = values(collection); return shuffleSelf(array, baseClamp(n, 0, array.length)); } /** * The base implementation of `_.set`. * * @private * @param {Object} object The object to modify. * @param {Array|string} path The path of the property to set. * @param {*} value The value to set. * @param {Function} [customizer] The function to customize path creation. * @returns {Object} Returns `object`. */ function baseSet(object, path, value, customizer) { if (!isObject(object)) { return object; } path = castPath(path, object); var index = -1, length = path.length, lastIndex = length - 1, nested = object; while (nested != null && ++index < length) { var key = toKey(path[index]), newValue = value; if (key === "__proto__" || key === "constructor" || key === "prototype") { return object; } if (index != lastIndex) { var objValue = nested[key]; newValue = customizer ? customizer(objValue, key, nested) : undefined; if (newValue === undefined) { newValue = isObject(objValue) ? objValue : isIndex(path[index + 1]) ? [] : {}; } } assignValue(nested, key, newValue); nested = nested[key]; } return object; } /** * The base implementation of `setData` without support for hot loop shorting. * * @private * @param {Function} func The function to associate metadata with. * @param {*} data The metadata. * @returns {Function} Returns `func`. */ var baseSetData = !metaMap ? identity : function(func, data) { metaMap.set(func, data); return func; }; /** * The base implementation of `setToString` without support for hot loop shorting. * * @private * @param {Function} func The function to modify. * @param {Function} string The `toString` result. * @returns {Function} Returns `func`. */ var baseSetToString = !defineProperty ? identity : function(func, string) { return defineProperty(func, "toString", { "configurable": true, "enumerable": false, "value": constant(string), "writable": true }); }; /** * The base implementation of `_.shuffle`. * * @private * @param {Array|Object} collection The collection to shuffle. * @returns {Array} Returns the new shuffled array. */ function baseShuffle(collection) { return shuffleSelf(values(collection)); } /** * The base implementation of `_.slice` without an iteratee call guard. * * @private * @param {Array} array The array to slice. * @param {number} [start=0] The start position. * @param {number} [end=array.length] The end position. * @returns {Array} Returns the slice of `array`. */ function baseSlice(array, start, end) { var index = -1, length = array.length; if (start < 0) { start = -start > length ? 0 : length + start; } end = end > length ? length : end; if (end < 0) { end += length; } length = start > end ? 0 : end - start >>> 0; start >>>= 0; var result = Array(length); while (++index < length) { result[index] = array[index + start]; } return result; } /** * The base implementation of `_.some` without support for iteratee shorthands. * * @private * @param {Array|Object} collection The collection to iterate over. * @param {Function} predicate The function invoked per iteration. * @returns {boolean} Returns `true` if any element passes the predicate check, * else `false`. */ function baseSome(collection, predicate) { var result; baseEach(collection, function(value, index, collection) { result = predicate(value, index, collection); return !result; }); return !!result; } /** * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which * performs a binary search of `array` to determine the index at which `value` * should be inserted into `array` in order to maintain its sort order. * * @private * @param {Array} array The sorted array to inspect. * @param {*} value The value to evaluate. * @param {boolean} [retHighest] Specify returning the highest qualified index. * @returns {number} Returns the index at which `value` should be inserted * into `array`. */ function baseSortedIndex(array, value, retHighest) { var low = 0, high = array == null ? low : array.length; if (typeof value == "number" && value === value && high <= HALF_MAX_ARRAY_LENGTH) { while (low < high) { var mid = low + high >>> 1, computed = array[mid]; if (computed !== null && !isSymbol(computed) && (retHighest ? computed <= value : computed < value)) { low = mid + 1; } else { high = mid; } } return high; } return baseSortedIndexBy(array, value, identity, retHighest); } /** * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy` * which invokes `iteratee` for `value` and each element of `array` to compute * their sort ranking. The iteratee is invoked with one argument; (value). * * @private * @param {Array} array The sorted array to inspect. * @param {*} value The value to evaluate. * @param {Function} iteratee The iteratee invoked per element. * @param {boolean} [retHighest] Specify returning the highest qualified index. * @returns {number} Returns the index at which `value` should be inserted * into `array`. */ function baseSortedIndexBy(array, value, iteratee, retHighest) { var low = 0, high = array == null ? 0 : array.length; if (high === 0) { return 0; } value = iteratee(value); var valIsNaN = value !== value, valIsNull = value === null, valIsSymbol = isSymbol(value), valIsUndefined = value === undefined; while (low < high) { var mid = nativeFloor((low + high) / 2), computed = iteratee(array[mid]), othIsDefined = computed !== undefined, othIsNull = computed === null, othIsReflexive = computed === computed, othIsSymbol = isSymbol(computed); if (valIsNaN) { var setLow = retHighest || othIsReflexive; } else if (valIsUndefined) { setLow = othIsReflexive && (retHighest || othIsDefined); } else if (valIsNull) { setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull); } else if (valIsSymbol) { setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol); } else if (othIsNull || othIsSymbol) { setLow = false; } else { setLow = retHighest ? computed <= value : computed < value; } if (setLow) { low = mid + 1; } else { high = mid; } } return nativeMin(high, MAX_ARRAY_INDEX); } /** * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without * support for iteratee shorthands. * * @private * @param {Array} array The array to inspect. * @param {Function} [iteratee] The iteratee invoked per element. * @returns {Array} Returns the new duplicate free array. */ function baseSortedUniq(array, iteratee) { var index = -1, length = array.length, resIndex = 0, result = []; while (++index < length) { var value = array[index], computed = iteratee ? iteratee(value) : value; if (!index || !eq(computed, seen)) { var seen = computed; result[resIndex++] = value === 0 ? 0 : value; } } return result; } /** * The base implementation of `_.toNumber` which doesn't ensure correct * conversions of binary, hexadecimal, or octal string values. * * @private * @param {*} value The value to process. * @returns {number} Returns the number. */ function baseToNumber(value) { if (typeof value == "number") { return value; } if (isSymbol(value)) { return NAN; } return +value; } /** * The base implementation of `_.toString` which doesn't convert nullish * values to empty strings. * * @private * @param {*} value The value to process. * @returns {string} Returns the string. */ function baseToString(value) { if (typeof value == "string") { return value; } if (isArray(value)) { return arrayMap(value, baseToString) + ""; } if (isSymbol(value)) { return symbolToString ? symbolToString.call(value) : ""; } var result = value + ""; return result == "0" && 1 / value == -INFINITY ? "-0" : result; } /** * The base implementation of `_.uniqBy` without support for iteratee shorthands. * * @private * @param {Array} array The array to inspect. * @param {Function} [iteratee] The iteratee invoked per element. * @param {Function} [comparator] The comparator invoked per element. * @returns {Array} Returns the new duplicate free array. */ function baseUniq(array, iteratee, comparator) { var index = -1, includes = arrayIncludes, length = array.length, isCommon = true, result = [], seen = result; if (comparator) { isCommon = false; includes = arrayIncludesWith; } else if (length >= LARGE_ARRAY_SIZE) { var set = iteratee ? null : createSet(array); if (set) { return setToArray(set); } isCommon = false; includes = cacheHas; seen = new SetCache(); } else { seen = iteratee ? [] : result; } outer: while (++index < length) { var value = array[index], computed = iteratee ? iteratee(value) : value; value = comparator || value !== 0 ? value : 0; if (isCommon && computed === computed) { var seenIndex = seen.length; while (seenIndex--) { if (seen[seenIndex] === computed) { continue outer; } } if (iteratee) { seen.push(computed); } result.push(value); } else if (!includes(seen, computed, comparator)) { if (seen !== result) { seen.push(computed); } result.push(value); } } return result; } /** * The base implementation of `_.unset`. * * @private * @param {Object} object The object to modify. * @param {Array|string} path The property path to unset. * @returns {boolean} Returns `true` if the property is deleted, else `false`. */ function baseUnset(object, path) { path = castPath(path, object); object = parent(object, path); return object == null || delete object[toKey(last(path))]; } /** * The base implementation of `_.update`. * * @private * @param {Object} object The object to modify. * @param {Array|string} path The path of the property to update. * @param {Function} updater The function to produce the updated value. * @param {Function} [customizer] The function to customize path creation. * @returns {Object} Returns `object`. */ function baseUpdate(object, path, updater, customizer) { return baseSet(object, path, updater(baseGet(object, path)), customizer); } /** * The base implementation of methods like `_.dropWhile` and `_.takeWhile` * without support for iteratee shorthands. * * @private * @param {Array} array The array to query. * @param {Function} predicate The function invoked per iteration. * @param {boolean} [isDrop] Specify dropping elements instead of taking them. * @param {boolean} [fromRight] Specify iterating from right to left. * @returns {Array} Returns the slice of `array`. */ function baseWhile(array, predicate, isDrop, fromRight) { var length = array.length, index = fromRight ? length : -1; while ((fromRight ? index-- : ++index < length) && predicate(array[index], index, array)) {} return isDrop ? baseSlice(array, fromRight ? 0 : index, fromRight ? index + 1 : length) : baseSlice(array, fromRight ? index + 1 : 0, fromRight ? length : index); } /** * The base implementation of `wrapperValue` which returns the result of * performing a sequence of actions on the unwrapped `value`, where each * successive action is supplied the return value of the previous. * * @private * @param {*} value The unwrapped value. * @param {Array} actions Actions to perform to resolve the unwrapped value. * @returns {*} Returns the resolved value. */ function baseWrapperValue(value, actions) { var result = value; if (result instanceof LazyWrapper) { result = result.value(); } return arrayReduce(actions, function(result, action) { return action.func.apply(action.thisArg, arrayPush([result], action.args)); }, result); } /** * The base implementation of methods like `_.xor`, without support for * iteratee shorthands, that accepts an array of arrays to inspect. * * @private * @param {Array} arrays The arrays to inspect. * @param {Function} [iteratee] The iteratee invoked per element. * @param {Function} [comparator] The comparator invoked per element. * @returns {Array} Returns the new array of values. */ function baseXor(arrays, iteratee, comparator) { var length = arrays.length; if (length < 2) { return length ? baseUniq(arrays[0]) : []; } var index = -1, result = Array(length); while (++index < length) { var array = arrays[index], othIndex = -1; while (++othIndex < length) { if (othIndex != index) { result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator); } } } return baseUniq(baseFlatten(result, 1), iteratee, comparator); } /** * This base implementation of `_.zipObject` which assigns values using `assignFunc`. * * @private * @param {Array} props The property identifiers. * @param {Array} values The property values. * @param {Function} assignFunc The function to assign values. * @returns {Object} Returns the new object. */ function baseZipObject(props, values, assignFunc) { var index = -1, length = props.length, valsLength = values.length, result = {}; while (++index < length) { var value = index < valsLength ? values[index] : undefined; assignFunc(result, props[index], value); } return result; } /** * Casts `value` to an empty array if it's not an array like object. * * @private * @param {*} value The value to inspect. * @returns {Array|Object} Returns the cast array-like object. */ function castArrayLikeObject(value) { return isArrayLikeObject(value) ? value : []; } /** * Casts `value` to `identity` if it's not a function. * * @private * @param {*} value The value to inspect. * @returns {Function} Returns cast function. */ function castFunction(value) { return typeof value == "function" ? value : identity; } /** * Casts `value` to a path array if it's not one. * * @private * @param {*} value The value to inspect. * @param {Object} [object] The object to query keys on. * @returns {Array} Returns the cast property path array. */ function castPath(value, object) { if (isArray(value)) { return value; } return isKey(value, object) ? [value] : stringToPath(toString(value)); } /** * A `baseRest` alias which can be replaced with `identity` by module * replacement plugins. * * @private * @type {Function} * @param {Function} func The function to apply a rest parameter to. * @returns {Function} Returns the new function. */ var castRest = baseRest; /** * Casts `array` to a slice if it's needed. * * @private * @param {Array} array The array to inspect. * @param {number} start The start position. * @param {number} [end=array.length] The end position. * @returns {Array} Returns the cast slice. */ function castSlice(array, start, end) { var length = array.length; end = end === undefined ? length : end; return !start && end >= length ? array : baseSlice(array, start, end); } /** * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout). * * @private * @param {number|Object} id The timer id or timeout object of the timer to clear. */ var clearTimeout = ctxClearTimeout || function(id) { return root.clearTimeout(id); }; /** * Creates a clone of `buffer`. * * @private * @param {Buffer} buffer The buffer to clone. * @param {boolean} [isDeep] Specify a deep clone. * @returns {Buffer} Returns the cloned buffer. */ function cloneBuffer(buffer, isDeep) { if (isDeep) { return buffer.slice(); } var length = buffer.length, result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); buffer.copy(result); return result; } /** * Creates a clone of `arrayBuffer`. * * @private * @param {ArrayBuffer} arrayBuffer The array buffer to clone. * @returns {ArrayBuffer} Returns the cloned array buffer. */ function cloneArrayBuffer(arrayBuffer) { var result = new arrayBuffer.constructor(arrayBuffer.byteLength); new Uint8Array(result).set(new Uint8Array(arrayBuffer)); return result; } /** * Creates a clone of `dataView`. * * @private * @param {Object} dataView The data view to clone. * @param {boolean} [isDeep] Specify a deep clone. * @returns {Object} Returns the cloned data view. */ function cloneDataView(dataView, isDeep) { var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); } /** * Creates a clone of `regexp`. * * @private * @param {Object} regexp The regexp to clone. * @returns {Object} Returns the cloned regexp. */ function cloneRegExp(regexp) { var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); result.lastIndex = regexp.lastIndex; return result; } /** * Creates a clone of the `symbol` object. * * @private * @param {Object} symbol The symbol object to clone. * @returns {Object} Returns the cloned symbol object. */ function cloneSymbol(symbol) { return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; } /** * Creates a clone of `typedArray`. * * @private * @param {Object} typedArray The typed array to clone. * @param {boolean} [isDeep] Specify a deep clone. * @returns {Object} Returns the cloned typed array. */ function cloneTypedArray(typedArray, isDeep) { var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); } /** * Compares values to sort them in ascending order. * * @private * @param {*} value The value to compare. * @param {*} other The other value to compare. * @returns {number} Returns the sort order indicator for `value`. */ function compareAscending(value, other) { if (value !== other) { var valIsDefined = value !== undefined, valIsNull = value === null, valIsReflexive = value === value, valIsSymbol = isSymbol(value); var othIsDefined = other !== undefined, othIsNull = other === null, othIsReflexive = other === other, othIsSymbol = isSymbol(other); if (!othIsNull && !othIsSymbol && !valIsSymbol && value > other || valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol || valIsNull && othIsDefined && othIsReflexive || !valIsDefined && othIsReflexive || !valIsReflexive) { return 1; } if (!valIsNull && !valIsSymbol && !othIsSymbol && value < other || othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol || othIsNull && valIsDefined && valIsReflexive || !othIsDefined && valIsReflexive || !othIsReflexive) { return -1; } } return 0; } /** * Used by `_.orderBy` to compare multiple properties of a value to another * and stable sort them. * * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, * specify an order of "desc" for descending or "asc" for ascending sort order * of corresponding values. * * @private * @param {Object} object The object to compare. * @param {Object} other The other object to compare. * @param {boolean[]|string[]} orders The order to sort by for each property. * @returns {number} Returns the sort order indicator for `object`. */ function compareMultiple(object, other, orders) { var index = -1, objCriteria = object.criteria, othCriteria = other.criteria, length = objCriteria.length, ordersLength = orders.length; while (++index < length) { var result = compareAscending(objCriteria[index], othCriteria[index]); if (result) { if (index >= ordersLength) { return result; } var order = orders[index]; return result * (order == "desc" ? -1 : 1); } } return object.index - other.index; } /** * Creates an array that is the composition of partially applied arguments, * placeholders, and provided arguments into a single array of arguments. * * @private * @param {Array} args The provided arguments. * @param {Array} partials The arguments to prepend to those provided. * @param {Array} holders The `partials` placeholder indexes. * @params {boolean} [isCurried] Specify composing for a curried function. * @returns {Array} Returns the new array of composed arguments. */ function composeArgs(args, partials, holders, isCurried) { var argsIndex = -1, argsLength = args.length, holdersLength = holders.length, leftIndex = -1, leftLength = partials.length, rangeLength = nativeMax(argsLength - holdersLength, 0), result = Array(leftLength + rangeLength), isUncurried = !isCurried; while (++leftIndex < leftLength) { result[leftIndex] = partials[leftIndex]; } while (++argsIndex < holdersLength) { if (isUncurried || argsIndex < argsLength) { result[holders[argsIndex]] = args[argsIndex]; } } while (rangeLength--) { result[leftIndex++] = args[argsIndex++]; } return result; } /** * This function is like `composeArgs` except that the arguments composition * is tailored for `_.partialRight`. * * @private * @param {Array} args The provided arguments. * @param {Array} partials The arguments to append to those provided. * @param {Array} holders The `partials` placeholder indexes. * @params {boolean} [isCurried] Specify composing for a curried function. * @returns {Array} Returns the new array of composed arguments. */ function composeArgsRight(args, partials, holders, isCurried) { var argsIndex = -1, argsLength = args.length, holdersIndex = -1, holdersLength = holders.length, rightIndex = -1, rightLength = partials.length, rangeLength = nativeMax(argsLength - holdersLength, 0), result = Array(rangeLength + rightLength), isUncurried = !isCurried; while (++argsIndex < rangeLength) { result[argsIndex] = args[argsIndex]; } var offset = argsIndex; while (++rightIndex < rightLength) { result[offset + rightIndex] = partials[rightIndex]; } while (++holdersIndex < holdersLength) { if (isUncurried || argsIndex < argsLength) { result[offset + holders[holdersIndex]] = args[argsIndex++]; } } return result; } /** * Copies the values of `source` to `array`. * * @private * @param {Array} source The array to copy values from. * @param {Array} [array=[]] The array to copy values to. * @returns {Array} Returns `array`. */ function copyArray(source, array) { var index = -1, length = source.length; array || (array = Array(length)); while (++index < length) { array[index] = source[index]; } return array; } /** * Copies properties of `source` to `object`. * * @private * @param {Object} source The object to copy properties from. * @param {Array} props The property identifiers to copy. * @param {Object} [object={}] The object to copy properties to. * @param {Function} [customizer] The function to customize copied values. * @returns {Object} Returns `object`. */ function copyObject(source, props, object, customizer) { var isNew = !object; object || (object = {}); var index = -1, length = props.length; while (++index < length) { var key = props[index]; var newValue = customizer ? customizer(object[key], source[key], key, object, source) : undefined; if (newValue === undefined) { newValue = source[key]; } if (isNew) { baseAssignValue(object, key, newValue); } else { assignValue(object, key, newValue); } } return object; } /** * Copies own symbols of `source` to `object`. * * @private * @param {Object} source The object to copy symbols from. * @param {Object} [object={}] The object to copy symbols to. * @returns {Object} Returns `object`. */ function copySymbols(source, object) { return copyObject(source, getSymbols(source), object); } /** * Copies own and inherited symbols of `source` to `object`. * * @private * @param {Object} source The object to copy symbols from. * @param {Object} [object={}] The object to copy symbols to. * @returns {Object} Returns `object`. */ function copySymbolsIn(source, object) { return copyObject(source, getSymbolsIn(source), object); } /** * Creates a function like `_.groupBy`. * * @private * @param {Function} setter The function to set accumulator values. * @param {Function} [initializer] The accumulator object initializer. * @returns {Function} Returns the new aggregator function. */ function createAggregator(setter, initializer) { return function(collection, iteratee) { var func = isArray(collection) ? arrayAggregator : baseAggregator, accumulator = initializer ? initializer() : {}; return func(collection, setter, getIteratee(iteratee, 2), accumulator); }; } /** * Creates a function like `_.assign`. * * @private * @param {Function} assigner The function to assign values. * @returns {Function} Returns the new assigner function. */ function createAssigner(assigner) { return baseRest(function(object, sources) { var index = -1, length = sources.length, customizer = length > 1 ? sources[length - 1] : undefined, guard = length > 2 ? sources[2] : undefined; customizer = assigner.length > 3 && typeof customizer == "function" ? (length--, customizer) : undefined; if (guard && isIterateeCall(sources[0], sources[1], guard)) { customizer = length < 3 ? undefined : customizer; length = 1; } object = Object(object); while (++index < length) { var source = sources[index]; if (source) { assigner(object, source, index, customizer); } } return object; }); } /** * Creates a `baseEach` or `baseEachRight` function. * * @private * @param {Function} eachFunc The function to iterate over a collection. * @param {boolean} [fromRight] Specify iterating from right to left. * @returns {Function} Returns the new base function. */ function createBaseEach(eachFunc, fromRight) { return function(collection, iteratee) { if (collection == null) { return collection; } if (!isArrayLike(collection)) { return eachFunc(collection, iteratee); } var length = collection.length, index = fromRight ? length : -1, iterable = Object(collection); while (fromRight ? index-- : ++index < length) { if (iteratee(iterable[index], index, iterable) === false) { break; } } return collection; }; } /** * Creates a base function for methods like `_.forIn` and `_.forOwn`. * * @private * @param {boolean} [fromRight] Specify iterating from right to left. * @returns {Function} Returns the new base function. */ function createBaseFor(fromRight) { return function(object, iteratee, keysFunc) { var index = -1, iterable = Object(object), props = keysFunc(object), length = props.length; while (length--) { var key = props[fromRight ? length : ++index]; if (iteratee(iterable[key], key, iterable) === false) { break; } } return object; }; } /** * Creates a function that wraps `func` to invoke it with the optional `this` * binding of `thisArg`. * * @private * @param {Function} func The function to wrap. * @param {number} bitmask The bitmask flags. See `createWrap` for more details. * @param {*} [thisArg] The `this` binding of `func`. * @returns {Function} Returns the new wrapped function. */ function createBind(func, bitmask, thisArg) { var isBind = bitmask & WRAP_BIND_FLAG, Ctor = createCtor(func); function wrapper() { var fn = this && this !== root && this instanceof wrapper ? Ctor : func; return fn.apply(isBind ? thisArg : this, arguments); } return wrapper; } /** * Creates a function like `_.lowerFirst`. * * @private * @param {string} methodName The name of the `String` case method to use. * @returns {Function} Returns the new case function. */ function createCaseFirst(methodName) { return function(string) { string = toString(string); var strSymbols = hasUnicode(string) ? stringToArray(string) : undefined; var chr = strSymbols ? strSymbols[0] : string.charAt(0); var trailing = strSymbols ? castSlice(strSymbols, 1).join("") : string.slice(1); return chr[methodName]() + trailing; }; } /** * Creates a function like `_.camelCase`. * * @private * @param {Function} callback The function to combine each word. * @returns {Function} Returns the new compounder function. */ function createCompounder(callback) { return function(string) { return arrayReduce(words(deburr(string).replace(reApos, "")), callback, ""); }; } /** * Creates a function that produces an instance of `Ctor` regardless of * whether it was invoked as part of a `new` expression or by `call` or `apply`. * * @private * @param {Function} Ctor The constructor to wrap. * @returns {Function} Returns the new wrapped function. */ function createCtor(Ctor) { return function() { var args = arguments; switch (args.length) { case 0: return new Ctor(); case 1: return new Ctor(args[0]); case 2: return new Ctor(args[0], args[1]); case 3: return new Ctor(args[0], args[1], args[2]); case 4: return new Ctor(args[0], args[1], args[2], args[3]); case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); } var thisBinding = baseCreate(Ctor.prototype), result = Ctor.apply(thisBinding, args); return isObject(result) ? result : thisBinding; }; } /** * Creates a function that wraps `func` to enable currying. * * @private * @param {Function} func The function to wrap. * @param {number} bitmask The bitmask flags. See `createWrap` for more details. * @param {number} arity The arity of `func`. * @returns {Function} Returns the new wrapped function. */ function createCurry(func, bitmask, arity) { var Ctor = createCtor(func); function wrapper() { var length = arguments.length, args = Array(length), index = length, placeholder = getHolder(wrapper); while (index--) { args[index] = arguments[index]; } var holders = length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder ? [] : replaceHolders(args, placeholder); length -= holders.length; if (length < arity) { return createRecurry(func, bitmask, createHybrid, wrapper.placeholder, undefined, args, holders, undefined, undefined, arity - length); } var fn = this && this !== root && this instanceof wrapper ? Ctor : func; return apply(fn, this, args); } return wrapper; } /** * Creates a `_.find` or `_.findLast` function. * * @private * @param {Function} findIndexFunc The function to find the collection index. * @returns {Function} Returns the new find function. */ function createFind(findIndexFunc) { return function(collection, predicate, fromIndex) { var iterable = Object(collection); if (!isArrayLike(collection)) { var iteratee = getIteratee(predicate, 3); collection = keys(collection); predicate = function(key) { return iteratee(iterable[key], key, iterable); }; } var index = findIndexFunc(collection, predicate, fromIndex); return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; }; } /** * Creates a `_.flow` or `_.flowRight` function. * * @private * @param {boolean} [fromRight] Specify iterating from right to left. * @returns {Function} Returns the new flow function. */ function createFlow(fromRight) { return flatRest(function(funcs) { var length = funcs.length, index = length, prereq = LodashWrapper.prototype.thru; if (fromRight) { funcs.reverse(); } while (index--) { var func = funcs[index]; if (typeof func != "function") { throw new TypeError(FUNC_ERROR_TEXT); } if (prereq && !wrapper && getFuncName(func) == "wrapper") { var wrapper = new LodashWrapper([], true); } } index = wrapper ? index : length; while (++index < length) { func = funcs[index]; var funcName = getFuncName(func), data = funcName == "wrapper" ? getData(func) : undefined; if (data && isLaziable(data[0]) && data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) && !data[4].length && data[9] == 1) { wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); } else { wrapper = func.length == 1 && isLaziable(func) ? wrapper[funcName]() : wrapper.thru(func); } } return function() { var args = arguments, value = args[0]; if (wrapper && args.length == 1 && isArray(value)) { return wrapper.plant(value).value(); } var index = 0, result = length ? funcs[index].apply(this, args) : value; while (++index < length) { result = funcs[index].call(this, result); } return result; }; }); } /** * Creates a function that wraps `func` to invoke it with optional `this` * binding of `thisArg`, partial application, and currying. * * @private * @param {Function|string} func The function or method name to wrap. * @param {number} bitmask The bitmask flags. See `createWrap` for more details. * @param {*} [thisArg] The `this` binding of `func`. * @param {Array} [partials] The arguments to prepend to those provided to * the new function. * @param {Array} [holders] The `partials` placeholder indexes. * @param {Array} [partialsRight] The arguments to append to those provided * to the new function. * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. * @param {Array} [argPos] The argument positions of the new function. * @param {number} [ary] The arity cap of `func`. * @param {number} [arity] The arity of `func`. * @returns {Function} Returns the new wrapped function. */ function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { var isAry = bitmask & WRAP_ARY_FLAG, isBind = bitmask & WRAP_BIND_FLAG, isBindKey = bitmask & WRAP_BIND_KEY_FLAG, isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG), isFlip = bitmask & WRAP_FLIP_FLAG, Ctor = isBindKey ? undefined : createCtor(func); function wrapper() { var length = arguments.length, args = Array(length), index = length; while (index--) { args[index] = arguments[index]; } if (isCurried) { var placeholder = getHolder(wrapper), holdersCount = countHolders(args, placeholder); } if (partials) { args = composeArgs(args, partials, holders, isCurried); } if (partialsRight) { args = composeArgsRight(args, partialsRight, holdersRight, isCurried); } length -= holdersCount; if (isCurried && length < arity) { var newHolders = replaceHolders(args, placeholder); return createRecurry(func, bitmask, createHybrid, wrapper.placeholder, thisArg, args, newHolders, argPos, ary, arity - length); } var thisBinding = isBind ? thisArg : this, fn = isBindKey ? thisBinding[func] : func; length = args.length; if (argPos) { args = reorder(args, argPos); } else if (isFlip && length > 1) { args.reverse(); } if (isAry && ary < length) { args.length = ary; } if (this && this !== root && this instanceof wrapper) { fn = Ctor || createCtor(fn); } return fn.apply(thisBinding, args); } return wrapper; } /** * Creates a function like `_.invertBy`. * * @private * @param {Function} setter The function to set accumulator values. * @param {Function} toIteratee The function to resolve iteratees. * @returns {Function} Returns the new inverter function. */ function createInverter(setter, toIteratee) { return function(object, iteratee) { return baseInverter(object, setter, toIteratee(iteratee), {}); }; } /** * Creates a function that performs a mathematical operation on two values. * * @private * @param {Function} operator The function to perform the operation. * @param {number} [defaultValue] The value used for `undefined` arguments. * @returns {Function} Returns the new mathematical operation function. */ function createMathOperation(operator, defaultValue) { return function(value, other) { var result; if (value === undefined && other === undefined) { return defaultValue; } if (value !== undefined) { result = value; } if (other !== undefined) { if (result === undefined) { return other; } if (typeof value == "string" || typeof other == "string") { value = baseToString(value); other = baseToString(other); } else { value = baseToNumber(value); other = baseToNumber(other); } result = operator(value, other); } return result; }; } /** * Creates a function like `_.over`. * * @private * @param {Function} arrayFunc The function to iterate over iteratees. * @returns {Function} Returns the new over function. */ function createOver(arrayFunc) { return flatRest(function(iteratees) { iteratees = arrayMap(iteratees, baseUnary(getIteratee())); return baseRest(function(args) { var thisArg = this; return arrayFunc(iteratees, function(iteratee) { return apply(iteratee, thisArg, args); }); }); }); } /** * Creates the padding for `string` based on `length`. The `chars` string * is truncated if the number of characters exceeds `length`. * * @private * @param {number} length The padding length. * @param {string} [chars=' '] The string used as padding. * @returns {string} Returns the padding for `string`. */ function createPadding(length, chars) { chars = chars === undefined ? " " : baseToString(chars); var charsLength = chars.length; if (charsLength < 2) { return charsLength ? baseRepeat(chars, length) : chars; } var result = baseRepeat(chars, nativeCeil(length / stringSize(chars))); return hasUnicode(chars) ? castSlice(stringToArray(result), 0, length).join("") : result.slice(0, length); } /** * Creates a function that wraps `func` to invoke it with the `this` binding * of `thisArg` and `partials` prepended to the arguments it receives. * * @private * @param {Function} func The function to wrap. * @param {number} bitmask The bitmask flags. See `createWrap` for more details. * @param {*} thisArg The `this` binding of `func`. * @param {Array} partials The arguments to prepend to those provided to * the new function. * @returns {Function} Returns the new wrapped function. */ function createPartial(func, bitmask, thisArg, partials) { var isBind = bitmask & WRAP_BIND_FLAG, Ctor = createCtor(func); function wrapper() { var argsIndex = -1, argsLength = arguments.length, leftIndex = -1, leftLength = partials.length, args = Array(leftLength + argsLength), fn = this && this !== root && this instanceof wrapper ? Ctor : func; while (++leftIndex < leftLength) { args[leftIndex] = partials[leftIndex]; } while (argsLength--) { args[leftIndex++] = arguments[++argsIndex]; } return apply(fn, isBind ? thisArg : this, args); } return wrapper; } /** * Creates a `_.range` or `_.rangeRight` function. * * @private * @param {boolean} [fromRight] Specify iterating from right to left. * @returns {Function} Returns the new range function. */ function createRange(fromRight) { return function(start, end, step) { if (step && typeof step != "number" && isIterateeCall(start, end, step)) { end = step = undefined; } start = toFinite(start); if (end === undefined) { end = start; start = 0; } else { end = toFinite(end); } step = step === undefined ? start < end ? 1 : -1 : toFinite(step); return baseRange(start, end, step, fromRight); }; } /** * Creates a function that performs a relational operation on two values. * * @private * @param {Function} operator The function to perform the operation. * @returns {Function} Returns the new relational operation function. */ function createRelationalOperation(operator) { return function(value, other) { if (!(typeof value == "string" && typeof other == "string")) { value = toNumber(value); other = toNumber(other); } return operator(value, other); }; } /** * Creates a function that wraps `func` to continue currying. * * @private * @param {Function} func The function to wrap. * @param {number} bitmask The bitmask flags. See `createWrap` for more details. * @param {Function} wrapFunc The function to create the `func` wrapper. * @param {*} placeholder The placeholder value. * @param {*} [thisArg] The `this` binding of `func`. * @param {Array} [partials] The arguments to prepend to those provided to * the new function. * @param {Array} [holders] The `partials` placeholder indexes. * @param {Array} [argPos] The argument positions of the new function. * @param {number} [ary] The arity cap of `func`. * @param {number} [arity] The arity of `func`. * @returns {Function} Returns the new wrapped function. */ function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) { var isCurry = bitmask & WRAP_CURRY_FLAG, newHolders = isCurry ? holders : undefined, newHoldersRight = isCurry ? undefined : holders, newPartials = isCurry ? partials : undefined, newPartialsRight = isCurry ? undefined : partials; bitmask |= isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG; bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG); if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) { bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG); } var newData = [ func, bitmask, thisArg, newPartials, newHolders, newPartialsRight, newHoldersRight, argPos, ary, arity ]; var result = wrapFunc.apply(undefined, newData); if (isLaziable(func)) { setData(result, newData); } result.placeholder = placeholder; return setWrapToString(result, func, bitmask); } /** * Creates a function like `_.round`. * * @private * @param {string} methodName The name of the `Math` method to use when rounding. * @returns {Function} Returns the new round function. */ function createRound(methodName) { var func = Math[methodName]; return function(number, precision) { number = toNumber(number); precision = precision == null ? 0 : nativeMin(toInteger(precision), 292); if (precision && nativeIsFinite(number)) { var pair = (toString(number) + "e").split("e"), value = func(pair[0] + "e" + (+pair[1] + precision)); pair = (toString(value) + "e").split("e"); return +(pair[0] + "e" + (+pair[1] - precision)); } return func(number); }; } /** * Creates a set object of `values`. * * @private * @param {Array} values The values to add to the set. * @returns {Object} Returns the new set. */ var createSet = !(Set && 1 / setToArray(new Set([, -0]))[1] == INFINITY) ? noop : function(values) { return new Set(values); }; /** * Creates a `_.toPairs` or `_.toPairsIn` function. * * @private * @param {Function} keysFunc The function to get the keys of a given object. * @returns {Function} Returns the new pairs function. */ function createToPairs(keysFunc) { return function(object) { var tag = getTag(object); if (tag == mapTag) { return mapToArray(object); } if (tag == setTag) { return setToPairs(object); } return baseToPairs(object, keysFunc(object)); }; } /** * Creates a function that either curries or invokes `func` with optional * `this` binding and partially applied arguments. * * @private * @param {Function|string} func The function or method name to wrap. * @param {number} bitmask The bitmask flags. * 1 - `_.bind` * 2 - `_.bindKey` * 4 - `_.curry` or `_.curryRight` of a bound function * 8 - `_.curry` * 16 - `_.curryRight` * 32 - `_.partial` * 64 - `_.partialRight` * 128 - `_.rearg` * 256 - `_.ary` * 512 - `_.flip` * @param {*} [thisArg] The `this` binding of `func`. * @param {Array} [partials] The arguments to be partially applied. * @param {Array} [holders] The `partials` placeholder indexes. * @param {Array} [argPos] The argument positions of the new function. * @param {number} [ary] The arity cap of `func`. * @param {number} [arity] The arity of `func`. * @returns {Function} Returns the new wrapped function. */ function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { var isBindKey = bitmask & WRAP_BIND_KEY_FLAG; if (!isBindKey && typeof func != "function") { throw new TypeError(FUNC_ERROR_TEXT); } var length = partials ? partials.length : 0; if (!length) { bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG); partials = holders = undefined; } ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0); arity = arity === undefined ? arity : toInteger(arity); length -= holders ? holders.length : 0; if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) { var partialsRight = partials, holdersRight = holders; partials = holders = undefined; } var data = isBindKey ? undefined : getData(func); var newData = [ func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity ]; if (data) { mergeData(newData, data); } func = newData[0]; bitmask = newData[1]; thisArg = newData[2]; partials = newData[3]; holders = newData[4]; arity = newData[9] = newData[9] === undefined ? isBindKey ? 0 : func.length : nativeMax(newData[9] - length, 0); if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) { bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG); } if (!bitmask || bitmask == WRAP_BIND_FLAG) { var result = createBind(func, bitmask, thisArg); } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) { result = createCurry(func, bitmask, arity); } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) { result = createPartial(func, bitmask, thisArg, partials); } else { result = createHybrid.apply(undefined, newData); } var setter = data ? baseSetData : setData; return setWrapToString(setter(result, newData), func, bitmask); } /** * Used by `_.defaults` to customize its `_.assignIn` use to assign properties * of source objects to the destination object for all destination properties * that resolve to `undefined`. * * @private * @param {*} objValue The destination value. * @param {*} srcValue The source value. * @param {string} key The key of the property to assign. * @param {Object} object The parent object of `objValue`. * @returns {*} Returns the value to assign. */ function customDefaultsAssignIn(objValue, srcValue, key, object) { if (objValue === undefined || eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key)) { return srcValue; } return objValue; } /** * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source * objects into destination objects that are passed thru. * * @private * @param {*} objValue The destination value. * @param {*} srcValue The source value. * @param {string} key The key of the property to merge. * @param {Object} object The parent object of `objValue`. * @param {Object} source The parent object of `srcValue`. * @param {Object} [stack] Tracks traversed source values and their merged * counterparts. * @returns {*} Returns the value to assign. */ function customDefaultsMerge(objValue, srcValue, key, object, source, stack) { if (isObject(objValue) && isObject(srcValue)) { stack.set(srcValue, objValue); baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack); stack["delete"](srcValue); } return objValue; } /** * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain * objects. * * @private * @param {*} value The value to inspect. * @param {string} key The key of the property to inspect. * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`. */ function customOmitClone(value) { return isPlainObject(value) ? undefined : value; } /** * A specialized version of `baseIsEqualDeep` for arrays with support for * partial deep comparisons. * * @private * @param {Array} array The array to compare. * @param {Array} other The other array to compare. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. * @param {Function} customizer The function to customize comparisons. * @param {Function} equalFunc The function to determine equivalents of values. * @param {Object} stack Tracks traversed `array` and `other` objects. * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. */ function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { var isPartial = bitmask & COMPARE_PARTIAL_FLAG, arrLength = array.length, othLength = other.length; if (arrLength != othLength && !(isPartial && othLength > arrLength)) { return false; } var arrStacked = stack.get(array); var othStacked = stack.get(other); if (arrStacked && othStacked) { return arrStacked == other && othStacked == array; } var index = -1, result = true, seen = bitmask & COMPARE_UNORDERED_FLAG ? new SetCache() : undefined; stack.set(array, other); stack.set(other, array); while (++index < arrLength) { var arrValue = array[index], othValue = other[index]; if (customizer) { var compared = isPartial ? customizer(othValue, arrValue, index, other, array, stack) : customizer(arrValue, othValue, index, array, other, stack); } if (compared !== undefined) { if (compared) { continue; } result = false; break; } if (seen) { if (!arraySome(other, function(othValue, othIndex) { if (!cacheHas(seen, othIndex) && (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { return seen.push(othIndex); } })) { result = false; break; } } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { result = false; break; } } stack["delete"](array); stack["delete"](other); return result; } /** * A specialized version of `baseIsEqualDeep` for comparing objects of * the same `toStringTag`. * * **Note:** This function only supports comparing values with tags of * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. * * @private * @param {Object} object The object to compare. * @param {Object} other The other object to compare. * @param {string} tag The `toStringTag` of the objects to compare. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. * @param {Function} customizer The function to customize comparisons. * @param {Function} equalFunc The function to determine equivalents of values. * @param {Object} stack Tracks traversed `object` and `other` objects. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. */ function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { switch (tag) { case dataViewTag: if (object.byteLength != other.byteLength || object.byteOffset != other.byteOffset) { return false; } object = object.buffer; other = other.buffer; case arrayBufferTag: if (object.byteLength != other.byteLength || !equalFunc(new Uint8Array(object), new Uint8Array(other))) { return false; } return true; case boolTag: case dateTag: case numberTag: return eq(+object, +other); case errorTag: return object.name == other.name && object.message == other.message; case regexpTag: case stringTag: return object == other + ""; case mapTag: var convert = mapToArray; case setTag: var isPartial = bitmask & COMPARE_PARTIAL_FLAG; convert || (convert = setToArray); if (object.size != other.size && !isPartial) { return false; } var stacked = stack.get(object); if (stacked) { return stacked == other; } bitmask |= COMPARE_UNORDERED_FLAG; stack.set(object, other); var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); stack["delete"](object); return result; case symbolTag: if (symbolValueOf) { return symbolValueOf.call(object) == symbolValueOf.call(other); } } return false; } /** * A specialized version of `baseIsEqualDeep` for objects with support for * partial deep comparisons. * * @private * @param {Object} object The object to compare. * @param {Object} other The other object to compare. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. * @param {Function} customizer The function to customize comparisons. * @param {Function} equalFunc The function to determine equivalents of values. * @param {Object} stack Tracks traversed `object` and `other` objects. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. */ function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { var isPartial = bitmask & COMPARE_PARTIAL_FLAG, objProps = getAllKeys(object), objLength = objProps.length, othProps = getAllKeys(other), othLength = othProps.length; if (objLength != othLength && !isPartial) { return false; } var index = objLength; while (index--) { var key = objProps[index]; if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) { return false; } } var objStacked = stack.get(object); var othStacked = stack.get(other); if (objStacked && othStacked) { return objStacked == other && othStacked == object; } var result = true; stack.set(object, other); stack.set(other, object); var skipCtor = isPartial; while (++index < objLength) { key = objProps[index]; var objValue = object[key], othValue = other[key]; if (customizer) { var compared = isPartial ? customizer(othValue, objValue, key, other, object, stack) : customizer(objValue, othValue, key, object, other, stack); } if (!(compared === undefined ? objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack) : compared)) { result = false; break; } skipCtor || (skipCtor = key == "constructor"); } if (result && !skipCtor) { var objCtor = object.constructor, othCtor = other.constructor; if (objCtor != othCtor && "constructor" in object && "constructor" in other && !(typeof objCtor == "function" && objCtor instanceof objCtor && typeof othCtor == "function" && othCtor instanceof othCtor)) { result = false; } } stack["delete"](object); stack["delete"](other); return result; } /** * A specialized version of `baseRest` which flattens the rest array. * * @private * @param {Function} func The function to apply a rest parameter to. * @returns {Function} Returns the new function. */ function flatRest(func) { return setToString(overRest(func, undefined, flatten), func + ""); } /** * Creates an array of own enumerable property names and symbols of `object`. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of property names and symbols. */ function getAllKeys(object) { return baseGetAllKeys(object, keys, getSymbols); } /** * Creates an array of own and inherited enumerable property names and * symbols of `object`. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of property names and symbols. */ function getAllKeysIn(object) { return baseGetAllKeys(object, keysIn, getSymbolsIn); } /** * Gets metadata for `func`. * * @private * @param {Function} func The function to query. * @returns {*} Returns the metadata for `func`. */ var getData = !metaMap ? noop : function(func) { return metaMap.get(func); }; /** * Gets the name of `func`. * * @private * @param {Function} func The function to query. * @returns {string} Returns the function name. */ function getFuncName(func) { var result = func.name + "", array = realNames[result], length = hasOwnProperty.call(realNames, result) ? array.length : 0; while (length--) { var data = array[length], otherFunc = data.func; if (otherFunc == null || otherFunc == func) { return data.name; } } return result; } /** * Gets the argument placeholder value for `func`. * * @private * @param {Function} func The function to inspect. * @returns {*} Returns the placeholder value. */ function getHolder(func) { var object = hasOwnProperty.call(lodash, "placeholder") ? lodash : func; return object.placeholder; } /** * Gets the appropriate "iteratee" function. If `_.iteratee` is customized, * this function returns the custom method, otherwise it returns `baseIteratee`. * If arguments are provided, the chosen function is invoked with them and * its result is returned. * * @private * @param {*} [value] The value to convert to an iteratee. * @param {number} [arity] The arity of the created iteratee. * @returns {Function} Returns the chosen function or its result. */ function getIteratee() { var result = lodash.iteratee || iteratee; result = result === iteratee ? baseIteratee : result; return arguments.length ? result(arguments[0], arguments[1]) : result; } /** * Gets the data for `map`. * * @private * @param {Object} map The map to query. * @param {string} key The reference key. * @returns {*} Returns the map data. */ function getMapData(map, key) { var data = map.__data__; return isKeyable(key) ? data[typeof key == "string" ? "string" : "hash"] : data.map; } /** * Gets the property names, values, and compare flags of `object`. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the match data of `object`. */ function getMatchData(object) { var result = keys(object), length = result.length; while (length--) { var key = result[length], value = object[key]; result[length] = [ key, value, isStrictComparable(value) ]; } return result; } /** * Gets the native function at `key` of `object`. * * @private * @param {Object} object The object to query. * @param {string} key The key of the method to get. * @returns {*} Returns the function if it's native, else `undefined`. */ function getNative(object, key) { var value = getValue(object, key); return baseIsNative(value) ? value : undefined; } /** * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. * * @private * @param {*} value The value to query. * @returns {string} Returns the raw `toStringTag`. */ function getRawTag(value) { var isOwn = hasOwnProperty.call(value, symToStringTag), tag = value[symToStringTag]; try { value[symToStringTag] = undefined; var unmasked = true; } catch (e) {} var result = nativeObjectToString.call(value); if (unmasked) { if (isOwn) { value[symToStringTag] = tag; } else { delete value[symToStringTag]; } } return result; } /** * Creates an array of the own enumerable symbols of `object`. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of symbols. */ var getSymbols = !nativeGetSymbols ? stubArray : function(object) { if (object == null) { return []; } object = Object(object); return arrayFilter(nativeGetSymbols(object), function(symbol) { return propertyIsEnumerable.call(object, symbol); }); }; /** * Creates an array of the own and inherited enumerable symbols of `object`. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of symbols. */ var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) { var result = []; while (object) { arrayPush(result, getSymbols(object)); object = getPrototype(object); } return result; }; /** * Gets the `toStringTag` of `value`. * * @private * @param {*} value The value to query. * @returns {string} Returns the `toStringTag`. */ var getTag = baseGetTag; if (DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag || Map && getTag(new Map()) != mapTag || Promise && getTag(Promise.resolve()) != promiseTag || Set && getTag(new Set()) != setTag || WeakMap && getTag(new WeakMap()) != weakMapTag) { getTag = function(value) { var result = baseGetTag(value), Ctor = result == objectTag ? value.constructor : undefined, ctorString = Ctor ? toSource(Ctor) : ""; if (ctorString) { switch (ctorString) { case dataViewCtorString: return dataViewTag; case mapCtorString: return mapTag; case promiseCtorString: return promiseTag; case setCtorString: return setTag; case weakMapCtorString: return weakMapTag; } } return result; }; } /** * Gets the view, applying any `transforms` to the `start` and `end` positions. * * @private * @param {number} start The start of the view. * @param {number} end The end of the view. * @param {Array} transforms The transformations to apply to the view. * @returns {Object} Returns an object containing the `start` and `end` * positions of the view. */ function getView(start, end, transforms) { var index = -1, length = transforms.length; while (++index < length) { var data = transforms[index], size = data.size; switch (data.type) { case "drop": start += size; break; case "dropRight": end -= size; break; case "take": end = nativeMin(end, start + size); break; case "takeRight": start = nativeMax(start, end - size); break; } } return { "start": start, "end": end }; } /** * Extracts wrapper details from the `source` body comment. * * @private * @param {string} source The source to inspect. * @returns {Array} Returns the wrapper details. */ function getWrapDetails(source) { var match = source.match(reWrapDetails); return match ? match[1].split(reSplitDetails) : []; } /** * Checks if `path` exists on `object`. * * @private * @param {Object} object The object to query. * @param {Array|string} path The path to check. * @param {Function} hasFunc The function to check properties. * @returns {boolean} Returns `true` if `path` exists, else `false`. */ function hasPath(object, path, hasFunc) { path = castPath(path, object); var index = -1, length = path.length, result = false; while (++index < length) { var key = toKey(path[index]); if (!(result = object != null && hasFunc(object, key))) { break; } object = object[key]; } if (result || ++index != length) { return result; } length = object == null ? 0 : object.length; return !!length && isLength(length) && isIndex(key, length) && (isArray(object) || isArguments(object)); } /** * Initializes an array clone. * * @private * @param {Array} array The array to clone. * @returns {Array} Returns the initialized clone. */ function initCloneArray(array) { var length = array.length, result = new array.constructor(length); if (length && typeof array[0] == "string" && hasOwnProperty.call(array, "index")) { result.index = array.index; result.input = array.input; } return result; } /** * Initializes an object clone. * * @private * @param {Object} object The object to clone. * @returns {Object} Returns the initialized clone. */ function initCloneObject(object) { return typeof object.constructor == "function" && !isPrototype(object) ? baseCreate(getPrototype(object)) : {}; } /** * Initializes an object clone based on its `toStringTag`. * * **Note:** This function only supports cloning values with tags of * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. * * @private * @param {Object} object The object to clone. * @param {string} tag The `toStringTag` of the object to clone. * @param {boolean} [isDeep] Specify a deep clone. * @returns {Object} Returns the initialized clone. */ function initCloneByTag(object, tag, isDeep) { var Ctor = object.constructor; switch (tag) { case arrayBufferTag: return cloneArrayBuffer(object); case boolTag: case dateTag: return new Ctor(+object); case dataViewTag: return cloneDataView(object, isDeep); case float32Tag: case float64Tag: case int8Tag: case int16Tag: case int32Tag: case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: return cloneTypedArray(object, isDeep); case mapTag: return new Ctor(); case numberTag: case stringTag: return new Ctor(object); case regexpTag: return cloneRegExp(object); case setTag: return new Ctor(); case symbolTag: return cloneSymbol(object); } } /** * Inserts wrapper `details` in a comment at the top of the `source` body. * * @private * @param {string} source The source to modify. * @returns {Array} details The details to insert. * @returns {string} Returns the modified source. */ function insertWrapDetails(source, details) { var length = details.length; if (!length) { return source; } var lastIndex = length - 1; details[lastIndex] = (length > 1 ? "& " : "") + details[lastIndex]; details = details.join(length > 2 ? ", " : " "); return source.replace(reWrapComment, "{\n/* [wrapped with " + details + "] */\n"); } /** * Checks if `value` is a flattenable `arguments` object or array. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. */ function isFlattenable(value) { return isArray(value) || isArguments(value) || !!(spreadableSymbol && value && value[spreadableSymbol]); } /** * Checks if `value` is a valid array-like index. * * @private * @param {*} value The value to check. * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. */ function isIndex(value, length) { var type = typeof value; length = length == null ? MAX_SAFE_INTEGER : length; return !!length && (type == "number" || type != "symbol" && reIsUint.test(value)) && value > -1 && value % 1 == 0 && value < length; } /** * Checks if the given arguments are from an iteratee call. * * @private * @param {*} value The potential iteratee value argument. * @param {*} index The potential iteratee index or key argument. * @param {*} object The potential iteratee object argument. * @returns {boolean} Returns `true` if the arguments are from an iteratee call, * else `false`. */ function isIterateeCall(value, index, object) { if (!isObject(object)) { return false; } var type = typeof index; if (type == "number" ? isArrayLike(object) && isIndex(index, object.length) : type == "string" && index in object) { return eq(object[index], value); } return false; } /** * Checks if `value` is a property name and not a property path. * * @private * @param {*} value The value to check. * @param {Object} [object] The object to query keys on. * @returns {boolean} Returns `true` if `value` is a property name, else `false`. */ function isKey(value, object) { if (isArray(value)) { return false; } var type = typeof value; if (type == "number" || type == "symbol" || type == "boolean" || value == null || isSymbol(value)) { return true; } return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || object != null && value in Object(object); } /** * Checks if `value` is suitable for use as unique object key. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is suitable, else `false`. */ function isKeyable(value) { var type = typeof value; return type == "string" || type == "number" || type == "symbol" || type == "boolean" ? value !== "__proto__" : value === null; } /** * Checks if `func` has a lazy counterpart. * * @private * @param {Function} func The function to check. * @returns {boolean} Returns `true` if `func` has a lazy counterpart, * else `false`. */ function isLaziable(func) { var funcName = getFuncName(func), other = lodash[funcName]; if (typeof other != "function" || !(funcName in LazyWrapper.prototype)) { return false; } if (func === other) { return true; } var data = getData(other); return !!data && func === data[0]; } /** * Checks if `func` has its source masked. * * @private * @param {Function} func The function to check. * @returns {boolean} Returns `true` if `func` is masked, else `false`. */ function isMasked(func) { return !!maskSrcKey && maskSrcKey in func; } /** * Checks if `func` is capable of being masked. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `func` is maskable, else `false`. */ var isMaskable = coreJsData ? isFunction : stubFalse; /** * Checks if `value` is likely a prototype object. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. */ function isPrototype(value) { var Ctor = value && value.constructor, proto = typeof Ctor == "function" && Ctor.prototype || objectProto; return value === proto; } /** * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` if suitable for strict * equality comparisons, else `false`. */ function isStrictComparable(value) { return value === value && !isObject(value); } /** * A specialized version of `matchesProperty` for source values suitable * for strict equality comparisons, i.e. `===`. * * @private * @param {string} key The key of the property to get. * @param {*} srcValue The value to match. * @returns {Function} Returns the new spec function. */ function matchesStrictComparable(key, srcValue) { return function(object) { if (object == null) { return false; } return object[key] === srcValue && (srcValue !== undefined || key in Object(object)); }; } /** * A specialized version of `_.memoize` which clears the memoized function's * cache when it exceeds `MAX_MEMOIZE_SIZE`. * * @private * @param {Function} func The function to have its output memoized. * @returns {Function} Returns the new memoized function. */ function memoizeCapped(func) { var result = memoize(func, function(key) { if (cache.size === MAX_MEMOIZE_SIZE) { cache.clear(); } return key; }); var cache = result.cache; return result; } /** * Merges the function metadata of `source` into `data`. * * Merging metadata reduces the number of wrappers used to invoke a function. * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` * may be applied regardless of execution order. Methods like `_.ary` and * `_.rearg` modify function arguments, making the order in which they are * executed important, preventing the merging of metadata. However, we make * an exception for a safe combined case where curried functions have `_.ary` * and or `_.rearg` applied. * * @private * @param {Array} data The destination metadata. * @param {Array} source The source metadata. * @returns {Array} Returns `data`. */ function mergeData(data, source) { var bitmask = data[1], srcBitmask = source[1], newBitmask = bitmask | srcBitmask, isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG); var isCombo = srcBitmask == WRAP_ARY_FLAG && bitmask == WRAP_CURRY_FLAG || srcBitmask == WRAP_ARY_FLAG && bitmask == WRAP_REARG_FLAG && data[7].length <= source[8] || srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG) && source[7].length <= source[8] && bitmask == WRAP_CURRY_FLAG; if (!(isCommon || isCombo)) { return data; } if (srcBitmask & WRAP_BIND_FLAG) { data[2] = source[2]; newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG; } var value = source[3]; if (value) { var partials = data[3]; data[3] = partials ? composeArgs(partials, value, source[4]) : value; data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4]; } value = source[5]; if (value) { partials = data[5]; data[5] = partials ? composeArgsRight(partials, value, source[6]) : value; data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6]; } value = source[7]; if (value) { data[7] = value; } if (srcBitmask & WRAP_ARY_FLAG) { data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); } if (data[9] == null) { data[9] = source[9]; } data[0] = source[0]; data[1] = newBitmask; return data; } /** * This function is like * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) * except that it includes inherited enumerable properties. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. */ function nativeKeysIn(object) { var result = []; if (object != null) { for (var key in Object(object)) { result.push(key); } } return result; } /** * Converts `value` to a string using `Object.prototype.toString`. * * @private * @param {*} value The value to convert. * @returns {string} Returns the converted string. */ function objectToString(value) { return nativeObjectToString.call(value); } /** * A specialized version of `baseRest` which transforms the rest array. * * @private * @param {Function} func The function to apply a rest parameter to. * @param {number} [start=func.length-1] The start position of the rest parameter. * @param {Function} transform The rest array transform. * @returns {Function} Returns the new function. */ function overRest(func, start, transform) { start = nativeMax(start === undefined ? func.length - 1 : start, 0); return function() { var args = arguments, index = -1, length = nativeMax(args.length - start, 0), array = Array(length); while (++index < length) { array[index] = args[start + index]; } index = -1; var otherArgs = Array(start + 1); while (++index < start) { otherArgs[index] = args[index]; } otherArgs[start] = transform(array); return apply(func, this, otherArgs); }; } /** * Gets the parent value at `path` of `object`. * * @private * @param {Object} object The object to query. * @param {Array} path The path to get the parent value of. * @returns {*} Returns the parent value. */ function parent(object, path) { return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1)); } /** * Reorder `array` according to the specified indexes where the element at * the first index is assigned as the first element, the element at * the second index is assigned as the second element, and so on. * * @private * @param {Array} array The array to reorder. * @param {Array} indexes The arranged array indexes. * @returns {Array} Returns `array`. */ function reorder(array, indexes) { var arrLength = array.length, length = nativeMin(indexes.length, arrLength), oldArray = copyArray(array); while (length--) { var index = indexes[length]; array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; } return array; } /** * Gets the value at `key`, unless `key` is "__proto__" or "constructor". * * @private * @param {Object} object The object to query. * @param {string} key The key of the property to get. * @returns {*} Returns the property value. */ function safeGet(object, key) { if (key === "constructor" && typeof object[key] === "function") { return; } if (key == "__proto__") { return; } return object[key]; } /** * Sets metadata for `func`. * * **Note:** If this function becomes hot, i.e. is invoked a lot in a short * period of time, it will trip its breaker and transition to an identity * function to avoid garbage collection pauses in V8. See * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070) * for more details. * * @private * @param {Function} func The function to associate metadata with. * @param {*} data The metadata. * @returns {Function} Returns `func`. */ var setData = shortOut(baseSetData); /** * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout). * * @private * @param {Function} func The function to delay. * @param {number} wait The number of milliseconds to delay invocation. * @returns {number|Object} Returns the timer id or timeout object. */ var setTimeout = ctxSetTimeout || function(func, wait) { return root.setTimeout(func, wait); }; /** * Sets the `toString` method of `func` to return `string`. * * @private * @param {Function} func The function to modify. * @param {Function} string The `toString` result. * @returns {Function} Returns `func`. */ var setToString = shortOut(baseSetToString); /** * Sets the `toString` method of `wrapper` to mimic the source of `reference` * with wrapper details in a comment at the top of the source body. * * @private * @param {Function} wrapper The function to modify. * @param {Function} reference The reference function. * @param {number} bitmask The bitmask flags. See `createWrap` for more details. * @returns {Function} Returns `wrapper`. */ function setWrapToString(wrapper, reference, bitmask) { var source = reference + ""; return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask))); } /** * Creates a function that'll short out and invoke `identity` instead * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` * milliseconds. * * @private * @param {Function} func The function to restrict. * @returns {Function} Returns the new shortable function. */ function shortOut(func) { var count = 0, lastCalled = 0; return function() { var stamp = nativeNow(), remaining = HOT_SPAN - (stamp - lastCalled); lastCalled = stamp; if (remaining > 0) { if (++count >= HOT_COUNT) { return arguments[0]; } } else { count = 0; } return func.apply(undefined, arguments); }; } /** * A specialized version of `_.shuffle` which mutates and sets the size of `array`. * * @private * @param {Array} array The array to shuffle. * @param {number} [size=array.length] The size of `array`. * @returns {Array} Returns `array`. */ function shuffleSelf(array, size) { var index = -1, length = array.length, lastIndex = length - 1; size = size === undefined ? length : size; while (++index < size) { var rand = baseRandom(index, lastIndex), value = array[rand]; array[rand] = array[index]; array[index] = value; } array.length = size; return array; } /** * Converts `string` to a property path array. * * @private * @param {string} string The string to convert. * @returns {Array} Returns the property path array. */ var stringToPath = memoizeCapped(function(string) { var result = []; if (string.charCodeAt(0) === 46) { result.push(""); } string.replace(rePropName, function(match, number, quote, subString) { result.push(quote ? subString.replace(reEscapeChar, "$1") : number || match); }); return result; }); /** * Converts `value` to a string key if it's not a string or symbol. * * @private * @param {*} value The value to inspect. * @returns {string|symbol} Returns the key. */ function toKey(value) { if (typeof value == "string" || isSymbol(value)) { return value; } var result = value + ""; return result == "0" && 1 / value == -INFINITY ? "-0" : result; } /** * Converts `func` to its source code. * * @private * @param {Function} func The function to convert. * @returns {string} Returns the source code. */ function toSource(func) { if (func != null) { try { return funcToString.call(func); } catch (e) {} try { return func + ""; } catch (e) {} } return ""; } /** * Updates wrapper `details` based on `bitmask` flags. * * @private * @returns {Array} details The details to modify. * @param {number} bitmask The bitmask flags. See `createWrap` for more details. * @returns {Array} Returns `details`. */ function updateWrapDetails(details, bitmask) { arrayEach(wrapFlags, function(pair) { var value = "_." + pair[0]; if (bitmask & pair[1] && !arrayIncludes(details, value)) { details.push(value); } }); return details.sort(); } /** * Creates a clone of `wrapper`. * * @private * @param {Object} wrapper The wrapper to clone. * @returns {Object} Returns the cloned wrapper. */ function wrapperClone(wrapper) { if (wrapper instanceof LazyWrapper) { return wrapper.clone(); } var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__); result.__actions__ = copyArray(wrapper.__actions__); result.__index__ = wrapper.__index__; result.__values__ = wrapper.__values__; return result; } /** * Creates an array of elements split into groups the length of `size`. * If `array` can't be split evenly, the final chunk will be the remaining * elements. * * @static * @memberOf _ * @since 3.0.0 * @category Array * @param {Array} array The array to process. * @param {number} [size=1] The length of each chunk * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. * @returns {Array} Returns the new array of chunks. * @example * * _.chunk(['a', 'b', 'c', 'd'], 2); * // => [['a', 'b'], ['c', 'd']] * * _.chunk(['a', 'b', 'c', 'd'], 3); * // => [['a', 'b', 'c'], ['d']] */ function chunk(array, size, guard) { if (guard ? isIterateeCall(array, size, guard) : size === undefined) { size = 1; } else { size = nativeMax(toInteger(size), 0); } var length = array == null ? 0 : array.length; if (!length || size < 1) { return []; } var index = 0, resIndex = 0, result = Array(nativeCeil(length / size)); while (index < length) { result[resIndex++] = baseSlice(array, index, index += size); } return result; } /** * Creates an array with all falsey values removed. The values `false`, `null`, * `0`, `""`, `undefined`, and `NaN` are falsey. * * @static * @memberOf _ * @since 0.1.0 * @category Array * @param {Array} array The array to compact. * @returns {Array} Returns the new array of filtered values. * @example * * _.compact([0, 1, false, 2, '', 3]); * // => [1, 2, 3] */ function compact(array) { var index = -1, length = array == null ? 0 : array.length, resIndex = 0, result = []; while (++index < length) { var value = array[index]; if (value) { result[resIndex++] = value; } } return result; } /** * Creates a new array concatenating `array` with any additional arrays * and/or values. * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The array to concatenate. * @param {...*} [values] The values to concatenate. * @returns {Array} Returns the new concatenated array. * @example * * var array = [1]; * var other = _.concat(array, 2, [3], [[4]]); * * console.log(other); * // => [1, 2, 3, [4]] * * console.log(array); * // => [1] */ function concat() { var length = arguments.length; if (!length) { return []; } var args = Array(length - 1), array = arguments[0], index = length; while (index--) { args[index - 1] = arguments[index]; } return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1)); } /** * Creates an array of `array` values not included in the other given arrays * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * for equality comparisons. The order and references of result values are * determined by the first array. * * **Note:** Unlike `_.pullAll`, this method returns a new array. * * @static * @memberOf _ * @since 0.1.0 * @category Array * @param {Array} array The array to inspect. * @param {...Array} [values] The values to exclude. * @returns {Array} Returns the new array of filtered values. * @see _.without, _.xor * @example * * _.difference([2, 1], [2, 3]); * // => [1] */ var difference = baseRest(function(array, values) { return isArrayLikeObject(array) ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true)) : []; }); /** * This method is like `_.difference` except that it accepts `iteratee` which * is invoked for each element of `array` and `values` to generate the criterion * by which they're compared. The order and references of result values are * determined by the first array. The iteratee is invoked with one argument: * (value). * * **Note:** Unlike `_.pullAllBy`, this method returns a new array. * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The array to inspect. * @param {...Array} [values] The values to exclude. * @param {Function} [iteratee=_.identity] The iteratee invoked per element. * @returns {Array} Returns the new array of filtered values. * @example * * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor); * // => [1.2] * * // The `_.property` iteratee shorthand. * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x'); * // => [{ 'x': 2 }] */ var differenceBy = baseRest(function(array, values) { var iteratee = last(values); if (isArrayLikeObject(iteratee)) { iteratee = undefined; } return isArrayLikeObject(array) ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2)) : []; }); /** * This method is like `_.difference` except that it accepts `comparator` * which is invoked to compare elements of `array` to `values`. The order and * references of result values are determined by the first array. The comparator * is invoked with two arguments: (arrVal, othVal). * * **Note:** Unlike `_.pullAllWith`, this method returns a new array. * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The array to inspect. * @param {...Array} [values] The values to exclude. * @param {Function} [comparator] The comparator invoked per element. * @returns {Array} Returns the new array of filtered values. * @example * * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; * * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual); * // => [{ 'x': 2, 'y': 1 }] */ var differenceWith = baseRest(function(array, values) { var comparator = last(values); if (isArrayLikeObject(comparator)) { comparator = undefined; } return isArrayLikeObject(array) ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator) : []; }); /** * Creates a slice of `array` with `n` elements dropped from the beginning. * * @static * @memberOf _ * @since 0.5.0 * @category Array * @param {Array} array The array to query. * @param {number} [n=1] The number of elements to drop. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. * @returns {Array} Returns the slice of `array`. * @example * * _.drop([1, 2, 3]); * // => [2, 3] * * _.drop([1, 2, 3], 2); * // => [3] * * _.drop([1, 2, 3], 5); * // => [] * * _.drop([1, 2, 3], 0); * // => [1, 2, 3] */ function drop(array, n, guard) { var length = array == null ? 0 : array.length; if (!length) { return []; } n = guard || n === undefined ? 1 : toInteger(n); return baseSlice(array, n < 0 ? 0 : n, length); } /** * Creates a slice of `array` with `n` elements dropped from the end. * * @static * @memberOf _ * @since 3.0.0 * @category Array * @param {Array} array The array to query. * @param {number} [n=1] The number of elements to drop. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. * @returns {Array} Returns the slice of `array`. * @example * * _.dropRight([1, 2, 3]); * // => [1, 2] * * _.dropRight([1, 2, 3], 2); * // => [1] * * _.dropRight([1, 2, 3], 5); * // => [] * * _.dropRight([1, 2, 3], 0); * // => [1, 2, 3] */ function dropRight(array, n, guard) { var length = array == null ? 0 : array.length; if (!length) { return []; } n = guard || n === undefined ? 1 : toInteger(n); n = length - n; return baseSlice(array, 0, n < 0 ? 0 : n); } /** * Creates a slice of `array` excluding elements dropped from the end. * Elements are dropped until `predicate` returns falsey. The predicate is * invoked with three arguments: (value, index, array). * * @static * @memberOf _ * @since 3.0.0 * @category Array * @param {Array} array The array to query. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @returns {Array} Returns the slice of `array`. * @example * * var users = [ * { 'user': 'barney', 'active': true }, * { 'user': 'fred', 'active': false }, * { 'user': 'pebbles', 'active': false } * ]; * * _.dropRightWhile(users, function(o) { return !o.active; }); * // => objects for ['barney'] * * // The `_.matches` iteratee shorthand. * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false }); * // => objects for ['barney', 'fred'] * * // The `_.matchesProperty` iteratee shorthand. * _.dropRightWhile(users, ['active', false]); * // => objects for ['barney'] * * // The `_.property` iteratee shorthand. * _.dropRightWhile(users, 'active'); * // => objects for ['barney', 'fred', 'pebbles'] */ function dropRightWhile(array, predicate) { return array && array.length ? baseWhile(array, getIteratee(predicate, 3), true, true) : []; } /** * Creates a slice of `array` excluding elements dropped from the beginning. * Elements are dropped until `predicate` returns falsey. The predicate is * invoked with three arguments: (value, index, array). * * @static * @memberOf _ * @since 3.0.0 * @category Array * @param {Array} array The array to query. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @returns {Array} Returns the slice of `array`. * @example * * var users = [ * { 'user': 'barney', 'active': false }, * { 'user': 'fred', 'active': false }, * { 'user': 'pebbles', 'active': true } * ]; * * _.dropWhile(users, function(o) { return !o.active; }); * // => objects for ['pebbles'] * * // The `_.matches` iteratee shorthand. * _.dropWhile(users, { 'user': 'barney', 'active': false }); * // => objects for ['fred', 'pebbles'] * * // The `_.matchesProperty` iteratee shorthand. * _.dropWhile(users, ['active', false]); * // => objects for ['pebbles'] * * // The `_.property` iteratee shorthand. * _.dropWhile(users, 'active'); * // => objects for ['barney', 'fred', 'pebbles'] */ function dropWhile(array, predicate) { return array && array.length ? baseWhile(array, getIteratee(predicate, 3), true) : []; } /** * Fills elements of `array` with `value` from `start` up to, but not * including, `end`. * * **Note:** This method mutates `array`. * * @static * @memberOf _ * @since 3.2.0 * @category Array * @param {Array} array The array to fill. * @param {*} value The value to fill `array` with. * @param {number} [start=0] The start position. * @param {number} [end=array.length] The end position. * @returns {Array} Returns `array`. * @example * * var array = [1, 2, 3]; * * _.fill(array, 'a'); * console.log(array); * // => ['a', 'a', 'a'] * * _.fill(Array(3), 2); * // => [2, 2, 2] * * _.fill([4, 6, 8, 10], '*', 1, 3); * // => [4, '*', '*', 10] */ function fill(array, value, start, end) { var length = array == null ? 0 : array.length; if (!length) { return []; } if (start && typeof start != "number" && isIterateeCall(array, value, start)) { start = 0; end = length; } return baseFill(array, value, start, end); } /** * This method is like `_.find` except that it returns the index of the first * element `predicate` returns truthy for instead of the element itself. * * @static * @memberOf _ * @since 1.1.0 * @category Array * @param {Array} array The array to inspect. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @param {number} [fromIndex=0] The index to search from. * @returns {number} Returns the index of the found element, else `-1`. * @example * * var users = [ * { 'user': 'barney', 'active': false }, * { 'user': 'fred', 'active': false }, * { 'user': 'pebbles', 'active': true } * ]; * * _.findIndex(users, function(o) { return o.user == 'barney'; }); * // => 0 * * // The `_.matches` iteratee shorthand. * _.findIndex(users, { 'user': 'fred', 'active': false }); * // => 1 * * // The `_.matchesProperty` iteratee shorthand. * _.findIndex(users, ['active', false]); * // => 0 * * // The `_.property` iteratee shorthand. * _.findIndex(users, 'active'); * // => 2 */ function findIndex(array, predicate, fromIndex) { var length = array == null ? 0 : array.length; if (!length) { return -1; } var index = fromIndex == null ? 0 : toInteger(fromIndex); if (index < 0) { index = nativeMax(length + index, 0); } return baseFindIndex(array, getIteratee(predicate, 3), index); } /** * This method is like `_.findIndex` except that it iterates over elements * of `collection` from right to left. * * @static * @memberOf _ * @since 2.0.0 * @category Array * @param {Array} array The array to inspect. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @param {number} [fromIndex=array.length-1] The index to search from. * @returns {number} Returns the index of the found element, else `-1`. * @example * * var users = [ * { 'user': 'barney', 'active': true }, * { 'user': 'fred', 'active': false }, * { 'user': 'pebbles', 'active': false } * ]; * * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; }); * // => 2 * * // The `_.matches` iteratee shorthand. * _.findLastIndex(users, { 'user': 'barney', 'active': true }); * // => 0 * * // The `_.matchesProperty` iteratee shorthand. * _.findLastIndex(users, ['active', false]); * // => 2 * * // The `_.property` iteratee shorthand. * _.findLastIndex(users, 'active'); * // => 0 */ function findLastIndex(array, predicate, fromIndex) { var length = array == null ? 0 : array.length; if (!length) { return -1; } var index = length - 1; if (fromIndex !== undefined) { index = toInteger(fromIndex); index = fromIndex < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1); } return baseFindIndex(array, getIteratee(predicate, 3), index, true); } /** * Flattens `array` a single level deep. * * @static * @memberOf _ * @since 0.1.0 * @category Array * @param {Array} array The array to flatten. * @returns {Array} Returns the new flattened array. * @example * * _.flatten([1, [2, [3, [4]], 5]]); * // => [1, 2, [3, [4]], 5] */ function flatten(array) { var length = array == null ? 0 : array.length; return length ? baseFlatten(array, 1) : []; } /** * Recursively flattens `array`. * * @static * @memberOf _ * @since 3.0.0 * @category Array * @param {Array} array The array to flatten. * @returns {Array} Returns the new flattened array. * @example * * _.flattenDeep([1, [2, [3, [4]], 5]]); * // => [1, 2, 3, 4, 5] */ function flattenDeep(array) { var length = array == null ? 0 : array.length; return length ? baseFlatten(array, INFINITY) : []; } /** * Recursively flatten `array` up to `depth` times. * * @static * @memberOf _ * @since 4.4.0 * @category Array * @param {Array} array The array to flatten. * @param {number} [depth=1] The maximum recursion depth. * @returns {Array} Returns the new flattened array. * @example * * var array = [1, [2, [3, [4]], 5]]; * * _.flattenDepth(array, 1); * // => [1, 2, [3, [4]], 5] * * _.flattenDepth(array, 2); * // => [1, 2, 3, [4], 5] */ function flattenDepth(array, depth) { var length = array == null ? 0 : array.length; if (!length) { return []; } depth = depth === undefined ? 1 : toInteger(depth); return baseFlatten(array, depth); } /** * The inverse of `_.toPairs`; this method returns an object composed * from key-value `pairs`. * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} pairs The key-value pairs. * @returns {Object} Returns the new object. * @example * * _.fromPairs([['a', 1], ['b', 2]]); * // => { 'a': 1, 'b': 2 } */ function fromPairs(pairs) { var index = -1, length = pairs == null ? 0 : pairs.length, result = {}; while (++index < length) { var pair = pairs[index]; result[pair[0]] = pair[1]; } return result; } /** * Gets the first element of `array`. * * @static * @memberOf _ * @since 0.1.0 * @alias first * @category Array * @param {Array} array The array to query. * @returns {*} Returns the first element of `array`. * @example * * _.head([1, 2, 3]); * // => 1 * * _.head([]); * // => undefined */ function head(array) { return array && array.length ? array[0] : undefined; } /** * Gets the index at which the first occurrence of `value` is found in `array` * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * for equality comparisons. If `fromIndex` is negative, it's used as the * offset from the end of `array`. * * @static * @memberOf _ * @since 0.1.0 * @category Array * @param {Array} array The array to inspect. * @param {*} value The value to search for. * @param {number} [fromIndex=0] The index to search from. * @returns {number} Returns the index of the matched value, else `-1`. * @example * * _.indexOf([1, 2, 1, 2], 2); * // => 1 * * // Search from the `fromIndex`. * _.indexOf([1, 2, 1, 2], 2, 2); * // => 3 */ function indexOf(array, value, fromIndex) { var length = array == null ? 0 : array.length; if (!length) { return -1; } var index = fromIndex == null ? 0 : toInteger(fromIndex); if (index < 0) { index = nativeMax(length + index, 0); } return baseIndexOf(array, value, index); } /** * Gets all but the last element of `array`. * * @static * @memberOf _ * @since 0.1.0 * @category Array * @param {Array} array The array to query. * @returns {Array} Returns the slice of `array`. * @example * * _.initial([1, 2, 3]); * // => [1, 2] */ function initial(array) { var length = array == null ? 0 : array.length; return length ? baseSlice(array, 0, -1) : []; } /** * Creates an array of unique values that are included in all given arrays * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * for equality comparisons. The order and references of result values are * determined by the first array. * * @static * @memberOf _ * @since 0.1.0 * @category Array * @param {...Array} [arrays] The arrays to inspect. * @returns {Array} Returns the new array of intersecting values. * @example * * _.intersection([2, 1], [2, 3]); * // => [2] */ var intersection = baseRest(function(arrays) { var mapped = arrayMap(arrays, castArrayLikeObject); return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped) : []; }); /** * This method is like `_.intersection` except that it accepts `iteratee` * which is invoked for each element of each `arrays` to generate the criterion * by which they're compared. The order and references of result values are * determined by the first array. The iteratee is invoked with one argument: * (value). * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {...Array} [arrays] The arrays to inspect. * @param {Function} [iteratee=_.identity] The iteratee invoked per element. * @returns {Array} Returns the new array of intersecting values. * @example * * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor); * // => [2.1] * * // The `_.property` iteratee shorthand. * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); * // => [{ 'x': 1 }] */ var intersectionBy = baseRest(function(arrays) { var iteratee = last(arrays), mapped = arrayMap(arrays, castArrayLikeObject); if (iteratee === last(mapped)) { iteratee = undefined; } else { mapped.pop(); } return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped, getIteratee(iteratee, 2)) : []; }); /** * This method is like `_.intersection` except that it accepts `comparator` * which is invoked to compare elements of `arrays`. The order and references * of result values are determined by the first array. The comparator is * invoked with two arguments: (arrVal, othVal). * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {...Array} [arrays] The arrays to inspect. * @param {Function} [comparator] The comparator invoked per element. * @returns {Array} Returns the new array of intersecting values. * @example * * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; * * _.intersectionWith(objects, others, _.isEqual); * // => [{ 'x': 1, 'y': 2 }] */ var intersectionWith = baseRest(function(arrays) { var comparator = last(arrays), mapped = arrayMap(arrays, castArrayLikeObject); comparator = typeof comparator == "function" ? comparator : undefined; if (comparator) { mapped.pop(); } return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped, undefined, comparator) : []; }); /** * Converts all elements in `array` into a string separated by `separator`. * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The array to convert. * @param {string} [separator=','] The element separator. * @returns {string} Returns the joined string. * @example * * _.join(['a', 'b', 'c'], '~'); * // => 'a~b~c' */ function join(array, separator) { return array == null ? "" : nativeJoin.call(array, separator); } /** * Gets the last element of `array`. * * @static * @memberOf _ * @since 0.1.0 * @category Array * @param {Array} array The array to query. * @returns {*} Returns the last element of `array`. * @example * * _.last([1, 2, 3]); * // => 3 */ function last(array) { var length = array == null ? 0 : array.length; return length ? array[length - 1] : undefined; } /** * This method is like `_.indexOf` except that it iterates over elements of * `array` from right to left. * * @static * @memberOf _ * @since 0.1.0 * @category Array * @param {Array} array The array to inspect. * @param {*} value The value to search for. * @param {number} [fromIndex=array.length-1] The index to search from. * @returns {number} Returns the index of the matched value, else `-1`. * @example * * _.lastIndexOf([1, 2, 1, 2], 2); * // => 3 * * // Search from the `fromIndex`. * _.lastIndexOf([1, 2, 1, 2], 2, 2); * // => 1 */ function lastIndexOf(array, value, fromIndex) { var length = array == null ? 0 : array.length; if (!length) { return -1; } var index = length; if (fromIndex !== undefined) { index = toInteger(fromIndex); index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1); } return value === value ? strictLastIndexOf(array, value, index) : baseFindIndex(array, baseIsNaN, index, true); } /** * Gets the element at index `n` of `array`. If `n` is negative, the nth * element from the end is returned. * * @static * @memberOf _ * @since 4.11.0 * @category Array * @param {Array} array The array to query. * @param {number} [n=0] The index of the element to return. * @returns {*} Returns the nth element of `array`. * @example * * var array = ['a', 'b', 'c', 'd']; * * _.nth(array, 1); * // => 'b' * * _.nth(array, -2); * // => 'c'; */ function nth(array, n) { return array && array.length ? baseNth(array, toInteger(n)) : undefined; } /** * Removes all given values from `array` using * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * for equality comparisons. * * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove` * to remove elements from an array by predicate. * * @static * @memberOf _ * @since 2.0.0 * @category Array * @param {Array} array The array to modify. * @param {...*} [values] The values to remove. * @returns {Array} Returns `array`. * @example * * var array = ['a', 'b', 'c', 'a', 'b', 'c']; * * _.pull(array, 'a', 'c'); * console.log(array); * // => ['b', 'b'] */ var pull = baseRest(pullAll); /** * This method is like `_.pull` except that it accepts an array of values to remove. * * **Note:** Unlike `_.difference`, this method mutates `array`. * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The array to modify. * @param {Array} values The values to remove. * @returns {Array} Returns `array`. * @example * * var array = ['a', 'b', 'c', 'a', 'b', 'c']; * * _.pullAll(array, ['a', 'c']); * console.log(array); * // => ['b', 'b'] */ function pullAll(array, values) { return array && array.length && values && values.length ? basePullAll(array, values) : array; } /** * This method is like `_.pullAll` except that it accepts `iteratee` which is * invoked for each element of `array` and `values` to generate the criterion * by which they're compared. The iteratee is invoked with one argument: (value). * * **Note:** Unlike `_.differenceBy`, this method mutates `array`. * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The array to modify. * @param {Array} values The values to remove. * @param {Function} [iteratee=_.identity] The iteratee invoked per element. * @returns {Array} Returns `array`. * @example * * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }]; * * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x'); * console.log(array); * // => [{ 'x': 2 }] */ function pullAllBy(array, values, iteratee) { return array && array.length && values && values.length ? basePullAll(array, values, getIteratee(iteratee, 2)) : array; } /** * This method is like `_.pullAll` except that it accepts `comparator` which * is invoked to compare elements of `array` to `values`. The comparator is * invoked with two arguments: (arrVal, othVal). * * **Note:** Unlike `_.differenceWith`, this method mutates `array`. * * @static * @memberOf _ * @since 4.6.0 * @category Array * @param {Array} array The array to modify. * @param {Array} values The values to remove. * @param {Function} [comparator] The comparator invoked per element. * @returns {Array} Returns `array`. * @example * * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }]; * * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual); * console.log(array); * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }] */ function pullAllWith(array, values, comparator) { return array && array.length && values && values.length ? basePullAll(array, values, undefined, comparator) : array; } /** * Removes elements from `array` corresponding to `indexes` and returns an * array of removed elements. * * **Note:** Unlike `_.at`, this method mutates `array`. * * @static * @memberOf _ * @since 3.0.0 * @category Array * @param {Array} array The array to modify. * @param {...(number|number[])} [indexes] The indexes of elements to remove. * @returns {Array} Returns the new array of removed elements. * @example * * var array = ['a', 'b', 'c', 'd']; * var pulled = _.pullAt(array, [1, 3]); * * console.log(array); * // => ['a', 'c'] * * console.log(pulled); * // => ['b', 'd'] */ var pullAt = flatRest(function(array, indexes) { var length = array == null ? 0 : array.length, result = baseAt(array, indexes); basePullAt(array, arrayMap(indexes, function(index) { return isIndex(index, length) ? +index : index; }).sort(compareAscending)); return result; }); /** * Removes all elements from `array` that `predicate` returns truthy for * and returns an array of the removed elements. The predicate is invoked * with three arguments: (value, index, array). * * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull` * to pull elements from an array by value. * * @static * @memberOf _ * @since 2.0.0 * @category Array * @param {Array} array The array to modify. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @returns {Array} Returns the new array of removed elements. * @example * * var array = [1, 2, 3, 4]; * var evens = _.remove(array, function(n) { * return n % 2 == 0; * }); * * console.log(array); * // => [1, 3] * * console.log(evens); * // => [2, 4] */ function remove(array, predicate) { var result = []; if (!(array && array.length)) { return result; } var index = -1, indexes = [], length = array.length; predicate = getIteratee(predicate, 3); while (++index < length) { var value = array[index]; if (predicate(value, index, array)) { result.push(value); indexes.push(index); } } basePullAt(array, indexes); return result; } /** * Reverses `array` so that the first element becomes the last, the second * element becomes the second to last, and so on. * * **Note:** This method mutates `array` and is based on * [`Array#reverse`](https://mdn.io/Array/reverse). * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The array to modify. * @returns {Array} Returns `array`. * @example * * var array = [1, 2, 3]; * * _.reverse(array); * // => [3, 2, 1] * * console.log(array); * // => [3, 2, 1] */ function reverse(array) { return array == null ? array : nativeReverse.call(array); } /** * Creates a slice of `array` from `start` up to, but not including, `end`. * * **Note:** This method is used instead of * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are * returned. * * @static * @memberOf _ * @since 3.0.0 * @category Array * @param {Array} array The array to slice. * @param {number} [start=0] The start position. * @param {number} [end=array.length] The end position. * @returns {Array} Returns the slice of `array`. */ function slice(array, start, end) { var length = array == null ? 0 : array.length; if (!length) { return []; } if (end && typeof end != "number" && isIterateeCall(array, start, end)) { start = 0; end = length; } else { start = start == null ? 0 : toInteger(start); end = end === undefined ? length : toInteger(end); } return baseSlice(array, start, end); } /** * Uses a binary search to determine the lowest index at which `value` * should be inserted into `array` in order to maintain its sort order. * * @static * @memberOf _ * @since 0.1.0 * @category Array * @param {Array} array The sorted array to inspect. * @param {*} value The value to evaluate. * @returns {number} Returns the index at which `value` should be inserted * into `array`. * @example * * _.sortedIndex([30, 50], 40); * // => 1 */ function sortedIndex(array, value) { return baseSortedIndex(array, value); } /** * This method is like `_.sortedIndex` except that it accepts `iteratee` * which is invoked for `value` and each element of `array` to compute their * sort ranking. The iteratee is invoked with one argument: (value). * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The sorted array to inspect. * @param {*} value The value to evaluate. * @param {Function} [iteratee=_.identity] The iteratee invoked per element. * @returns {number} Returns the index at which `value` should be inserted * into `array`. * @example * * var objects = [{ 'x': 4 }, { 'x': 5 }]; * * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; }); * // => 0 * * // The `_.property` iteratee shorthand. * _.sortedIndexBy(objects, { 'x': 4 }, 'x'); * // => 0 */ function sortedIndexBy(array, value, iteratee) { return baseSortedIndexBy(array, value, getIteratee(iteratee, 2)); } /** * This method is like `_.indexOf` except that it performs a binary * search on a sorted `array`. * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The array to inspect. * @param {*} value The value to search for. * @returns {number} Returns the index of the matched value, else `-1`. * @example * * _.sortedIndexOf([4, 5, 5, 5, 6], 5); * // => 1 */ function sortedIndexOf(array, value) { var length = array == null ? 0 : array.length; if (length) { var index = baseSortedIndex(array, value); if (index < length && eq(array[index], value)) { return index; } } return -1; } /** * This method is like `_.sortedIndex` except that it returns the highest * index at which `value` should be inserted into `array` in order to * maintain its sort order. * * @static * @memberOf _ * @since 3.0.0 * @category Array * @param {Array} array The sorted array to inspect. * @param {*} value The value to evaluate. * @returns {number} Returns the index at which `value` should be inserted * into `array`. * @example * * _.sortedLastIndex([4, 5, 5, 5, 6], 5); * // => 4 */ function sortedLastIndex(array, value) { return baseSortedIndex(array, value, true); } /** * This method is like `_.sortedLastIndex` except that it accepts `iteratee` * which is invoked for `value` and each element of `array` to compute their * sort ranking. The iteratee is invoked with one argument: (value). * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The sorted array to inspect. * @param {*} value The value to evaluate. * @param {Function} [iteratee=_.identity] The iteratee invoked per element. * @returns {number} Returns the index at which `value` should be inserted * into `array`. * @example * * var objects = [{ 'x': 4 }, { 'x': 5 }]; * * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; }); * // => 1 * * // The `_.property` iteratee shorthand. * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x'); * // => 1 */ function sortedLastIndexBy(array, value, iteratee) { return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true); } /** * This method is like `_.lastIndexOf` except that it performs a binary * search on a sorted `array`. * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The array to inspect. * @param {*} value The value to search for. * @returns {number} Returns the index of the matched value, else `-1`. * @example * * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5); * // => 3 */ function sortedLastIndexOf(array, value) { var length = array == null ? 0 : array.length; if (length) { var index = baseSortedIndex(array, value, true) - 1; if (eq(array[index], value)) { return index; } } return -1; } /** * This method is like `_.uniq` except that it's designed and optimized * for sorted arrays. * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The array to inspect. * @returns {Array} Returns the new duplicate free array. * @example * * _.sortedUniq([1, 1, 2]); * // => [1, 2] */ function sortedUniq(array) { return array && array.length ? baseSortedUniq(array) : []; } /** * This method is like `_.uniqBy` except that it's designed and optimized * for sorted arrays. * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The array to inspect. * @param {Function} [iteratee] The iteratee invoked per element. * @returns {Array} Returns the new duplicate free array. * @example * * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor); * // => [1.1, 2.3] */ function sortedUniqBy(array, iteratee) { return array && array.length ? baseSortedUniq(array, getIteratee(iteratee, 2)) : []; } /** * Gets all but the first element of `array`. * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The array to query. * @returns {Array} Returns the slice of `array`. * @example * * _.tail([1, 2, 3]); * // => [2, 3] */ function tail(array) { var length = array == null ? 0 : array.length; return length ? baseSlice(array, 1, length) : []; } /** * Creates a slice of `array` with `n` elements taken from the beginning. * * @static * @memberOf _ * @since 0.1.0 * @category Array * @param {Array} array The array to query. * @param {number} [n=1] The number of elements to take. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. * @returns {Array} Returns the slice of `array`. * @example * * _.take([1, 2, 3]); * // => [1] * * _.take([1, 2, 3], 2); * // => [1, 2] * * _.take([1, 2, 3], 5); * // => [1, 2, 3] * * _.take([1, 2, 3], 0); * // => [] */ function take(array, n, guard) { if (!(array && array.length)) { return []; } n = guard || n === undefined ? 1 : toInteger(n); return baseSlice(array, 0, n < 0 ? 0 : n); } /** * Creates a slice of `array` with `n` elements taken from the end. * * @static * @memberOf _ * @since 3.0.0 * @category Array * @param {Array} array The array to query. * @param {number} [n=1] The number of elements to take. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. * @returns {Array} Returns the slice of `array`. * @example * * _.takeRight([1, 2, 3]); * // => [3] * * _.takeRight([1, 2, 3], 2); * // => [2, 3] * * _.takeRight([1, 2, 3], 5); * // => [1, 2, 3] * * _.takeRight([1, 2, 3], 0); * // => [] */ function takeRight(array, n, guard) { var length = array == null ? 0 : array.length; if (!length) { return []; } n = guard || n === undefined ? 1 : toInteger(n); n = length - n; return baseSlice(array, n < 0 ? 0 : n, length); } /** * Creates a slice of `array` with elements taken from the end. Elements are * taken until `predicate` returns falsey. The predicate is invoked with * three arguments: (value, index, array). * * @static * @memberOf _ * @since 3.0.0 * @category Array * @param {Array} array The array to query. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @returns {Array} Returns the slice of `array`. * @example * * var users = [ * { 'user': 'barney', 'active': true }, * { 'user': 'fred', 'active': false }, * { 'user': 'pebbles', 'active': false } * ]; * * _.takeRightWhile(users, function(o) { return !o.active; }); * // => objects for ['fred', 'pebbles'] * * // The `_.matches` iteratee shorthand. * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false }); * // => objects for ['pebbles'] * * // The `_.matchesProperty` iteratee shorthand. * _.takeRightWhile(users, ['active', false]); * // => objects for ['fred', 'pebbles'] * * // The `_.property` iteratee shorthand. * _.takeRightWhile(users, 'active'); * // => [] */ function takeRightWhile(array, predicate) { return array && array.length ? baseWhile(array, getIteratee(predicate, 3), false, true) : []; } /** * Creates a slice of `array` with elements taken from the beginning. Elements * are taken until `predicate` returns falsey. The predicate is invoked with * three arguments: (value, index, array). * * @static * @memberOf _ * @since 3.0.0 * @category Array * @param {Array} array The array to query. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @returns {Array} Returns the slice of `array`. * @example * * var users = [ * { 'user': 'barney', 'active': false }, * { 'user': 'fred', 'active': false }, * { 'user': 'pebbles', 'active': true } * ]; * * _.takeWhile(users, function(o) { return !o.active; }); * // => objects for ['barney', 'fred'] * * // The `_.matches` iteratee shorthand. * _.takeWhile(users, { 'user': 'barney', 'active': false }); * // => objects for ['barney'] * * // The `_.matchesProperty` iteratee shorthand. * _.takeWhile(users, ['active', false]); * // => objects for ['barney', 'fred'] * * // The `_.property` iteratee shorthand. * _.takeWhile(users, 'active'); * // => [] */ function takeWhile(array, predicate) { return array && array.length ? baseWhile(array, getIteratee(predicate, 3)) : []; } /** * Creates an array of unique values, in order, from all given arrays using * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * for equality comparisons. * * @static * @memberOf _ * @since 0.1.0 * @category Array * @param {...Array} [arrays] The arrays to inspect. * @returns {Array} Returns the new array of combined values. * @example * * _.union([2], [1, 2]); * // => [2, 1] */ var union = baseRest(function(arrays) { return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true)); }); /** * This method is like `_.union` except that it accepts `iteratee` which is * invoked for each element of each `arrays` to generate the criterion by * which uniqueness is computed. Result values are chosen from the first * array in which the value occurs. The iteratee is invoked with one argument: * (value). * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {...Array} [arrays] The arrays to inspect. * @param {Function} [iteratee=_.identity] The iteratee invoked per element. * @returns {Array} Returns the new array of combined values. * @example * * _.unionBy([2.1], [1.2, 2.3], Math.floor); * // => [2.1, 1.2] * * // The `_.property` iteratee shorthand. * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); * // => [{ 'x': 1 }, { 'x': 2 }] */ var unionBy = baseRest(function(arrays) { var iteratee = last(arrays); if (isArrayLikeObject(iteratee)) { iteratee = undefined; } return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2)); }); /** * This method is like `_.union` except that it accepts `comparator` which * is invoked to compare elements of `arrays`. Result values are chosen from * the first array in which the value occurs. The comparator is invoked * with two arguments: (arrVal, othVal). * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {...Array} [arrays] The arrays to inspect. * @param {Function} [comparator] The comparator invoked per element. * @returns {Array} Returns the new array of combined values. * @example * * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; * * _.unionWith(objects, others, _.isEqual); * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] */ var unionWith = baseRest(function(arrays) { var comparator = last(arrays); comparator = typeof comparator == "function" ? comparator : undefined; return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator); }); /** * Creates a duplicate-free version of an array, using * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * for equality comparisons, in which only the first occurrence of each element * is kept. The order of result values is determined by the order they occur * in the array. * * @static * @memberOf _ * @since 0.1.0 * @category Array * @param {Array} array The array to inspect. * @returns {Array} Returns the new duplicate free array. * @example * * _.uniq([2, 1, 2]); * // => [2, 1] */ function uniq(array) { return array && array.length ? baseUniq(array) : []; } /** * This method is like `_.uniq` except that it accepts `iteratee` which is * invoked for each element in `array` to generate the criterion by which * uniqueness is computed. The order of result values is determined by the * order they occur in the array. The iteratee is invoked with one argument: * (value). * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The array to inspect. * @param {Function} [iteratee=_.identity] The iteratee invoked per element. * @returns {Array} Returns the new duplicate free array. * @example * * _.uniqBy([2.1, 1.2, 2.3], Math.floor); * // => [2.1, 1.2] * * // The `_.property` iteratee shorthand. * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); * // => [{ 'x': 1 }, { 'x': 2 }] */ function uniqBy(array, iteratee) { return array && array.length ? baseUniq(array, getIteratee(iteratee, 2)) : []; } /** * This method is like `_.uniq` except that it accepts `comparator` which * is invoked to compare elements of `array`. The order of result values is * determined by the order they occur in the array.The comparator is invoked * with two arguments: (arrVal, othVal). * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The array to inspect. * @param {Function} [comparator] The comparator invoked per element. * @returns {Array} Returns the new duplicate free array. * @example * * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }]; * * _.uniqWith(objects, _.isEqual); * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }] */ function uniqWith(array, comparator) { comparator = typeof comparator == "function" ? comparator : undefined; return array && array.length ? baseUniq(array, undefined, comparator) : []; } /** * This method is like `_.zip` except that it accepts an array of grouped * elements and creates an array regrouping the elements to their pre-zip * configuration. * * @static * @memberOf _ * @since 1.2.0 * @category Array * @param {Array} array The array of grouped elements to process. * @returns {Array} Returns the new array of regrouped elements. * @example * * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]); * // => [['a', 1, true], ['b', 2, false]] * * _.unzip(zipped); * // => [['a', 'b'], [1, 2], [true, false]] */ function unzip(array) { if (!(array && array.length)) { return []; } var length = 0; array = arrayFilter(array, function(group) { if (isArrayLikeObject(group)) { length = nativeMax(group.length, length); return true; } }); return baseTimes(length, function(index) { return arrayMap(array, baseProperty(index)); }); } /** * This method is like `_.unzip` except that it accepts `iteratee` to specify * how regrouped values should be combined. The iteratee is invoked with the * elements of each group: (...group). * * @static * @memberOf _ * @since 3.8.0 * @category Array * @param {Array} array The array of grouped elements to process. * @param {Function} [iteratee=_.identity] The function to combine * regrouped values. * @returns {Array} Returns the new array of regrouped elements. * @example * * var zipped = _.zip([1, 2], [10, 20], [100, 200]); * // => [[1, 10, 100], [2, 20, 200]] * * _.unzipWith(zipped, _.add); * // => [3, 30, 300] */ function unzipWith(array, iteratee) { if (!(array && array.length)) { return []; } var result = unzip(array); if (iteratee == null) { return result; } return arrayMap(result, function(group) { return apply(iteratee, undefined, group); }); } /** * Creates an array excluding all given values using * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * for equality comparisons. * * **Note:** Unlike `_.pull`, this method returns a new array. * * @static * @memberOf _ * @since 0.1.0 * @category Array * @param {Array} array The array to inspect. * @param {...*} [values] The values to exclude. * @returns {Array} Returns the new array of filtered values. * @see _.difference, _.xor * @example * * _.without([2, 1, 2, 3], 1, 2); * // => [3] */ var without = baseRest(function(array, values) { return isArrayLikeObject(array) ? baseDifference(array, values) : []; }); /** * Creates an array of unique values that is the * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) * of the given arrays. The order of result values is determined by the order * they occur in the arrays. * * @static * @memberOf _ * @since 2.4.0 * @category Array * @param {...Array} [arrays] The arrays to inspect. * @returns {Array} Returns the new array of filtered values. * @see _.difference, _.without * @example * * _.xor([2, 1], [2, 3]); * // => [1, 3] */ var xor = baseRest(function(arrays) { return baseXor(arrayFilter(arrays, isArrayLikeObject)); }); /** * This method is like `_.xor` except that it accepts `iteratee` which is * invoked for each element of each `arrays` to generate the criterion by * which by which they're compared. The order of result values is determined * by the order they occur in the arrays. The iteratee is invoked with one * argument: (value). * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {...Array} [arrays] The arrays to inspect. * @param {Function} [iteratee=_.identity] The iteratee invoked per element. * @returns {Array} Returns the new array of filtered values. * @example * * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor); * // => [1.2, 3.4] * * // The `_.property` iteratee shorthand. * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); * // => [{ 'x': 2 }] */ var xorBy = baseRest(function(arrays) { var iteratee = last(arrays); if (isArrayLikeObject(iteratee)) { iteratee = undefined; } return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2)); }); /** * This method is like `_.xor` except that it accepts `comparator` which is * invoked to compare elements of `arrays`. The order of result values is * determined by the order they occur in the arrays. The comparator is invoked * with two arguments: (arrVal, othVal). * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {...Array} [arrays] The arrays to inspect. * @param {Function} [comparator] The comparator invoked per element. * @returns {Array} Returns the new array of filtered values. * @example * * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; * * _.xorWith(objects, others, _.isEqual); * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] */ var xorWith = baseRest(function(arrays) { var comparator = last(arrays); comparator = typeof comparator == "function" ? comparator : undefined; return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator); }); /** * Creates an array of grouped elements, the first of which contains the * first elements of the given arrays, the second of which contains the * second elements of the given arrays, and so on. * * @static * @memberOf _ * @since 0.1.0 * @category Array * @param {...Array} [arrays] The arrays to process. * @returns {Array} Returns the new array of grouped elements. * @example * * _.zip(['a', 'b'], [1, 2], [true, false]); * // => [['a', 1, true], ['b', 2, false]] */ var zip = baseRest(unzip); /** * This method is like `_.fromPairs` except that it accepts two arrays, * one of property identifiers and one of corresponding values. * * @static * @memberOf _ * @since 0.4.0 * @category Array * @param {Array} [props=[]] The property identifiers. * @param {Array} [values=[]] The property values. * @returns {Object} Returns the new object. * @example * * _.zipObject(['a', 'b'], [1, 2]); * // => { 'a': 1, 'b': 2 } */ function zipObject(props, values) { return baseZipObject(props || [], values || [], assignValue); } /** * This method is like `_.zipObject` except that it supports property paths. * * @static * @memberOf _ * @since 4.1.0 * @category Array * @param {Array} [props=[]] The property identifiers. * @param {Array} [values=[]] The property values. * @returns {Object} Returns the new object. * @example * * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]); * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } } */ function zipObjectDeep(props, values) { return baseZipObject(props || [], values || [], baseSet); } /** * This method is like `_.zip` except that it accepts `iteratee` to specify * how grouped values should be combined. The iteratee is invoked with the * elements of each group: (...group). * * @static * @memberOf _ * @since 3.8.0 * @category Array * @param {...Array} [arrays] The arrays to process. * @param {Function} [iteratee=_.identity] The function to combine * grouped values. * @returns {Array} Returns the new array of grouped elements. * @example * * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) { * return a + b + c; * }); * // => [111, 222] */ var zipWith = baseRest(function(arrays) { var length = arrays.length, iteratee = length > 1 ? arrays[length - 1] : undefined; iteratee = typeof iteratee == "function" ? (arrays.pop(), iteratee) : undefined; return unzipWith(arrays, iteratee); }); /** * Creates a `lodash` wrapper instance that wraps `value` with explicit method * chain sequences enabled. The result of such sequences must be unwrapped * with `_#value`. * * @static * @memberOf _ * @since 1.3.0 * @category Seq * @param {*} value The value to wrap. * @returns {Object} Returns the new `lodash` wrapper instance. * @example * * var users = [ * { 'user': 'barney', 'age': 36 }, * { 'user': 'fred', 'age': 40 }, * { 'user': 'pebbles', 'age': 1 } * ]; * * var youngest = _ * .chain(users) * .sortBy('age') * .map(function(o) { * return o.user + ' is ' + o.age; * }) * .head() * .value(); * // => 'pebbles is 1' */ function chain(value) { var result = lodash(value); result.__chain__ = true; return result; } /** * This method invokes `interceptor` and returns `value`. The interceptor * is invoked with one argument; (value). The purpose of this method is to * "tap into" a method chain sequence in order to modify intermediate results. * * @static * @memberOf _ * @since 0.1.0 * @category Seq * @param {*} value The value to provide to `interceptor`. * @param {Function} interceptor The function to invoke. * @returns {*} Returns `value`. * @example * * _([1, 2, 3]) * .tap(function(array) { * // Mutate input array. * array.pop(); * }) * .reverse() * .value(); * // => [2, 1] */ function tap(value, interceptor) { interceptor(value); return value; } /** * This method is like `_.tap` except that it returns the result of `interceptor`. * The purpose of this method is to "pass thru" values replacing intermediate * results in a method chain sequence. * * @static * @memberOf _ * @since 3.0.0 * @category Seq * @param {*} value The value to provide to `interceptor`. * @param {Function} interceptor The function to invoke. * @returns {*} Returns the result of `interceptor`. * @example * * _(' abc ') * .chain() * .trim() * .thru(function(value) { * return [value]; * }) * .value(); * // => ['abc'] */ function thru(value, interceptor) { return interceptor(value); } /** * This method is the wrapper version of `_.at`. * * @name at * @memberOf _ * @since 1.0.0 * @category Seq * @param {...(string|string[])} [paths] The property paths to pick. * @returns {Object} Returns the new `lodash` wrapper instance. * @example * * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; * * _(object).at(['a[0].b.c', 'a[1]']).value(); * // => [3, 4] */ var wrapperAt = flatRest(function(paths) { var length = paths.length, start = length ? paths[0] : 0, value = this.__wrapped__, interceptor = function(object) { return baseAt(object, paths); }; if (length > 1 || this.__actions__.length || !(value instanceof LazyWrapper) || !isIndex(start)) { return this.thru(interceptor); } value = value.slice(start, +start + (length ? 1 : 0)); value.__actions__.push({ "func": thru, "args": [interceptor], "thisArg": undefined }); return new LodashWrapper(value, this.__chain__).thru(function(array) { if (length && !array.length) { array.push(undefined); } return array; }); }); /** * Creates a `lodash` wrapper instance with explicit method chain sequences enabled. * * @name chain * @memberOf _ * @since 0.1.0 * @category Seq * @returns {Object} Returns the new `lodash` wrapper instance. * @example * * var users = [ * { 'user': 'barney', 'age': 36 }, * { 'user': 'fred', 'age': 40 } * ]; * * // A sequence without explicit chaining. * _(users).head(); * // => { 'user': 'barney', 'age': 36 } * * // A sequence with explicit chaining. * _(users) * .chain() * .head() * .pick('user') * .value(); * // => { 'user': 'barney' } */ function wrapperChain() { return chain(this); } /** * Executes the chain sequence and returns the wrapped result. * * @name commit * @memberOf _ * @since 3.2.0 * @category Seq * @returns {Object} Returns the new `lodash` wrapper instance. * @example * * var array = [1, 2]; * var wrapped = _(array).push(3); * * console.log(array); * // => [1, 2] * * wrapped = wrapped.commit(); * console.log(array); * // => [1, 2, 3] * * wrapped.last(); * // => 3 * * console.log(array); * // => [1, 2, 3] */ function wrapperCommit() { return new LodashWrapper(this.value(), this.__chain__); } /** * Gets the next value on a wrapped object following the * [iterator protocol](https://mdn.io/iteration_protocols#iterator). * * @name next * @memberOf _ * @since 4.0.0 * @category Seq * @returns {Object} Returns the next iterator value. * @example * * var wrapped = _([1, 2]); * * wrapped.next(); * // => { 'done': false, 'value': 1 } * * wrapped.next(); * // => { 'done': false, 'value': 2 } * * wrapped.next(); * // => { 'done': true, 'value': undefined } */ function wrapperNext() { if (this.__values__ === undefined) { this.__values__ = toArray(this.value()); } var done = this.__index__ >= this.__values__.length, value = done ? undefined : this.__values__[this.__index__++]; return { "done": done, "value": value }; } /** * Enables the wrapper to be iterable. * * @name Symbol.iterator * @memberOf _ * @since 4.0.0 * @category Seq * @returns {Object} Returns the wrapper object. * @example * * var wrapped = _([1, 2]); * * wrapped[Symbol.iterator]() === wrapped; * // => true * * Array.from(wrapped); * // => [1, 2] */ function wrapperToIterator() { return this; } /** * Creates a clone of the chain sequence planting `value` as the wrapped value. * * @name plant * @memberOf _ * @since 3.2.0 * @category Seq * @param {*} value The value to plant. * @returns {Object} Returns the new `lodash` wrapper instance. * @example * * function square(n) { * return n * n; * } * * var wrapped = _([1, 2]).map(square); * var other = wrapped.plant([3, 4]); * * other.value(); * // => [9, 16] * * wrapped.value(); * // => [1, 4] */ function wrapperPlant(value) { var result, parent = this; while (parent instanceof baseLodash) { var clone = wrapperClone(parent); clone.__index__ = 0; clone.__values__ = undefined; if (result) { previous.__wrapped__ = clone; } else { result = clone; } var previous = clone; parent = parent.__wrapped__; } previous.__wrapped__ = value; return result; } /** * This method is the wrapper version of `_.reverse`. * * **Note:** This method mutates the wrapped array. * * @name reverse * @memberOf _ * @since 0.1.0 * @category Seq * @returns {Object} Returns the new `lodash` wrapper instance. * @example * * var array = [1, 2, 3]; * * _(array).reverse().value() * // => [3, 2, 1] * * console.log(array); * // => [3, 2, 1] */ function wrapperReverse() { var value = this.__wrapped__; if (value instanceof LazyWrapper) { var wrapped = value; if (this.__actions__.length) { wrapped = new LazyWrapper(this); } wrapped = wrapped.reverse(); wrapped.__actions__.push({ "func": thru, "args": [reverse], "thisArg": undefined }); return new LodashWrapper(wrapped, this.__chain__); } return this.thru(reverse); } /** * Executes the chain sequence to resolve the unwrapped value. * * @name value * @memberOf _ * @since 0.1.0 * @alias toJSON, valueOf * @category Seq * @returns {*} Returns the resolved unwrapped value. * @example * * _([1, 2, 3]).value(); * // => [1, 2, 3] */ function wrapperValue() { return baseWrapperValue(this.__wrapped__, this.__actions__); } /** * Creates an object composed of keys generated from the results of running * each element of `collection` thru `iteratee`. The corresponding value of * each key is the number of times the key was returned by `iteratee`. The * iteratee is invoked with one argument: (value). * * @static * @memberOf _ * @since 0.5.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The iteratee to transform keys. * @returns {Object} Returns the composed aggregate object. * @example * * _.countBy([6.1, 4.2, 6.3], Math.floor); * // => { '4': 1, '6': 2 } * * // The `_.property` iteratee shorthand. * _.countBy(['one', 'two', 'three'], 'length'); * // => { '3': 2, '5': 1 } */ var countBy = createAggregator(function(result, value, key) { if (hasOwnProperty.call(result, key)) { ++result[key]; } else { baseAssignValue(result, key, 1); } }); /** * Checks if `predicate` returns truthy for **all** elements of `collection`. * Iteration is stopped once `predicate` returns falsey. The predicate is * invoked with three arguments: (value, index|key, collection). * * **Note:** This method returns `true` for * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of * elements of empty collections. * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. * @returns {boolean} Returns `true` if all elements pass the predicate check, * else `false`. * @example * * _.every([true, 1, null, 'yes'], Boolean); * // => false * * var users = [ * { 'user': 'barney', 'age': 36, 'active': false }, * { 'user': 'fred', 'age': 40, 'active': false } * ]; * * // The `_.matches` iteratee shorthand. * _.every(users, { 'user': 'barney', 'active': false }); * // => false * * // The `_.matchesProperty` iteratee shorthand. * _.every(users, ['active', false]); * // => true * * // The `_.property` iteratee shorthand. * _.every(users, 'active'); * // => false */ function every(collection, predicate, guard) { var func = isArray(collection) ? arrayEvery : baseEvery; if (guard && isIterateeCall(collection, predicate, guard)) { predicate = undefined; } return func(collection, getIteratee(predicate, 3)); } /** * Iterates over elements of `collection`, returning an array of all elements * `predicate` returns truthy for. The predicate is invoked with three * arguments: (value, index|key, collection). * * **Note:** Unlike `_.remove`, this method returns a new array. * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @returns {Array} Returns the new filtered array. * @see _.reject * @example * * var users = [ * { 'user': 'barney', 'age': 36, 'active': true }, * { 'user': 'fred', 'age': 40, 'active': false } * ]; * * _.filter(users, function(o) { return !o.active; }); * // => objects for ['fred'] * * // The `_.matches` iteratee shorthand. * _.filter(users, { 'age': 36, 'active': true }); * // => objects for ['barney'] * * // The `_.matchesProperty` iteratee shorthand. * _.filter(users, ['active', false]); * // => objects for ['fred'] * * // The `_.property` iteratee shorthand. * _.filter(users, 'active'); * // => objects for ['barney'] * * // Combining several predicates using `_.overEvery` or `_.overSome`. * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]])); * // => objects for ['fred', 'barney'] */ function filter(collection, predicate) { var func = isArray(collection) ? arrayFilter : baseFilter; return func(collection, getIteratee(predicate, 3)); } /** * Iterates over elements of `collection`, returning the first element * `predicate` returns truthy for. The predicate is invoked with three * arguments: (value, index|key, collection). * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object} collection The collection to inspect. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @param {number} [fromIndex=0] The index to search from. * @returns {*} Returns the matched element, else `undefined`. * @example * * var users = [ * { 'user': 'barney', 'age': 36, 'active': true }, * { 'user': 'fred', 'age': 40, 'active': false }, * { 'user': 'pebbles', 'age': 1, 'active': true } * ]; * * _.find(users, function(o) { return o.age < 40; }); * // => object for 'barney' * * // The `_.matches` iteratee shorthand. * _.find(users, { 'age': 1, 'active': true }); * // => object for 'pebbles' * * // The `_.matchesProperty` iteratee shorthand. * _.find(users, ['active', false]); * // => object for 'fred' * * // The `_.property` iteratee shorthand. * _.find(users, 'active'); * // => object for 'barney' */ var find = createFind(findIndex); /** * This method is like `_.find` except that it iterates over elements of * `collection` from right to left. * * @static * @memberOf _ * @since 2.0.0 * @category Collection * @param {Array|Object} collection The collection to inspect. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @param {number} [fromIndex=collection.length-1] The index to search from. * @returns {*} Returns the matched element, else `undefined`. * @example * * _.findLast([1, 2, 3, 4], function(n) { * return n % 2 == 1; * }); * // => 3 */ var findLast = createFind(findLastIndex); /** * Creates a flattened array of values by running each element in `collection` * thru `iteratee` and flattening the mapped results. The iteratee is invoked * with three arguments: (value, index|key, collection). * * @static * @memberOf _ * @since 4.0.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @returns {Array} Returns the new flattened array. * @example * * function duplicate(n) { * return [n, n]; * } * * _.flatMap([1, 2], duplicate); * // => [1, 1, 2, 2] */ function flatMap(collection, iteratee) { return baseFlatten(map(collection, iteratee), 1); } /** * This method is like `_.flatMap` except that it recursively flattens the * mapped results. * * @static * @memberOf _ * @since 4.7.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @returns {Array} Returns the new flattened array. * @example * * function duplicate(n) { * return [[[n, n]]]; * } * * _.flatMapDeep([1, 2], duplicate); * // => [1, 1, 2, 2] */ function flatMapDeep(collection, iteratee) { return baseFlatten(map(collection, iteratee), INFINITY); } /** * This method is like `_.flatMap` except that it recursively flattens the * mapped results up to `depth` times. * * @static * @memberOf _ * @since 4.7.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @param {number} [depth=1] The maximum recursion depth. * @returns {Array} Returns the new flattened array. * @example * * function duplicate(n) { * return [[[n, n]]]; * } * * _.flatMapDepth([1, 2], duplicate, 2); * // => [[1, 1], [2, 2]] */ function flatMapDepth(collection, iteratee, depth) { depth = depth === undefined ? 1 : toInteger(depth); return baseFlatten(map(collection, iteratee), depth); } /** * Iterates over elements of `collection` and invokes `iteratee` for each element. * The iteratee is invoked with three arguments: (value, index|key, collection). * Iteratee functions may exit iteration early by explicitly returning `false`. * * **Note:** As with other "Collections" methods, objects with a "length" * property are iterated like arrays. To avoid this behavior use `_.forIn` * or `_.forOwn` for object iteration. * * @static * @memberOf _ * @since 0.1.0 * @alias each * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @returns {Array|Object} Returns `collection`. * @see _.forEachRight * @example * * _.forEach([1, 2], function(value) { * console.log(value); * }); * // => Logs `1` then `2`. * * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { * console.log(key); * }); * // => Logs 'a' then 'b' (iteration order is not guaranteed). */ function forEach(collection, iteratee) { var func = isArray(collection) ? arrayEach : baseEach; return func(collection, getIteratee(iteratee, 3)); } /** * This method is like `_.forEach` except that it iterates over elements of * `collection` from right to left. * * @static * @memberOf _ * @since 2.0.0 * @alias eachRight * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @returns {Array|Object} Returns `collection`. * @see _.forEach * @example * * _.forEachRight([1, 2], function(value) { * console.log(value); * }); * // => Logs `2` then `1`. */ function forEachRight(collection, iteratee) { var func = isArray(collection) ? arrayEachRight : baseEachRight; return func(collection, getIteratee(iteratee, 3)); } /** * Creates an object composed of keys generated from the results of running * each element of `collection` thru `iteratee`. The order of grouped values * is determined by the order they occur in `collection`. The corresponding * value of each key is an array of elements responsible for generating the * key. The iteratee is invoked with one argument: (value). * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The iteratee to transform keys. * @returns {Object} Returns the composed aggregate object. * @example * * _.groupBy([6.1, 4.2, 6.3], Math.floor); * // => { '4': [4.2], '6': [6.1, 6.3] } * * // The `_.property` iteratee shorthand. * _.groupBy(['one', 'two', 'three'], 'length'); * // => { '3': ['one', 'two'], '5': ['three'] } */ var groupBy = createAggregator(function(result, value, key) { if (hasOwnProperty.call(result, key)) { result[key].push(value); } else { baseAssignValue(result, key, [value]); } }); /** * Checks if `value` is in `collection`. If `collection` is a string, it's * checked for a substring of `value`, otherwise * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * is used for equality comparisons. If `fromIndex` is negative, it's used as * the offset from the end of `collection`. * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object|string} collection The collection to inspect. * @param {*} value The value to search for. * @param {number} [fromIndex=0] The index to search from. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. * @returns {boolean} Returns `true` if `value` is found, else `false`. * @example * * _.includes([1, 2, 3], 1); * // => true * * _.includes([1, 2, 3], 1, 2); * // => false * * _.includes({ 'a': 1, 'b': 2 }, 1); * // => true * * _.includes('abcd', 'bc'); * // => true */ function includes(collection, value, fromIndex, guard) { collection = isArrayLike(collection) ? collection : values(collection); fromIndex = fromIndex && !guard ? toInteger(fromIndex) : 0; var length = collection.length; if (fromIndex < 0) { fromIndex = nativeMax(length + fromIndex, 0); } return isString(collection) ? fromIndex <= length && collection.indexOf(value, fromIndex) > -1 : !!length && baseIndexOf(collection, value, fromIndex) > -1; } /** * Invokes the method at `path` of each element in `collection`, returning * an array of the results of each invoked method. Any additional arguments * are provided to each invoked method. If `path` is a function, it's invoked * for, and `this` bound to, each element in `collection`. * * @static * @memberOf _ * @since 4.0.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Array|Function|string} path The path of the method to invoke or * the function invoked per iteration. * @param {...*} [args] The arguments to invoke each method with. * @returns {Array} Returns the array of results. * @example * * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort'); * // => [[1, 5, 7], [1, 2, 3]] * * _.invokeMap([123, 456], String.prototype.split, ''); * // => [['1', '2', '3'], ['4', '5', '6']] */ var invokeMap = baseRest(function(collection, path, args) { var index = -1, isFunc = typeof path == "function", result = isArrayLike(collection) ? Array(collection.length) : []; baseEach(collection, function(value) { result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args); }); return result; }); /** * Creates an object composed of keys generated from the results of running * each element of `collection` thru `iteratee`. The corresponding value of * each key is the last element responsible for generating the key. The * iteratee is invoked with one argument: (value). * * @static * @memberOf _ * @since 4.0.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The iteratee to transform keys. * @returns {Object} Returns the composed aggregate object. * @example * * var array = [ * { 'dir': 'left', 'code': 97 }, * { 'dir': 'right', 'code': 100 } * ]; * * _.keyBy(array, function(o) { * return String.fromCharCode(o.code); * }); * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } * * _.keyBy(array, 'dir'); * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } */ var keyBy = createAggregator(function(result, value, key) { baseAssignValue(result, key, value); }); /** * Creates an array of values by running each element in `collection` thru * `iteratee`. The iteratee is invoked with three arguments: * (value, index|key, collection). * * Many lodash methods are guarded to work as iteratees for methods like * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. * * The guarded methods are: * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, * `template`, `trim`, `trimEnd`, `trimStart`, and `words` * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @returns {Array} Returns the new mapped array. * @example * * function square(n) { * return n * n; * } * * _.map([4, 8], square); * // => [16, 64] * * _.map({ 'a': 4, 'b': 8 }, square); * // => [16, 64] (iteration order is not guaranteed) * * var users = [ * { 'user': 'barney' }, * { 'user': 'fred' } * ]; * * // The `_.property` iteratee shorthand. * _.map(users, 'user'); * // => ['barney', 'fred'] */ function map(collection, iteratee) { var func = isArray(collection) ? arrayMap : baseMap; return func(collection, getIteratee(iteratee, 3)); } /** * This method is like `_.sortBy` except that it allows specifying the sort * orders of the iteratees to sort by. If `orders` is unspecified, all values * are sorted in ascending order. Otherwise, specify an order of "desc" for * descending or "asc" for ascending sort order of corresponding values. * * @static * @memberOf _ * @since 4.0.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]] * The iteratees to sort by. * @param {string[]} [orders] The sort orders of `iteratees`. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. * @returns {Array} Returns the new sorted array. * @example * * var users = [ * { 'user': 'fred', 'age': 48 }, * { 'user': 'barney', 'age': 34 }, * { 'user': 'fred', 'age': 40 }, * { 'user': 'barney', 'age': 36 } * ]; * * // Sort by `user` in ascending order and by `age` in descending order. * _.orderBy(users, ['user', 'age'], ['asc', 'desc']); * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]] */ function orderBy(collection, iteratees, orders, guard) { if (collection == null) { return []; } if (!isArray(iteratees)) { iteratees = iteratees == null ? [] : [iteratees]; } orders = guard ? undefined : orders; if (!isArray(orders)) { orders = orders == null ? [] : [orders]; } return baseOrderBy(collection, iteratees, orders); } /** * Creates an array of elements split into two groups, the first of which * contains elements `predicate` returns truthy for, the second of which * contains elements `predicate` returns falsey for. The predicate is * invoked with one argument: (value). * * @static * @memberOf _ * @since 3.0.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @returns {Array} Returns the array of grouped elements. * @example * * var users = [ * { 'user': 'barney', 'age': 36, 'active': false }, * { 'user': 'fred', 'age': 40, 'active': true }, * { 'user': 'pebbles', 'age': 1, 'active': false } * ]; * * _.partition(users, function(o) { return o.active; }); * // => objects for [['fred'], ['barney', 'pebbles']] * * // The `_.matches` iteratee shorthand. * _.partition(users, { 'age': 1, 'active': false }); * // => objects for [['pebbles'], ['barney', 'fred']] * * // The `_.matchesProperty` iteratee shorthand. * _.partition(users, ['active', false]); * // => objects for [['barney', 'pebbles'], ['fred']] * * // The `_.property` iteratee shorthand. * _.partition(users, 'active'); * // => objects for [['fred'], ['barney', 'pebbles']] */ var partition = createAggregator(function(result, value, key) { result[key ? 0 : 1].push(value); }, function() { return [[], []]; }); /** * Reduces `collection` to a value which is the accumulated result of running * each element in `collection` thru `iteratee`, where each successive * invocation is supplied the return value of the previous. If `accumulator` * is not given, the first element of `collection` is used as the initial * value. The iteratee is invoked with four arguments: * (accumulator, value, index|key, collection). * * Many lodash methods are guarded to work as iteratees for methods like * `_.reduce`, `_.reduceRight`, and `_.transform`. * * The guarded methods are: * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, * and `sortBy` * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @param {*} [accumulator] The initial value. * @returns {*} Returns the accumulated value. * @see _.reduceRight * @example * * _.reduce([1, 2], function(sum, n) { * return sum + n; * }, 0); * // => 3 * * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { * (result[value] || (result[value] = [])).push(key); * return result; * }, {}); * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) */ function reduce(collection, iteratee, accumulator) { var func = isArray(collection) ? arrayReduce : baseReduce, initAccum = arguments.length < 3; return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach); } /** * This method is like `_.reduce` except that it iterates over elements of * `collection` from right to left. * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @param {*} [accumulator] The initial value. * @returns {*} Returns the accumulated value. * @see _.reduce * @example * * var array = [[0, 1], [2, 3], [4, 5]]; * * _.reduceRight(array, function(flattened, other) { * return flattened.concat(other); * }, []); * // => [4, 5, 2, 3, 0, 1] */ function reduceRight(collection, iteratee, accumulator) { var func = isArray(collection) ? arrayReduceRight : baseReduce, initAccum = arguments.length < 3; return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight); } /** * The opposite of `_.filter`; this method returns the elements of `collection` * that `predicate` does **not** return truthy for. * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @returns {Array} Returns the new filtered array. * @see _.filter * @example * * var users = [ * { 'user': 'barney', 'age': 36, 'active': false }, * { 'user': 'fred', 'age': 40, 'active': true } * ]; * * _.reject(users, function(o) { return !o.active; }); * // => objects for ['fred'] * * // The `_.matches` iteratee shorthand. * _.reject(users, { 'age': 40, 'active': true }); * // => objects for ['barney'] * * // The `_.matchesProperty` iteratee shorthand. * _.reject(users, ['active', false]); * // => objects for ['fred'] * * // The `_.property` iteratee shorthand. * _.reject(users, 'active'); * // => objects for ['barney'] */ function reject(collection, predicate) { var func = isArray(collection) ? arrayFilter : baseFilter; return func(collection, negate(getIteratee(predicate, 3))); } /** * Gets a random element from `collection`. * * @static * @memberOf _ * @since 2.0.0 * @category Collection * @param {Array|Object} collection The collection to sample. * @returns {*} Returns the random element. * @example * * _.sample([1, 2, 3, 4]); * // => 2 */ function sample(collection) { var func = isArray(collection) ? arraySample : baseSample; return func(collection); } /** * Gets `n` random elements at unique keys from `collection` up to the * size of `collection`. * * @static * @memberOf _ * @since 4.0.0 * @category Collection * @param {Array|Object} collection The collection to sample. * @param {number} [n=1] The number of elements to sample. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. * @returns {Array} Returns the random elements. * @example * * _.sampleSize([1, 2, 3], 2); * // => [3, 1] * * _.sampleSize([1, 2, 3], 4); * // => [2, 3, 1] */ function sampleSize(collection, n, guard) { if (guard ? isIterateeCall(collection, n, guard) : n === undefined) { n = 1; } else { n = toInteger(n); } var func = isArray(collection) ? arraySampleSize : baseSampleSize; return func(collection, n); } /** * Creates an array of shuffled values, using a version of the * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object} collection The collection to shuffle. * @returns {Array} Returns the new shuffled array. * @example * * _.shuffle([1, 2, 3, 4]); * // => [4, 1, 3, 2] */ function shuffle(collection) { var func = isArray(collection) ? arrayShuffle : baseShuffle; return func(collection); } /** * Gets the size of `collection` by returning its length for array-like * values or the number of own enumerable string keyed properties for objects. * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object|string} collection The collection to inspect. * @returns {number} Returns the collection size. * @example * * _.size([1, 2, 3]); * // => 3 * * _.size({ 'a': 1, 'b': 2 }); * // => 2 * * _.size('pebbles'); * // => 7 */ function size(collection) { if (collection == null) { return 0; } if (isArrayLike(collection)) { return isString(collection) ? stringSize(collection) : collection.length; } var tag = getTag(collection); if (tag == mapTag || tag == setTag) { return collection.size; } return baseKeys(collection).length; } /** * Checks if `predicate` returns truthy for **any** element of `collection`. * Iteration is stopped once `predicate` returns truthy. The predicate is * invoked with three arguments: (value, index|key, collection). * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. * @returns {boolean} Returns `true` if any element passes the predicate check, * else `false`. * @example * * _.some([null, 0, 'yes', false], Boolean); * // => true * * var users = [ * { 'user': 'barney', 'active': true }, * { 'user': 'fred', 'active': false } * ]; * * // The `_.matches` iteratee shorthand. * _.some(users, { 'user': 'barney', 'active': false }); * // => false * * // The `_.matchesProperty` iteratee shorthand. * _.some(users, ['active', false]); * // => true * * // The `_.property` iteratee shorthand. * _.some(users, 'active'); * // => true */ function some(collection, predicate, guard) { var func = isArray(collection) ? arraySome : baseSome; if (guard && isIterateeCall(collection, predicate, guard)) { predicate = undefined; } return func(collection, getIteratee(predicate, 3)); } /** * Creates an array of elements, sorted in ascending order by the results of * running each element in a collection thru each iteratee. This method * performs a stable sort, that is, it preserves the original sort order of * equal elements. The iteratees are invoked with one argument: (value). * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {...(Function|Function[])} [iteratees=[_.identity]] * The iteratees to sort by. * @returns {Array} Returns the new sorted array. * @example * * var users = [ * { 'user': 'fred', 'age': 48 }, * { 'user': 'barney', 'age': 36 }, * { 'user': 'fred', 'age': 30 }, * { 'user': 'barney', 'age': 34 } * ]; * * _.sortBy(users, [function(o) { return o.user; }]); * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]] * * _.sortBy(users, ['user', 'age']); * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]] */ var sortBy = baseRest(function(collection, iteratees) { if (collection == null) { return []; } var length = iteratees.length; if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) { iteratees = []; } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) { iteratees = [iteratees[0]]; } return baseOrderBy(collection, baseFlatten(iteratees, 1), []); }); /** * Gets the timestamp of the number of milliseconds that have elapsed since * the Unix epoch (1 January 1970 00:00:00 UTC). * * @static * @memberOf _ * @since 2.4.0 * @category Date * @returns {number} Returns the timestamp. * @example * * _.defer(function(stamp) { * console.log(_.now() - stamp); * }, _.now()); * // => Logs the number of milliseconds it took for the deferred invocation. */ var now = ctxNow || function() { return root.Date.now(); }; /** * The opposite of `_.before`; this method creates a function that invokes * `func` once it's called `n` or more times. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {number} n The number of calls before `func` is invoked. * @param {Function} func The function to restrict. * @returns {Function} Returns the new restricted function. * @example * * var saves = ['profile', 'settings']; * * var done = _.after(saves.length, function() { * console.log('done saving!'); * }); * * _.forEach(saves, function(type) { * asyncSave({ 'type': type, 'complete': done }); * }); * // => Logs 'done saving!' after the two async saves have completed. */ function after(n, func) { if (typeof func != "function") { throw new TypeError(FUNC_ERROR_TEXT); } n = toInteger(n); return function() { if (--n < 1) { return func.apply(this, arguments); } }; } /** * Creates a function that invokes `func`, with up to `n` arguments, * ignoring any additional arguments. * * @static * @memberOf _ * @since 3.0.0 * @category Function * @param {Function} func The function to cap arguments for. * @param {number} [n=func.length] The arity cap. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. * @returns {Function} Returns the new capped function. * @example * * _.map(['6', '8', '10'], _.ary(parseInt, 1)); * // => [6, 8, 10] */ function ary(func, n, guard) { n = guard ? undefined : n; n = func && n == null ? func.length : n; return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n); } /** * Creates a function that invokes `func`, with the `this` binding and arguments * of the created function, while it's called less than `n` times. Subsequent * calls to the created function return the result of the last `func` invocation. * * @static * @memberOf _ * @since 3.0.0 * @category Function * @param {number} n The number of calls at which `func` is no longer invoked. * @param {Function} func The function to restrict. * @returns {Function} Returns the new restricted function. * @example * * jQuery(element).on('click', _.before(5, addContactToList)); * // => Allows adding up to 4 contacts to the list. */ function before(n, func) { var result; if (typeof func != "function") { throw new TypeError(FUNC_ERROR_TEXT); } n = toInteger(n); return function() { if (--n > 0) { result = func.apply(this, arguments); } if (n <= 1) { func = undefined; } return result; }; } /** * Creates a function that invokes `func` with the `this` binding of `thisArg` * and `partials` prepended to the arguments it receives. * * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, * may be used as a placeholder for partially applied arguments. * * **Note:** Unlike native `Function#bind`, this method doesn't set the "length" * property of bound functions. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {Function} func The function to bind. * @param {*} thisArg The `this` binding of `func`. * @param {...*} [partials] The arguments to be partially applied. * @returns {Function} Returns the new bound function. * @example * * function greet(greeting, punctuation) { * return greeting + ' ' + this.user + punctuation; * } * * var object = { 'user': 'fred' }; * * var bound = _.bind(greet, object, 'hi'); * bound('!'); * // => 'hi fred!' * * // Bound with placeholders. * var bound = _.bind(greet, object, _, '!'); * bound('hi'); * // => 'hi fred!' */ var bind = baseRest(function(func, thisArg, partials) { var bitmask = WRAP_BIND_FLAG; if (partials.length) { var holders = replaceHolders(partials, getHolder(bind)); bitmask |= WRAP_PARTIAL_FLAG; } return createWrap(func, bitmask, thisArg, partials, holders); }); /** * Creates a function that invokes the method at `object[key]` with `partials` * prepended to the arguments it receives. * * This method differs from `_.bind` by allowing bound functions to reference * methods that may be redefined or don't yet exist. See * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern) * for more details. * * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic * builds, may be used as a placeholder for partially applied arguments. * * @static * @memberOf _ * @since 0.10.0 * @category Function * @param {Object} object The object to invoke the method on. * @param {string} key The key of the method. * @param {...*} [partials] The arguments to be partially applied. * @returns {Function} Returns the new bound function. * @example * * var object = { * 'user': 'fred', * 'greet': function(greeting, punctuation) { * return greeting + ' ' + this.user + punctuation; * } * }; * * var bound = _.bindKey(object, 'greet', 'hi'); * bound('!'); * // => 'hi fred!' * * object.greet = function(greeting, punctuation) { * return greeting + 'ya ' + this.user + punctuation; * }; * * bound('!'); * // => 'hiya fred!' * * // Bound with placeholders. * var bound = _.bindKey(object, 'greet', _, '!'); * bound('hi'); * // => 'hiya fred!' */ var bindKey = baseRest(function(object, key, partials) { var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG; if (partials.length) { var holders = replaceHolders(partials, getHolder(bindKey)); bitmask |= WRAP_PARTIAL_FLAG; } return createWrap(key, bitmask, object, partials, holders); }); /** * Creates a function that accepts arguments of `func` and either invokes * `func` returning its result, if at least `arity` number of arguments have * been provided, or returns a function that accepts the remaining `func` * arguments, and so on. The arity of `func` may be specified if `func.length` * is not sufficient. * * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, * may be used as a placeholder for provided arguments. * * **Note:** This method doesn't set the "length" property of curried functions. * * @static * @memberOf _ * @since 2.0.0 * @category Function * @param {Function} func The function to curry. * @param {number} [arity=func.length] The arity of `func`. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. * @returns {Function} Returns the new curried function. * @example * * var abc = function(a, b, c) { * return [a, b, c]; * }; * * var curried = _.curry(abc); * * curried(1)(2)(3); * // => [1, 2, 3] * * curried(1, 2)(3); * // => [1, 2, 3] * * curried(1, 2, 3); * // => [1, 2, 3] * * // Curried with placeholders. * curried(1)(_, 3)(2); * // => [1, 2, 3] */ function curry(func, arity, guard) { arity = guard ? undefined : arity; var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity); result.placeholder = curry.placeholder; return result; } /** * This method is like `_.curry` except that arguments are applied to `func` * in the manner of `_.partialRight` instead of `_.partial`. * * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic * builds, may be used as a placeholder for provided arguments. * * **Note:** This method doesn't set the "length" property of curried functions. * * @static * @memberOf _ * @since 3.0.0 * @category Function * @param {Function} func The function to curry. * @param {number} [arity=func.length] The arity of `func`. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. * @returns {Function} Returns the new curried function. * @example * * var abc = function(a, b, c) { * return [a, b, c]; * }; * * var curried = _.curryRight(abc); * * curried(3)(2)(1); * // => [1, 2, 3] * * curried(2, 3)(1); * // => [1, 2, 3] * * curried(1, 2, 3); * // => [1, 2, 3] * * // Curried with placeholders. * curried(3)(1, _)(2); * // => [1, 2, 3] */ function curryRight(func, arity, guard) { arity = guard ? undefined : arity; var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity); result.placeholder = curryRight.placeholder; return result; } /** * Creates a debounced function that delays invoking `func` until after `wait` * milliseconds have elapsed since the last time the debounced function was * invoked. The debounced function comes with a `cancel` method to cancel * delayed `func` invocations and a `flush` method to immediately invoke them. * Provide `options` to indicate whether `func` should be invoked on the * leading and/or trailing edge of the `wait` timeout. The `func` is invoked * with the last arguments provided to the debounced function. Subsequent * calls to the debounced function return the result of the last `func` * invocation. * * **Note:** If `leading` and `trailing` options are `true`, `func` is * invoked on the trailing edge of the timeout only if the debounced function * is invoked more than once during the `wait` timeout. * * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred * until to the next tick, similar to `setTimeout` with a timeout of `0`. * * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) * for details over the differences between `_.debounce` and `_.throttle`. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {Function} func The function to debounce. * @param {number} [wait=0] The number of milliseconds to delay. * @param {Object} [options={}] The options object. * @param {boolean} [options.leading=false] * Specify invoking on the leading edge of the timeout. * @param {number} [options.maxWait] * The maximum time `func` is allowed to be delayed before it's invoked. * @param {boolean} [options.trailing=true] * Specify invoking on the trailing edge of the timeout. * @returns {Function} Returns the new debounced function. * @example * * // Avoid costly calculations while the window size is in flux. * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); * * // Invoke `sendMail` when clicked, debouncing subsequent calls. * jQuery(element).on('click', _.debounce(sendMail, 300, { * 'leading': true, * 'trailing': false * })); * * // Ensure `batchLog` is invoked once after 1 second of debounced calls. * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); * var source = new EventSource('/stream'); * jQuery(source).on('message', debounced); * * // Cancel the trailing debounced invocation. * jQuery(window).on('popstate', debounced.cancel); */ function debounce(func, wait, options) { var lastArgs, lastThis, maxWait, result, timerId, lastCallTime, lastInvokeTime = 0, leading = false, maxing = false, trailing = true; if (typeof func != "function") { throw new TypeError(FUNC_ERROR_TEXT); } wait = toNumber(wait) || 0; if (isObject(options)) { leading = !!options.leading; maxing = "maxWait" in options; maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; trailing = "trailing" in options ? !!options.trailing : trailing; } function invokeFunc(time) { var args = lastArgs, thisArg = lastThis; lastArgs = lastThis = undefined; lastInvokeTime = time; result = func.apply(thisArg, args); return result; } function leadingEdge(time) { lastInvokeTime = time; timerId = setTimeout(timerExpired, wait); return leading ? invokeFunc(time) : result; } function remainingWait(time) { var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime, timeWaiting = wait - timeSinceLastCall; return maxing ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke) : timeWaiting; } function shouldInvoke(time) { var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime; return lastCallTime === undefined || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && timeSinceLastInvoke >= maxWait; } function timerExpired() { var time = now(); if (shouldInvoke(time)) { return trailingEdge(time); } timerId = setTimeout(timerExpired, remainingWait(time)); } function trailingEdge(time) { timerId = undefined; if (trailing && lastArgs) { return invokeFunc(time); } lastArgs = lastThis = undefined; return result; } function cancel() { if (timerId !== undefined) { clearTimeout(timerId); } lastInvokeTime = 0; lastArgs = lastCallTime = lastThis = timerId = undefined; } function flush() { return timerId === undefined ? result : trailingEdge(now()); } function debounced() { var time = now(), isInvoking = shouldInvoke(time); lastArgs = arguments; lastThis = this; lastCallTime = time; if (isInvoking) { if (timerId === undefined) { return leadingEdge(lastCallTime); } if (maxing) { clearTimeout(timerId); timerId = setTimeout(timerExpired, wait); return invokeFunc(lastCallTime); } } if (timerId === undefined) { timerId = setTimeout(timerExpired, wait); } return result; } debounced.cancel = cancel; debounced.flush = flush; return debounced; } /** * Defers invoking the `func` until the current call stack has cleared. Any * additional arguments are provided to `func` when it's invoked. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {Function} func The function to defer. * @param {...*} [args] The arguments to invoke `func` with. * @returns {number} Returns the timer id. * @example * * _.defer(function(text) { * console.log(text); * }, 'deferred'); * // => Logs 'deferred' after one millisecond. */ var defer = baseRest(function(func, args) { return baseDelay(func, 1, args); }); /** * Invokes `func` after `wait` milliseconds. Any additional arguments are * provided to `func` when it's invoked. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {Function} func The function to delay. * @param {number} wait The number of milliseconds to delay invocation. * @param {...*} [args] The arguments to invoke `func` with. * @returns {number} Returns the timer id. * @example * * _.delay(function(text) { * console.log(text); * }, 1000, 'later'); * // => Logs 'later' after one second. */ var delay = baseRest(function(func, wait, args) { return baseDelay(func, toNumber(wait) || 0, args); }); /** * Creates a function that invokes `func` with arguments reversed. * * @static * @memberOf _ * @since 4.0.0 * @category Function * @param {Function} func The function to flip arguments for. * @returns {Function} Returns the new flipped function. * @example * * var flipped = _.flip(function() { * return _.toArray(arguments); * }); * * flipped('a', 'b', 'c', 'd'); * // => ['d', 'c', 'b', 'a'] */ function flip(func) { return createWrap(func, WRAP_FLIP_FLAG); } /** * Creates a function that memoizes the result of `func`. If `resolver` is * provided, it determines the cache key for storing the result based on the * arguments provided to the memoized function. By default, the first argument * provided to the memoized function is used as the map cache key. The `func` * is invoked with the `this` binding of the memoized function. * * **Note:** The cache is exposed as the `cache` property on the memoized * function. Its creation may be customized by replacing the `_.memoize.Cache` * constructor with one whose instances implement the * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) * method interface of `clear`, `delete`, `get`, `has`, and `set`. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {Function} func The function to have its output memoized. * @param {Function} [resolver] The function to resolve the cache key. * @returns {Function} Returns the new memoized function. * @example * * var object = { 'a': 1, 'b': 2 }; * var other = { 'c': 3, 'd': 4 }; * * var values = _.memoize(_.values); * values(object); * // => [1, 2] * * values(other); * // => [3, 4] * * object.a = 2; * values(object); * // => [1, 2] * * // Modify the result cache. * values.cache.set(object, ['a', 'b']); * values(object); * // => ['a', 'b'] * * // Replace `_.memoize.Cache`. * _.memoize.Cache = WeakMap; */ function memoize(func, resolver) { if (typeof func != "function" || resolver != null && typeof resolver != "function") { throw new TypeError(FUNC_ERROR_TEXT); } var memoized = function() { var args = arguments, key = resolver ? resolver.apply(this, args) : args[0], cache = memoized.cache; if (cache.has(key)) { return cache.get(key); } var result = func.apply(this, args); memoized.cache = cache.set(key, result) || cache; return result; }; memoized.cache = new (memoize.Cache || MapCache)(); return memoized; } memoize.Cache = MapCache; /** * Creates a function that negates the result of the predicate `func`. The * `func` predicate is invoked with the `this` binding and arguments of the * created function. * * @static * @memberOf _ * @since 3.0.0 * @category Function * @param {Function} predicate The predicate to negate. * @returns {Function} Returns the new negated function. * @example * * function isEven(n) { * return n % 2 == 0; * } * * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); * // => [1, 3, 5] */ function negate(predicate) { if (typeof predicate != "function") { throw new TypeError(FUNC_ERROR_TEXT); } return function() { var args = arguments; switch (args.length) { case 0: return !predicate.call(this); case 1: return !predicate.call(this, args[0]); case 2: return !predicate.call(this, args[0], args[1]); case 3: return !predicate.call(this, args[0], args[1], args[2]); } return !predicate.apply(this, args); }; } /** * Creates a function that is restricted to invoking `func` once. Repeat calls * to the function return the value of the first invocation. The `func` is * invoked with the `this` binding and arguments of the created function. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {Function} func The function to restrict. * @returns {Function} Returns the new restricted function. * @example * * var initialize = _.once(createApplication); * initialize(); * initialize(); * // => `createApplication` is invoked once */ function once(func) { return before(2, func); } /** * Creates a function that invokes `func` with its arguments transformed. * * @static * @since 4.0.0 * @memberOf _ * @category Function * @param {Function} func The function to wrap. * @param {...(Function|Function[])} [transforms=[_.identity]] * The argument transforms. * @returns {Function} Returns the new function. * @example * * function doubled(n) { * return n * 2; * } * * function square(n) { * return n * n; * } * * var func = _.overArgs(function(x, y) { * return [x, y]; * }, [square, doubled]); * * func(9, 3); * // => [81, 6] * * func(10, 5); * // => [100, 10] */ var overArgs = castRest(function(func, transforms) { transforms = transforms.length == 1 && isArray(transforms[0]) ? arrayMap(transforms[0], baseUnary(getIteratee())) : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee())); var funcsLength = transforms.length; return baseRest(function(args) { var index = -1, length = nativeMin(args.length, funcsLength); while (++index < length) { args[index] = transforms[index].call(this, args[index]); } return apply(func, this, args); }); }); /** * Creates a function that invokes `func` with `partials` prepended to the * arguments it receives. This method is like `_.bind` except it does **not** * alter the `this` binding. * * The `_.partial.placeholder` value, which defaults to `_` in monolithic * builds, may be used as a placeholder for partially applied arguments. * * **Note:** This method doesn't set the "length" property of partially * applied functions. * * @static * @memberOf _ * @since 0.2.0 * @category Function * @param {Function} func The function to partially apply arguments to. * @param {...*} [partials] The arguments to be partially applied. * @returns {Function} Returns the new partially applied function. * @example * * function greet(greeting, name) { * return greeting + ' ' + name; * } * * var sayHelloTo = _.partial(greet, 'hello'); * sayHelloTo('fred'); * // => 'hello fred' * * // Partially applied with placeholders. * var greetFred = _.partial(greet, _, 'fred'); * greetFred('hi'); * // => 'hi fred' */ var partial = baseRest(function(func, partials) { var holders = replaceHolders(partials, getHolder(partial)); return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders); }); /** * This method is like `_.partial` except that partially applied arguments * are appended to the arguments it receives. * * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic * builds, may be used as a placeholder for partially applied arguments. * * **Note:** This method doesn't set the "length" property of partially * applied functions. * * @static * @memberOf _ * @since 1.0.0 * @category Function * @param {Function} func The function to partially apply arguments to. * @param {...*} [partials] The arguments to be partially applied. * @returns {Function} Returns the new partially applied function. * @example * * function greet(greeting, name) { * return greeting + ' ' + name; * } * * var greetFred = _.partialRight(greet, 'fred'); * greetFred('hi'); * // => 'hi fred' * * // Partially applied with placeholders. * var sayHelloTo = _.partialRight(greet, 'hello', _); * sayHelloTo('fred'); * // => 'hello fred' */ var partialRight = baseRest(function(func, partials) { var holders = replaceHolders(partials, getHolder(partialRight)); return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders); }); /** * Creates a function that invokes `func` with arguments arranged according * to the specified `indexes` where the argument value at the first index is * provided as the first argument, the argument value at the second index is * provided as the second argument, and so on. * * @static * @memberOf _ * @since 3.0.0 * @category Function * @param {Function} func The function to rearrange arguments for. * @param {...(number|number[])} indexes The arranged argument indexes. * @returns {Function} Returns the new function. * @example * * var rearged = _.rearg(function(a, b, c) { * return [a, b, c]; * }, [2, 0, 1]); * * rearged('b', 'c', 'a') * // => ['a', 'b', 'c'] */ var rearg = flatRest(function(func, indexes) { return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes); }); /** * Creates a function that invokes `func` with the `this` binding of the * created function and arguments from `start` and beyond provided as * an array. * * **Note:** This method is based on the * [rest parameter](https://mdn.io/rest_parameters). * * @static * @memberOf _ * @since 4.0.0 * @category Function * @param {Function} func The function to apply a rest parameter to. * @param {number} [start=func.length-1] The start position of the rest parameter. * @returns {Function} Returns the new function. * @example * * var say = _.rest(function(what, names) { * return what + ' ' + _.initial(names).join(', ') + * (_.size(names) > 1 ? ', & ' : '') + _.last(names); * }); * * say('hello', 'fred', 'barney', 'pebbles'); * // => 'hello fred, barney, & pebbles' */ function rest(func, start) { if (typeof func != "function") { throw new TypeError(FUNC_ERROR_TEXT); } start = start === undefined ? start : toInteger(start); return baseRest(func, start); } /** * Creates a function that invokes `func` with the `this` binding of the * create function and an array of arguments much like * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply). * * **Note:** This method is based on the * [spread operator](https://mdn.io/spread_operator). * * @static * @memberOf _ * @since 3.2.0 * @category Function * @param {Function} func The function to spread arguments over. * @param {number} [start=0] The start position of the spread. * @returns {Function} Returns the new function. * @example * * var say = _.spread(function(who, what) { * return who + ' says ' + what; * }); * * say(['fred', 'hello']); * // => 'fred says hello' * * var numbers = Promise.all([ * Promise.resolve(40), * Promise.resolve(36) * ]); * * numbers.then(_.spread(function(x, y) { * return x + y; * })); * // => a Promise of 76 */ function spread(func, start) { if (typeof func != "function") { throw new TypeError(FUNC_ERROR_TEXT); } start = start == null ? 0 : nativeMax(toInteger(start), 0); return baseRest(function(args) { var array = args[start], otherArgs = castSlice(args, 0, start); if (array) { arrayPush(otherArgs, array); } return apply(func, this, otherArgs); }); } /** * Creates a throttled function that only invokes `func` at most once per * every `wait` milliseconds. The throttled function comes with a `cancel` * method to cancel delayed `func` invocations and a `flush` method to * immediately invoke them. Provide `options` to indicate whether `func` * should be invoked on the leading and/or trailing edge of the `wait` * timeout. The `func` is invoked with the last arguments provided to the * throttled function. Subsequent calls to the throttled function return the * result of the last `func` invocation. * * **Note:** If `leading` and `trailing` options are `true`, `func` is * invoked on the trailing edge of the timeout only if the throttled function * is invoked more than once during the `wait` timeout. * * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred * until to the next tick, similar to `setTimeout` with a timeout of `0`. * * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) * for details over the differences between `_.throttle` and `_.debounce`. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {Function} func The function to throttle. * @param {number} [wait=0] The number of milliseconds to throttle invocations to. * @param {Object} [options={}] The options object. * @param {boolean} [options.leading=true] * Specify invoking on the leading edge of the timeout. * @param {boolean} [options.trailing=true] * Specify invoking on the trailing edge of the timeout. * @returns {Function} Returns the new throttled function. * @example * * // Avoid excessively updating the position while scrolling. * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); * * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes. * var throttled = _.throttle(renewToken, 300000, { 'trailing': false }); * jQuery(element).on('click', throttled); * * // Cancel the trailing throttled invocation. * jQuery(window).on('popstate', throttled.cancel); */ function throttle(func, wait, options) { var leading = true, trailing = true; if (typeof func != "function") { throw new TypeError(FUNC_ERROR_TEXT); } if (isObject(options)) { leading = "leading" in options ? !!options.leading : leading; trailing = "trailing" in options ? !!options.trailing : trailing; } return debounce(func, wait, { "leading": leading, "maxWait": wait, "trailing": trailing }); } /** * Creates a function that accepts up to one argument, ignoring any * additional arguments. * * @static * @memberOf _ * @since 4.0.0 * @category Function * @param {Function} func The function to cap arguments for. * @returns {Function} Returns the new capped function. * @example * * _.map(['6', '8', '10'], _.unary(parseInt)); * // => [6, 8, 10] */ function unary(func) { return ary(func, 1); } /** * Creates a function that provides `value` to `wrapper` as its first * argument. Any additional arguments provided to the function are appended * to those provided to the `wrapper`. The wrapper is invoked with the `this` * binding of the created function. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {*} value The value to wrap. * @param {Function} [wrapper=identity] The wrapper function. * @returns {Function} Returns the new function. * @example * * var p = _.wrap(_.escape, function(func, text) { * return '

' + func(text) + '

'; * }); * * p('fred, barney, & pebbles'); * // => '

fred, barney, & pebbles

' */ function wrap(value, wrapper) { return partial(castFunction(wrapper), value); } /** * Casts `value` as an array if it's not one. * * @static * @memberOf _ * @since 4.4.0 * @category Lang * @param {*} value The value to inspect. * @returns {Array} Returns the cast array. * @example * * _.castArray(1); * // => [1] * * _.castArray({ 'a': 1 }); * // => [{ 'a': 1 }] * * _.castArray('abc'); * // => ['abc'] * * _.castArray(null); * // => [null] * * _.castArray(undefined); * // => [undefined] * * _.castArray(); * // => [] * * var array = [1, 2, 3]; * console.log(_.castArray(array) === array); * // => true */ function castArray() { if (!arguments.length) { return []; } var value = arguments[0]; return isArray(value) ? value : [value]; } /** * Creates a shallow clone of `value`. * * **Note:** This method is loosely based on the * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) * and supports cloning arrays, array buffers, booleans, date objects, maps, * numbers, `Object` objects, regexes, sets, strings, symbols, and typed * arrays. The own enumerable properties of `arguments` objects are cloned * as plain objects. An empty object is returned for uncloneable values such * as error objects, functions, DOM nodes, and WeakMaps. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to clone. * @returns {*} Returns the cloned value. * @see _.cloneDeep * @example * * var objects = [{ 'a': 1 }, { 'b': 2 }]; * * var shallow = _.clone(objects); * console.log(shallow[0] === objects[0]); * // => true */ function clone(value) { return baseClone(value, CLONE_SYMBOLS_FLAG); } /** * This method is like `_.clone` except that it accepts `customizer` which * is invoked to produce the cloned value. If `customizer` returns `undefined`, * cloning is handled by the method instead. The `customizer` is invoked with * up to four arguments; (value [, index|key, object, stack]). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to clone. * @param {Function} [customizer] The function to customize cloning. * @returns {*} Returns the cloned value. * @see _.cloneDeepWith * @example * * function customizer(value) { * if (_.isElement(value)) { * return value.cloneNode(false); * } * } * * var el = _.cloneWith(document.body, customizer); * * console.log(el === document.body); * // => false * console.log(el.nodeName); * // => 'BODY' * console.log(el.childNodes.length); * // => 0 */ function cloneWith(value, customizer) { customizer = typeof customizer == "function" ? customizer : undefined; return baseClone(value, CLONE_SYMBOLS_FLAG, customizer); } /** * This method is like `_.clone` except that it recursively clones `value`. * * @static * @memberOf _ * @since 1.0.0 * @category Lang * @param {*} value The value to recursively clone. * @returns {*} Returns the deep cloned value. * @see _.clone * @example * * var objects = [{ 'a': 1 }, { 'b': 2 }]; * * var deep = _.cloneDeep(objects); * console.log(deep[0] === objects[0]); * // => false */ function cloneDeep(value) { return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); } /** * This method is like `_.cloneWith` except that it recursively clones `value`. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to recursively clone. * @param {Function} [customizer] The function to customize cloning. * @returns {*} Returns the deep cloned value. * @see _.cloneWith * @example * * function customizer(value) { * if (_.isElement(value)) { * return value.cloneNode(true); * } * } * * var el = _.cloneDeepWith(document.body, customizer); * * console.log(el === document.body); * // => false * console.log(el.nodeName); * // => 'BODY' * console.log(el.childNodes.length); * // => 20 */ function cloneDeepWith(value, customizer) { customizer = typeof customizer == "function" ? customizer : undefined; return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer); } /** * Checks if `object` conforms to `source` by invoking the predicate * properties of `source` with the corresponding property values of `object`. * * **Note:** This method is equivalent to `_.conforms` when `source` is * partially applied. * * @static * @memberOf _ * @since 4.14.0 * @category Lang * @param {Object} object The object to inspect. * @param {Object} source The object of property predicates to conform to. * @returns {boolean} Returns `true` if `object` conforms, else `false`. * @example * * var object = { 'a': 1, 'b': 2 }; * * _.conformsTo(object, { 'b': function(n) { return n > 1; } }); * // => true * * _.conformsTo(object, { 'b': function(n) { return n > 2; } }); * // => false */ function conformsTo(object, source) { return source == null || baseConformsTo(object, source, keys(source)); } /** * Performs a * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * comparison between two values to determine if they are equivalent. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to compare. * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if the values are equivalent, else `false`. * @example * * var object = { 'a': 1 }; * var other = { 'a': 1 }; * * _.eq(object, object); * // => true * * _.eq(object, other); * // => false * * _.eq('a', 'a'); * // => true * * _.eq('a', Object('a')); * // => false * * _.eq(NaN, NaN); * // => true */ function eq(value, other) { return value === other || value !== value && other !== other; } /** * Checks if `value` is greater than `other`. * * @static * @memberOf _ * @since 3.9.0 * @category Lang * @param {*} value The value to compare. * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if `value` is greater than `other`, * else `false`. * @see _.lt * @example * * _.gt(3, 1); * // => true * * _.gt(3, 3); * // => false * * _.gt(1, 3); * // => false */ var gt = createRelationalOperation(baseGt); /** * Checks if `value` is greater than or equal to `other`. * * @static * @memberOf _ * @since 3.9.0 * @category Lang * @param {*} value The value to compare. * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if `value` is greater than or equal to * `other`, else `false`. * @see _.lte * @example * * _.gte(3, 1); * // => true * * _.gte(3, 3); * // => true * * _.gte(1, 3); * // => false */ var gte = createRelationalOperation(function(value, other) { return value >= other; }); /** * Checks if `value` is likely an `arguments` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an `arguments` object, * else `false`. * @example * * _.isArguments(function() { return arguments; }()); * // => true * * _.isArguments([1, 2, 3]); * // => false */ var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { return isObjectLike(value) && hasOwnProperty.call(value, "callee") && !propertyIsEnumerable.call(value, "callee"); }; /** * Checks if `value` is classified as an `Array` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an array, else `false`. * @example * * _.isArray([1, 2, 3]); * // => true * * _.isArray(document.body.children); * // => false * * _.isArray('abc'); * // => false * * _.isArray(_.noop); * // => false */ var isArray = Array.isArray; /** * Checks if `value` is classified as an `ArrayBuffer` object. * * @static * @memberOf _ * @since 4.3.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`. * @example * * _.isArrayBuffer(new ArrayBuffer(2)); * // => true * * _.isArrayBuffer(new Array(2)); * // => false */ var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer; /** * Checks if `value` is array-like. A value is considered array-like if it's * not a function and has a `value.length` that's an integer greater than or * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is array-like, else `false`. * @example * * _.isArrayLike([1, 2, 3]); * // => true * * _.isArrayLike(document.body.children); * // => true * * _.isArrayLike('abc'); * // => true * * _.isArrayLike(_.noop); * // => false */ function isArrayLike(value) { return value != null && isLength(value.length) && !isFunction(value); } /** * This method is like `_.isArrayLike` except that it also checks if `value` * is an object. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an array-like object, * else `false`. * @example * * _.isArrayLikeObject([1, 2, 3]); * // => true * * _.isArrayLikeObject(document.body.children); * // => true * * _.isArrayLikeObject('abc'); * // => false * * _.isArrayLikeObject(_.noop); * // => false */ function isArrayLikeObject(value) { return isObjectLike(value) && isArrayLike(value); } /** * Checks if `value` is classified as a boolean primitive or object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a boolean, else `false`. * @example * * _.isBoolean(false); * // => true * * _.isBoolean(null); * // => false */ function isBoolean(value) { return value === true || value === false || isObjectLike(value) && baseGetTag(value) == boolTag; } /** * Checks if `value` is a buffer. * * @static * @memberOf _ * @since 4.3.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. * @example * * _.isBuffer(new Buffer(2)); * // => true * * _.isBuffer(new Uint8Array(2)); * // => false */ var isBuffer = nativeIsBuffer || stubFalse; /** * Checks if `value` is classified as a `Date` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a date object, else `false`. * @example * * _.isDate(new Date); * // => true * * _.isDate('Mon April 23 2012'); * // => false */ var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate; /** * Checks if `value` is likely a DOM element. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. * @example * * _.isElement(document.body); * // => true * * _.isElement(''); * // => false */ function isElement(value) { return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value); } /** * Checks if `value` is an empty object, collection, map, or set. * * Objects are considered empty if they have no own enumerable string keyed * properties. * * Array-like values such as `arguments` objects, arrays, buffers, strings, or * jQuery-like collections are considered empty if they have a `length` of `0`. * Similarly, maps and sets are considered empty if they have a `size` of `0`. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is empty, else `false`. * @example * * _.isEmpty(null); * // => true * * _.isEmpty(true); * // => true * * _.isEmpty(1); * // => true * * _.isEmpty([1, 2, 3]); * // => false * * _.isEmpty({ 'a': 1 }); * // => false */ function isEmpty(value) { if (value == null) { return true; } if (isArrayLike(value) && (isArray(value) || typeof value == "string" || typeof value.splice == "function" || isBuffer(value) || isTypedArray(value) || isArguments(value))) { return !value.length; } var tag = getTag(value); if (tag == mapTag || tag == setTag) { return !value.size; } if (isPrototype(value)) { return !baseKeys(value).length; } for (var key in value) { if (hasOwnProperty.call(value, key)) { return false; } } return true; } /** * Performs a deep comparison between two values to determine if they are * equivalent. * * **Note:** This method supports comparing arrays, array buffers, booleans, * date objects, error objects, maps, numbers, `Object` objects, regexes, * sets, strings, symbols, and typed arrays. `Object` objects are compared * by their own, not inherited, enumerable properties. Functions and DOM * nodes are compared by strict equality, i.e. `===`. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to compare. * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if the values are equivalent, else `false`. * @example * * var object = { 'a': 1 }; * var other = { 'a': 1 }; * * _.isEqual(object, other); * // => true * * object === other; * // => false */ function isEqual(value, other) { return baseIsEqual(value, other); } /** * This method is like `_.isEqual` except that it accepts `customizer` which * is invoked to compare values. If `customizer` returns `undefined`, comparisons * are handled by the method instead. The `customizer` is invoked with up to * six arguments: (objValue, othValue [, index|key, object, other, stack]). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to compare. * @param {*} other The other value to compare. * @param {Function} [customizer] The function to customize comparisons. * @returns {boolean} Returns `true` if the values are equivalent, else `false`. * @example * * function isGreeting(value) { * return /^h(?:i|ello)$/.test(value); * } * * function customizer(objValue, othValue) { * if (isGreeting(objValue) && isGreeting(othValue)) { * return true; * } * } * * var array = ['hello', 'goodbye']; * var other = ['hi', 'goodbye']; * * _.isEqualWith(array, other, customizer); * // => true */ function isEqualWith(value, other, customizer) { customizer = typeof customizer == "function" ? customizer : undefined; var result = customizer ? customizer(value, other) : undefined; return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result; } /** * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, * `SyntaxError`, `TypeError`, or `URIError` object. * * @static * @memberOf _ * @since 3.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an error object, else `false`. * @example * * _.isError(new Error); * // => true * * _.isError(Error); * // => false */ function isError(value) { if (!isObjectLike(value)) { return false; } var tag = baseGetTag(value); return tag == errorTag || tag == domExcTag || typeof value.message == "string" && typeof value.name == "string" && !isPlainObject(value); } /** * Checks if `value` is a finite primitive number. * * **Note:** This method is based on * [`Number.isFinite`](https://mdn.io/Number/isFinite). * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. * @example * * _.isFinite(3); * // => true * * _.isFinite(Number.MIN_VALUE); * // => true * * _.isFinite(Infinity); * // => false * * _.isFinite('3'); * // => false */ function isFinite(value) { return typeof value == "number" && nativeIsFinite(value); } /** * Checks if `value` is classified as a `Function` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a function, else `false`. * @example * * _.isFunction(_); * // => true * * _.isFunction(/abc/); * // => false */ function isFunction(value) { if (!isObject(value)) { return false; } var tag = baseGetTag(value); return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; } /** * Checks if `value` is an integer. * * **Note:** This method is based on * [`Number.isInteger`](https://mdn.io/Number/isInteger). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an integer, else `false`. * @example * * _.isInteger(3); * // => true * * _.isInteger(Number.MIN_VALUE); * // => false * * _.isInteger(Infinity); * // => false * * _.isInteger('3'); * // => false */ function isInteger(value) { return typeof value == "number" && value == toInteger(value); } /** * Checks if `value` is a valid array-like length. * * **Note:** This method is loosely based on * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. * @example * * _.isLength(3); * // => true * * _.isLength(Number.MIN_VALUE); * // => false * * _.isLength(Infinity); * // => false * * _.isLength('3'); * // => false */ function isLength(value) { return typeof value == "number" && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; } /** * Checks if `value` is the * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an object, else `false`. * @example * * _.isObject({}); * // => true * * _.isObject([1, 2, 3]); * // => true * * _.isObject(_.noop); * // => true * * _.isObject(null); * // => false */ function isObject(value) { var type = typeof value; return value != null && (type == "object" || type == "function"); } /** * Checks if `value` is object-like. A value is object-like if it's not `null` * and has a `typeof` result of "object". * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is object-like, else `false`. * @example * * _.isObjectLike({}); * // => true * * _.isObjectLike([1, 2, 3]); * // => true * * _.isObjectLike(_.noop); * // => false * * _.isObjectLike(null); * // => false */ function isObjectLike(value) { return value != null && typeof value == "object"; } /** * Checks if `value` is classified as a `Map` object. * * @static * @memberOf _ * @since 4.3.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a map, else `false`. * @example * * _.isMap(new Map); * // => true * * _.isMap(new WeakMap); * // => false */ var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap; /** * Performs a partial deep comparison between `object` and `source` to * determine if `object` contains equivalent property values. * * **Note:** This method is equivalent to `_.matches` when `source` is * partially applied. * * Partial comparisons will match empty array and empty object `source` * values against any array or object value, respectively. See `_.isEqual` * for a list of supported value comparisons. * * @static * @memberOf _ * @since 3.0.0 * @category Lang * @param {Object} object The object to inspect. * @param {Object} source The object of property values to match. * @returns {boolean} Returns `true` if `object` is a match, else `false`. * @example * * var object = { 'a': 1, 'b': 2 }; * * _.isMatch(object, { 'b': 2 }); * // => true * * _.isMatch(object, { 'b': 1 }); * // => false */ function isMatch(object, source) { return object === source || baseIsMatch(object, source, getMatchData(source)); } /** * This method is like `_.isMatch` except that it accepts `customizer` which * is invoked to compare values. If `customizer` returns `undefined`, comparisons * are handled by the method instead. The `customizer` is invoked with five * arguments: (objValue, srcValue, index|key, object, source). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {Object} object The object to inspect. * @param {Object} source The object of property values to match. * @param {Function} [customizer] The function to customize comparisons. * @returns {boolean} Returns `true` if `object` is a match, else `false`. * @example * * function isGreeting(value) { * return /^h(?:i|ello)$/.test(value); * } * * function customizer(objValue, srcValue) { * if (isGreeting(objValue) && isGreeting(srcValue)) { * return true; * } * } * * var object = { 'greeting': 'hello' }; * var source = { 'greeting': 'hi' }; * * _.isMatchWith(object, source, customizer); * // => true */ function isMatchWith(object, source, customizer) { customizer = typeof customizer == "function" ? customizer : undefined; return baseIsMatch(object, source, getMatchData(source), customizer); } /** * Checks if `value` is `NaN`. * * **Note:** This method is based on * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for * `undefined` and other non-number values. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. * @example * * _.isNaN(NaN); * // => true * * _.isNaN(new Number(NaN)); * // => true * * isNaN(undefined); * // => true * * _.isNaN(undefined); * // => false */ function isNaN(value) { return isNumber(value) && value != +value; } /** * Checks if `value` is a pristine native function. * * **Note:** This method can't reliably detect native functions in the presence * of the core-js package because core-js circumvents this kind of detection. * Despite multiple requests, the core-js maintainer has made it clear: any * attempt to fix the detection will be obstructed. As a result, we're left * with little choice but to throw an error. Unfortunately, this also affects * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill), * which rely on core-js. * * @static * @memberOf _ * @since 3.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a native function, * else `false`. * @example * * _.isNative(Array.prototype.push); * // => true * * _.isNative(_); * // => false */ function isNative(value) { if (isMaskable(value)) { throw new Error(CORE_ERROR_TEXT); } return baseIsNative(value); } /** * Checks if `value` is `null`. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is `null`, else `false`. * @example * * _.isNull(null); * // => true * * _.isNull(void 0); * // => false */ function isNull(value) { return value === null; } /** * Checks if `value` is `null` or `undefined`. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is nullish, else `false`. * @example * * _.isNil(null); * // => true * * _.isNil(void 0); * // => true * * _.isNil(NaN); * // => false */ function isNil(value) { return value == null; } /** * Checks if `value` is classified as a `Number` primitive or object. * * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are * classified as numbers, use the `_.isFinite` method. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a number, else `false`. * @example * * _.isNumber(3); * // => true * * _.isNumber(Number.MIN_VALUE); * // => true * * _.isNumber(Infinity); * // => true * * _.isNumber('3'); * // => false */ function isNumber(value) { return typeof value == "number" || isObjectLike(value) && baseGetTag(value) == numberTag; } /** * Checks if `value` is a plain object, that is, an object created by the * `Object` constructor or one with a `[[Prototype]]` of `null`. * * @static * @memberOf _ * @since 0.8.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. * @example * * function Foo() { * this.a = 1; * } * * _.isPlainObject(new Foo); * // => false * * _.isPlainObject([1, 2, 3]); * // => false * * _.isPlainObject({ 'x': 0, 'y': 0 }); * // => true * * _.isPlainObject(Object.create(null)); * // => true */ function isPlainObject(value) { if (!isObjectLike(value) || baseGetTag(value) != objectTag) { return false; } var proto = getPrototype(value); if (proto === null) { return true; } var Ctor = hasOwnProperty.call(proto, "constructor") && proto.constructor; return typeof Ctor == "function" && Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString; } /** * Checks if `value` is classified as a `RegExp` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. * @example * * _.isRegExp(/abc/); * // => true * * _.isRegExp('/abc/'); * // => false */ var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp; /** * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754 * double precision number which isn't the result of a rounded unsafe integer. * * **Note:** This method is based on * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`. * @example * * _.isSafeInteger(3); * // => true * * _.isSafeInteger(Number.MIN_VALUE); * // => false * * _.isSafeInteger(Infinity); * // => false * * _.isSafeInteger('3'); * // => false */ function isSafeInteger(value) { return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER; } /** * Checks if `value` is classified as a `Set` object. * * @static * @memberOf _ * @since 4.3.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a set, else `false`. * @example * * _.isSet(new Set); * // => true * * _.isSet(new WeakSet); * // => false */ var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet; /** * Checks if `value` is classified as a `String` primitive or object. * * @static * @since 0.1.0 * @memberOf _ * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a string, else `false`. * @example * * _.isString('abc'); * // => true * * _.isString(1); * // => false */ function isString(value) { return typeof value == "string" || !isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag; } /** * Checks if `value` is classified as a `Symbol` primitive or object. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. * @example * * _.isSymbol(Symbol.iterator); * // => true * * _.isSymbol('abc'); * // => false */ function isSymbol(value) { return typeof value == "symbol" || isObjectLike(value) && baseGetTag(value) == symbolTag; } /** * Checks if `value` is classified as a typed array. * * @static * @memberOf _ * @since 3.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. * @example * * _.isTypedArray(new Uint8Array); * // => true * * _.isTypedArray([]); * // => false */ var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; /** * Checks if `value` is `undefined`. * * @static * @since 0.1.0 * @memberOf _ * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. * @example * * _.isUndefined(void 0); * // => true * * _.isUndefined(null); * // => false */ function isUndefined(value) { return value === undefined; } /** * Checks if `value` is classified as a `WeakMap` object. * * @static * @memberOf _ * @since 4.3.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a weak map, else `false`. * @example * * _.isWeakMap(new WeakMap); * // => true * * _.isWeakMap(new Map); * // => false */ function isWeakMap(value) { return isObjectLike(value) && getTag(value) == weakMapTag; } /** * Checks if `value` is classified as a `WeakSet` object. * * @static * @memberOf _ * @since 4.3.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a weak set, else `false`. * @example * * _.isWeakSet(new WeakSet); * // => true * * _.isWeakSet(new Set); * // => false */ function isWeakSet(value) { return isObjectLike(value) && baseGetTag(value) == weakSetTag; } /** * Checks if `value` is less than `other`. * * @static * @memberOf _ * @since 3.9.0 * @category Lang * @param {*} value The value to compare. * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if `value` is less than `other`, * else `false`. * @see _.gt * @example * * _.lt(1, 3); * // => true * * _.lt(3, 3); * // => false * * _.lt(3, 1); * // => false */ var lt = createRelationalOperation(baseLt); /** * Checks if `value` is less than or equal to `other`. * * @static * @memberOf _ * @since 3.9.0 * @category Lang * @param {*} value The value to compare. * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if `value` is less than or equal to * `other`, else `false`. * @see _.gte * @example * * _.lte(1, 3); * // => true * * _.lte(3, 3); * // => true * * _.lte(3, 1); * // => false */ var lte = createRelationalOperation(function(value, other) { return value <= other; }); /** * Converts `value` to an array. * * @static * @since 0.1.0 * @memberOf _ * @category Lang * @param {*} value The value to convert. * @returns {Array} Returns the converted array. * @example * * _.toArray({ 'a': 1, 'b': 2 }); * // => [1, 2] * * _.toArray('abc'); * // => ['a', 'b', 'c'] * * _.toArray(1); * // => [] * * _.toArray(null); * // => [] */ function toArray(value) { if (!value) { return []; } if (isArrayLike(value)) { return isString(value) ? stringToArray(value) : copyArray(value); } if (symIterator && value[symIterator]) { return iteratorToArray(value[symIterator]()); } var tag = getTag(value), func = tag == mapTag ? mapToArray : tag == setTag ? setToArray : values; return func(value); } /** * Converts `value` to a finite number. * * @static * @memberOf _ * @since 4.12.0 * @category Lang * @param {*} value The value to convert. * @returns {number} Returns the converted number. * @example * * _.toFinite(3.2); * // => 3.2 * * _.toFinite(Number.MIN_VALUE); * // => 5e-324 * * _.toFinite(Infinity); * // => 1.7976931348623157e+308 * * _.toFinite('3.2'); * // => 3.2 */ function toFinite(value) { if (!value) { return value === 0 ? value : 0; } value = toNumber(value); if (value === INFINITY || value === -INFINITY) { var sign = value < 0 ? -1 : 1; return sign * MAX_INTEGER; } return value === value ? value : 0; } /** * Converts `value` to an integer. * * **Note:** This method is loosely based on * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to convert. * @returns {number} Returns the converted integer. * @example * * _.toInteger(3.2); * // => 3 * * _.toInteger(Number.MIN_VALUE); * // => 0 * * _.toInteger(Infinity); * // => 1.7976931348623157e+308 * * _.toInteger('3.2'); * // => 3 */ function toInteger(value) { var result = toFinite(value), remainder = result % 1; return result === result ? remainder ? result - remainder : result : 0; } /** * Converts `value` to an integer suitable for use as the length of an * array-like object. * * **Note:** This method is based on * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to convert. * @returns {number} Returns the converted integer. * @example * * _.toLength(3.2); * // => 3 * * _.toLength(Number.MIN_VALUE); * // => 0 * * _.toLength(Infinity); * // => 4294967295 * * _.toLength('3.2'); * // => 3 */ function toLength(value) { return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0; } /** * Converts `value` to a number. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to process. * @returns {number} Returns the number. * @example * * _.toNumber(3.2); * // => 3.2 * * _.toNumber(Number.MIN_VALUE); * // => 5e-324 * * _.toNumber(Infinity); * // => Infinity * * _.toNumber('3.2'); * // => 3.2 */ function toNumber(value) { if (typeof value == "number") { return value; } if (isSymbol(value)) { return NAN; } if (isObject(value)) { var other = typeof value.valueOf == "function" ? value.valueOf() : value; value = isObject(other) ? other + "" : other; } if (typeof value != "string") { return value === 0 ? value : +value; } value = baseTrim(value); var isBinary = reIsBinary.test(value); return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value; } /** * Converts `value` to a plain object flattening inherited enumerable string * keyed properties of `value` to own properties of the plain object. * * @static * @memberOf _ * @since 3.0.0 * @category Lang * @param {*} value The value to convert. * @returns {Object} Returns the converted plain object. * @example * * function Foo() { * this.b = 2; * } * * Foo.prototype.c = 3; * * _.assign({ 'a': 1 }, new Foo); * // => { 'a': 1, 'b': 2 } * * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); * // => { 'a': 1, 'b': 2, 'c': 3 } */ function toPlainObject(value) { return copyObject(value, keysIn(value)); } /** * Converts `value` to a safe integer. A safe integer can be compared and * represented correctly. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to convert. * @returns {number} Returns the converted integer. * @example * * _.toSafeInteger(3.2); * // => 3 * * _.toSafeInteger(Number.MIN_VALUE); * // => 0 * * _.toSafeInteger(Infinity); * // => 9007199254740991 * * _.toSafeInteger('3.2'); * // => 3 */ function toSafeInteger(value) { return value ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER) : value === 0 ? value : 0; } /** * Converts `value` to a string. An empty string is returned for `null` * and `undefined` values. The sign of `-0` is preserved. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to convert. * @returns {string} Returns the converted string. * @example * * _.toString(null); * // => '' * * _.toString(-0); * // => '-0' * * _.toString([1, 2, 3]); * // => '1,2,3' */ function toString(value) { return value == null ? "" : baseToString(value); } /** * Assigns own enumerable string keyed properties of source objects to the * destination object. Source objects are applied from left to right. * Subsequent sources overwrite property assignments of previous sources. * * **Note:** This method mutates `object` and is loosely based on * [`Object.assign`](https://mdn.io/Object/assign). * * @static * @memberOf _ * @since 0.10.0 * @category Object * @param {Object} object The destination object. * @param {...Object} [sources] The source objects. * @returns {Object} Returns `object`. * @see _.assignIn * @example * * function Foo() { * this.a = 1; * } * * function Bar() { * this.c = 3; * } * * Foo.prototype.b = 2; * Bar.prototype.d = 4; * * _.assign({ 'a': 0 }, new Foo, new Bar); * // => { 'a': 1, 'c': 3 } */ var assign = createAssigner(function(object, source) { if (isPrototype(source) || isArrayLike(source)) { copyObject(source, keys(source), object); return; } for (var key in source) { if (hasOwnProperty.call(source, key)) { assignValue(object, key, source[key]); } } }); /** * This method is like `_.assign` except that it iterates over own and * inherited source properties. * * **Note:** This method mutates `object`. * * @static * @memberOf _ * @since 4.0.0 * @alias extend * @category Object * @param {Object} object The destination object. * @param {...Object} [sources] The source objects. * @returns {Object} Returns `object`. * @see _.assign * @example * * function Foo() { * this.a = 1; * } * * function Bar() { * this.c = 3; * } * * Foo.prototype.b = 2; * Bar.prototype.d = 4; * * _.assignIn({ 'a': 0 }, new Foo, new Bar); * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 } */ var assignIn = createAssigner(function(object, source) { copyObject(source, keysIn(source), object); }); /** * This method is like `_.assignIn` except that it accepts `customizer` * which is invoked to produce the assigned values. If `customizer` returns * `undefined`, assignment is handled by the method instead. The `customizer` * is invoked with five arguments: (objValue, srcValue, key, object, source). * * **Note:** This method mutates `object`. * * @static * @memberOf _ * @since 4.0.0 * @alias extendWith * @category Object * @param {Object} object The destination object. * @param {...Object} sources The source objects. * @param {Function} [customizer] The function to customize assigned values. * @returns {Object} Returns `object`. * @see _.assignWith * @example * * function customizer(objValue, srcValue) { * return _.isUndefined(objValue) ? srcValue : objValue; * } * * var defaults = _.partialRight(_.assignInWith, customizer); * * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); * // => { 'a': 1, 'b': 2 } */ var assignInWith = createAssigner(function(object, source, srcIndex, customizer) { copyObject(source, keysIn(source), object, customizer); }); /** * This method is like `_.assign` except that it accepts `customizer` * which is invoked to produce the assigned values. If `customizer` returns * `undefined`, assignment is handled by the method instead. The `customizer` * is invoked with five arguments: (objValue, srcValue, key, object, source). * * **Note:** This method mutates `object`. * * @static * @memberOf _ * @since 4.0.0 * @category Object * @param {Object} object The destination object. * @param {...Object} sources The source objects. * @param {Function} [customizer] The function to customize assigned values. * @returns {Object} Returns `object`. * @see _.assignInWith * @example * * function customizer(objValue, srcValue) { * return _.isUndefined(objValue) ? srcValue : objValue; * } * * var defaults = _.partialRight(_.assignWith, customizer); * * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); * // => { 'a': 1, 'b': 2 } */ var assignWith = createAssigner(function(object, source, srcIndex, customizer) { copyObject(source, keys(source), object, customizer); }); /** * Creates an array of values corresponding to `paths` of `object`. * * @static * @memberOf _ * @since 1.0.0 * @category Object * @param {Object} object The object to iterate over. * @param {...(string|string[])} [paths] The property paths to pick. * @returns {Array} Returns the picked values. * @example * * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; * * _.at(object, ['a[0].b.c', 'a[1]']); * // => [3, 4] */ var at = flatRest(baseAt); /** * Creates an object that inherits from the `prototype` object. If a * `properties` object is given, its own enumerable string keyed properties * are assigned to the created object. * * @static * @memberOf _ * @since 2.3.0 * @category Object * @param {Object} prototype The object to inherit from. * @param {Object} [properties] The properties to assign to the object. * @returns {Object} Returns the new object. * @example * * function Shape() { * this.x = 0; * this.y = 0; * } * * function Circle() { * Shape.call(this); * } * * Circle.prototype = _.create(Shape.prototype, { * 'constructor': Circle * }); * * var circle = new Circle; * circle instanceof Circle; * // => true * * circle instanceof Shape; * // => true */ function create(prototype, properties) { var result = baseCreate(prototype); return properties == null ? result : baseAssign(result, properties); } /** * Assigns own and inherited enumerable string keyed properties of source * objects to the destination object for all destination properties that * resolve to `undefined`. Source objects are applied from left to right. * Once a property is set, additional values of the same property are ignored. * * **Note:** This method mutates `object`. * * @static * @since 0.1.0 * @memberOf _ * @category Object * @param {Object} object The destination object. * @param {...Object} [sources] The source objects. * @returns {Object} Returns `object`. * @see _.defaultsDeep * @example * * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); * // => { 'a': 1, 'b': 2 } */ var defaults = baseRest(function(object, sources) { object = Object(object); var index = -1; var length = sources.length; var guard = length > 2 ? sources[2] : undefined; if (guard && isIterateeCall(sources[0], sources[1], guard)) { length = 1; } while (++index < length) { var source = sources[index]; var props = keysIn(source); var propsIndex = -1; var propsLength = props.length; while (++propsIndex < propsLength) { var key = props[propsIndex]; var value = object[key]; if (value === undefined || eq(value, objectProto[key]) && !hasOwnProperty.call(object, key)) { object[key] = source[key]; } } } return object; }); /** * This method is like `_.defaults` except that it recursively assigns * default properties. * * **Note:** This method mutates `object`. * * @static * @memberOf _ * @since 3.10.0 * @category Object * @param {Object} object The destination object. * @param {...Object} [sources] The source objects. * @returns {Object} Returns `object`. * @see _.defaults * @example * * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } }); * // => { 'a': { 'b': 2, 'c': 3 } } */ var defaultsDeep = baseRest(function(args) { args.push(undefined, customDefaultsMerge); return apply(mergeWith, undefined, args); }); /** * This method is like `_.find` except that it returns the key of the first * element `predicate` returns truthy for instead of the element itself. * * @static * @memberOf _ * @since 1.1.0 * @category Object * @param {Object} object The object to inspect. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @returns {string|undefined} Returns the key of the matched element, * else `undefined`. * @example * * var users = { * 'barney': { 'age': 36, 'active': true }, * 'fred': { 'age': 40, 'active': false }, * 'pebbles': { 'age': 1, 'active': true } * }; * * _.findKey(users, function(o) { return o.age < 40; }); * // => 'barney' (iteration order is not guaranteed) * * // The `_.matches` iteratee shorthand. * _.findKey(users, { 'age': 1, 'active': true }); * // => 'pebbles' * * // The `_.matchesProperty` iteratee shorthand. * _.findKey(users, ['active', false]); * // => 'fred' * * // The `_.property` iteratee shorthand. * _.findKey(users, 'active'); * // => 'barney' */ function findKey(object, predicate) { return baseFindKey(object, getIteratee(predicate, 3), baseForOwn); } /** * This method is like `_.findKey` except that it iterates over elements of * a collection in the opposite order. * * @static * @memberOf _ * @since 2.0.0 * @category Object * @param {Object} object The object to inspect. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @returns {string|undefined} Returns the key of the matched element, * else `undefined`. * @example * * var users = { * 'barney': { 'age': 36, 'active': true }, * 'fred': { 'age': 40, 'active': false }, * 'pebbles': { 'age': 1, 'active': true } * }; * * _.findLastKey(users, function(o) { return o.age < 40; }); * // => returns 'pebbles' assuming `_.findKey` returns 'barney' * * // The `_.matches` iteratee shorthand. * _.findLastKey(users, { 'age': 36, 'active': true }); * // => 'barney' * * // The `_.matchesProperty` iteratee shorthand. * _.findLastKey(users, ['active', false]); * // => 'fred' * * // The `_.property` iteratee shorthand. * _.findLastKey(users, 'active'); * // => 'pebbles' */ function findLastKey(object, predicate) { return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight); } /** * Iterates over own and inherited enumerable string keyed properties of an * object and invokes `iteratee` for each property. The iteratee is invoked * with three arguments: (value, key, object). Iteratee functions may exit * iteration early by explicitly returning `false`. * * @static * @memberOf _ * @since 0.3.0 * @category Object * @param {Object} object The object to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @returns {Object} Returns `object`. * @see _.forInRight * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.forIn(new Foo, function(value, key) { * console.log(key); * }); * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). */ function forIn(object, iteratee) { return object == null ? object : baseFor(object, getIteratee(iteratee, 3), keysIn); } /** * This method is like `_.forIn` except that it iterates over properties of * `object` in the opposite order. * * @static * @memberOf _ * @since 2.0.0 * @category Object * @param {Object} object The object to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @returns {Object} Returns `object`. * @see _.forIn * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.forInRight(new Foo, function(value, key) { * console.log(key); * }); * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'. */ function forInRight(object, iteratee) { return object == null ? object : baseForRight(object, getIteratee(iteratee, 3), keysIn); } /** * Iterates over own enumerable string keyed properties of an object and * invokes `iteratee` for each property. The iteratee is invoked with three * arguments: (value, key, object). Iteratee functions may exit iteration * early by explicitly returning `false`. * * @static * @memberOf _ * @since 0.3.0 * @category Object * @param {Object} object The object to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @returns {Object} Returns `object`. * @see _.forOwnRight * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.forOwn(new Foo, function(value, key) { * console.log(key); * }); * // => Logs 'a' then 'b' (iteration order is not guaranteed). */ function forOwn(object, iteratee) { return object && baseForOwn(object, getIteratee(iteratee, 3)); } /** * This method is like `_.forOwn` except that it iterates over properties of * `object` in the opposite order. * * @static * @memberOf _ * @since 2.0.0 * @category Object * @param {Object} object The object to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @returns {Object} Returns `object`. * @see _.forOwn * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.forOwnRight(new Foo, function(value, key) { * console.log(key); * }); * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'. */ function forOwnRight(object, iteratee) { return object && baseForOwnRight(object, getIteratee(iteratee, 3)); } /** * Creates an array of function property names from own enumerable properties * of `object`. * * @static * @since 0.1.0 * @memberOf _ * @category Object * @param {Object} object The object to inspect. * @returns {Array} Returns the function names. * @see _.functionsIn * @example * * function Foo() { * this.a = _.constant('a'); * this.b = _.constant('b'); * } * * Foo.prototype.c = _.constant('c'); * * _.functions(new Foo); * // => ['a', 'b'] */ function functions(object) { return object == null ? [] : baseFunctions(object, keys(object)); } /** * Creates an array of function property names from own and inherited * enumerable properties of `object`. * * @static * @memberOf _ * @since 4.0.0 * @category Object * @param {Object} object The object to inspect. * @returns {Array} Returns the function names. * @see _.functions * @example * * function Foo() { * this.a = _.constant('a'); * this.b = _.constant('b'); * } * * Foo.prototype.c = _.constant('c'); * * _.functionsIn(new Foo); * // => ['a', 'b', 'c'] */ function functionsIn(object) { return object == null ? [] : baseFunctions(object, keysIn(object)); } /** * Gets the value at `path` of `object`. If the resolved value is * `undefined`, the `defaultValue` is returned in its place. * * @static * @memberOf _ * @since 3.7.0 * @category Object * @param {Object} object The object to query. * @param {Array|string} path The path of the property to get. * @param {*} [defaultValue] The value returned for `undefined` resolved values. * @returns {*} Returns the resolved value. * @example * * var object = { 'a': [{ 'b': { 'c': 3 } }] }; * * _.get(object, 'a[0].b.c'); * // => 3 * * _.get(object, ['a', '0', 'b', 'c']); * // => 3 * * _.get(object, 'a.b.c', 'default'); * // => 'default' */ function get(object, path, defaultValue) { var result = object == null ? undefined : baseGet(object, path); return result === undefined ? defaultValue : result; } /** * Checks if `path` is a direct property of `object`. * * @static * @since 0.1.0 * @memberOf _ * @category Object * @param {Object} object The object to query. * @param {Array|string} path The path to check. * @returns {boolean} Returns `true` if `path` exists, else `false`. * @example * * var object = { 'a': { 'b': 2 } }; * var other = _.create({ 'a': _.create({ 'b': 2 }) }); * * _.has(object, 'a'); * // => true * * _.has(object, 'a.b'); * // => true * * _.has(object, ['a', 'b']); * // => true * * _.has(other, 'a'); * // => false */ function has(object, path) { return object != null && hasPath(object, path, baseHas); } /** * Checks if `path` is a direct or inherited property of `object`. * * @static * @memberOf _ * @since 4.0.0 * @category Object * @param {Object} object The object to query. * @param {Array|string} path The path to check. * @returns {boolean} Returns `true` if `path` exists, else `false`. * @example * * var object = _.create({ 'a': _.create({ 'b': 2 }) }); * * _.hasIn(object, 'a'); * // => true * * _.hasIn(object, 'a.b'); * // => true * * _.hasIn(object, ['a', 'b']); * // => true * * _.hasIn(object, 'b'); * // => false */ function hasIn(object, path) { return object != null && hasPath(object, path, baseHasIn); } /** * Creates an object composed of the inverted keys and values of `object`. * If `object` contains duplicate values, subsequent values overwrite * property assignments of previous values. * * @static * @memberOf _ * @since 0.7.0 * @category Object * @param {Object} object The object to invert. * @returns {Object} Returns the new inverted object. * @example * * var object = { 'a': 1, 'b': 2, 'c': 1 }; * * _.invert(object); * // => { '1': 'c', '2': 'b' } */ var invert = createInverter(function(result, value, key) { if (value != null && typeof value.toString != "function") { value = nativeObjectToString.call(value); } result[value] = key; }, constant(identity)); /** * This method is like `_.invert` except that the inverted object is generated * from the results of running each element of `object` thru `iteratee`. The * corresponding inverted value of each inverted key is an array of keys * responsible for generating the inverted value. The iteratee is invoked * with one argument: (value). * * @static * @memberOf _ * @since 4.1.0 * @category Object * @param {Object} object The object to invert. * @param {Function} [iteratee=_.identity] The iteratee invoked per element. * @returns {Object} Returns the new inverted object. * @example * * var object = { 'a': 1, 'b': 2, 'c': 1 }; * * _.invertBy(object); * // => { '1': ['a', 'c'], '2': ['b'] } * * _.invertBy(object, function(value) { * return 'group' + value; * }); * // => { 'group1': ['a', 'c'], 'group2': ['b'] } */ var invertBy = createInverter(function(result, value, key) { if (value != null && typeof value.toString != "function") { value = nativeObjectToString.call(value); } if (hasOwnProperty.call(result, value)) { result[value].push(key); } else { result[value] = [key]; } }, getIteratee); /** * Invokes the method at `path` of `object`. * * @static * @memberOf _ * @since 4.0.0 * @category Object * @param {Object} object The object to query. * @param {Array|string} path The path of the method to invoke. * @param {...*} [args] The arguments to invoke the method with. * @returns {*} Returns the result of the invoked method. * @example * * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] }; * * _.invoke(object, 'a[0].b.c.slice', 1, 3); * // => [2, 3] */ var invoke = baseRest(baseInvoke); /** * Creates an array of the own enumerable property names of `object`. * * **Note:** Non-object values are coerced to objects. See the * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) * for more details. * * @static * @since 0.1.0 * @memberOf _ * @category Object * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.keys(new Foo); * // => ['a', 'b'] (iteration order is not guaranteed) * * _.keys('hi'); * // => ['0', '1'] */ function keys(object) { return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); } /** * Creates an array of the own and inherited enumerable property names of `object`. * * **Note:** Non-object values are coerced to objects. * * @static * @memberOf _ * @since 3.0.0 * @category Object * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.keysIn(new Foo); * // => ['a', 'b', 'c'] (iteration order is not guaranteed) */ function keysIn(object) { return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); } /** * The opposite of `_.mapValues`; this method creates an object with the * same values as `object` and keys generated by running each own enumerable * string keyed property of `object` thru `iteratee`. The iteratee is invoked * with three arguments: (value, key, object). * * @static * @memberOf _ * @since 3.8.0 * @category Object * @param {Object} object The object to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @returns {Object} Returns the new mapped object. * @see _.mapValues * @example * * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { * return key + value; * }); * // => { 'a1': 1, 'b2': 2 } */ function mapKeys(object, iteratee) { var result = {}; iteratee = getIteratee(iteratee, 3); baseForOwn(object, function(value, key, object) { baseAssignValue(result, iteratee(value, key, object), value); }); return result; } /** * Creates an object with the same keys as `object` and values generated * by running each own enumerable string keyed property of `object` thru * `iteratee`. The iteratee is invoked with three arguments: * (value, key, object). * * @static * @memberOf _ * @since 2.4.0 * @category Object * @param {Object} object The object to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @returns {Object} Returns the new mapped object. * @see _.mapKeys * @example * * var users = { * 'fred': { 'user': 'fred', 'age': 40 }, * 'pebbles': { 'user': 'pebbles', 'age': 1 } * }; * * _.mapValues(users, function(o) { return o.age; }); * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) * * // The `_.property` iteratee shorthand. * _.mapValues(users, 'age'); * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) */ function mapValues(object, iteratee) { var result = {}; iteratee = getIteratee(iteratee, 3); baseForOwn(object, function(value, key, object) { baseAssignValue(result, key, iteratee(value, key, object)); }); return result; } /** * This method is like `_.assign` except that it recursively merges own and * inherited enumerable string keyed properties of source objects into the * destination object. Source properties that resolve to `undefined` are * skipped if a destination value exists. Array and plain object properties * are merged recursively. Other objects and value types are overridden by * assignment. Source objects are applied from left to right. Subsequent * sources overwrite property assignments of previous sources. * * **Note:** This method mutates `object`. * * @static * @memberOf _ * @since 0.5.0 * @category Object * @param {Object} object The destination object. * @param {...Object} [sources] The source objects. * @returns {Object} Returns `object`. * @example * * var object = { * 'a': [{ 'b': 2 }, { 'd': 4 }] * }; * * var other = { * 'a': [{ 'c': 3 }, { 'e': 5 }] * }; * * _.merge(object, other); * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] } */ var merge = createAssigner(function(object, source, srcIndex) { baseMerge(object, source, srcIndex); }); /** * This method is like `_.merge` except that it accepts `customizer` which * is invoked to produce the merged values of the destination and source * properties. If `customizer` returns `undefined`, merging is handled by the * method instead. The `customizer` is invoked with six arguments: * (objValue, srcValue, key, object, source, stack). * * **Note:** This method mutates `object`. * * @static * @memberOf _ * @since 4.0.0 * @category Object * @param {Object} object The destination object. * @param {...Object} sources The source objects. * @param {Function} customizer The function to customize assigned values. * @returns {Object} Returns `object`. * @example * * function customizer(objValue, srcValue) { * if (_.isArray(objValue)) { * return objValue.concat(srcValue); * } * } * * var object = { 'a': [1], 'b': [2] }; * var other = { 'a': [3], 'b': [4] }; * * _.mergeWith(object, other, customizer); * // => { 'a': [1, 3], 'b': [2, 4] } */ var mergeWith = createAssigner(function(object, source, srcIndex, customizer) { baseMerge(object, source, srcIndex, customizer); }); /** * The opposite of `_.pick`; this method creates an object composed of the * own and inherited enumerable property paths of `object` that are not omitted. * * **Note:** This method is considerably slower than `_.pick`. * * @static * @since 0.1.0 * @memberOf _ * @category Object * @param {Object} object The source object. * @param {...(string|string[])} [paths] The property paths to omit. * @returns {Object} Returns the new object. * @example * * var object = { 'a': 1, 'b': '2', 'c': 3 }; * * _.omit(object, ['a', 'c']); * // => { 'b': '2' } */ var omit = flatRest(function(object, paths) { var result = {}; if (object == null) { return result; } var isDeep = false; paths = arrayMap(paths, function(path) { path = castPath(path, object); isDeep || (isDeep = path.length > 1); return path; }); copyObject(object, getAllKeysIn(object), result); if (isDeep) { result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone); } var length = paths.length; while (length--) { baseUnset(result, paths[length]); } return result; }); /** * The opposite of `_.pickBy`; this method creates an object composed of * the own and inherited enumerable string keyed properties of `object` that * `predicate` doesn't return truthy for. The predicate is invoked with two * arguments: (value, key). * * @static * @memberOf _ * @since 4.0.0 * @category Object * @param {Object} object The source object. * @param {Function} [predicate=_.identity] The function invoked per property. * @returns {Object} Returns the new object. * @example * * var object = { 'a': 1, 'b': '2', 'c': 3 }; * * _.omitBy(object, _.isNumber); * // => { 'b': '2' } */ function omitBy(object, predicate) { return pickBy(object, negate(getIteratee(predicate))); } /** * Creates an object composed of the picked `object` properties. * * @static * @since 0.1.0 * @memberOf _ * @category Object * @param {Object} object The source object. * @param {...(string|string[])} [paths] The property paths to pick. * @returns {Object} Returns the new object. * @example * * var object = { 'a': 1, 'b': '2', 'c': 3 }; * * _.pick(object, ['a', 'c']); * // => { 'a': 1, 'c': 3 } */ var pick = flatRest(function(object, paths) { return object == null ? {} : basePick(object, paths); }); /** * Creates an object composed of the `object` properties `predicate` returns * truthy for. The predicate is invoked with two arguments: (value, key). * * @static * @memberOf _ * @since 4.0.0 * @category Object * @param {Object} object The source object. * @param {Function} [predicate=_.identity] The function invoked per property. * @returns {Object} Returns the new object. * @example * * var object = { 'a': 1, 'b': '2', 'c': 3 }; * * _.pickBy(object, _.isNumber); * // => { 'a': 1, 'c': 3 } */ function pickBy(object, predicate) { if (object == null) { return {}; } var props = arrayMap(getAllKeysIn(object), function(prop) { return [prop]; }); predicate = getIteratee(predicate); return basePickBy(object, props, function(value, path) { return predicate(value, path[0]); }); } /** * This method is like `_.get` except that if the resolved value is a * function it's invoked with the `this` binding of its parent object and * its result is returned. * * @static * @since 0.1.0 * @memberOf _ * @category Object * @param {Object} object The object to query. * @param {Array|string} path The path of the property to resolve. * @param {*} [defaultValue] The value returned for `undefined` resolved values. * @returns {*} Returns the resolved value. * @example * * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; * * _.result(object, 'a[0].b.c1'); * // => 3 * * _.result(object, 'a[0].b.c2'); * // => 4 * * _.result(object, 'a[0].b.c3', 'default'); * // => 'default' * * _.result(object, 'a[0].b.c3', _.constant('default')); * // => 'default' */ function result(object, path, defaultValue) { path = castPath(path, object); var index = -1, length = path.length; if (!length) { length = 1; object = undefined; } while (++index < length) { var value = object == null ? undefined : object[toKey(path[index])]; if (value === undefined) { index = length; value = defaultValue; } object = isFunction(value) ? value.call(object) : value; } return object; } /** * Sets the value at `path` of `object`. If a portion of `path` doesn't exist, * it's created. Arrays are created for missing index properties while objects * are created for all other missing properties. Use `_.setWith` to customize * `path` creation. * * **Note:** This method mutates `object`. * * @static * @memberOf _ * @since 3.7.0 * @category Object * @param {Object} object The object to modify. * @param {Array|string} path The path of the property to set. * @param {*} value The value to set. * @returns {Object} Returns `object`. * @example * * var object = { 'a': [{ 'b': { 'c': 3 } }] }; * * _.set(object, 'a[0].b.c', 4); * console.log(object.a[0].b.c); * // => 4 * * _.set(object, ['x', '0', 'y', 'z'], 5); * console.log(object.x[0].y.z); * // => 5 */ function set(object, path, value) { return object == null ? object : baseSet(object, path, value); } /** * This method is like `_.set` except that it accepts `customizer` which is * invoked to produce the objects of `path`. If `customizer` returns `undefined` * path creation is handled by the method instead. The `customizer` is invoked * with three arguments: (nsValue, key, nsObject). * * **Note:** This method mutates `object`. * * @static * @memberOf _ * @since 4.0.0 * @category Object * @param {Object} object The object to modify. * @param {Array|string} path The path of the property to set. * @param {*} value The value to set. * @param {Function} [customizer] The function to customize assigned values. * @returns {Object} Returns `object`. * @example * * var object = {}; * * _.setWith(object, '[0][1]', 'a', Object); * // => { '0': { '1': 'a' } } */ function setWith(object, path, value, customizer) { customizer = typeof customizer == "function" ? customizer : undefined; return object == null ? object : baseSet(object, path, value, customizer); } /** * Creates an array of own enumerable string keyed-value pairs for `object` * which can be consumed by `_.fromPairs`. If `object` is a map or set, its * entries are returned. * * @static * @memberOf _ * @since 4.0.0 * @alias entries * @category Object * @param {Object} object The object to query. * @returns {Array} Returns the key-value pairs. * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.toPairs(new Foo); * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed) */ var toPairs = createToPairs(keys); /** * Creates an array of own and inherited enumerable string keyed-value pairs * for `object` which can be consumed by `_.fromPairs`. If `object` is a map * or set, its entries are returned. * * @static * @memberOf _ * @since 4.0.0 * @alias entriesIn * @category Object * @param {Object} object The object to query. * @returns {Array} Returns the key-value pairs. * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.toPairsIn(new Foo); * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed) */ var toPairsIn = createToPairs(keysIn); /** * An alternative to `_.reduce`; this method transforms `object` to a new * `accumulator` object which is the result of running each of its own * enumerable string keyed properties thru `iteratee`, with each invocation * potentially mutating the `accumulator` object. If `accumulator` is not * provided, a new object with the same `[[Prototype]]` will be used. The * iteratee is invoked with four arguments: (accumulator, value, key, object). * Iteratee functions may exit iteration early by explicitly returning `false`. * * @static * @memberOf _ * @since 1.3.0 * @category Object * @param {Object} object The object to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @param {*} [accumulator] The custom accumulator value. * @returns {*} Returns the accumulated value. * @example * * _.transform([2, 3, 4], function(result, n) { * result.push(n *= n); * return n % 2 == 0; * }, []); * // => [4, 9] * * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { * (result[value] || (result[value] = [])).push(key); * }, {}); * // => { '1': ['a', 'c'], '2': ['b'] } */ function transform(object, iteratee, accumulator) { var isArr = isArray(object), isArrLike = isArr || isBuffer(object) || isTypedArray(object); iteratee = getIteratee(iteratee, 4); if (accumulator == null) { var Ctor = object && object.constructor; if (isArrLike) { accumulator = isArr ? new Ctor() : []; } else if (isObject(object)) { accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {}; } else { accumulator = {}; } } (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) { return iteratee(accumulator, value, index, object); }); return accumulator; } /** * Removes the property at `path` of `object`. * * **Note:** This method mutates `object`. * * @static * @memberOf _ * @since 4.0.0 * @category Object * @param {Object} object The object to modify. * @param {Array|string} path The path of the property to unset. * @returns {boolean} Returns `true` if the property is deleted, else `false`. * @example * * var object = { 'a': [{ 'b': { 'c': 7 } }] }; * _.unset(object, 'a[0].b.c'); * // => true * * console.log(object); * // => { 'a': [{ 'b': {} }] }; * * _.unset(object, ['a', '0', 'b', 'c']); * // => true * * console.log(object); * // => { 'a': [{ 'b': {} }] }; */ function unset(object, path) { return object == null ? true : baseUnset(object, path); } /** * This method is like `_.set` except that accepts `updater` to produce the * value to set. Use `_.updateWith` to customize `path` creation. The `updater` * is invoked with one argument: (value). * * **Note:** This method mutates `object`. * * @static * @memberOf _ * @since 4.6.0 * @category Object * @param {Object} object The object to modify. * @param {Array|string} path The path of the property to set. * @param {Function} updater The function to produce the updated value. * @returns {Object} Returns `object`. * @example * * var object = { 'a': [{ 'b': { 'c': 3 } }] }; * * _.update(object, 'a[0].b.c', function(n) { return n * n; }); * console.log(object.a[0].b.c); * // => 9 * * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; }); * console.log(object.x[0].y.z); * // => 0 */ function update(object, path, updater) { return object == null ? object : baseUpdate(object, path, castFunction(updater)); } /** * This method is like `_.update` except that it accepts `customizer` which is * invoked to produce the objects of `path`. If `customizer` returns `undefined` * path creation is handled by the method instead. The `customizer` is invoked * with three arguments: (nsValue, key, nsObject). * * **Note:** This method mutates `object`. * * @static * @memberOf _ * @since 4.6.0 * @category Object * @param {Object} object The object to modify. * @param {Array|string} path The path of the property to set. * @param {Function} updater The function to produce the updated value. * @param {Function} [customizer] The function to customize assigned values. * @returns {Object} Returns `object`. * @example * * var object = {}; * * _.updateWith(object, '[0][1]', _.constant('a'), Object); * // => { '0': { '1': 'a' } } */ function updateWith(object, path, updater, customizer) { customizer = typeof customizer == "function" ? customizer : undefined; return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer); } /** * Creates an array of the own enumerable string keyed property values of `object`. * * **Note:** Non-object values are coerced to objects. * * @static * @since 0.1.0 * @memberOf _ * @category Object * @param {Object} object The object to query. * @returns {Array} Returns the array of property values. * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.values(new Foo); * // => [1, 2] (iteration order is not guaranteed) * * _.values('hi'); * // => ['h', 'i'] */ function values(object) { return object == null ? [] : baseValues(object, keys(object)); } /** * Creates an array of the own and inherited enumerable string keyed property * values of `object`. * * **Note:** Non-object values are coerced to objects. * * @static * @memberOf _ * @since 3.0.0 * @category Object * @param {Object} object The object to query. * @returns {Array} Returns the array of property values. * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.valuesIn(new Foo); * // => [1, 2, 3] (iteration order is not guaranteed) */ function valuesIn(object) { return object == null ? [] : baseValues(object, keysIn(object)); } /** * Clamps `number` within the inclusive `lower` and `upper` bounds. * * @static * @memberOf _ * @since 4.0.0 * @category Number * @param {number} number The number to clamp. * @param {number} [lower] The lower bound. * @param {number} upper The upper bound. * @returns {number} Returns the clamped number. * @example * * _.clamp(-10, -5, 5); * // => -5 * * _.clamp(10, -5, 5); * // => 5 */ function clamp(number, lower, upper) { if (upper === undefined) { upper = lower; lower = undefined; } if (upper !== undefined) { upper = toNumber(upper); upper = upper === upper ? upper : 0; } if (lower !== undefined) { lower = toNumber(lower); lower = lower === lower ? lower : 0; } return baseClamp(toNumber(number), lower, upper); } /** * Checks if `n` is between `start` and up to, but not including, `end`. If * `end` is not specified, it's set to `start` with `start` then set to `0`. * If `start` is greater than `end` the params are swapped to support * negative ranges. * * @static * @memberOf _ * @since 3.3.0 * @category Number * @param {number} number The number to check. * @param {number} [start=0] The start of the range. * @param {number} end The end of the range. * @returns {boolean} Returns `true` if `number` is in the range, else `false`. * @see _.range, _.rangeRight * @example * * _.inRange(3, 2, 4); * // => true * * _.inRange(4, 8); * // => true * * _.inRange(4, 2); * // => false * * _.inRange(2, 2); * // => false * * _.inRange(1.2, 2); * // => true * * _.inRange(5.2, 4); * // => false * * _.inRange(-3, -2, -6); * // => true */ function inRange(number, start, end) { start = toFinite(start); if (end === undefined) { end = start; start = 0; } else { end = toFinite(end); } number = toNumber(number); return baseInRange(number, start, end); } /** * Produces a random number between the inclusive `lower` and `upper` bounds. * If only one argument is provided a number between `0` and the given number * is returned. If `floating` is `true`, or either `lower` or `upper` are * floats, a floating-point number is returned instead of an integer. * * **Note:** JavaScript follows the IEEE-754 standard for resolving * floating-point values which can produce unexpected results. * * @static * @memberOf _ * @since 0.7.0 * @category Number * @param {number} [lower=0] The lower bound. * @param {number} [upper=1] The upper bound. * @param {boolean} [floating] Specify returning a floating-point number. * @returns {number} Returns the random number. * @example * * _.random(0, 5); * // => an integer between 0 and 5 * * _.random(5); * // => also an integer between 0 and 5 * * _.random(5, true); * // => a floating-point number between 0 and 5 * * _.random(1.2, 5.2); * // => a floating-point number between 1.2 and 5.2 */ function random(lower, upper, floating) { if (floating && typeof floating != "boolean" && isIterateeCall(lower, upper, floating)) { upper = floating = undefined; } if (floating === undefined) { if (typeof upper == "boolean") { floating = upper; upper = undefined; } else if (typeof lower == "boolean") { floating = lower; lower = undefined; } } if (lower === undefined && upper === undefined) { lower = 0; upper = 1; } else { lower = toFinite(lower); if (upper === undefined) { upper = lower; lower = 0; } else { upper = toFinite(upper); } } if (lower > upper) { var temp = lower; lower = upper; upper = temp; } if (floating || lower % 1 || upper % 1) { var rand = nativeRandom(); return nativeMin(lower + rand * (upper - lower + freeParseFloat("1e-" + ((rand + "").length - 1))), upper); } return baseRandom(lower, upper); } /** * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). * * @static * @memberOf _ * @since 3.0.0 * @category String * @param {string} [string=''] The string to convert. * @returns {string} Returns the camel cased string. * @example * * _.camelCase('Foo Bar'); * // => 'fooBar' * * _.camelCase('--foo-bar--'); * // => 'fooBar' * * _.camelCase('__FOO_BAR__'); * // => 'fooBar' */ var camelCase = createCompounder(function(result, word, index) { word = word.toLowerCase(); return result + (index ? capitalize(word) : word); }); /** * Converts the first character of `string` to upper case and the remaining * to lower case. * * @static * @memberOf _ * @since 3.0.0 * @category String * @param {string} [string=''] The string to capitalize. * @returns {string} Returns the capitalized string. * @example * * _.capitalize('FRED'); * // => 'Fred' */ function capitalize(string) { return upperFirst(toString(string).toLowerCase()); } /** * Deburrs `string` by converting * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A) * letters to basic Latin letters and removing * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). * * @static * @memberOf _ * @since 3.0.0 * @category String * @param {string} [string=''] The string to deburr. * @returns {string} Returns the deburred string. * @example * * _.deburr('déjà vu'); * // => 'deja vu' */ function deburr(string) { string = toString(string); return string && string.replace(reLatin, deburrLetter).replace(reComboMark, ""); } /** * Checks if `string` ends with the given target string. * * @static * @memberOf _ * @since 3.0.0 * @category String * @param {string} [string=''] The string to inspect. * @param {string} [target] The string to search for. * @param {number} [position=string.length] The position to search up to. * @returns {boolean} Returns `true` if `string` ends with `target`, * else `false`. * @example * * _.endsWith('abc', 'c'); * // => true * * _.endsWith('abc', 'b'); * // => false * * _.endsWith('abc', 'b', 2); * // => true */ function endsWith(string, target, position) { string = toString(string); target = baseToString(target); var length = string.length; position = position === undefined ? length : baseClamp(toInteger(position), 0, length); var end = position; position -= target.length; return position >= 0 && string.slice(position, end) == target; } /** * Converts the characters "&", "<", ">", '"', and "'" in `string` to their * corresponding HTML entities. * * **Note:** No other characters are escaped. To escape additional * characters use a third-party library like [_he_](https://mths.be/he). * * Though the ">" character is escaped for symmetry, characters like * ">" and "/" don't need escaping in HTML and have no special meaning * unless they're part of a tag or unquoted attribute value. See * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) * (under "semi-related fun fact") for more details. * * When working with HTML you should always * [quote attribute values](http://wonko.com/post/html-escaping) to reduce * XSS vectors. * * @static * @since 0.1.0 * @memberOf _ * @category String * @param {string} [string=''] The string to escape. * @returns {string} Returns the escaped string. * @example * * _.escape('fred, barney, & pebbles'); * // => 'fred, barney, & pebbles' */ function escape(string) { string = toString(string); return string && reHasUnescapedHtml.test(string) ? string.replace(reUnescapedHtml, escapeHtmlChar) : string; } /** * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+", * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`. * * @static * @memberOf _ * @since 3.0.0 * @category String * @param {string} [string=''] The string to escape. * @returns {string} Returns the escaped string. * @example * * _.escapeRegExp('[lodash](https://lodash.com/)'); * // => '\[lodash\]\(https://lodash\.com/\)' */ function escapeRegExp(string) { string = toString(string); return string && reHasRegExpChar.test(string) ? string.replace(reRegExpChar, "\\$&") : string; } /** * Converts `string` to * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). * * @static * @memberOf _ * @since 3.0.0 * @category String * @param {string} [string=''] The string to convert. * @returns {string} Returns the kebab cased string. * @example * * _.kebabCase('Foo Bar'); * // => 'foo-bar' * * _.kebabCase('fooBar'); * // => 'foo-bar' * * _.kebabCase('__FOO_BAR__'); * // => 'foo-bar' */ var kebabCase = createCompounder(function(result, word, index) { return result + (index ? "-" : "") + word.toLowerCase(); }); /** * Converts `string`, as space separated words, to lower case. * * @static * @memberOf _ * @since 4.0.0 * @category String * @param {string} [string=''] The string to convert. * @returns {string} Returns the lower cased string. * @example * * _.lowerCase('--Foo-Bar--'); * // => 'foo bar' * * _.lowerCase('fooBar'); * // => 'foo bar' * * _.lowerCase('__FOO_BAR__'); * // => 'foo bar' */ var lowerCase = createCompounder(function(result, word, index) { return result + (index ? " " : "") + word.toLowerCase(); }); /** * Converts the first character of `string` to lower case. * * @static * @memberOf _ * @since 4.0.0 * @category String * @param {string} [string=''] The string to convert. * @returns {string} Returns the converted string. * @example * * _.lowerFirst('Fred'); * // => 'fred' * * _.lowerFirst('FRED'); * // => 'fRED' */ var lowerFirst = createCaseFirst("toLowerCase"); /** * Pads `string` on the left and right sides if it's shorter than `length`. * Padding characters are truncated if they can't be evenly divided by `length`. * * @static * @memberOf _ * @since 3.0.0 * @category String * @param {string} [string=''] The string to pad. * @param {number} [length=0] The padding length. * @param {string} [chars=' '] The string used as padding. * @returns {string} Returns the padded string. * @example * * _.pad('abc', 8); * // => ' abc ' * * _.pad('abc', 8, '_-'); * // => '_-abc_-_' * * _.pad('abc', 3); * // => 'abc' */ function pad(string, length, chars) { string = toString(string); length = toInteger(length); var strLength = length ? stringSize(string) : 0; if (!length || strLength >= length) { return string; } var mid = (length - strLength) / 2; return createPadding(nativeFloor(mid), chars) + string + createPadding(nativeCeil(mid), chars); } /** * Pads `string` on the right side if it's shorter than `length`. Padding * characters are truncated if they exceed `length`. * * @static * @memberOf _ * @since 4.0.0 * @category String * @param {string} [string=''] The string to pad. * @param {number} [length=0] The padding length. * @param {string} [chars=' '] The string used as padding. * @returns {string} Returns the padded string. * @example * * _.padEnd('abc', 6); * // => 'abc ' * * _.padEnd('abc', 6, '_-'); * // => 'abc_-_' * * _.padEnd('abc', 3); * // => 'abc' */ function padEnd(string, length, chars) { string = toString(string); length = toInteger(length); var strLength = length ? stringSize(string) : 0; return length && strLength < length ? string + createPadding(length - strLength, chars) : string; } /** * Pads `string` on the left side if it's shorter than `length`. Padding * characters are truncated if they exceed `length`. * * @static * @memberOf _ * @since 4.0.0 * @category String * @param {string} [string=''] The string to pad. * @param {number} [length=0] The padding length. * @param {string} [chars=' '] The string used as padding. * @returns {string} Returns the padded string. * @example * * _.padStart('abc', 6); * // => ' abc' * * _.padStart('abc', 6, '_-'); * // => '_-_abc' * * _.padStart('abc', 3); * // => 'abc' */ function padStart(string, length, chars) { string = toString(string); length = toInteger(length); var strLength = length ? stringSize(string) : 0; return length && strLength < length ? createPadding(length - strLength, chars) + string : string; } /** * Converts `string` to an integer of the specified radix. If `radix` is * `undefined` or `0`, a `radix` of `10` is used unless `value` is a * hexadecimal, in which case a `radix` of `16` is used. * * **Note:** This method aligns with the * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`. * * @static * @memberOf _ * @since 1.1.0 * @category String * @param {string} string The string to convert. * @param {number} [radix=10] The radix to interpret `value` by. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. * @returns {number} Returns the converted integer. * @example * * _.parseInt('08'); * // => 8 * * _.map(['6', '08', '10'], _.parseInt); * // => [6, 8, 10] */ function parseInt(string, radix, guard) { if (guard || radix == null) { radix = 0; } else if (radix) { radix = +radix; } return nativeParseInt(toString(string).replace(reTrimStart, ""), radix || 0); } /** * Repeats the given string `n` times. * * @static * @memberOf _ * @since 3.0.0 * @category String * @param {string} [string=''] The string to repeat. * @param {number} [n=1] The number of times to repeat the string. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. * @returns {string} Returns the repeated string. * @example * * _.repeat('*', 3); * // => '***' * * _.repeat('abc', 2); * // => 'abcabc' * * _.repeat('abc', 0); * // => '' */ function repeat(string, n, guard) { if (guard ? isIterateeCall(string, n, guard) : n === undefined) { n = 1; } else { n = toInteger(n); } return baseRepeat(toString(string), n); } /** * Replaces matches for `pattern` in `string` with `replacement`. * * **Note:** This method is based on * [`String#replace`](https://mdn.io/String/replace). * * @static * @memberOf _ * @since 4.0.0 * @category String * @param {string} [string=''] The string to modify. * @param {RegExp|string} pattern The pattern to replace. * @param {Function|string} replacement The match replacement. * @returns {string} Returns the modified string. * @example * * _.replace('Hi Fred', 'Fred', 'Barney'); * // => 'Hi Barney' */ function replace() { var args = arguments, string = toString(args[0]); return args.length < 3 ? string : string.replace(args[1], args[2]); } /** * Converts `string` to * [snake case](https://en.wikipedia.org/wiki/Snake_case). * * @static * @memberOf _ * @since 3.0.0 * @category String * @param {string} [string=''] The string to convert. * @returns {string} Returns the snake cased string. * @example * * _.snakeCase('Foo Bar'); * // => 'foo_bar' * * _.snakeCase('fooBar'); * // => 'foo_bar' * * _.snakeCase('--FOO-BAR--'); * // => 'foo_bar' */ var snakeCase = createCompounder(function(result, word, index) { return result + (index ? "_" : "") + word.toLowerCase(); }); /** * Splits `string` by `separator`. * * **Note:** This method is based on * [`String#split`](https://mdn.io/String/split). * * @static * @memberOf _ * @since 4.0.0 * @category String * @param {string} [string=''] The string to split. * @param {RegExp|string} separator The separator pattern to split by. * @param {number} [limit] The length to truncate results to. * @returns {Array} Returns the string segments. * @example * * _.split('a-b-c', '-', 2); * // => ['a', 'b'] */ function split(string, separator, limit) { if (limit && typeof limit != "number" && isIterateeCall(string, separator, limit)) { separator = limit = undefined; } limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0; if (!limit) { return []; } string = toString(string); if (string && (typeof separator == "string" || separator != null && !isRegExp(separator))) { separator = baseToString(separator); if (!separator && hasUnicode(string)) { return castSlice(stringToArray(string), 0, limit); } } return string.split(separator, limit); } /** * Converts `string` to * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). * * @static * @memberOf _ * @since 3.1.0 * @category String * @param {string} [string=''] The string to convert. * @returns {string} Returns the start cased string. * @example * * _.startCase('--foo-bar--'); * // => 'Foo Bar' * * _.startCase('fooBar'); * // => 'Foo Bar' * * _.startCase('__FOO_BAR__'); * // => 'FOO BAR' */ var startCase = createCompounder(function(result, word, index) { return result + (index ? " " : "") + upperFirst(word); }); /** * Checks if `string` starts with the given target string. * * @static * @memberOf _ * @since 3.0.0 * @category String * @param {string} [string=''] The string to inspect. * @param {string} [target] The string to search for. * @param {number} [position=0] The position to search from. * @returns {boolean} Returns `true` if `string` starts with `target`, * else `false`. * @example * * _.startsWith('abc', 'a'); * // => true * * _.startsWith('abc', 'b'); * // => false * * _.startsWith('abc', 'b', 1); * // => true */ function startsWith(string, target, position) { string = toString(string); position = position == null ? 0 : baseClamp(toInteger(position), 0, string.length); target = baseToString(target); return string.slice(position, position + target.length) == target; } /** * Creates a compiled template function that can interpolate data properties * in "interpolate" delimiters, HTML-escape interpolated data properties in * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data * properties may be accessed as free variables in the template. If a setting * object is given, it takes precedence over `_.templateSettings` values. * * **Note:** In the development build `_.template` utilizes * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) * for easier debugging. * * For more information on precompiling templates see * [lodash's custom builds documentation](https://lodash.com/custom-builds). * * For more information on Chrome extension sandboxes see * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval). * * @static * @since 0.1.0 * @memberOf _ * @category String * @param {string} [string=''] The template string. * @param {Object} [options={}] The options object. * @param {RegExp} [options.escape=_.templateSettings.escape] * The HTML "escape" delimiter. * @param {RegExp} [options.evaluate=_.templateSettings.evaluate] * The "evaluate" delimiter. * @param {Object} [options.imports=_.templateSettings.imports] * An object to import into the template as free variables. * @param {RegExp} [options.interpolate=_.templateSettings.interpolate] * The "interpolate" delimiter. * @param {string} [options.sourceURL='lodash.templateSources[n]'] * The sourceURL of the compiled template. * @param {string} [options.variable='obj'] * The data object variable name. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. * @returns {Function} Returns the compiled template function. * @example * * // Use the "interpolate" delimiter to create a compiled template. * var compiled = _.template('hello <%= user %>!'); * compiled({ 'user': 'fred' }); * // => 'hello fred!' * * // Use the HTML "escape" delimiter to escape data property values. * var compiled = _.template('<%- value %>'); * compiled({ 'value': '