Initial commit

master
Semisol 2021-10-07 12:47:33 +03:00
commit 751a3a97c3
Signed by: Semisol
GPG Key ID: D5D485E3231A5764
7 changed files with 976 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
.DS_Store
data.json
config.json
node_modules

11
LICENSE Normal file
View File

@ -0,0 +1,11 @@
Copyright 2021 Semisol
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. 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.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

3
README.md Normal file
View File

@ -0,0 +1,3 @@
# CertServ
Certificate expiry utilities

26
config.example.json Normal file
View File

@ -0,0 +1,26 @@
{
"user": {
"nick": "CertServ",
"ident": "certserv",
"gecos": "CertServ",
"oper": {
"name": "CertServ",
"password": "password"
}
},
"channels": [
"#services"
],
"server": {
"host": "localhost",
"port": 6697,
"secure": true
},
"timeout": 10000,
"rate": 10,
"log": true,
"prefix": ".",
"overrideHost": {
"example-irc-server-name.invalid": "example.com"
}
}

367
index.js Normal file
View File

@ -0,0 +1,367 @@
const fs = require("fs")
const tls = require("tls")
const IRC = require("irc-framework")
const statsRegexp = /^\*\*\* Listener on .+:([0-9]+) \(IPv(?:4|6)\): has [0-9]+ client\(s\), options: (.*)$/
let config = JSON.parse(fs.readFileSync(__dirname + "/config.json"))
let state = {
expiryState: {},
networkState: {},
expiryLastUpdated: Date.now(),
networkLastUpdated: Date.now()
}
if (fs.existsSync(__dirname + "/data.json")) {
state = JSON.parse(fs.readFileSync(__dirname + "/data.json"))
} else {
saveState()
}
let temp = {
expiryState: null,
queue: [],
networkState: null,
pendingStats: new Set(),
refreshCallbacks: [],
rev: 0,
inProgress: 0,
isRefreshAll: false
}
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0
function log(str, ...args) {
if (config.log) {
console.log(str, ...args)
}
}
const bot = new IRC.Client({
nick: config.user.nick,
username: config.user.ident,
gecos: config.user.gecos,
version: "CertServ",
host: config.server.host,
tls: config.server.secure,
port: config.server.port
})
bot.on("registered", () => {
bot.raw("oper", config.user.oper.name, config.user.oper.password)
config.channels.forEach(channel => {
bot.join(channel)
})
refreshState()
})
function saveState() {
fs.writeFileSync(__dirname + "/data.json", JSON.stringify(state))
log("Persisted data to disk")
}
function refreshState() {
bot.raw("links")
log("Refreshing network state")
}
bot.on("server links", (links) => {
log("Got link data")
let servers = new Set()
let rev = ++temp.rev
temp.networkState = {}
temp.pendingStats = new Set()
links.links.forEach(link => {
servers.add(link.address)
servers.add(link.access_via)
})
servers = [...servers]
log("Got %s servers", servers.length)
servers.forEach(el => {
temp.networkState[el] = {
c2s: [],
s2s: []
}
temp.pendingStats.add(el)
bot.raw("stats", "P", el)
})
setTimeout(() => {
if (rev !== temp.rev) return
let deleted = 0
for (let i of temp.pendingStats) {
delete temp.networkState[i]
deleted++
}
temp.pendingStats.clear()
state.networkState = temp.networkState
state.networkLastUpdated = Date.now()
temp.networkState = null
saveState()
log("State refresh complete with %s not responding", deleted)
temp.refreshCallbacks.forEach(cb => cb())
temp.refreshCallbacks = []
}, 3000)
})
bot.on("notice", notice => {
let match
if (notice.from_server && notice.target === config.user.nick && temp.pendingStats.has(notice.hostname) && (match = notice.message.match(statsRegexp))) {
let server = notice.hostname
let opts = match[2].replace(/ +$/, "").split(" ")
let port = +match[1]
if (!opts.includes("tls")) return
let arr = temp.networkState[server][opts.includes("serversonly") ? "s2s" : "c2s"]
if (!arr.includes(port)) {
arr.push(port)
}
}
})
bot.on("raw", line => {
if (!line.from_server) return
let match
if (match = line.line.match(/:([^ ]+) 219 [^ ]+ P :End of \/STATS report\r?\n/)) {
temp.pendingStats.delete(match[1])
}
})
bot.on("privmsg", msg => {
if (msg.batch && msg.batch.type === "chathistory") return
if (config.channels.includes(msg.target) && msg.message.length > config.prefix.length && msg.message.startsWith(config.prefix)) {
let args = msg.message.slice(config.prefix.length).split(" ")
let cmd = args.shift()
switch (cmd) {
case "help": {
msg.reply("CertServ is a utility to view information about certificate expiry.")
msg.reply("Source: https://git.semisol.dev/Semisol/CertServ")
msg.reply(" help: Get this message")
msg.reply(" refreshnet: Refresh network state")
msg.reply(" refresh <server>: Refresh a server")
msg.reply(" check <server>: Check a server")
msg.reply(" refreshall: Refresh all servers")
msg.reply(" info: Show information about the bot, and statistics")
msg.reply(" expired: Show expired certificates")
msg.reply(" expiringsoon: Show certificates expiring in 7 days")
break
}
case "refresh": {
if (args.length === 0) {
msg.reply(`ERROR: Please provide a server argument`)
return
}
if (!state.networkState[args[0]]) {
msg.reply(`ERROR: No such server`)
return
}
let ports = state.networkState[args[0]]
delete temp.expiryState[args[0]]
for (let i of ports.c2s) {
temp.queue.push({
server: args[0],
addr: config.overrideHost[args[0]] || args[0],
port: i,
type: "c2s"
})
}
for (let i of ports.s2s) {
temp.queue.push({
server: args[0],
addr: config.overrideHost[args[0]] || args[0],
port: i,
type: "s2s"
})
}
msg.reply(`Added ${ports.s2s.length + ports.c2s.length} jobs`)
break
}
case "refreshnet": {
temp.refreshCallbacks.push(function () {
msg.reply("Done!")
})
msg.reply("Please wait...")
refreshState()
break
}
case "refreshall": {
let jobs = 0
let servers = 0
temp.expiryState = {}
temp.isRefreshAll = true
Object.keys(state.networkState).forEach(srv => {
let ports = state.networkState[srv]
for (let i of ports.c2s) {
temp.queue.push({
server: srv,
addr: config.overrideHost[srv] || srv,
port: i,
type: "c2s"
})
jobs++
}
for (let i of ports.s2s) {
temp.queue.push({
server: srv,
addr: config.overrideHost[srv] || srv,
port: i,
type: "s2s"
})
jobs++
}
servers++
})
msg.reply(`Added ${jobs} jobs (${servers} servers)`)
log("Refreshing all...")
break
}
case "check": {
if (args.length === 0) {
msg.reply(`ERROR: Please provide a server argument`)
return
}
if (!state.expiryState[args[0]]) {
if (!state.networkState[args[0]]) {
msg.reply(`ERROR: No such server`)
} else {
msg.reply(`ERROR: Please \`refresh\` the server, as it has not been processed yet.`)
}
return
}
let seenInvalid = false
msg.reply(`Server information for ${args[0]}:`)
state.expiryState[args[0]].checks.forEach(check => {
let addr = `${args[0] === check.addr ? `Port ` : `${check.addr}:`}${check.port} (${check.type.toUpperCase()})`
switch (check.status) {
case "success": {
if (check.expiryTS > Date.now()) {
if (check.valid) seenInvalid = true
msg.reply(` ${addr}: Expires in ${((check.expiryTS - Date.now()) / 86400000).toFixed(2)}d (${check.expiry})${check.valid ? "" : " (!)"}`)
} else {
msg.reply(` ${addr}: Expired ${((Date.now() - check.expiryTS) / 86400000).toFixed(2)}d ago (${check.expiry})`)
}
break
}
case "timeout": {
msg.reply(` ${addr}: Timed out while connecting`)
break
}
case "error": {
msg.reply(` ${addr}: Encountered error while connecting`)
break
}
}
})
if (seenInvalid) msg.reply(`(!): Self signed, wrong domain or something else`)
break
}
case "info": {
msg.reply(`CertServ version 1.0.0`)
if (temp.pendingStats.length > 0) {
msg.reply(`Network refresh: Waiting for ${temp.pendingStats.length} server${temp.pendingStats.length === 1 ? "" : "s"}`)
} else if (temp.networkState) {
msg.reply(`Network refresh: Waiting...`)
}
if (temp.queue.length > 0 || temp.inProgress > 0) {
msg.reply(`Expiry refresh: ${temp.queue.length} in queue`)
msg.reply(`Expiry refresh: Waiting for ${temp.inProgress} connection${temp.inProgress === 1 ? "" : "s"}`)
msg.reply(`Expiry refresh: Processing ${config.rate} job${config.rate === 1 ? "" : "s"} per second`)
}
msg.reply(`Network state: ${Object.keys(state.networkState).length} servers`)
msg.reply(`Network state: Last updated ${((Date.now() - state.networkLastUpdated) / 1000 / 60).toFixed(2)}m ago`)
msg.reply(`Expiry state: ${Object.keys(state.expiryState).length} servers`)
msg.reply(`Expiry state: Last updated ${((Date.now() - state.expiryLastUpdated) / 1000 / 60 / 60).toFixed(2)}h ago`)
if (temp.expiryState && temp.queue.length === 0 && temp.inProgress === 0)
msg.reply(`WARNING: No jobs are running but a transient state exists`)
break
}
case "expiringsoon": {
let checks = []
msg.reply(`Certificates expiring soon:`)
Object.keys(state.expiryState).forEach(srv => {
state.expiryState[srv].checks.forEach(check => {
if (check.status !== "success") return
if (check.expiryTS < (Date.now() + (7 * 24 * 60 * 60 * 1000)) && check.expiryTS > Date.now()) {
checks.push({...check, server: srv})
}
})
})
checks.sort((b, a) => a.expiryTS - b.expiryTS)
checks.forEach(check => {
let addr = `${check.addr}:${check.port}${check.server !== check.addr ? ` (${check.server})` : `` } (${check.type.toUpperCase()})`
msg.reply(` ${addr}, in ${((check.expiryTS - Date.now()) / 86400000).toFixed(2)}d`)
})
if (checks.length === 0) msg.reply("None! \\o/")
break
}
case "expired": {
let checks = []
msg.reply(`Certificates that expired:`)
Object.keys(state.expiryState).forEach(srv => {
state.expiryState[srv].checks.forEach(check => {
if (check.status !== "success") return
if (check.expiryTS < Date.now()) {
checks.push({...check, server: srv})
}
})
})
checks.sort((b, a) => a.expiryTS - b.expiryTS)
checks.forEach(check => {
let addr = `${check.addr}:${check.port}${check.server !== check.addr ? ` (${check.server})` : `` } (${check.type.toUpperCase()})`
msg.reply(` ${addr}, ${((Date.now() - check.expiryTS) / 86400000).toFixed(2)}d ago`)
})
if (checks.length === 0) msg.reply("None! \\o/")
break
}
}
}
})
setInterval(() => {
if (temp.queue.length > 0) {
if (!temp.expiryState) {
temp.expiryState = { ...state.expiryState }
log("Copying original state to transient")
}
let job = temp.queue.shift()
log("Starting job %s, %s:%s, %s", job.server, job.addr, job.port, job.type)
temp.inProgress++
let hasFinished = false
let res = {
addr: job.addr,
type: job.type,
port: job.port,
status: "unknown"
}
function jobEnded() {
temp.inProgress--
hasFinished = true
log("Ended job %s, %s:%s, %s with status %s", job.server, job.addr, job.port, job.type, res.status)
if (!temp.expiryState[job.server]) {
temp.expiryState[job.server] = {
checks: []
}
}
temp.expiryState[job.server].checks.push(res)
if (temp.inProgress === 0 && temp.queue.length === 0) {
log("Replaced original state with transient state")
state.expiryState = temp.expiryState
temp.expiryState = null
saveState()
}
}
let conn = tls.connect({
host: job.server,
port: job.port,
timeout: config.timeout
}, () => {
if (hasFinished) return
let cert = conn.getPeerX509Certificate()
res.status = "success"
res.expiry = cert.validTo
res.expiryTS = +new Date(cert.validTo)
res.valid = conn.authorized
jobEnded()
conn.end()
})
conn.on("error", () => {
if (hasFinished) return
res.status = "error"
jobEnded()
conn.end()
})
conn.on("timeout", () => {
if (hasFinished) return
res.status = "timeout"
jobEnded()
conn.end()
})
}
}, 1000 / config.rate)
bot.connect()

16
package.json Normal file
View File

@ -0,0 +1,16 @@
{
"name": "certserv",
"version": "1.0.0",
"description": "Certificate expiry utilities",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Semisol",
"license": "BSD-3-Clause",
"keywords": [],
"dependencies": {
"irc-framework": "^4.11.0"
},
"devDependencies": {}
}

549
pnpm-lock.yaml Normal file
View File

@ -0,0 +1,549 @@
lockfileVersion: 5.3
specifiers:
irc-framework: ^4.11.0
dependencies:
irc-framework: registry.npmjs.org/irc-framework/4.11.0
packages:
registry.npmjs.org/available-typed-arrays/1.0.5:
resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz}
name: available-typed-arrays
version: 1.0.5
engines: {node: '>= 0.4'}
dev: false
registry.npmjs.org/base64-js/1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz}
name: base64-js
version: 1.5.1
dev: false
registry.npmjs.org/buffer/6.0.3:
resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz}
name: buffer
version: 6.0.3
dependencies:
base64-js: registry.npmjs.org/base64-js/1.5.1
ieee754: registry.npmjs.org/ieee754/1.2.1
dev: false
registry.npmjs.org/call-bind/1.0.2:
resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz}
name: call-bind
version: 1.0.2
dependencies:
function-bind: registry.npmjs.org/function-bind/1.1.1
get-intrinsic: registry.npmjs.org/get-intrinsic/1.1.1
dev: false
registry.npmjs.org/core-js/3.18.2:
resolution: {integrity: sha512-zNhPOUoSgoizoSQFdX1MeZO16ORRb9FFQLts8gSYbZU5FcgXhp24iMWMxnOQo5uIaIG7/6FA/IqJPwev1o9ZXQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/core-js/-/core-js-3.18.2.tgz}
name: core-js
version: 3.18.2
requiresBuild: true
dev: false
registry.npmjs.org/define-properties/1.1.3:
resolution: {integrity: sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz}
name: define-properties
version: 1.1.3
engines: {node: '>= 0.4'}
dependencies:
object-keys: registry.npmjs.org/object-keys/1.1.1
dev: false
registry.npmjs.org/es-abstract/1.19.1:
resolution: {integrity: sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz}
name: es-abstract
version: 1.19.1
engines: {node: '>= 0.4'}
dependencies:
call-bind: registry.npmjs.org/call-bind/1.0.2
es-to-primitive: registry.npmjs.org/es-to-primitive/1.2.1
function-bind: registry.npmjs.org/function-bind/1.1.1
get-intrinsic: registry.npmjs.org/get-intrinsic/1.1.1
get-symbol-description: registry.npmjs.org/get-symbol-description/1.0.0
has: registry.npmjs.org/has/1.0.3
has-symbols: registry.npmjs.org/has-symbols/1.0.2
internal-slot: registry.npmjs.org/internal-slot/1.0.3
is-callable: registry.npmjs.org/is-callable/1.2.4
is-negative-zero: registry.npmjs.org/is-negative-zero/2.0.1
is-regex: registry.npmjs.org/is-regex/1.1.4
is-shared-array-buffer: registry.npmjs.org/is-shared-array-buffer/1.0.1
is-string: registry.npmjs.org/is-string/1.0.7
is-weakref: registry.npmjs.org/is-weakref/1.0.1
object-inspect: registry.npmjs.org/object-inspect/1.11.0
object-keys: registry.npmjs.org/object-keys/1.1.1
object.assign: registry.npmjs.org/object.assign/4.1.2
string.prototype.trimend: registry.npmjs.org/string.prototype.trimend/1.0.4
string.prototype.trimstart: registry.npmjs.org/string.prototype.trimstart/1.0.4
unbox-primitive: registry.npmjs.org/unbox-primitive/1.0.1
dev: false
registry.npmjs.org/es-to-primitive/1.2.1:
resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz}
name: es-to-primitive
version: 1.2.1
engines: {node: '>= 0.4'}
dependencies:
is-callable: registry.npmjs.org/is-callable/1.2.4
is-date-object: registry.npmjs.org/is-date-object/1.0.5
is-symbol: registry.npmjs.org/is-symbol/1.0.4
dev: false
registry.npmjs.org/eventemitter3/4.0.7:
resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz}
name: eventemitter3
version: 4.0.7
dev: false
registry.npmjs.org/fast-text-encoding/1.0.3:
resolution: {integrity: sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz}
name: fast-text-encoding
version: 1.0.3
dev: false
registry.npmjs.org/foreach/2.0.5:
resolution: {integrity: sha1-C+4AUBiusmDQo6865ljdATbsG5k=, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz}
name: foreach
version: 2.0.5
dev: false
registry.npmjs.org/function-bind/1.1.1:
resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz}
name: function-bind
version: 1.1.1
dev: false
registry.npmjs.org/get-intrinsic/1.1.1:
resolution: {integrity: sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz}
name: get-intrinsic
version: 1.1.1
dependencies:
function-bind: registry.npmjs.org/function-bind/1.1.1
has: registry.npmjs.org/has/1.0.3
has-symbols: registry.npmjs.org/has-symbols/1.0.2
dev: false
registry.npmjs.org/get-symbol-description/1.0.0:
resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz}
name: get-symbol-description
version: 1.0.0
engines: {node: '>= 0.4'}
dependencies:
call-bind: registry.npmjs.org/call-bind/1.0.2
get-intrinsic: registry.npmjs.org/get-intrinsic/1.1.1
dev: false
registry.npmjs.org/grapheme-splitter/1.0.4:
resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz}
name: grapheme-splitter
version: 1.0.4
dev: false
registry.npmjs.org/has-bigints/1.0.1:
resolution: {integrity: sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz}
name: has-bigints
version: 1.0.1
dev: false
registry.npmjs.org/has-symbols/1.0.2:
resolution: {integrity: sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz}
name: has-symbols
version: 1.0.2
engines: {node: '>= 0.4'}
dev: false
registry.npmjs.org/has-tostringtag/1.0.0:
resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz}
name: has-tostringtag
version: 1.0.0
engines: {node: '>= 0.4'}
dependencies:
has-symbols: registry.npmjs.org/has-symbols/1.0.2
dev: false
registry.npmjs.org/has/1.0.3:
resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/has/-/has-1.0.3.tgz}
name: has
version: 1.0.3
engines: {node: '>= 0.4.0'}
dependencies:
function-bind: registry.npmjs.org/function-bind/1.1.1
dev: false
registry.npmjs.org/iconv-lite/0.6.3:
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz}
name: iconv-lite
version: 0.6.3
engines: {node: '>=0.10.0'}
dependencies:
safer-buffer: registry.npmjs.org/safer-buffer/2.1.2
dev: false
registry.npmjs.org/ieee754/1.2.1:
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz}
name: ieee754
version: 1.2.1
dev: false
registry.npmjs.org/inherits/2.0.4:
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz}
name: inherits
version: 2.0.4
dev: false
registry.npmjs.org/internal-slot/1.0.3:
resolution: {integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz}
name: internal-slot
version: 1.0.3
engines: {node: '>= 0.4'}
dependencies:
get-intrinsic: registry.npmjs.org/get-intrinsic/1.1.1
has: registry.npmjs.org/has/1.0.3
side-channel: registry.npmjs.org/side-channel/1.0.4
dev: false
registry.npmjs.org/ip/1.1.5:
resolution: {integrity: sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/ip/-/ip-1.1.5.tgz}
name: ip
version: 1.1.5
dev: false
registry.npmjs.org/irc-framework/4.11.0:
resolution: {integrity: sha512-A7AoNxAGzViARQv4sVchmTzRiWiQZMCuQVnCOhrggEgAMsc8Vr345U5/JMN5I45gqL4LVfjtruWokp5YiU23Iw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/irc-framework/-/irc-framework-4.11.0.tgz}
name: irc-framework
version: 4.11.0
dependencies:
buffer: registry.npmjs.org/buffer/6.0.3
core-js: registry.npmjs.org/core-js/3.18.2
eventemitter3: registry.npmjs.org/eventemitter3/4.0.7
grapheme-splitter: registry.npmjs.org/grapheme-splitter/1.0.4
iconv-lite: registry.npmjs.org/iconv-lite/0.6.3
isomorphic-textencoder: registry.npmjs.org/isomorphic-textencoder/1.0.1
lodash: registry.npmjs.org/lodash/4.17.21
middleware-handler: registry.npmjs.org/middleware-handler/0.2.0
regenerator-runtime: registry.npmjs.org/regenerator-runtime/0.13.9
socks: registry.npmjs.org/socks/2.6.1
stream-browserify: registry.npmjs.org/stream-browserify/3.0.0
util: registry.npmjs.org/util/0.12.4
dev: false
registry.npmjs.org/is-arguments/1.1.1:
resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz}
name: is-arguments
version: 1.1.1
engines: {node: '>= 0.4'}
dependencies:
call-bind: registry.npmjs.org/call-bind/1.0.2
has-tostringtag: registry.npmjs.org/has-tostringtag/1.0.0
dev: false
registry.npmjs.org/is-bigint/1.0.4:
resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz}
name: is-bigint
version: 1.0.4
dependencies:
has-bigints: registry.npmjs.org/has-bigints/1.0.1
dev: false
registry.npmjs.org/is-boolean-object/1.1.2:
resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz}
name: is-boolean-object
version: 1.1.2
engines: {node: '>= 0.4'}
dependencies:
call-bind: registry.npmjs.org/call-bind/1.0.2
has-tostringtag: registry.npmjs.org/has-tostringtag/1.0.0
dev: false
registry.npmjs.org/is-callable/1.2.4:
resolution: {integrity: sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz}
name: is-callable
version: 1.2.4
engines: {node: '>= 0.4'}
dev: false
registry.npmjs.org/is-date-object/1.0.5:
resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz}
name: is-date-object
version: 1.0.5
engines: {node: '>= 0.4'}
dependencies:
has-tostringtag: registry.npmjs.org/has-tostringtag/1.0.0
dev: false
registry.npmjs.org/is-generator-function/1.0.10:
resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz}
name: is-generator-function
version: 1.0.10
engines: {node: '>= 0.4'}
dependencies:
has-tostringtag: registry.npmjs.org/has-tostringtag/1.0.0
dev: false
registry.npmjs.org/is-negative-zero/2.0.1:
resolution: {integrity: sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz}
name: is-negative-zero
version: 2.0.1
engines: {node: '>= 0.4'}
dev: false
registry.npmjs.org/is-number-object/1.0.6:
resolution: {integrity: sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz}
name: is-number-object
version: 1.0.6
engines: {node: '>= 0.4'}
dependencies:
has-tostringtag: registry.npmjs.org/has-tostringtag/1.0.0
dev: false
registry.npmjs.org/is-regex/1.1.4:
resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz}
name: is-regex
version: 1.1.4
engines: {node: '>= 0.4'}
dependencies:
call-bind: registry.npmjs.org/call-bind/1.0.2
has-tostringtag: registry.npmjs.org/has-tostringtag/1.0.0
dev: false
registry.npmjs.org/is-shared-array-buffer/1.0.1:
resolution: {integrity: sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz}
name: is-shared-array-buffer
version: 1.0.1
dev: false
registry.npmjs.org/is-string/1.0.7:
resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz}
name: is-string
version: 1.0.7
engines: {node: '>= 0.4'}
dependencies:
has-tostringtag: registry.npmjs.org/has-tostringtag/1.0.0
dev: false
registry.npmjs.org/is-symbol/1.0.4:
resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz}
name: is-symbol
version: 1.0.4
engines: {node: '>= 0.4'}
dependencies:
has-symbols: registry.npmjs.org/has-symbols/1.0.2
dev: false
registry.npmjs.org/is-typed-array/1.1.8:
resolution: {integrity: sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.8.tgz}
name: is-typed-array
version: 1.1.8
engines: {node: '>= 0.4'}
dependencies:
available-typed-arrays: registry.npmjs.org/available-typed-arrays/1.0.5
call-bind: registry.npmjs.org/call-bind/1.0.2
es-abstract: registry.npmjs.org/es-abstract/1.19.1
foreach: registry.npmjs.org/foreach/2.0.5
has-tostringtag: registry.npmjs.org/has-tostringtag/1.0.0
dev: false
registry.npmjs.org/is-weakref/1.0.1:
resolution: {integrity: sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz}
name: is-weakref
version: 1.0.1
dependencies:
call-bind: registry.npmjs.org/call-bind/1.0.2
dev: false
registry.npmjs.org/isomorphic-textencoder/1.0.1:
resolution: {integrity: sha512-676hESgHullDdHDsj469hr+7t3i/neBKU9J7q1T4RHaWwLAsaQnywC0D1dIUId0YZ+JtVrShzuBk1soo0+GVcQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/isomorphic-textencoder/-/isomorphic-textencoder-1.0.1.tgz}
name: isomorphic-textencoder
version: 1.0.1
dependencies:
fast-text-encoding: registry.npmjs.org/fast-text-encoding/1.0.3
dev: false
registry.npmjs.org/lodash/4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz}
name: lodash
version: 4.17.21
dev: false
registry.npmjs.org/middleware-handler/0.2.0:
resolution: {integrity: sha1-vwKvfmtXfAIwYJsq5Y3w5Ebz/QI=, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/middleware-handler/-/middleware-handler-0.2.0.tgz}
name: middleware-handler
version: 0.2.0
dev: false
registry.npmjs.org/object-inspect/1.11.0:
resolution: {integrity: sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz}
name: object-inspect
version: 1.11.0
dev: false
registry.npmjs.org/object-keys/1.1.1:
resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz}
name: object-keys
version: 1.1.1
engines: {node: '>= 0.4'}
dev: false
registry.npmjs.org/object.assign/4.1.2:
resolution: {integrity: sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz}
name: object.assign
version: 4.1.2
engines: {node: '>= 0.4'}
dependencies:
call-bind: registry.npmjs.org/call-bind/1.0.2
define-properties: registry.npmjs.org/define-properties/1.1.3
has-symbols: registry.npmjs.org/has-symbols/1.0.2
object-keys: registry.npmjs.org/object-keys/1.1.1
dev: false
registry.npmjs.org/readable-stream/3.6.0:
resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz}
name: readable-stream
version: 3.6.0
engines: {node: '>= 6'}
dependencies:
inherits: registry.npmjs.org/inherits/2.0.4
string_decoder: registry.npmjs.org/string_decoder/1.3.0
util-deprecate: registry.npmjs.org/util-deprecate/1.0.2
dev: false
registry.npmjs.org/regenerator-runtime/0.13.9:
resolution: {integrity: sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz}
name: regenerator-runtime
version: 0.13.9
dev: false
registry.npmjs.org/safe-buffer/5.2.1:
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz}
name: safe-buffer
version: 5.2.1
dev: false
registry.npmjs.org/safer-buffer/2.1.2:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz}
name: safer-buffer
version: 2.1.2
dev: false
registry.npmjs.org/side-channel/1.0.4:
resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz}
name: side-channel
version: 1.0.4
dependencies:
call-bind: registry.npmjs.org/call-bind/1.0.2
get-intrinsic: registry.npmjs.org/get-intrinsic/1.1.1
object-inspect: registry.npmjs.org/object-inspect/1.11.0
dev: false
registry.npmjs.org/smart-buffer/4.2.0:
resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz}
name: smart-buffer
version: 4.2.0
engines: {node: '>= 6.0.0', npm: '>= 3.0.0'}
dev: false
registry.npmjs.org/socks/2.6.1:
resolution: {integrity: sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/socks/-/socks-2.6.1.tgz}
name: socks
version: 2.6.1
engines: {node: '>= 10.13.0', npm: '>= 3.0.0'}
dependencies:
ip: registry.npmjs.org/ip/1.1.5
smart-buffer: registry.npmjs.org/smart-buffer/4.2.0
dev: false
registry.npmjs.org/stream-browserify/3.0.0:
resolution: {integrity: sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz}
name: stream-browserify
version: 3.0.0
dependencies:
inherits: registry.npmjs.org/inherits/2.0.4
readable-stream: registry.npmjs.org/readable-stream/3.6.0
dev: false
registry.npmjs.org/string.prototype.trimend/1.0.4:
resolution: {integrity: sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz}
name: string.prototype.trimend
version: 1.0.4
dependencies:
call-bind: registry.npmjs.org/call-bind/1.0.2
define-properties: registry.npmjs.org/define-properties/1.1.3
dev: false
registry.npmjs.org/string.prototype.trimstart/1.0.4:
resolution: {integrity: sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz}
name: string.prototype.trimstart
version: 1.0.4
dependencies:
call-bind: registry.npmjs.org/call-bind/1.0.2
define-properties: registry.npmjs.org/define-properties/1.1.3
dev: false
registry.npmjs.org/string_decoder/1.3.0:
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz}
name: string_decoder
version: 1.3.0
dependencies:
safe-buffer: registry.npmjs.org/safe-buffer/5.2.1
dev: false
registry.npmjs.org/unbox-primitive/1.0.1:
resolution: {integrity: sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz}
name: unbox-primitive
version: 1.0.1
dependencies:
function-bind: registry.npmjs.org/function-bind/1.1.1
has-bigints: registry.npmjs.org/has-bigints/1.0.1
has-symbols: registry.npmjs.org/has-symbols/1.0.2
which-boxed-primitive: registry.npmjs.org/which-boxed-primitive/1.0.2
dev: false
registry.npmjs.org/util-deprecate/1.0.2:
resolution: {integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz}
name: util-deprecate
version: 1.0.2
dev: false
registry.npmjs.org/util/0.12.4:
resolution: {integrity: sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/util/-/util-0.12.4.tgz}
name: util
version: 0.12.4
dependencies:
inherits: registry.npmjs.org/inherits/2.0.4
is-arguments: registry.npmjs.org/is-arguments/1.1.1
is-generator-function: registry.npmjs.org/is-generator-function/1.0.10
is-typed-array: registry.npmjs.org/is-typed-array/1.1.8
safe-buffer: registry.npmjs.org/safe-buffer/5.2.1
which-typed-array: registry.npmjs.org/which-typed-array/1.1.7
dev: false
registry.npmjs.org/which-boxed-primitive/1.0.2:
resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz}
name: which-boxed-primitive
version: 1.0.2
dependencies:
is-bigint: registry.npmjs.org/is-bigint/1.0.4
is-boolean-object: registry.npmjs.org/is-boolean-object/1.1.2
is-number-object: registry.npmjs.org/is-number-object/1.0.6
is-string: registry.npmjs.org/is-string/1.0.7
is-symbol: registry.npmjs.org/is-symbol/1.0.4
dev: false
registry.npmjs.org/which-typed-array/1.1.7:
resolution: {integrity: sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.7.tgz}
name: which-typed-array
version: 1.1.7
engines: {node: '>= 0.4'}
dependencies:
available-typed-arrays: registry.npmjs.org/available-typed-arrays/1.0.5
call-bind: registry.npmjs.org/call-bind/1.0.2
es-abstract: registry.npmjs.org/es-abstract/1.19.1
foreach: registry.npmjs.org/foreach/2.0.5
has-tostringtag: registry.npmjs.org/has-tostringtag/1.0.0
is-typed-array: registry.npmjs.org/is-typed-array/1.1.8
dev: false