From da3a6d69c6201af6e145c528e0fe3b66a183953a Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Fri, 25 Nov 2022 17:38:59 -0800 Subject: [PATCH] work better --- .gitignore | 2 + dither-image.js | 752 ++++++++++++++++++++++++ package-lock.json | 1382 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 6 + 4 files changed, 2142 insertions(+) create mode 100644 dither-image.js create mode 100644 package-lock.json create mode 100644 package.json diff --git a/.gitignore b/.gitignore index 010428c..c9b697a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ .DS_Store +node_modules *.o *.xex *.pxd canvas*.png +*.s.png \ No newline at end of file diff --git a/dither-image.js b/dither-image.js new file mode 100644 index 0000000..fc26fed --- /dev/null +++ b/dither-image.js @@ -0,0 +1,752 @@ +import { + readFileSync, + writeFileSync +} from 'fs'; + +import Jimp from 'Jimp'; + +function toLinear(val) { + // use a 2.4 gamma approximation + // this is BT.1886 compatible + // and simpler than sRGB + let unit = val / 255; + unit **= 2.4; + return unit * 255; +} + +function fromLinear(val) { + let unit = val / 255; + unit **= (1 / 2.4); + return unit * 255; +} + +class RGB { + constructor(r, g, b) { + this.r = r; + this.g = g; + this.b = b; + } + + static fromHex(val) { + let r = val & 0xff; + let g = (val >> 8) & 0xff; + let b = (val >> 16) & 0xff; + return new RGB(r,g,b); + } + + toLinear() { + return new RGB( + toLinear(this.r), + toLinear(this.g), + toLinear(this.b) + ); + } + + fromLinear() { + return new RGB( + fromLinear(this.r), + fromLinear(this.g), + fromLinear(this.b) + ); + } + + cap() { + if (this.r < 0) { + this.r = 0; + } + if (this.g < 0) { + this.g = 0; + } + if (this.b < 0) { + this.b = 0; + } + if (this.r > 255) { + this.r = 255; + } + if (this.g > 255) { + this.g = 255; + } + if (this.b > 255) { + this.b = 255; + } + } + + inc(other) { + this.r += other.r; + this.g += other.g; + this.b += other.b; + return this; + } + + add(other) { + return new RGB( + this.r + other.r, + this.g + other.g, + this.b + other.b + ); + } + + difference(other) { + return new RGB( + this.r - other.r, + this.g - other.g, + this.b - other.b + ); + } + + divide(scalar) { + return new RGB( + this.r / scalar, + this.g / scalar, + this.b / scalar, + ); + } + + magnitude() { + return Math.sqrt( + this.r * this.r + + this.g * this.g + + this.b * this.b + ); + } + + distance(other) { + return this.difference(other).magnitude(); + } +} + +// snarfed from https://lospec.com/palette-list/atari-8-bit-family-gtia +// which was calculated with Retrospecs App's Atari 800 emulator +let atariRGB = [ + 0x000000, + 0x111111, + 0x222222, + 0x333333, + 0x444444, + 0x555555, + 0x666666, + 0x777777, + 0x888888, + 0x999999, + 0xaaaaaa, + 0xbbbbbb, + 0xcccccc, + 0xdddddd, + 0xeeeeee, + 0xffffff, + 0x190700, + 0x2a1800, + 0x3b2900, + 0x4c3a00, + 0x5d4b00, + 0x6e5c00, + 0x7f6d00, + 0x907e09, + 0xa18f1a, + 0xb3a02b, + 0xc3b13c, + 0xd4c24d, + 0xe5d35e, + 0xf7e46f, + 0xfff582, + 0xffff96, + 0x310000, + 0x3f0000, + 0x531700, + 0x642800, + 0x753900, + 0x864a00, + 0x975b0a, + 0xa86c1b, + 0xb97d2c, + 0xca8e3d, + 0xdb9f4e, + 0xecb05f, + 0xfdc170, + 0xffd285, + 0xffe39c, + 0xfff4b2, + 0x420404, + 0x4f0000, + 0x600800, + 0x711900, + 0x822a0d, + 0x933b1e, + 0xa44c2f, + 0xb55d40, + 0xc66e51, + 0xd77f62, + 0xe89073, + 0xf9a183, + 0xffb298, + 0xffc3ae, + 0xffd4c4, + 0xffe5da, + 0x410103, + 0x50000f, + 0x61001b, + 0x720f2b, + 0x83203c, + 0x94314d, + 0xa5425e, + 0xb6536f, + 0xc76480, + 0xd87591, + 0xe986a2, + 0xfa97b3, + 0xffa8c8, + 0xffb9de, + 0xffcaef, + 0xfbdcf6, + 0x330035, + 0x440041, + 0x55004c, + 0x660c5c, + 0x771d6d, + 0x882e7e, + 0x993f8f, + 0xaa50a0, + 0xbb61b1, + 0xcc72c2, + 0xdd83d3, + 0xee94e4, + 0xffa5e4, + 0xffb6e9, + 0xffc7ee, + 0xffd8f3, + 0x1d005c, + 0x2e0068, + 0x400074, + 0x511084, + 0x622195, + 0x7332a6, + 0x8443b7, + 0x9554c8, + 0xa665d9, + 0xb776ea, + 0xc887eb, + 0xd998eb, + 0xe9a9ec, + 0xfbbaeb, + 0xffcbef, + 0xffdff9, + 0x020071, + 0x13007d, + 0x240b8c, + 0x351c9d, + 0x462dae, + 0x573ebf, + 0x684fd0, + 0x7960e1, + 0x8a71f2, + 0x9b82f7, + 0xac93f7, + 0xbda4f7, + 0xceb5f7, + 0xdfc6f7, + 0xf0d7f7, + 0xffe8f8, + 0x000068, + 0x000a7c, + 0x081b90, + 0x192ca1, + 0x2a3db2, + 0x3b4ec3, + 0x4c5fd4, + 0x5d70e5, + 0x6e81f6, + 0x7f92ff, + 0x90a3ff, + 0xa1b4ff, + 0xb2c5ff, + 0xc3d6ff, + 0xd4e7ff, + 0xe5f8ff, + 0x000a4d, + 0x001b63, + 0x002c79, + 0x023d8f, + 0x134ea0, + 0x245fb1, + 0x3570c2, + 0x4681d3, + 0x5792e4, + 0x68a3f5, + 0x79b4ff, + 0x8ac5ff, + 0x9bd6ff, + 0xace7ff, + 0xbdf8ff, + 0xceffff, + 0x001a26, + 0x002b3c, + 0x003c52, + 0x004d68, + 0x065e7c, + 0x176f8d, + 0x28809e, + 0x3991af, + 0x4aa2c0, + 0x5bb3d1, + 0x6cc4e2, + 0x7dd5f3, + 0x8ee6ff, + 0x9ff7ff, + 0xb0ffff, + 0xc1ffff, + 0x01250a, + 0x023610, + 0x004622, + 0x005738, + 0x05684d, + 0x16795e, + 0x278a6f, + 0x389b80, + 0x49ac91, + 0x5abda2, + 0x6bceb3, + 0x7cdfc4, + 0x8df0d5, + 0x9effe5, + 0xaffff1, + 0xc0fffd, + 0x04260d, + 0x043811, + 0x054713, + 0x005a1b, + 0x106b1b, + 0x217c2c, + 0x328d3d, + 0x439e4e, + 0x54af5f, + 0x65c070, + 0x76d181, + 0x87e292, + 0x98f3a3, + 0xa9ffb3, + 0xbaffbf, + 0xcbffcb, + 0x00230a, + 0x003510, + 0x044613, + 0x155613, + 0x266713, + 0x377813, + 0x488914, + 0x599a25, + 0x6aab36, + 0x7bbc47, + 0x8ccd58, + 0x9dde69, + 0xaeef7a, + 0xbfff8b, + 0xd0ff97, + 0xe1ffa3, + 0x001707, + 0x0e2808, + 0x1f3908, + 0x304a08, + 0x415b08, + 0x526c08, + 0x637d08, + 0x748e0d, + 0x859f1e, + 0x96b02f, + 0xa7c140, + 0xb8d251, + 0xc9e362, + 0xdaf473, + 0xebff82, + 0xfcff8e, + 0x1b0701, + 0x2c1801, + 0x3c2900, + 0x4d3b00, + 0x5f4c00, + 0x705e00, + 0x816f00, + 0x938009, + 0xa4921a, + 0xb2a02b, + 0xc7b43d, + 0xd8c64e, + 0xead760, + 0xf6e46f, + 0xfffa84, + 0xffff99, +].map((hex) => RGB.fromHex(hex).toLinear()); + +/** + * Dither RGB input data with a target palette size. + * If the number of used colors exceeds `n`, the + * palette will be reduced until it fits. + * @param {RGB[]} input source scanline data, in linear RGB + * @param {number[]} palette - current working palette, as Atari 8-bit color values (low nybble luminance, high nybble hue) + * @param {number} n - target color count + * @param {Object} inputError + * @returns {{output: Uint8Array, palette: number[], error: {red: Float64Array, green: Float64Array, blue: Float64Array}}} + */ +function decimate(input, palette, n, inputError) { + // to brute-force, the possible palettes are: + // 255 * 254 * 253 = 16,386,810 + // + // we could brute force it but that's a lot :D + // but can do some bisection :D + // + // need a fitness metric. + // each pixel in the dithered line gives a distance + // sum/average them? median? maximum? + // summing evens out the ups/downs from dithering + // but doesn't distinguish between two close and two distant options + // consider median, 90th-percentile, and max of abs(distance) + // consider doing the distance for each channel? + + let width = input.length; + + // Apply dithering with given palette and collect color usage stats + let dither = (palette) => { + let fitness = new Float64Array(width); + let error = { + right: new RGB(0, 0, 0), + next: [], + }; + for (let i = 0; i < width; i++) { + error.next[i] = new RGB(0, 0, 0); + } + + let output = new Uint8Array(width); + let popularity = new Int32Array(width); + + let nextError = new RGB(0, 0, 0); + + // Try dithering with this palette. + for (let x = 0; x < width; x++) { + let rgb = input[x]; + rgb = rgb.add(error.right); + if (inputError) { + rgb.inc(inputError[x]); + } + + // find the closest possible color + // @todo consider doing the difference scoring in luminance and hue spaces + let shortest = Infinity; + let pick = 1; + + for (let i = 0; i < palette.length; i++) { + let diff = rgb.difference(atariRGB[palette[i]]); + let dist = diff.magnitude(); + if (dist < shortest) { + nextError = diff; + shortest = dist; + pick = i; + } + } + + output[x] = pick; + popularity[pick]++; + + if (x == width - 1) { + let half = nextError.divide(2); + error.next[x - 1].inc(half); + error.next[x].inc(half); + } else { + let quarter = nextError.divide(4); + error.right = quarter; + error.next[x - 1]?.inc(quarter); // @fixme should we change the amount? + error.next[x].inc(quarter); + error.next[x + 1].inc(quarter); + } + + // 442 is the 3d distance across the rgb cube + //fitness[x] = 442 - (nextError.magnitude()); + //fitness[x] = 442 / (442 - nextError.magnitude()); + fitness[x] = 255 / (256 - Math.max(0, nextError.r, nextError.g, nextError.b)); + } + return { + output, + palette, + fitness, + popularity, + error: error.next + }; + }; + + + let decimated = palette.slice(); + + while (decimated.length > n) { + let {popularity, fitness, output} = dither(decimated); + + // Try dropping least used color on each iteration + let least = Infinity; + let pick = -1; + for (let i = 1; i < decimated.length; i++) { + + //let coolFactor = popularity[i]; + + let coolFactor = 0; + if (popularity[i]) { + for (let x = 0; x < width; x++) { + if (output[x] == i) { + // Scale up the scoring for close matches to prioritize + // color accuracy over raw linear usage. + //coolFactor += (fitness[x] ** 2); + coolFactor += (fitness[x] ** 4); + } + } + } + + if (coolFactor < least) { + pick = i; + least = coolFactor; + } + } + decimated = decimated.filter((color, i) => { + if (i == 0) { + return true; + } + if (i == pick) { + return false; + } + // Also drop any non-black unused colors to save trouble. + // However -- this may change dither results. + // Try this with/without later. + if (popularity[i] == 0) { + return false; + } + return true; + }); + } + + // Palette fits + return dither(decimated); +} + +/** + * Read an image file into a buffer + * @param {string} src + * @returns {{width: number, height: number, rgba: Uint8Array}} + */ +async function loadImage(src) { + let image = await Jimp.read(src); + let width = image.bitmap.width; + let height = image.bitmap.height; + let rgba = image.bitmap.data.slice(); + return { + width, + height, + rgba, + }; +} + +/** + * Halve the horizontal resolution, interpolating input. + * @param {Uint8Array} rgba + * @returns {Uint8Array} + **/ +function halveImage(rgba) { + let out = new Uint8Array(rgba.length >> 1); + for (let i = 0; i < rgba.length; i += 8) { + let j = i >> 1; + out[j + 0] = (rgba[i + 0] + rgba[i + 4] + 1) >> 1; + out[j + 1] = (rgba[i + 1] + rgba[i + 5] + 1) >> 1; + out[j + 2] = (rgba[i + 2] + rgba[i + 6] + 1) >> 1; + out[j + 3] = (rgba[i + 3] + rgba[i + 7] + 1) >> 1; + } + return out; +} + +function imageToLinearRGB(rgba) { + let input = []; + for (let i = 0; i < rgba.length; i += 4) { + input.push(new RGB( + rgba[i + 0], + rgba[i + 1], + rgba[i + 2] + ).toLinear()); + } + return input; +} + +/** + * Read an image file, squish to 160px if necessary, + * and dither to 4 colors per scan line. + * + * @param {string} source path to source image file + * @returns {{width: number, height: number, lines: {palette: Array, output: Uint8Array}[]}} + */ +async function convert(source, nbits) { + + let { + width, + height, + rgba + } = await loadImage(source); + + if (width == 320) { + width = 160; + rgba = halveImage(rgba); + } + + if (width !== 160) { + throw new Error(`expected 160px-compatible width, got ${width} pixels`); + } + + if (height !== 192) { + // @fixme support up to 240px + throw new Error(`expected 192px height, got ${height} pixels`); + } + + if (rgba.length != width * 4 * height) { + console.log(` + width: ${width} + height: ${height} + rgba.length: ${rgba.length}`) + throw new Error('inconsistent data size'); + } + + let input = imageToLinearRGB(rgba); + + if (input.length != width * height) { + console.log(` + width: ${width} + height: ${height} + rgba.length: ${input.length}`) + throw new Error('inconsistent data size on input'); + } + + // Start with all colors usable with regular CTIA modes + // (not the 16-luminance special mode on GTIA) + let allColors = []; + for (let i = 0; i < 0xff; i += 2) { + allColors.push(i); + } + + let lines = []; + for (let y = 0; y < height; y++) { + let error = lines[y - 1]?.error; + let inputLine = input.slice(y * width, (y + 1) * width); + console.log(`DOING LINE ${y}; have ${inputLine.length} pixels`); + let line = decimate(inputLine, allColors, 4, error); + lines.push(line); + console.log(`DID LINE ${y}; have ${line.output.length} pixels`); + } + return { + width, + height, + lines + }; +} + + +function indexedToBitmap(width, nbits, src, dest) { + let nbytes = width >> nbits; + for (let i = 0; i < nbytes; i++) { + let a = 0; + for (let b = 0; b < 8; b += nbits) { + a <<= nbits; + a |= src[i]; + } + dest[i] = a; + } +} + +function byte2byte(arr) { + let lines = []; + for (let i=0; i < arr.length; i++) { + lines.push(`.byte ${lines[i]}`); + } + return lines.join('\n'); +} + +function genAssembly(width, height, nbits, lines) { + let stride = width * nbits / 8; + let palette1 = new Uint8Array(height); + let palette2 = new Uint8Array(height); + let palette3 = new Uint8Array(height); + let framebuffer = new Uint8Array(stride * height); + for (let y = 0; y < height; y++) { + palette1[y] = lines[y].palette[1]; + palette2[y] = lines[y].palette[2]; + palette3[y] = lines[y].palette[3]; + indexedToBitmap(width, nbits, lines[y].output, framebuffer.slice(y * stride)); + } + + return ` +.data + +.export palette1: + ${byte2byte(palette1)} + +.export palette2: + ${byte2byte(palette2)} + +.export palette3: + ${byte2byte(palette3)} + +.export framebuffer: + ${byte2byte(framebuffer)} + +`; +} + +/** + * Double width and save as an image file + * @param {number} width + * @param {number} height + * @param {{output: number[], palette: number[]}} lines + * @param {string} dest + */ +async function saveImage(width, height, lines, dest) { + let width2 = width * 2; + let stride = width2 * 4; + let rgba = new Uint8Array(stride * height); + + for (let y = 0; y < height; y++) { + let {output, palette} = lines[y]; + for (let x = 0; x < width2; x++) { + let i = x >> 1; + if (i >= width) { + throw new Error('i >= width'); + } + let rgb = atariRGB[palette[output[i]]]; + + rgba[y * stride + x * 4 + 0] = fromLinear(rgb.r); + rgba[y * stride + x * 4 + 1] = fromLinear(rgb.g); + rgba[y * stride + x * 4 + 2] = fromLinear(rgb.b); + rgba[y * stride + x * 4 + 3] = 255; + } + } + + let image = await new Promise((resolve, reject) => { + new Jimp({ + data: rgba, + width: width2, + height, + }, (err, image) => { + if (err) reject(err); + resolve(image); + }); + }); + await image.writeAsync(dest); +} + +async function main() { + if (process.argv.length < 5) { + console.error("Usage: node dither-image.js source-image.jpg dest-asm.s dest-preview.png"); + process.exit(1); + } + + let nbits = 2; + + let {width, height, lines} = await convert(process.argv[2], nbits); + + let asm = genAssembly(width, height, nbits, lines); + writeFileSync(process.argv[3], asm, "utf-8"); + + await saveImage(width, height, lines, process.argv[4]); + + process.exit(0); +} + +main(); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..250f164 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1382 @@ +{ + "name": "dither4", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "dependencies": { + "jimp": "^0.16.2" + } + }, + "node_modules/@babel/runtime": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.1.tgz", + "integrity": "sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==", + "dependencies": { + "regenerator-runtime": "^0.13.10" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@jimp/bmp": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.16.2.tgz", + "integrity": "sha512-4g9vW45QfMoGhLVvaFj26h4e7cC+McHUQwyFQmNTLW4FfC1OonN9oUr2m/FEDGkTYKR7aqdXR5XUqqIkHWLaFw==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2", + "bmp-js": "^0.1.0" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } + }, + "node_modules/@jimp/core": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/core/-/core-0.16.2.tgz", + "integrity": "sha512-dp7HcyUMzjXphXYodI6PaXue+I9PXAavbb+AN+1XqFbotN22Z12DosNPEyy+UhLY/hZiQQqUkEaJHkvV31rs+w==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2", + "any-base": "^1.1.0", + "buffer": "^5.2.0", + "exif-parser": "^0.1.12", + "file-type": "^9.0.0", + "load-bmfont": "^1.3.1", + "mkdirp": "^0.5.1", + "phin": "^2.9.1", + "pixelmatch": "^4.0.2", + "tinycolor2": "^1.4.1" + } + }, + "node_modules/@jimp/custom": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.16.2.tgz", + "integrity": "sha512-GtNwOs4hcVS2GIbqRUf42rUuX07oLB92cj7cqxZb0ZGWwcwhnmSW0TFLAkNafXmqn9ug4VTpNvcJSUdiuECVKg==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/core": "^0.16.2" + } + }, + "node_modules/@jimp/gif": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/gif/-/gif-0.16.2.tgz", + "integrity": "sha512-TMdyT9Q0paIKNtT7c5KzQD29CNCsI/t8ka28jMrBjEK7j5RRTvBfuoOnHv7pDJRCjCIqeUoaUSJ7QcciKic6CA==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2", + "gifwrap": "^0.9.2", + "omggif": "^1.0.9" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } + }, + "node_modules/@jimp/jpeg": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.16.2.tgz", + "integrity": "sha512-BW5gZydgq6wdIwHd+3iUNgrTklvoQc/FUKSj9meM6A0FU21lUaansRX5BDdJqHkyXJLnnlDGwDt27J+hQuBAVw==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2", + "jpeg-js": "^0.4.2" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } + }, + "node_modules/@jimp/plugin-blit": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-0.16.2.tgz", + "integrity": "sha512-Z31rRfV80gC/r+B/bOPSVVpJEWXUV248j7MdnMOFLu4vr8DMqXVo9jYqvwU/s4LSTMAMXqm4Jg6E/jQfadPKAg==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } + }, + "node_modules/@jimp/plugin-blur": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-0.16.2.tgz", + "integrity": "sha512-ShkJCAzRI+1fAKPuLLgEkixpSpVmKTYaKEFROUcgmrv9AansDXGNCupchqVMTdxf8zPyW8rR1ilvG3OJobufLQ==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } + }, + "node_modules/@jimp/plugin-circle": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-circle/-/plugin-circle-0.16.2.tgz", + "integrity": "sha512-6T4z/48F4Z5+YwAVCLOvXQcyGmo0E3WztxCz6XGQf66r4JJK78+zcCDYZFLMx0BGM0091FogNK4QniP8JaOkrA==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } + }, + "node_modules/@jimp/plugin-color": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-0.16.2.tgz", + "integrity": "sha512-6oBV0g0J17/7E+aTquvUsgSc85nUbUi+64tIK5eFIDzvjhlqhjGNJYlc46KJMCWIs61qRJayQoZdL/iT/iQuGQ==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2", + "tinycolor2": "^1.4.1" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } + }, + "node_modules/@jimp/plugin-contain": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-0.16.2.tgz", + "integrity": "sha512-pLcxO3hVN3LCEhMNvpZ9B7xILHVlS433Vv16zFFJxLRqZdYvPLsc+ZzJhjAiHHuEjVblQrktHE3LGeQwGJPo0w==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5", + "@jimp/plugin-blit": ">=0.3.5", + "@jimp/plugin-resize": ">=0.3.5", + "@jimp/plugin-scale": ">=0.3.5" + } + }, + "node_modules/@jimp/plugin-cover": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-0.16.2.tgz", + "integrity": "sha512-gzWM7VvYeI8msyiwbUZxH+sGQEgO6Vd6adGxZ0CeKX00uQOe5lDzxb1Wjx7sHcJGz8a/5fmAuwz7rdDtpDUbkw==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5", + "@jimp/plugin-crop": ">=0.3.5", + "@jimp/plugin-resize": ">=0.3.5", + "@jimp/plugin-scale": ">=0.3.5" + } + }, + "node_modules/@jimp/plugin-crop": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-0.16.2.tgz", + "integrity": "sha512-qCd3hfMEE+Z2EuuyXewgXRTtKJGIerWzc1zLEJztsUkPz5i73IGgkOL+mrNutZwGaXZbm+8SwUaGb46sxAO6Tw==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } + }, + "node_modules/@jimp/plugin-displace": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-0.16.2.tgz", + "integrity": "sha512-6nXdvNNjCdD95v2o3/jPeur903dz08lG4Y8gmr5oL2yVv9LSSbMonoXYrR/ASesdyXqGdXJLU4NL+yZs4zUqbQ==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } + }, + "node_modules/@jimp/plugin-dither": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-0.16.2.tgz", + "integrity": "sha512-DERpIzy21ZanMkVsD0Tdy8HQLbD1E41OuvIzaMRoW4183PA6AgGNlrQoFTyXmzjy6FTy1SxaQgTEdouInAWZ9Q==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } + }, + "node_modules/@jimp/plugin-fisheye": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-fisheye/-/plugin-fisheye-0.16.2.tgz", + "integrity": "sha512-Df7PsGIwiIpQu3EygYCnaJyTfOwvwtYV3cmYJS7yFLtdiFUuod+hlSo5GkwEPLAy+QBxhUbDuUqnsWo4NQtbiQ==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } + }, + "node_modules/@jimp/plugin-flip": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-0.16.2.tgz", + "integrity": "sha512-+2uC8ioVQUr06mnjSWraskz2L33nJHze35LkQ8ZNsIpoZLkgvfiWatqAs5bj+1jGI/9kxoCFAaT1Is0f+a4/rw==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5", + "@jimp/plugin-rotate": ">=0.3.5" + } + }, + "node_modules/@jimp/plugin-gaussian": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-gaussian/-/plugin-gaussian-0.16.2.tgz", + "integrity": "sha512-2mnuDSg4ZEH8zcJig7DZZf4st/cYmQ5UYJKP76iGhZ+6JDACk6uejwAgT5xHecNhkVAaXMdCybA2eknH/9OE1w==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } + }, + "node_modules/@jimp/plugin-invert": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-invert/-/plugin-invert-0.16.2.tgz", + "integrity": "sha512-xFvHbVepTY/nus+6yXiYN1iq+UBRkT0MdnObbiQPstUrAsz0Imn6MWISsnAyMvcNxHGrxaxjuU777JT/esM0gg==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } + }, + "node_modules/@jimp/plugin-mask": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-0.16.2.tgz", + "integrity": "sha512-AbdO85xxhfgEDdxYKpUotEI9ixiCMaIpfYHD5a5O/VWeimz2kuwhcrzlHGiyq1kKAgRcl0WEneTCZAHVSyvPKA==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } + }, + "node_modules/@jimp/plugin-normalize": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-normalize/-/plugin-normalize-0.16.2.tgz", + "integrity": "sha512-+ItBWFwmB0Od7OfOtTYT1gm543PpHUgU8/DN55z83l1JqS0OomDJAe7BmCppo2405TN6YtVm/csXo7p4iWd/SQ==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } + }, + "node_modules/@jimp/plugin-print": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-0.16.2.tgz", + "integrity": "sha512-ifTGEeJ5UZTCiqC70HMeU3iXk/vsOmhWiwVGOXSFXhFeE8ZpDWvlmBsrMYnRrJGuaaogHOIrrQPI+kCdDBSBIQ==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2", + "load-bmfont": "^1.4.0" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5", + "@jimp/plugin-blit": ">=0.3.5" + } + }, + "node_modules/@jimp/plugin-resize": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-0.16.2.tgz", + "integrity": "sha512-gE4N9l6xuwzacFZ2EPCGZCJ/xR+aX2V7GdMndIl/6kYIw5/eib1SFuF9AZLvIPSFuE1FnGo8+vT0pr++SSbhYg==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } + }, + "node_modules/@jimp/plugin-rotate": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-0.16.2.tgz", + "integrity": "sha512-/CTEYkR1HrgmnE0VqPhhbBARbDAfFX590LWGIpxcYIYsUUGQCadl+8Qo4UX13FH0Nt8UHEtPA+O2x08uPYg9UA==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5", + "@jimp/plugin-blit": ">=0.3.5", + "@jimp/plugin-crop": ">=0.3.5", + "@jimp/plugin-resize": ">=0.3.5" + } + }, + "node_modules/@jimp/plugin-scale": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-scale/-/plugin-scale-0.16.2.tgz", + "integrity": "sha512-3inuxfrlquyLaqFdiiiQNJUurR0WbvN5wAf1qcYX2LubG1AG8grayYD6H7XVoxfUGTZXh1kpmeirEYlqA2zxcw==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5", + "@jimp/plugin-resize": ">=0.3.5" + } + }, + "node_modules/@jimp/plugin-shadow": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-shadow/-/plugin-shadow-0.16.2.tgz", + "integrity": "sha512-Q0aIs2/L6fWMcEh9Ms73u34bT1hyUMw/oxaVoIzOLo6/E8YzCs2Bi63H0/qaPS0MQpEppI++kvosPbblABY79w==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5", + "@jimp/plugin-blur": ">=0.3.5", + "@jimp/plugin-resize": ">=0.3.5" + } + }, + "node_modules/@jimp/plugin-threshold": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-threshold/-/plugin-threshold-0.16.2.tgz", + "integrity": "sha512-gyOwmBgjtMPvcuyOhkP6dOGWbQdaTfhcBRN22mYeI/k/Wh/Zh1OI21F6eKLApsVRmg15MoFnkrCz64RROC34sw==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5", + "@jimp/plugin-color": ">=0.8.0", + "@jimp/plugin-resize": ">=0.8.0" + } + }, + "node_modules/@jimp/plugins": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugins/-/plugins-0.16.2.tgz", + "integrity": "sha512-zCvYtCgctmC0tkYEu+y+kSwSIZBsNznqJ3/3vkpzxdyjd6wCfNY5Qc/68MPrLc1lmdeGo4cOOTYHG7Vc6myzRw==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/plugin-blit": "^0.16.2", + "@jimp/plugin-blur": "^0.16.2", + "@jimp/plugin-circle": "^0.16.2", + "@jimp/plugin-color": "^0.16.2", + "@jimp/plugin-contain": "^0.16.2", + "@jimp/plugin-cover": "^0.16.2", + "@jimp/plugin-crop": "^0.16.2", + "@jimp/plugin-displace": "^0.16.2", + "@jimp/plugin-dither": "^0.16.2", + "@jimp/plugin-fisheye": "^0.16.2", + "@jimp/plugin-flip": "^0.16.2", + "@jimp/plugin-gaussian": "^0.16.2", + "@jimp/plugin-invert": "^0.16.2", + "@jimp/plugin-mask": "^0.16.2", + "@jimp/plugin-normalize": "^0.16.2", + "@jimp/plugin-print": "^0.16.2", + "@jimp/plugin-resize": "^0.16.2", + "@jimp/plugin-rotate": "^0.16.2", + "@jimp/plugin-scale": "^0.16.2", + "@jimp/plugin-shadow": "^0.16.2", + "@jimp/plugin-threshold": "^0.16.2", + "timm": "^1.6.1" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } + }, + "node_modules/@jimp/png": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/png/-/png-0.16.2.tgz", + "integrity": "sha512-sFOtOSz/tzDwXEChFQ/Nxe+0+vG3Tj0eUxnZVDUG/StXE9dI8Bqmwj3MIa0EgK5s+QG3YlnDOmlPUa4JqmeYeQ==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2", + "pngjs": "^3.3.3" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } + }, + "node_modules/@jimp/tiff": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/tiff/-/tiff-0.16.2.tgz", + "integrity": "sha512-ADcdqmtZF+U2YoaaHTzFX8D6NFpmN4WZUT0BPMerEuY7Cq8QoLYU22z2h034FrVW+Rbi1b3y04sB9iDiQAlf2w==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "utif": "^2.0.1" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } + }, + "node_modules/@jimp/types": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/types/-/types-0.16.2.tgz", + "integrity": "sha512-0Ue5Sq0XnDF6TirisWv5E+8uOnRcd8vRLuwocJOhF76NIlcQrz+5r2k2XWKcr3d+11n28dHLXW5TKSqrUopxhA==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/bmp": "^0.16.2", + "@jimp/gif": "^0.16.2", + "@jimp/jpeg": "^0.16.2", + "@jimp/png": "^0.16.2", + "@jimp/tiff": "^0.16.2", + "timm": "^1.6.1" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } + }, + "node_modules/@jimp/utils": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.16.2.tgz", + "integrity": "sha512-XENrPvmigiXZQ8E2nxJqO6UVvWBLzbNwyYi3Y8Q1IECoYhYI3kgOQ0fmy4G269Vz1V0omh1bNmC42r4OfXg1Jg==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "regenerator-runtime": "^0.13.3" + } + }, + "node_modules/@types/node": { + "version": "16.9.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.1.tgz", + "integrity": "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==" + }, + "node_modules/any-base": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz", + "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bmp-js": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz", + "integrity": "sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw==" + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-equal": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", + "integrity": "sha512-RgSV6InVQ9ODPdLWJ5UAqBqJBOg370Nz6ZQtRzpt6nUjc8v0St97uJ4PYC6NztqIScrAXafKM3mZPMygSe1ggA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dom-walk": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", + "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" + }, + "node_modules/exif-parser": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz", + "integrity": "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw==" + }, + "node_modules/file-type": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-9.0.0.tgz", + "integrity": "sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/gifwrap": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.9.4.tgz", + "integrity": "sha512-MDMwbhASQuVeD4JKd1fKgNgCRL3fGqMM4WaqpNhWO0JiMOAjbQdumbs4BbBZEy9/M00EHEjKN3HieVhCUlwjeQ==", + "dependencies": { + "image-q": "^4.0.0", + "omggif": "^1.0.10" + } + }, + "node_modules/global": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", + "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "dependencies": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/image-q": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/image-q/-/image-q-4.0.0.tgz", + "integrity": "sha512-PfJGVgIfKQJuq3s0tTDOKtztksibuUEbJQIYT3by6wctQo+Rdlh7ef4evJ5NCdxY4CfMbvFkocEwbl4BF8RlJw==", + "dependencies": { + "@types/node": "16.9.1" + } + }, + "node_modules/is-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", + "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==" + }, + "node_modules/jimp": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/jimp/-/jimp-0.16.2.tgz", + "integrity": "sha512-UpItBk81a92f8oEyoGYbO3YK4QcM0hoIyuGHmShoF9Ov63P5Qo7Q/X2xsAgnODmSuDJFOtrPtJd5GSWW4LKdOQ==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "@jimp/custom": "^0.16.2", + "@jimp/plugins": "^0.16.2", + "@jimp/types": "^0.16.2", + "regenerator-runtime": "^0.13.3" + } + }, + "node_modules/jpeg-js": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz", + "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==" + }, + "node_modules/load-bmfont": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.1.tgz", + "integrity": "sha512-8UyQoYmdRDy81Brz6aLAUhfZLwr5zV0L3taTQ4hju7m6biuwiWiJXjPhBJxbUQJA8PrkvJ/7Enqmwk2sM14soA==", + "dependencies": { + "buffer-equal": "0.0.1", + "mime": "^1.3.4", + "parse-bmfont-ascii": "^1.0.3", + "parse-bmfont-binary": "^1.0.5", + "parse-bmfont-xml": "^1.1.4", + "phin": "^2.9.1", + "xhr": "^2.0.1", + "xtend": "^4.0.0" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/min-document": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", + "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", + "dependencies": { + "dom-walk": "^0.1.0" + } + }, + "node_modules/minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/omggif": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz", + "integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==" + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, + "node_modules/parse-bmfont-ascii": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz", + "integrity": "sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA==" + }, + "node_modules/parse-bmfont-binary": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz", + "integrity": "sha512-GxmsRea0wdGdYthjuUeWTMWPqm2+FAd4GI8vCvhgJsFnoGhTrLhXDDupwTo7rXVAgaLIGoVHDZS9p/5XbSqeWA==" + }, + "node_modules/parse-bmfont-xml": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/parse-bmfont-xml/-/parse-bmfont-xml-1.1.4.tgz", + "integrity": "sha512-bjnliEOmGv3y1aMEfREMBJ9tfL3WR0i0CKPj61DnSLaoxWR3nLrsQrEbCId/8rF4NyRF0cCqisSVXyQYWM+mCQ==", + "dependencies": { + "xml-parse-from-string": "^1.0.0", + "xml2js": "^0.4.5" + } + }, + "node_modules/parse-headers": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz", + "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==" + }, + "node_modules/phin": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/phin/-/phin-2.9.3.tgz", + "integrity": "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==" + }, + "node_modules/pixelmatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-4.0.2.tgz", + "integrity": "sha512-J8B6xqiO37sU/gkcMglv6h5Jbd9xNER7aHzpfRdNmV4IbQBzBpe4l9XmbG+xPF/znacgu2jfEw+wHffaq/YkXA==", + "dependencies": { + "pngjs": "^3.0.0" + }, + "bin": { + "pixelmatch": "bin/pixelmatch" + } + }, + "node_modules/pngjs": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", + "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "node_modules/timm": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/timm/-/timm-1.7.1.tgz", + "integrity": "sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw==" + }, + "node_modules/tinycolor2": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.2.tgz", + "integrity": "sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==", + "engines": { + "node": "*" + } + }, + "node_modules/utif": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/utif/-/utif-2.0.1.tgz", + "integrity": "sha512-Z/S1fNKCicQTf375lIP9G8Sa1H/phcysstNrrSdZKj1f9g58J4NMgb5IgiEZN9/nLMPDwF0W7hdOe9Qq2IYoLg==", + "dependencies": { + "pako": "^1.0.5" + } + }, + "node_modules/xhr": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", + "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", + "dependencies": { + "global": "~4.4.0", + "is-function": "^1.0.1", + "parse-headers": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/xml-parse-from-string": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz", + "integrity": "sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g==" + }, + "node_modules/xml2js": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", + "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + } + }, + "dependencies": { + "@babel/runtime": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.1.tgz", + "integrity": "sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==", + "requires": { + "regenerator-runtime": "^0.13.10" + } + }, + "@jimp/bmp": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.16.2.tgz", + "integrity": "sha512-4g9vW45QfMoGhLVvaFj26h4e7cC+McHUQwyFQmNTLW4FfC1OonN9oUr2m/FEDGkTYKR7aqdXR5XUqqIkHWLaFw==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2", + "bmp-js": "^0.1.0" + } + }, + "@jimp/core": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/core/-/core-0.16.2.tgz", + "integrity": "sha512-dp7HcyUMzjXphXYodI6PaXue+I9PXAavbb+AN+1XqFbotN22Z12DosNPEyy+UhLY/hZiQQqUkEaJHkvV31rs+w==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2", + "any-base": "^1.1.0", + "buffer": "^5.2.0", + "exif-parser": "^0.1.12", + "file-type": "^9.0.0", + "load-bmfont": "^1.3.1", + "mkdirp": "^0.5.1", + "phin": "^2.9.1", + "pixelmatch": "^4.0.2", + "tinycolor2": "^1.4.1" + } + }, + "@jimp/custom": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.16.2.tgz", + "integrity": "sha512-GtNwOs4hcVS2GIbqRUf42rUuX07oLB92cj7cqxZb0ZGWwcwhnmSW0TFLAkNafXmqn9ug4VTpNvcJSUdiuECVKg==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/core": "^0.16.2" + } + }, + "@jimp/gif": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/gif/-/gif-0.16.2.tgz", + "integrity": "sha512-TMdyT9Q0paIKNtT7c5KzQD29CNCsI/t8ka28jMrBjEK7j5RRTvBfuoOnHv7pDJRCjCIqeUoaUSJ7QcciKic6CA==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2", + "gifwrap": "^0.9.2", + "omggif": "^1.0.9" + } + }, + "@jimp/jpeg": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.16.2.tgz", + "integrity": "sha512-BW5gZydgq6wdIwHd+3iUNgrTklvoQc/FUKSj9meM6A0FU21lUaansRX5BDdJqHkyXJLnnlDGwDt27J+hQuBAVw==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2", + "jpeg-js": "^0.4.2" + } + }, + "@jimp/plugin-blit": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-0.16.2.tgz", + "integrity": "sha512-Z31rRfV80gC/r+B/bOPSVVpJEWXUV248j7MdnMOFLu4vr8DMqXVo9jYqvwU/s4LSTMAMXqm4Jg6E/jQfadPKAg==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + } + }, + "@jimp/plugin-blur": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-0.16.2.tgz", + "integrity": "sha512-ShkJCAzRI+1fAKPuLLgEkixpSpVmKTYaKEFROUcgmrv9AansDXGNCupchqVMTdxf8zPyW8rR1ilvG3OJobufLQ==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + } + }, + "@jimp/plugin-circle": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-circle/-/plugin-circle-0.16.2.tgz", + "integrity": "sha512-6T4z/48F4Z5+YwAVCLOvXQcyGmo0E3WztxCz6XGQf66r4JJK78+zcCDYZFLMx0BGM0091FogNK4QniP8JaOkrA==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + } + }, + "@jimp/plugin-color": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-0.16.2.tgz", + "integrity": "sha512-6oBV0g0J17/7E+aTquvUsgSc85nUbUi+64tIK5eFIDzvjhlqhjGNJYlc46KJMCWIs61qRJayQoZdL/iT/iQuGQ==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2", + "tinycolor2": "^1.4.1" + } + }, + "@jimp/plugin-contain": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-0.16.2.tgz", + "integrity": "sha512-pLcxO3hVN3LCEhMNvpZ9B7xILHVlS433Vv16zFFJxLRqZdYvPLsc+ZzJhjAiHHuEjVblQrktHE3LGeQwGJPo0w==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + } + }, + "@jimp/plugin-cover": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-0.16.2.tgz", + "integrity": "sha512-gzWM7VvYeI8msyiwbUZxH+sGQEgO6Vd6adGxZ0CeKX00uQOe5lDzxb1Wjx7sHcJGz8a/5fmAuwz7rdDtpDUbkw==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + } + }, + "@jimp/plugin-crop": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-0.16.2.tgz", + "integrity": "sha512-qCd3hfMEE+Z2EuuyXewgXRTtKJGIerWzc1zLEJztsUkPz5i73IGgkOL+mrNutZwGaXZbm+8SwUaGb46sxAO6Tw==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + } + }, + "@jimp/plugin-displace": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-0.16.2.tgz", + "integrity": "sha512-6nXdvNNjCdD95v2o3/jPeur903dz08lG4Y8gmr5oL2yVv9LSSbMonoXYrR/ASesdyXqGdXJLU4NL+yZs4zUqbQ==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + } + }, + "@jimp/plugin-dither": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-0.16.2.tgz", + "integrity": "sha512-DERpIzy21ZanMkVsD0Tdy8HQLbD1E41OuvIzaMRoW4183PA6AgGNlrQoFTyXmzjy6FTy1SxaQgTEdouInAWZ9Q==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + } + }, + "@jimp/plugin-fisheye": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-fisheye/-/plugin-fisheye-0.16.2.tgz", + "integrity": "sha512-Df7PsGIwiIpQu3EygYCnaJyTfOwvwtYV3cmYJS7yFLtdiFUuod+hlSo5GkwEPLAy+QBxhUbDuUqnsWo4NQtbiQ==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + } + }, + "@jimp/plugin-flip": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-0.16.2.tgz", + "integrity": "sha512-+2uC8ioVQUr06mnjSWraskz2L33nJHze35LkQ8ZNsIpoZLkgvfiWatqAs5bj+1jGI/9kxoCFAaT1Is0f+a4/rw==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + } + }, + "@jimp/plugin-gaussian": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-gaussian/-/plugin-gaussian-0.16.2.tgz", + "integrity": "sha512-2mnuDSg4ZEH8zcJig7DZZf4st/cYmQ5UYJKP76iGhZ+6JDACk6uejwAgT5xHecNhkVAaXMdCybA2eknH/9OE1w==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + } + }, + "@jimp/plugin-invert": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-invert/-/plugin-invert-0.16.2.tgz", + "integrity": "sha512-xFvHbVepTY/nus+6yXiYN1iq+UBRkT0MdnObbiQPstUrAsz0Imn6MWISsnAyMvcNxHGrxaxjuU777JT/esM0gg==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + } + }, + "@jimp/plugin-mask": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-0.16.2.tgz", + "integrity": "sha512-AbdO85xxhfgEDdxYKpUotEI9ixiCMaIpfYHD5a5O/VWeimz2kuwhcrzlHGiyq1kKAgRcl0WEneTCZAHVSyvPKA==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + } + }, + "@jimp/plugin-normalize": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-normalize/-/plugin-normalize-0.16.2.tgz", + "integrity": "sha512-+ItBWFwmB0Od7OfOtTYT1gm543PpHUgU8/DN55z83l1JqS0OomDJAe7BmCppo2405TN6YtVm/csXo7p4iWd/SQ==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + } + }, + "@jimp/plugin-print": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-0.16.2.tgz", + "integrity": "sha512-ifTGEeJ5UZTCiqC70HMeU3iXk/vsOmhWiwVGOXSFXhFeE8ZpDWvlmBsrMYnRrJGuaaogHOIrrQPI+kCdDBSBIQ==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2", + "load-bmfont": "^1.4.0" + } + }, + "@jimp/plugin-resize": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-0.16.2.tgz", + "integrity": "sha512-gE4N9l6xuwzacFZ2EPCGZCJ/xR+aX2V7GdMndIl/6kYIw5/eib1SFuF9AZLvIPSFuE1FnGo8+vT0pr++SSbhYg==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + } + }, + "@jimp/plugin-rotate": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-0.16.2.tgz", + "integrity": "sha512-/CTEYkR1HrgmnE0VqPhhbBARbDAfFX590LWGIpxcYIYsUUGQCadl+8Qo4UX13FH0Nt8UHEtPA+O2x08uPYg9UA==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + } + }, + "@jimp/plugin-scale": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-scale/-/plugin-scale-0.16.2.tgz", + "integrity": "sha512-3inuxfrlquyLaqFdiiiQNJUurR0WbvN5wAf1qcYX2LubG1AG8grayYD6H7XVoxfUGTZXh1kpmeirEYlqA2zxcw==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + } + }, + "@jimp/plugin-shadow": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-shadow/-/plugin-shadow-0.16.2.tgz", + "integrity": "sha512-Q0aIs2/L6fWMcEh9Ms73u34bT1hyUMw/oxaVoIzOLo6/E8YzCs2Bi63H0/qaPS0MQpEppI++kvosPbblABY79w==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + } + }, + "@jimp/plugin-threshold": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugin-threshold/-/plugin-threshold-0.16.2.tgz", + "integrity": "sha512-gyOwmBgjtMPvcuyOhkP6dOGWbQdaTfhcBRN22mYeI/k/Wh/Zh1OI21F6eKLApsVRmg15MoFnkrCz64RROC34sw==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2" + } + }, + "@jimp/plugins": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/plugins/-/plugins-0.16.2.tgz", + "integrity": "sha512-zCvYtCgctmC0tkYEu+y+kSwSIZBsNznqJ3/3vkpzxdyjd6wCfNY5Qc/68MPrLc1lmdeGo4cOOTYHG7Vc6myzRw==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/plugin-blit": "^0.16.2", + "@jimp/plugin-blur": "^0.16.2", + "@jimp/plugin-circle": "^0.16.2", + "@jimp/plugin-color": "^0.16.2", + "@jimp/plugin-contain": "^0.16.2", + "@jimp/plugin-cover": "^0.16.2", + "@jimp/plugin-crop": "^0.16.2", + "@jimp/plugin-displace": "^0.16.2", + "@jimp/plugin-dither": "^0.16.2", + "@jimp/plugin-fisheye": "^0.16.2", + "@jimp/plugin-flip": "^0.16.2", + "@jimp/plugin-gaussian": "^0.16.2", + "@jimp/plugin-invert": "^0.16.2", + "@jimp/plugin-mask": "^0.16.2", + "@jimp/plugin-normalize": "^0.16.2", + "@jimp/plugin-print": "^0.16.2", + "@jimp/plugin-resize": "^0.16.2", + "@jimp/plugin-rotate": "^0.16.2", + "@jimp/plugin-scale": "^0.16.2", + "@jimp/plugin-shadow": "^0.16.2", + "@jimp/plugin-threshold": "^0.16.2", + "timm": "^1.6.1" + } + }, + "@jimp/png": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/png/-/png-0.16.2.tgz", + "integrity": "sha512-sFOtOSz/tzDwXEChFQ/Nxe+0+vG3Tj0eUxnZVDUG/StXE9dI8Bqmwj3MIa0EgK5s+QG3YlnDOmlPUa4JqmeYeQ==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.2", + "pngjs": "^3.3.3" + } + }, + "@jimp/tiff": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/tiff/-/tiff-0.16.2.tgz", + "integrity": "sha512-ADcdqmtZF+U2YoaaHTzFX8D6NFpmN4WZUT0BPMerEuY7Cq8QoLYU22z2h034FrVW+Rbi1b3y04sB9iDiQAlf2w==", + "requires": { + "@babel/runtime": "^7.7.2", + "utif": "^2.0.1" + } + }, + "@jimp/types": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/types/-/types-0.16.2.tgz", + "integrity": "sha512-0Ue5Sq0XnDF6TirisWv5E+8uOnRcd8vRLuwocJOhF76NIlcQrz+5r2k2XWKcr3d+11n28dHLXW5TKSqrUopxhA==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/bmp": "^0.16.2", + "@jimp/gif": "^0.16.2", + "@jimp/jpeg": "^0.16.2", + "@jimp/png": "^0.16.2", + "@jimp/tiff": "^0.16.2", + "timm": "^1.6.1" + } + }, + "@jimp/utils": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.16.2.tgz", + "integrity": "sha512-XENrPvmigiXZQ8E2nxJqO6UVvWBLzbNwyYi3Y8Q1IECoYhYI3kgOQ0fmy4G269Vz1V0omh1bNmC42r4OfXg1Jg==", + "requires": { + "@babel/runtime": "^7.7.2", + "regenerator-runtime": "^0.13.3" + } + }, + "@types/node": { + "version": "16.9.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.1.tgz", + "integrity": "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==" + }, + "any-base": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz", + "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==" + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "bmp-js": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz", + "integrity": "sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw==" + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-equal": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", + "integrity": "sha512-RgSV6InVQ9ODPdLWJ5UAqBqJBOg370Nz6ZQtRzpt6nUjc8v0St97uJ4PYC6NztqIScrAXafKM3mZPMygSe1ggA==" + }, + "dom-walk": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", + "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" + }, + "exif-parser": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz", + "integrity": "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw==" + }, + "file-type": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-9.0.0.tgz", + "integrity": "sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw==" + }, + "gifwrap": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.9.4.tgz", + "integrity": "sha512-MDMwbhASQuVeD4JKd1fKgNgCRL3fGqMM4WaqpNhWO0JiMOAjbQdumbs4BbBZEy9/M00EHEjKN3HieVhCUlwjeQ==", + "requires": { + "image-q": "^4.0.0", + "omggif": "^1.0.10" + } + }, + "global": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", + "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "requires": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "image-q": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/image-q/-/image-q-4.0.0.tgz", + "integrity": "sha512-PfJGVgIfKQJuq3s0tTDOKtztksibuUEbJQIYT3by6wctQo+Rdlh7ef4evJ5NCdxY4CfMbvFkocEwbl4BF8RlJw==", + "requires": { + "@types/node": "16.9.1" + } + }, + "is-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", + "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==" + }, + "jimp": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/jimp/-/jimp-0.16.2.tgz", + "integrity": "sha512-UpItBk81a92f8oEyoGYbO3YK4QcM0hoIyuGHmShoF9Ov63P5Qo7Q/X2xsAgnODmSuDJFOtrPtJd5GSWW4LKdOQ==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/custom": "^0.16.2", + "@jimp/plugins": "^0.16.2", + "@jimp/types": "^0.16.2", + "regenerator-runtime": "^0.13.3" + } + }, + "jpeg-js": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz", + "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==" + }, + "load-bmfont": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.1.tgz", + "integrity": "sha512-8UyQoYmdRDy81Brz6aLAUhfZLwr5zV0L3taTQ4hju7m6biuwiWiJXjPhBJxbUQJA8PrkvJ/7Enqmwk2sM14soA==", + "requires": { + "buffer-equal": "0.0.1", + "mime": "^1.3.4", + "parse-bmfont-ascii": "^1.0.3", + "parse-bmfont-binary": "^1.0.5", + "parse-bmfont-xml": "^1.1.4", + "phin": "^2.9.1", + "xhr": "^2.0.1", + "xtend": "^4.0.0" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "min-document": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", + "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", + "requires": { + "dom-walk": "^0.1.0" + } + }, + "minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==" + }, + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "requires": { + "minimist": "^1.2.6" + } + }, + "omggif": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz", + "integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==" + }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, + "parse-bmfont-ascii": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz", + "integrity": "sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA==" + }, + "parse-bmfont-binary": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz", + "integrity": "sha512-GxmsRea0wdGdYthjuUeWTMWPqm2+FAd4GI8vCvhgJsFnoGhTrLhXDDupwTo7rXVAgaLIGoVHDZS9p/5XbSqeWA==" + }, + "parse-bmfont-xml": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/parse-bmfont-xml/-/parse-bmfont-xml-1.1.4.tgz", + "integrity": "sha512-bjnliEOmGv3y1aMEfREMBJ9tfL3WR0i0CKPj61DnSLaoxWR3nLrsQrEbCId/8rF4NyRF0cCqisSVXyQYWM+mCQ==", + "requires": { + "xml-parse-from-string": "^1.0.0", + "xml2js": "^0.4.5" + } + }, + "parse-headers": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz", + "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==" + }, + "phin": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/phin/-/phin-2.9.3.tgz", + "integrity": "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==" + }, + "pixelmatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-4.0.2.tgz", + "integrity": "sha512-J8B6xqiO37sU/gkcMglv6h5Jbd9xNER7aHzpfRdNmV4IbQBzBpe4l9XmbG+xPF/znacgu2jfEw+wHffaq/YkXA==", + "requires": { + "pngjs": "^3.0.0" + } + }, + "pngjs": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", + "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==" + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==" + }, + "regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "timm": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/timm/-/timm-1.7.1.tgz", + "integrity": "sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw==" + }, + "tinycolor2": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.2.tgz", + "integrity": "sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==" + }, + "utif": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/utif/-/utif-2.0.1.tgz", + "integrity": "sha512-Z/S1fNKCicQTf375lIP9G8Sa1H/phcysstNrrSdZKj1f9g58J4NMgb5IgiEZN9/nLMPDwF0W7hdOe9Qq2IYoLg==", + "requires": { + "pako": "^1.0.5" + } + }, + "xhr": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", + "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", + "requires": { + "global": "~4.4.0", + "is-function": "^1.0.1", + "parse-headers": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "xml-parse-from-string": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz", + "integrity": "sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g==" + }, + "xml2js": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", + "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + } + }, + "xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..cb9010d --- /dev/null +++ b/package.json @@ -0,0 +1,6 @@ +{ + "type": "module", + "dependencies": { + "jimp": "^0.16.2" + } +}