diff --git a/.npmignore b/.npmignore index 867e6b0a..0afad436 100644 --- a/.npmignore +++ b/.npmignore @@ -20,7 +20,6 @@ bundle.js .all-contributorsrc .editorconfig .gitignore -bundle-model.mjs jest.config.js tsconfig.cjs.json tsconfig.esm.json diff --git a/README.md b/README.md index c23019ac..f80612d5 100644 --- a/README.md +++ b/README.md @@ -113,25 +113,24 @@ You can also use same parameter and load the model from your website/server, as Model MobileNetV2 - [224x224](https://github.com/infinitered/nsfwjs/blob/master/models/mobilenet_v2/) ```js -const model = nsfwjs.load("/path/to/model/directory/"); +const model = nsfwjs.load("/path/to/mobilenet_v2/"); ``` If you're using a model that needs an image of dimension other than 224x224, you can pass the size in the options parameter. -Model MobileNetV2Mid - [299x299](https://github.com/infinitered/nsfwjs/tree/master/models/mobilenet_v2_mid) +Model MobileNetV2Mid - [Graph](https://github.com/infinitered/nsfwjs/tree/master/models/mobilenet_v2_mid) ```js -const model = nsfwjs.load("/path/to/model/", { size: 299 }); /* You may need to load this model with graph type */ -const model = nsfwjs.load("/path/to/model/", { type: 'graph' }); +const model = nsfwjs.load("/path/to/mobilenet_v2_mid/", { type: 'graph' }); ``` If you're using a graph model, you cannot use the infer method, and you'll need to tell model load that you're dealing with a graph model in options. -Model InceptionV3 - [Graph](https://github.com/infinitered/nsfwjs/tree/master/models/inception_v3) +Model InceptionV3 - [299x299](https://github.com/infinitered/nsfwjs/tree/master/models/inception_v3) ```js -const model = nsfwjs.load("/path/to/different/model/", { type: "graph" }); +const model = nsfwjs.load("/path/to/inception_v3/", { size: 299 }); ``` ### Caching @@ -226,13 +225,13 @@ Here is how to install the default model on a website: ### Tensorflow.js in the browser -The demo that powers https://nsfwjs.com/ is available in the `examples/nsfw_demo` folder. +The demo that powers https://nsfwjs.com/ is available in the [`examples/nsfw_demo`](https://github.com/infinitered/nsfwjs/tree/master/examples/nsfw_demo) folder. To run the demo, run `yarn prep` which will copy the latest code into the demo. After that's done, you can `cd` into the demo folder and run with `yarn start`. ### Browserify -A browserified version using nothing but promises and script tags is available in the `minimal_demo` folder. +A browserified version using nothing but promises and script tags is available in the [`minimal_demo`](https://github.com/infinitered/nsfwjs/tree/master/examples/minimal_demo) folder. ```js diff --git a/examples/minimal_demo/index.html b/examples/minimal_demo/index.html index 31bffffd..1e988f30 100644 --- a/examples/minimal_demo/index.html +++ b/examples/minimal_demo/index.html @@ -6,15 +6,15 @@ diff --git a/package.json b/package.json index d189be00..3d7e58f4 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,9 @@ { "name": "nsfwjs", "version": "4.1.0", - "unpkg": "dist/nsfwjs.min.js", + "unpkg": "dist/browser/nsfwjs.min.js", "description": "Detect NSFW content client-side", + "type": "commonjs", "module": "dist/esm/index.js", "main": "dist/cjs/index.js", "exports": { @@ -11,9 +12,9 @@ }, "scripts": { "lint": "tslint -p . -t verbose", - "build:esm": "tsc -p ./tsconfig.esm.json", + "build:esm": "tsc -p ./tsconfig.esm.json && node ./scripts/add-extensions.mjs", "build:cjs": "tsc -p ./tsconfig.cjs.json", - "build": "yarn build:esm && yarn build:cjs", + "build": "yarn build:esm && yarn build:cjs && node ./scripts/add-nested-package-json.mjs", "bundle:mobilenet_v2": "node ./scripts/bundle-model.mjs mobilenet_v2 1", "bundle:mobilenet_v2_mid": "node ./scripts/bundle-model.mjs mobilenet_v2_mid 2", "bundle:inception_v3": "node ./scripts/bundle-model.mjs inception_v3 6", @@ -36,9 +37,9 @@ "type": "git", "url": "git+https://github.com/infinitered/nsfwjs.git" }, - "dependencies": {}, "peerDependencies": { - "@tensorflow/tfjs": "^4.0.0" + "@tensorflow/tfjs": "^4.0.0", + "buffer": "^6.0.3" }, "devDependencies": { "@tensorflow/tfjs": "^4.0.0", @@ -47,7 +48,9 @@ "babel-core": "^6.26.3", "babel-plugin-transform-runtime": "~6.23.0", "browserify": "^17.0.0", + "buffer": "^6.0.3", "doctoc": "^2.2.0", + "esbuild": "^0.24.0", "jest": "^28.1.3", "jpeg-js": "^0.4.4", "np": "^10.0.0", @@ -73,5 +76,6 @@ "bugs": { "url": "https://github.com/infinitered/nsfwjs/issues" }, - "homepage": "https://nsfwjs.com" + "homepage": "https://nsfwjs.com", + "dependencies": {} } diff --git a/scripts/add-extensions.mjs b/scripts/add-extensions.mjs new file mode 100644 index 00000000..d25bee69 --- /dev/null +++ b/scripts/add-extensions.mjs @@ -0,0 +1,40 @@ +import { readdirSync, readFileSync, statSync, writeFileSync } from "fs"; +import { join } from "path"; + +const directory = "./dist/esm"; // Target directory +const extension = ".js"; + +function addExtensions(dir) { + const files = readdirSync(dir); + + files.forEach((file) => { + const fullPath = join(dir, file); + + if (statSync(fullPath).isDirectory()) { + addExtensions(fullPath); + } else if (fullPath.endsWith(".js")) { + let content = readFileSync(fullPath, "utf8"); + + // Add .js extension to static imports (from './path') + content = content.replace(/(from\s+['"]\.\/[^'"]+)/g, (match) => { + if (!match.endsWith(extension)) { + return `${match}${extension}`; + } + return match; + }); + + // Add .js extension to dynamic imports (import('./path')) + content = content.replace(/(import\(['"]\.\/[^'"]+)/g, (match) => { + if (!match.endsWith(extension)) { + return `${match}${extension}`; + } + return match; + }); + + writeFileSync(fullPath, content); + } + }); +} + +// Call the function on the target directory +addExtensions(directory); diff --git a/scripts/add-nested-package-json.mjs b/scripts/add-nested-package-json.mjs new file mode 100644 index 00000000..b009041d --- /dev/null +++ b/scripts/add-nested-package-json.mjs @@ -0,0 +1,13 @@ +import { writeFileSync } from "fs"; +import { join } from "path"; + +function addPackageJson(dir, type) { + const packageJsonContent = JSON.stringify({ type }, null, 2); + const filePath = join(dir, "package.json"); + writeFileSync(filePath, packageJsonContent); + console.log(`Created package.json in ${dir}`); +} + +// Add package.json for ESM and CJS builds +addPackageJson("./dist/esm", "module"); +addPackageJson("./dist/cjs", "commonjs"); diff --git a/scripts/bundle-model.mjs b/scripts/bundle-model.mjs index 1443b5c2..d39c84ef 100644 --- a/scripts/bundle-model.mjs +++ b/scripts/bundle-model.mjs @@ -6,74 +6,86 @@ import { unlinkSync, writeFileSync, } from "fs"; +import { promisify } from "util"; -// The first argument is the model name, the second argument is the number of shards +const execPromise = promisify(exec); const model = process.argv[2]; const numShards = +process.argv[3]; -const filenames = ["model"]; +const filenames = [ + "model", + ...Array.from( + { length: numShards }, + (_, i) => `group1-shard${i + 1}of${numShards}` + ), +]; -for (let i = 1; i <= numShards; i++) { - filenames.push(`group1-shard${i}of${numShards}`); -} +const BASE_MODEL_PATH = "./models/"; +const BASE_DIST_PATH = "./dist/"; +const JSON_EXT = ".json"; +const MIN_JS_EXT = ".min.js"; const binToJson = (sourcePath, outputPath) => { - // Read the binary file and convert it to Base64 const binFile = readFileSync(`${sourcePath}`); const base64String = binFile.toString("base64"); - - // Write the Base64 string to a .json file writeFileSync(`${outputPath}.json`, JSON.stringify(base64String)); }; -filenames.forEach((filename) => { - const sourcePath = `./models/${model}/${filename}`; - const outputDir = `./dist/models/${model}`; +const runCommand = async (command) => { + try { + const { stdout, stderr } = await execPromise(command); + if (stderr) console.error(`stderr: ${stderr}`); + if (stdout) console.log(`stdout: ${stdout}`); + } catch (error) { + console.error(`Error: ${error.message}`); + } +}; + +const generateUmd = async (outputPath, filename) => { + const identifier = filename.replace(/-/g, "_"); + await runCommand( + `browserify ${outputPath}.json -s ${identifier} -o ${outputPath}.js` + ); + await runCommand( + `terser ${outputPath}.js -c -m -o ${outputPath}${MIN_JS_EXT}` + ); + unlinkSync(`${outputPath}.js`); + unlinkSync(`${outputPath}.json`); +}; + +const generateEsm = async (outputPath) => { + await runCommand( + `esbuild ${outputPath}.json --bundle --format=esm --minify --outfile=${outputPath}${MIN_JS_EXT} --log-level=error` + ); + unlinkSync(`${outputPath}.json`); +}; + +const processBundle = async (filename, type) => { + const sourcePath = `${BASE_MODEL_PATH}${model}/${filename}`; + const outputDir = `${BASE_DIST_PATH}${type}/models/${model}`; const outputPath = `${outputDir}/${filename}`; - // Create the output directory if it doesn't exist mkdirSync(outputDir, { recursive: true }); if (filename === "model") { - // Copy the model.json file - copyFileSync(`${sourcePath}.json`, `${outputPath}.json`); + copyFileSync(`${sourcePath}${JSON_EXT}`, `${outputPath}${JSON_EXT}`); } else { binToJson(sourcePath, outputPath); } - // Browserify the .json file - const identifier = filename.replace(/-/g, "_"); - exec( - `browserify ${outputPath}.json -s ${identifier} -o ${outputPath}.js`, - (error, stdout, stderr) => { - if (error) { - console.log(`Error: ${error.message}`); - return; - } - if (stderr) { - console.log(`stderr: ${stderr}`); - return; - } - console.log(`stdout: ${stdout}`); - - // Minify the .js file with Terser - exec( - `terser ${outputPath}.js -c -m -o ${outputPath}.min.js`, - (error, stdout, stderr) => { - if (error) { - console.log(`Error: ${error.message}`); - return; - } - if (stderr) { - console.log(`stderr: ${stderr}`); - return; - } - console.log(`stdout: ${stdout}`); + if (type === "cjs") { + await generateUmd(outputPath, filename); + } else if (type === "esm") { + await generateEsm(outputPath); + } +}; - // Delete the original .js and .json files - unlinkSync(`${outputPath}.js`); - unlinkSync(`${outputPath}.json`); - } - ); - } +const bundleAll = async () => { + await Promise.all( + filenames.map(async (filename) => { + await processBundle(filename, "cjs"); + await processBundle(filename, "esm"); + }) ); -}); +}; + +bundleAll().catch((err) => console.error(err)); diff --git a/scripts/post-test.mjs b/scripts/post-test.mjs index 68799ad9..a2f65757 100644 --- a/scripts/post-test.mjs +++ b/scripts/post-test.mjs @@ -1,20 +1,5 @@ -import { readdirSync, unlinkSync } from "fs"; -import { join } from "path"; +import { rmSync } from "fs"; -const dir = "./models"; +const dir = "./src/models"; -// Get the names of all subfolders in the dir -const models = readdirSync(dir, { withFileTypes: true }) - .filter((dirent) => dirent.isDirectory()) - .map((dirent) => dirent.name); - -models.forEach((model) => { - const modelDir = join(dir, model); - - readdirSync(modelDir, { withFileTypes: true }) - .filter((dirent) => dirent.isFile() && dirent.name.endsWith(".min.js")) - .forEach((dirent) => { - const file = join(modelDir, dirent.name); - unlinkSync(file); - }); -}); +rmSync(dir, { recursive: true, force: true }); diff --git a/scripts/pre-test.mjs b/scripts/pre-test.mjs index 57c9db3b..244215ad 100644 --- a/scripts/pre-test.mjs +++ b/scripts/pre-test.mjs @@ -1,8 +1,8 @@ -import { copyFileSync, readdirSync } from "fs"; +import { copyFileSync, mkdirSync, readdirSync } from "fs"; import { join } from "path"; -const srcDir = "./dist/models"; -const destDir = "./models"; +const srcDir = "./dist/cjs/models"; +const destDir = "./src/models"; // Get the names of all subfolders in the srcDir const models = readdirSync(srcDir, { withFileTypes: true }) @@ -13,6 +13,8 @@ models.forEach((model) => { const modelSrcDir = join(srcDir, model); const modelDestDir = join(destDir, model); + mkdirSync(modelDestDir, { recursive: true }); + readdirSync(modelSrcDir, { withFileTypes: true }) .filter((dirent) => dirent.isFile() && dirent.name.endsWith(".min.js")) .forEach((dirent) => { diff --git a/src/index.ts b/src/index.ts index 2e9ad39f..d4935bcb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,5 @@ import * as tf from "@tensorflow/tfjs"; +import { Buffer } from "buffer"; import { NSFW_CLASSES } from "./nsfw_classes"; declare global { @@ -7,6 +8,9 @@ declare global { [x: string]: any; } } + interface Window { + [x: string]: any; + } } type IOHandler = tf.io.IOHandler; @@ -14,25 +18,25 @@ type ModelJSON = tf.io.ModelJSON; type ModelArtifacts = tf.io.ModelArtifacts; type WeightDataBase64 = { [x: string]: string }; -export type frameResult = { +export type FrameResult = { index: number; totalFrames: number; - predictions: Array; + predictions: Array; image: HTMLCanvasElement | ImageData; }; -export type classifyConfig = { +export type ClassifyConfig = { topk?: number; fps?: number; - onFrame?: (result: frameResult) => any; + onFrame?: (result: FrameResult) => any; }; -interface nsfwjsOptions { +interface NSFWJSOptions { size?: number; type?: string; } -export type predictionType = { +export type PredictionType = { className: (typeof NSFW_CLASSES)[keyof typeof NSFW_CLASSES]; probability: number; }; @@ -41,21 +45,18 @@ export type ModelName = "MobileNetV2" | "MobileNetV2Mid" | "InceptionV3"; type ModelConfig = { [key in ModelName]: { - path: string; numOfWeightBundles: number; - options?: nsfwjsOptions; + options?: NSFWJSOptions; }; }; const availableModels: ModelConfig = { - MobileNetV2: { path: "mobilenet_v2", numOfWeightBundles: 1 }, + MobileNetV2: { numOfWeightBundles: 1 }, MobileNetV2Mid: { - path: "mobilenet_v2_mid", numOfWeightBundles: 2, options: { type: "graph" }, }, InceptionV3: { - path: "inception_v3", numOfWeightBundles: 6, options: { size: 299 }, }, @@ -64,64 +65,110 @@ const availableModels: ModelConfig = { const DEFAULT_MODEL_NAME: ModelName = "MobileNetV2"; const IMAGE_SIZE = 224; // default to Mobilenet v2 +const getGlobal = () => { + if (typeof globalThis !== "undefined") + return globalThis as typeof globalThis & NodeJS.Global & Window; + if (typeof global !== "undefined") + return global as typeof globalThis & NodeJS.Global & Window; + if (typeof window !== "undefined") + return window as typeof globalThis & NodeJS.Global & Window; + if (typeof self !== "undefined") + return self as typeof globalThis & NodeJS.Global & Window; + throw new Error("Unable to locate global object"); +}; + function isModelName(name?: string): name is ModelName { return !!name && name in availableModels; } -async function loadWeights( - path: string, - numOfWeightBundles: number -): Promise { - const promises = [...Array(numOfWeightBundles)].map(async (_, index) => { - const num = index + 1; - const bundle = `group1-shard${num}of${numOfWeightBundles}`; - const identifier = bundle.replace(/-/g, "_"); - - try { - const weight = - global[identifier] || - (await import(`../models/${path}/${bundle}.min.js`)).default; - return { [bundle]: weight }; - } catch { - throw new Error( - `Could not load the weight data. Make sure you are importing the ${bundle}.min.js bundle.` - ); +const getModelJson = async (modelName: ModelName) => { + const globalModel = getGlobal().model; + + if (globalModel) { + // If the model is available globally (UMD via script tag), return it + return globalModel; + } + + let modelJson; + + if (modelName === "MobileNetV2") + ({ modelJson } = await import("./model_imports/mobilenet_v2")); + else if (modelName === "MobileNetV2Mid") + ({ modelJson } = await import("./model_imports/mobilenet_v2_mid")); + else if (modelName === "InceptionV3") + ({ modelJson } = await import("./model_imports/inception_v3")); + + return (await modelJson()).default; +}; + +const getWeightData = async ( + modelName: ModelName +): Promise => { + const { numOfWeightBundles } = availableModels[modelName]; + const bundles: WeightDataBase64[] = []; + + for (let i = 0; i < numOfWeightBundles; i++) { + const bundleName = `group1-shard${i + 1}of${numOfWeightBundles}`; + const identifier = bundleName.replace(/-/g, "_"); + + const globalWeight = getGlobal()[identifier]; + if (globalWeight) { + // If the weight data bundle is available globally (UMD via script tag), use it + bundles.push({ [bundleName]: globalWeight }); + } else { + let weightBundles; + + if (modelName === "MobileNetV2") + ({ weightBundles } = await import("./model_imports/mobilenet_v2")); + else if (modelName === "MobileNetV2Mid") + ({ weightBundles } = await import("./model_imports/mobilenet_v2_mid")); + else if (modelName === "InceptionV3") + ({ weightBundles } = await import("./model_imports/inception_v3")); + + const weight = (await weightBundles[i]()).default; + bundles.push({ [bundleName]: weight }); } - }); + } + + return Object.assign({}, ...bundles); +}; - const data = await Promise.all(promises); - return Object.assign({}, ...data); +async function loadWeights(modelName: ModelName): Promise { + try { + const weightDataBundles = await getWeightData(modelName); + return weightDataBundles; + } catch { + throw new Error( + `Could not load the weight data. Make sure you are importing the correct shard files from the models directory. Ref: https://github.com/infinitered/nsfwjs?tab=readme-ov-file#browserify` + ); + } } async function loadModel(modelName: ModelName | string) { - if (!isModelName(modelName)) return modelName; - const { path, numOfWeightBundles } = availableModels[modelName]; - let modelJson; + if (!isModelName(modelName)) return modelName; // Custom url for the model provided try { - modelJson = - global.model || (await import(`../models/${path}/model.min.js`)).default; + const modelJson = await getModelJson(modelName); + const weightData = await loadWeights(modelName); + const handler = new JSONHandler(modelJson, weightData); + return handler; } catch { throw new Error( - `Could not load the model. Make sure you are importing the model.min.js bundle.` + `Could not load the model. Make sure you are importing the model.min.js bundle. Ref: https://github.com/infinitered/nsfwjs?tab=readme-ov-file#browserify` ); } - - const weightData = await loadWeights(path, numOfWeightBundles); - const handler = new JSONHandler(modelJson, weightData); - return handler; } export async function load(modelOrUrl?: ModelName): Promise; export async function load( modelOrUrl?: string, - options?: nsfwjsOptions + options?: NSFWJSOptions ): Promise; export async function load( modelOrUrl?: string, - options: nsfwjsOptions = { size: IMAGE_SIZE } + options: NSFWJSOptions = { size: IMAGE_SIZE } ) { if (tf == null) { throw new Error( @@ -222,12 +269,12 @@ export class NSFWJS { public endpoints: string[]; public model: tf.LayersModel | tf.GraphModel; - private options: nsfwjsOptions; + private options: NSFWJSOptions; private urlOrIOHandler: string | IOHandler; private intermediateModels: { [layerName: string]: tf.LayersModel } = {}; private normalizationOffset: tf.Scalar; - constructor(modelUrlOrIOHandler: string | IOHandler, options: nsfwjsOptions) { + constructor(modelUrlOrIOHandler: string | IOHandler, options: NSFWJSOptions) { this.options = options; this.normalizationOffset = tf.scalar(255); this.urlOrIOHandler = modelUrlOrIOHandler; @@ -352,7 +399,7 @@ export class NSFWJS { | HTMLCanvasElement | HTMLVideoElement, topk = 5 - ): Promise> { + ): Promise> { const logits = this.infer(img) as tf.Tensor2D; const classes = await getTopKClasses(logits, topk); @@ -366,7 +413,7 @@ export class NSFWJS { async function getTopKClasses( logits: tf.Tensor2D, topK: number -): Promise> { +): Promise> { const values = await logits.data(); const valuesAndIndices: { @@ -386,7 +433,7 @@ async function getTopKClasses( topkIndices[i] = valuesAndIndices[i].index; } - const topClassesAndProbs: predictionType[] = []; + const topClassesAndProbs: PredictionType[] = []; for (let i = 0; i < topkIndices.length; i++) { topClassesAndProbs.push({ className: NSFW_CLASSES[topkIndices[i]], diff --git a/src/model_imports/inception_v3.ts b/src/model_imports/inception_v3.ts new file mode 100644 index 00000000..401eef5d --- /dev/null +++ b/src/model_imports/inception_v3.ts @@ -0,0 +1,11 @@ +export const modelJson = () => + import("../models/inception_v3/model.min.js" as string); + +export const weightBundles = [ + () => import("../models/inception_v3/group1-shard1of6.min.js" as string), + () => import("../models/inception_v3/group1-shard2of6.min.js" as string), + () => import("../models/inception_v3/group1-shard3of6.min.js" as string), + () => import("../models/inception_v3/group1-shard4of6.min.js" as string), + () => import("../models/inception_v3/group1-shard5of6.min.js" as string), + () => import("../models/inception_v3/group1-shard6of6.min.js" as string), +]; diff --git a/src/model_imports/mobilenet_v2.ts b/src/model_imports/mobilenet_v2.ts new file mode 100644 index 00000000..742f90dc --- /dev/null +++ b/src/model_imports/mobilenet_v2.ts @@ -0,0 +1,6 @@ +export const modelJson = () => + import("../models/mobilenet_v2/model.min.js" as string); + +export const weightBundles = [ + () => import("../models/mobilenet_v2/group1-shard1of1.min.js" as string), +]; diff --git a/src/model_imports/mobilenet_v2_mid.ts b/src/model_imports/mobilenet_v2_mid.ts new file mode 100644 index 00000000..51b6b9ba --- /dev/null +++ b/src/model_imports/mobilenet_v2_mid.ts @@ -0,0 +1,7 @@ +export const modelJson = () => + import("../models/mobilenet_v2_mid/model.min.js" as string); + +export const weightBundles = [ + () => import("../models/mobilenet_v2_mid/group1-shard1of2.min.js" as string), + () => import("../models/mobilenet_v2_mid/group1-shard2of2.min.js" as string), +]; diff --git a/tsconfig.cjs.json b/tsconfig.cjs.json index da7a1468..44b90283 100644 --- a/tsconfig.cjs.json +++ b/tsconfig.cjs.json @@ -4,4 +4,4 @@ "module": "commonjs", "outDir": "./dist/cjs" } -} \ No newline at end of file +} diff --git a/tsconfig.esm.json b/tsconfig.esm.json index 732ed150..0ebcdc1a 100644 --- a/tsconfig.esm.json +++ b/tsconfig.esm.json @@ -4,4 +4,4 @@ "module": "esnext", "outDir": "./dist/esm" } -} \ No newline at end of file +} diff --git a/tsconfig.json b/tsconfig.json index 999fdda6..2d5a1d58 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,26 +1,25 @@ { - "compilerOptions": { - "moduleResolution": "node", - "noImplicitAny": true, - "sourceMap": true, - "removeComments": true, - "preserveConstEnums": true, - "declaration": true, - "target": "es5", - "lib": ["es2015", "dom"], - "noUnusedLocals": true, - "noImplicitReturns": true, - "noImplicitThis": true, - "alwaysStrict": true, - "noUnusedParameters": false, - "esModuleInterop": true, - "pretty": true, - "noFallthroughCasesInSwitch": true, - "allowUnreachableCode": false, - "experimentalDecorators": true, - "skipLibCheck": true - }, - "include": ["src/"], - "exclude": ["node_modules/", "dist/"] - } - \ No newline at end of file + "compilerOptions": { + "moduleResolution": "node", + "noImplicitAny": true, + "sourceMap": true, + "removeComments": true, + "preserveConstEnums": true, + "declaration": true, + "target": "es5", + "lib": ["es2015", "dom"], + "noUnusedLocals": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "alwaysStrict": true, + "noUnusedParameters": false, + "esModuleInterop": true, + "pretty": true, + "noFallthroughCasesInSwitch": true, + "allowUnreachableCode": false, + "experimentalDecorators": true, + "skipLibCheck": true + }, + "include": ["src/"], + "exclude": ["node_modules/", "dist/"] +} diff --git a/yarn.lock b/yarn.lock index 2036f32e..a451ff45 100644 --- a/yarn.lock +++ b/yarn.lock @@ -390,6 +390,126 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" +"@esbuild/aix-ppc64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz#b57697945b50e99007b4c2521507dc613d4a648c" + integrity sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw== + +"@esbuild/android-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.24.0.tgz#1add7e0af67acefd556e407f8497e81fddad79c0" + integrity sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w== + +"@esbuild/android-arm@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.24.0.tgz#ab7263045fa8e090833a8e3c393b60d59a789810" + integrity sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew== + +"@esbuild/android-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.24.0.tgz#e8f8b196cfdfdd5aeaebbdb0110983460440e705" + integrity sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ== + +"@esbuild/darwin-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz#2d0d9414f2acbffd2d86e98253914fca603a53dd" + integrity sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw== + +"@esbuild/darwin-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.24.0.tgz#33087aab31a1eb64c89daf3d2cf8ce1775656107" + integrity sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA== + +"@esbuild/freebsd-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.0.tgz#bb76e5ea9e97fa3c753472f19421075d3a33e8a7" + integrity sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA== + +"@esbuild/freebsd-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.24.0.tgz#e0e2ce9249fdf6ee29e5dc3d420c7007fa579b93" + integrity sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ== + +"@esbuild/linux-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.24.0.tgz#d1b2aa58085f73ecf45533c07c82d81235388e75" + integrity sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g== + +"@esbuild/linux-arm@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.24.0.tgz#8e4915df8ea3e12b690a057e77a47b1d5935ef6d" + integrity sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw== + +"@esbuild/linux-ia32@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.24.0.tgz#8200b1110666c39ab316572324b7af63d82013fb" + integrity sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA== + +"@esbuild/linux-loong64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.24.0.tgz#6ff0c99cf647504df321d0640f0d32e557da745c" + integrity sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g== + +"@esbuild/linux-mips64el@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.24.0.tgz#3f720ccd4d59bfeb4c2ce276a46b77ad380fa1f3" + integrity sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA== + +"@esbuild/linux-ppc64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.24.0.tgz#9d6b188b15c25afd2e213474bf5f31e42e3aa09e" + integrity sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ== + +"@esbuild/linux-riscv64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.24.0.tgz#f989fdc9752dfda286c9cd87c46248e4dfecbc25" + integrity sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw== + +"@esbuild/linux-s390x@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.24.0.tgz#29ebf87e4132ea659c1489fce63cd8509d1c7319" + integrity sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g== + +"@esbuild/linux-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz#4af48c5c0479569b1f359ffbce22d15f261c0cef" + integrity sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA== + +"@esbuild/netbsd-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.24.0.tgz#1ae73d23cc044a0ebd4f198334416fb26c31366c" + integrity sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg== + +"@esbuild/openbsd-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.0.tgz#5d904a4f5158c89859fd902c427f96d6a9e632e2" + integrity sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg== + +"@esbuild/openbsd-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.24.0.tgz#4c8aa88c49187c601bae2971e71c6dc5e0ad1cdf" + integrity sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q== + +"@esbuild/sunos-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.24.0.tgz#8ddc35a0ea38575fa44eda30a5ee01ae2fa54dd4" + integrity sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA== + +"@esbuild/win32-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.24.0.tgz#6e79c8543f282c4539db684a207ae0e174a9007b" + integrity sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA== + +"@esbuild/win32-ia32@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.24.0.tgz#057af345da256b7192d18b676a02e95d0fa39103" + integrity sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw== + +"@esbuild/win32-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.24.0.tgz#168ab1c7e1c318b922637fad8f339d48b01e1244" + integrity sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA== + "@istanbuljs/load-nyc-config@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz#10602de5570baea82f8afbfa2630b24e7a8cfe5b" @@ -947,9 +1067,9 @@ pretty-format "^28.0.0" "@types/long@^4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9" - integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w== + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" + integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA== "@types/mdast@^3.0.0": version "3.0.10" @@ -959,10 +1079,12 @@ "@types/unist" "*" "@types/node-fetch@^2.1.2": - version "2.1.6" - resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.1.6.tgz#4326288b49f352a142f03c63526ebce0f4c50877" + version "2.6.11" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.11.tgz#9b39b78665dae0e82a08f02f4967d62c66f95d24" + integrity sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g== dependencies: "@types/node" "*" + form-data "^4.0.0" "@types/node@*": version "11.9.4" @@ -979,9 +1101,9 @@ integrity sha512-esIJx9bQg+QYF0ra8GnvfianIY8qWB0GBx54PK5Eps6m+xTj86KLavHv6qDhzKcu5UUOgNfJ2pWaIIV7TRUd9Q== "@types/offscreencanvas@~2019.7.0": - version "2019.7.0" - resolved "https://registry.yarnpkg.com/@types/offscreencanvas/-/offscreencanvas-2019.7.0.tgz#e4a932069db47bb3eabeb0b305502d01586fa90d" - integrity sha512-PGcyveRIpL1XIqK8eBsmRBt76eFgtzuPiSTyKHZxnGemp2yzGzWpjYKAfK3wIMiU7eH+851yEpiuP8JZerTmWg== + version "2019.7.3" + resolved "https://registry.yarnpkg.com/@types/offscreencanvas/-/offscreencanvas-2019.7.3.tgz#90267db13f64d6e9ccb5ae3eac92786a7c77a516" + integrity sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A== "@types/prettier@^2.1.5": version "2.6.3" @@ -989,9 +1111,9 @@ integrity sha512-ymZk3LEC/fsut+/Q5qejp6R9O1rMxz3XaRHDV6kX8MrGAhOSPqVARbDi+EZvInBpw+BnCX3TD240byVkOfQsHg== "@types/seedrandom@^2.4.28": - version "2.4.30" - resolved "https://registry.yarnpkg.com/@types/seedrandom/-/seedrandom-2.4.30.tgz#d2efe425869b84163c2d56e779dddadb9372cbfa" - integrity sha512-AnxLHewubLVzoF/A4qdxBGHCKifw8cY32iro3DQX9TPcetE95zBeVt3jnsvtvAUf1vwzMfwzp4t/L2yqPlnjkQ== + version "2.4.34" + resolved "https://registry.yarnpkg.com/@types/seedrandom/-/seedrandom-2.4.34.tgz#c725cd0fc0442e2d3d0e5913af005686ffb7eb99" + integrity sha512-ytDiArvrn/3Xk6/vtylys5tlY6eo7Ane0hvcx++TKo6RxQXuVfW0AF/oeWqAj9dN29SyhtawuXstgmPlwNcv/A== "@types/stack-utils@^2.0.0": version "2.0.0" @@ -1252,6 +1374,11 @@ async@^3.1.0: resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + available-typed-arrays@^1.0.0, available-typed-arrays@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz#6b098ca9d8039079ee3f77f7b783c4480ba513f5" @@ -1684,6 +1811,14 @@ buffer@^5.5.0: base64-js "^1.3.1" ieee754 "^1.1.13" +buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + buffer@~5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.2.1.tgz#dd57fa0f109ac59c602479044dca7b8b3d0b71d6" @@ -1980,6 +2115,13 @@ combine-source-map@^0.8.0, combine-source-map@~0.8.0: lodash.memoize "~3.0.3" source-map "~0.5.3" +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + commander@^2.12.1, commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -2263,6 +2405,11 @@ del@^7.1.0: rimraf "^3.0.2" slash "^4.0.0" +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + deps-sort@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/deps-sort/-/deps-sort-2.0.1.tgz#9dfdc876d2bcec3386b6829ac52162cda9fa208d" @@ -2522,6 +2669,36 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +esbuild@^0.24.0: + version "0.24.0" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.24.0.tgz#f2d470596885fcb2e91c21eb3da3b3c89c0b55e7" + integrity sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ== + optionalDependencies: + "@esbuild/aix-ppc64" "0.24.0" + "@esbuild/android-arm" "0.24.0" + "@esbuild/android-arm64" "0.24.0" + "@esbuild/android-x64" "0.24.0" + "@esbuild/darwin-arm64" "0.24.0" + "@esbuild/darwin-x64" "0.24.0" + "@esbuild/freebsd-arm64" "0.24.0" + "@esbuild/freebsd-x64" "0.24.0" + "@esbuild/linux-arm" "0.24.0" + "@esbuild/linux-arm64" "0.24.0" + "@esbuild/linux-ia32" "0.24.0" + "@esbuild/linux-loong64" "0.24.0" + "@esbuild/linux-mips64el" "0.24.0" + "@esbuild/linux-ppc64" "0.24.0" + "@esbuild/linux-riscv64" "0.24.0" + "@esbuild/linux-s390x" "0.24.0" + "@esbuild/linux-x64" "0.24.0" + "@esbuild/netbsd-x64" "0.24.0" + "@esbuild/openbsd-arm64" "0.24.0" + "@esbuild/openbsd-x64" "0.24.0" + "@esbuild/sunos-x64" "0.24.0" + "@esbuild/win32-arm64" "0.24.0" + "@esbuild/win32-ia32" "0.24.0" + "@esbuild/win32-x64" "0.24.0" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -2734,6 +2911,15 @@ form-data-encoder@^2.1.2: resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-2.1.4.tgz#261ea35d2a70d48d30ec7a9603130fa5515e9cd5" integrity sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw== +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + format@^0.2.0: version "0.2.2" resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b" @@ -3034,7 +3220,7 @@ iconv-lite@^0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -ieee754@^1.1.13: +ieee754@^1.1.13, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== @@ -4407,6 +4593,18 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" @@ -4534,13 +4732,20 @@ new-github-release-url@^2.0.0: dependencies: type-fest "^2.5.1" -node-fetch@^2.6.0, node-fetch@~2.6.1: +node-fetch@^2.6.0: version "2.6.7" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== dependencies: whatwg-url "^5.0.0" +node-fetch@~2.6.1: + version "2.6.13" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.13.tgz#a20acbbec73c2e09f9007de5cda17104122e0010" + integrity sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA== + dependencies: + whatwg-url "^5.0.0" + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -5162,11 +5367,16 @@ regenerator-runtime@^0.11.0: version "0.11.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" -regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.5: +regenerator-runtime@^0.13.4: version "0.13.7" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== +regenerator-runtime@^0.13.5: + version "0.13.11" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== + registry-auth-token@^5.0.1, registry-auth-token@^5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-5.0.2.tgz#8b026cc507c8552ebbe06724136267e63302f756" @@ -6345,11 +6555,6 @@ y18n@^4.0.0: resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4" integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ== -y18n@^5.0.2: - version "5.0.4" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.4.tgz#0ab2db89dd5873b5ec4682d8e703e833373ea897" - integrity sha512-deLOfD+RvFgrpAmSZgfGdWYE+OKyHcVHaRQ7NphG/63scpRvTHHeQMAxGGvaLVGJ+HYVcCXlzcTK0ZehFf+eHQ== - y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" @@ -6369,9 +6574,9 @@ yargs-parser@^18.1.2: decamelize "^1.2.0" yargs-parser@^20.2.2: - version "20.2.7" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a" - integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== yargs-parser@^21.0.0, yargs-parser@^21.0.1: version "21.0.1" @@ -6396,16 +6601,16 @@ yargs@^15.0.1: yargs-parser "^18.1.2" yargs@^16.0.3: - version "16.1.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.1.0.tgz#fc333fe4791660eace5a894b39d42f851cd48f2a" - integrity sha512-upWFJOmDdHN0syLuESuvXDmrRcWd1QafJolHskzaw79uZa7/x53gxQKiR07W59GWY1tFhhU/Th9DrtSfpS782g== + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== dependencies: cliui "^7.0.2" escalade "^3.1.1" get-caller-file "^2.0.5" require-directory "^2.1.1" string-width "^4.2.0" - y18n "^5.0.2" + y18n "^5.0.5" yargs-parser "^20.2.2" yargs@^17.3.1: