├── .gitignore ├── src ├── math.js ├── index.js ├── define.js ├── cubehelix.js ├── lab.js └── color.js ├── .eslintrc.json ├── test ├── .eslintrc.json ├── cubehelix-test.js ├── gray-test.js ├── lch-test.js ├── asserts.js ├── color-test.js ├── lab-test.js ├── hcl-test.js ├── rgb-test.js └── hsl-test.js ├── .github ├── eslint.json └── workflows │ └── node.js.yml ├── README.md ├── LICENSE ├── rollup.config.js ├── package.json └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | *.sublime-workspace 2 | .DS_Store 3 | dist/ 4 | node_modules 5 | npm-debug.log 6 | -------------------------------------------------------------------------------- /src/math.js: -------------------------------------------------------------------------------- 1 | export const radians = Math.PI / 180; 2 | export const degrees = 180 / Math.PI; 3 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | export {default as color, rgb, hsl} from "./color.js"; 2 | export {default as lab, hcl, lch, gray} from "./lab.js"; 3 | export {default as cubehelix} from "./cubehelix.js"; 4 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "eslint:recommended", 3 | "parserOptions": { 4 | "sourceType": "module", 5 | "ecmaVersion": 8 6 | }, 7 | "rules": { 8 | "no-cond-assign": 0 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "eslint:recommended", 3 | "parserOptions": { 4 | "sourceType": "module", 5 | "ecmaVersion": 8 6 | }, 7 | "rules": { 8 | "no-cond-assign": 0 9 | }, 10 | "env": { 11 | "mocha": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/cubehelix-test.js: -------------------------------------------------------------------------------- 1 | import assert from "assert"; 2 | import {color, cubehelix} from "../src/index.js"; 3 | 4 | it("cubehelix(…) returns an instance of cubehelix and color", () => { 5 | const c = cubehelix("steelblue"); 6 | assert(c instanceof cubehelix); 7 | assert(c instanceof color); 8 | }); 9 | -------------------------------------------------------------------------------- /src/define.js: -------------------------------------------------------------------------------- 1 | export default function(constructor, factory, prototype) { 2 | constructor.prototype = factory.prototype = prototype; 3 | prototype.constructor = constructor; 4 | } 5 | 6 | export function extend(parent, definition) { 7 | var prototype = Object.create(parent.prototype); 8 | for (var key in definition) prototype[key] = definition[key]; 9 | return prototype; 10 | } 11 | -------------------------------------------------------------------------------- /test/gray-test.js: -------------------------------------------------------------------------------- 1 | import {assertLabEqual} from "./asserts.js"; 2 | import {gray} from "../src/index.js"; 3 | 4 | it("gray(l[, opacity]) is an alias for lab(l, 0, 0[, opacity])", () => { 5 | assertLabEqual(gray(120), 120, 0, 0, 1); 6 | assertLabEqual(gray(120, 0.5), 120, 0, 0, 0.5); 7 | assertLabEqual(gray(120, null), 120, 0, 0, 1); 8 | assertLabEqual(gray(120, undefined), 120, 0, 0, 1); 9 | }); 10 | -------------------------------------------------------------------------------- /.github/eslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "problemMatcher": [ 3 | { 4 | "owner": "eslint-compact", 5 | "pattern": [ 6 | { 7 | "regexp": "^(.+):\\sline\\s(\\d+),\\scol\\s(\\d+),\\s(Error|Warning|Info)\\s-\\s(.+)\\s\\((.+)\\)$", 8 | "file": 1, 9 | "line": 2, 10 | "column": 3, 11 | "severity": 4, 12 | "message": 5, 13 | "code": 6 14 | } 15 | ] 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # d3-color 2 | 3 | 4 | 5 | Even though your browser understands a lot about colors, it doesn’t offer much help in manipulating colors through JavaScript. The d3-color module therefore provides representations for various color spaces, allowing specification, conversion and manipulation. (Also see [d3-interpolate](https://github.com/d3/d3-interpolate) for color interpolation.) 6 | 7 | ## Resources 8 | 9 | - [Documentation](https://d3js.org/d3-color) 10 | - [Examples](https://observablehq.com/collection/@d3/d3-color) 11 | - [Releases](https://github.com/d3/d3-color/releases) 12 | - [Getting help](https://d3js.org/community) 13 | -------------------------------------------------------------------------------- /test/lch-test.js: -------------------------------------------------------------------------------- 1 | import {lch, rgb} from "../src/index.js"; 2 | import {assertHclEqual} from "./asserts.js"; 3 | 4 | it("lch(color) is equivalent to hcl(color)", () => { 5 | assertHclEqual(lch("#abc"), 252.37145234745182, 11.223567114593477, 74.96879980931759, 1); 6 | assertHclEqual(lch(rgb("#abc")), 252.37145234745182, 11.223567114593477, 74.96879980931759, 1); 7 | }); 8 | 9 | it("lch(l, c, h[, opacity]) is equivalent to hcl(h, c, l[, opacity])", () => { 10 | assertHclEqual(lch(74, 11, 252), 252, 11, 74, 1); 11 | assertHclEqual(lch(74, 11, 252), 252, 11, 74, 1); 12 | assertHclEqual(lch(74, 11, 252, null), 252, 11, 74, 1); 13 | assertHclEqual(lch(74, 11, 252, undefined), 252, 11, 74, 1); 14 | assertHclEqual(lch(74, 11, 252, 0.5), 252, 11, 74, 0.5); 15 | }); 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2010-2022 Mike Bostock 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any purpose 4 | with or without fee is hereby granted, provided that the above copyright notice 5 | and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 8 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 9 | FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 10 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 11 | OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 12 | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 13 | THIS SOFTWARE. 14 | -------------------------------------------------------------------------------- /.github/workflows/node.js.yml: -------------------------------------------------------------------------------- 1 | # https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 2 | 3 | name: Node.js CI 4 | 5 | on: 6 | push: 7 | branches: [ main ] 8 | pull_request: 9 | branches: [ main ] 10 | 11 | jobs: 12 | build: 13 | 14 | runs-on: ubuntu-latest 15 | 16 | strategy: 17 | matrix: 18 | node-version: [14.x] 19 | 20 | steps: 21 | - uses: actions/checkout@v2 22 | - name: Use Node.js ${{ matrix.node-version }} 23 | uses: actions/setup-node@v1 24 | with: 25 | node-version: ${{ matrix.node-version }} 26 | - run: yarn --frozen-lockfile 27 | - run: | 28 | echo ::add-matcher::.github/eslint.json 29 | yarn run eslint src test --format=compact 30 | - run: yarn test 31 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import {readFileSync} from "fs"; 2 | import {terser} from "rollup-plugin-terser"; 3 | import * as meta from "./package.json"; 4 | 5 | // Extract copyrights from the LICENSE. 6 | const copyright = readFileSync("./LICENSE", "utf-8") 7 | .split(/\n/g) 8 | .filter(line => /^Copyright\s+/.test(line)) 9 | .map(line => line.replace(/^Copyright\s+/, "")) 10 | .join(", "); 11 | 12 | const config = { 13 | input: "src/index.js", 14 | external: Object.keys(meta.dependencies || {}).filter(key => /^d3-/.test(key)), 15 | output: { 16 | file: `dist/${meta.name}.js`, 17 | name: "d3", 18 | format: "umd", 19 | indent: false, 20 | extend: true, 21 | banner: `// ${meta.homepage} v${meta.version} Copyright ${copyright}`, 22 | globals: Object.assign({}, ...Object.keys(meta.dependencies || {}).filter(key => /^d3-/.test(key)).map(key => ({[key]: "d3"}))) 23 | }, 24 | plugins: [] 25 | }; 26 | 27 | export default [ 28 | config, 29 | { 30 | ...config, 31 | output: { 32 | ...config.output, 33 | file: `dist/${meta.name}.min.js` 34 | }, 35 | plugins: [ 36 | ...config.plugins, 37 | terser({ 38 | output: { 39 | preamble: config.output.banner 40 | } 41 | }) 42 | ] 43 | } 44 | ]; 45 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "d3-color", 3 | "version": "3.1.0", 4 | "description": "Color spaces! RGB, HSL, Cubehelix, Lab and HCL (Lch).", 5 | "homepage": "https://d3js.org/d3-color/", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/d3/d3-color.git" 9 | }, 10 | "keywords": [ 11 | "d3", 12 | "d3-module", 13 | "color", 14 | "rgb", 15 | "hsl", 16 | "lab", 17 | "hcl", 18 | "lch", 19 | "cubehelix" 20 | ], 21 | "license": "ISC", 22 | "author": { 23 | "name": "Mike Bostock", 24 | "url": "http://bost.ocks.org/mike" 25 | }, 26 | "type": "module", 27 | "files": [ 28 | "dist/**/*.js", 29 | "src/**/*.js" 30 | ], 31 | "module": "src/index.js", 32 | "main": "src/index.js", 33 | "jsdelivr": "dist/d3-color.min.js", 34 | "unpkg": "dist/d3-color.min.js", 35 | "exports": { 36 | "umd": "./dist/d3-color.min.js", 37 | "default": "./src/index.js" 38 | }, 39 | "sideEffects": false, 40 | "devDependencies": { 41 | "eslint": "8", 42 | "mocha": "9", 43 | "rollup": "2", 44 | "rollup-plugin-terser": "7" 45 | }, 46 | "scripts": { 47 | "test": "mocha 'test/**/*-test.js' && eslint src test", 48 | "prepublishOnly": "rm -rf dist && yarn test && rollup -c", 49 | "postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../${npm_package_name}/dist/${npm_package_name}.js ${npm_package_name}.v${npm_package_version%%.*}.js && cp ../${npm_package_name}/dist/${npm_package_name}.min.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git add ${npm_package_name}.v${npm_package_version%%.*}.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git commit -m \"${npm_package_name} ${npm_package_version}\" && git push && cd -" 50 | }, 51 | "engines": { 52 | "node": ">=12" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/cubehelix.js: -------------------------------------------------------------------------------- 1 | import define, {extend} from "./define.js"; 2 | import {Color, rgbConvert, Rgb, darker, brighter} from "./color.js"; 3 | import {degrees, radians} from "./math.js"; 4 | 5 | var A = -0.14861, 6 | B = +1.78277, 7 | C = -0.29227, 8 | D = -0.90649, 9 | E = +1.97294, 10 | ED = E * D, 11 | EB = E * B, 12 | BC_DA = B * C - D * A; 13 | 14 | function cubehelixConvert(o) { 15 | if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity); 16 | if (!(o instanceof Rgb)) o = rgbConvert(o); 17 | var r = o.r / 255, 18 | g = o.g / 255, 19 | b = o.b / 255, 20 | l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB), 21 | bl = b - l, 22 | k = (E * (g - l) - C * bl) / D, 23 | s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1 24 | h = s ? Math.atan2(k, bl) * degrees - 120 : NaN; 25 | return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity); 26 | } 27 | 28 | export default function cubehelix(h, s, l, opacity) { 29 | return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity); 30 | } 31 | 32 | export function Cubehelix(h, s, l, opacity) { 33 | this.h = +h; 34 | this.s = +s; 35 | this.l = +l; 36 | this.opacity = +opacity; 37 | } 38 | 39 | define(Cubehelix, cubehelix, extend(Color, { 40 | brighter(k) { 41 | k = k == null ? brighter : Math.pow(brighter, k); 42 | return new Cubehelix(this.h, this.s, this.l * k, this.opacity); 43 | }, 44 | darker(k) { 45 | k = k == null ? darker : Math.pow(darker, k); 46 | return new Cubehelix(this.h, this.s, this.l * k, this.opacity); 47 | }, 48 | rgb() { 49 | var h = isNaN(this.h) ? 0 : (this.h + 120) * radians, 50 | l = +this.l, 51 | a = isNaN(this.s) ? 0 : this.s * l * (1 - l), 52 | cosh = Math.cos(h), 53 | sinh = Math.sin(h); 54 | return new Rgb( 55 | 255 * (l + a * (A * cosh + B * sinh)), 56 | 255 * (l + a * (C * cosh + D * sinh)), 57 | 255 * (l + a * (E * cosh)), 58 | this.opacity 59 | ); 60 | } 61 | })); 62 | -------------------------------------------------------------------------------- /test/asserts.js: -------------------------------------------------------------------------------- 1 | import assert from "assert"; 2 | import {hcl, hsl, lab, rgb} from "../src/index.js"; 3 | 4 | export function assertRgbEqual(actual, r, g, b, opacity) { 5 | assert(actual instanceof rgb 6 | && (isNaN(r) ? isNaN(actual.r) && actual.r !== actual.r : actual.r === r) 7 | && (isNaN(g) ? isNaN(actual.g) && actual.g !== actual.g : actual.g === g) 8 | && (isNaN(b) ? isNaN(actual.b) && actual.b !== actual.b : actual.b === b) 9 | && (isNaN(opacity) ? isNaN(actual.opacity) && actual.opacity !== actual.opacity : actual.opacity === opacity) 10 | ); 11 | } 12 | 13 | export function assertRgbApproxEqual(actual, r, g, b, opacity) { 14 | assert(actual instanceof rgb 15 | && (isNaN(r) ? isNaN(actual.r) && actual.r !== actual.r : Math.round(actual.r) === Math.round(r)) 16 | && (isNaN(g) ? isNaN(actual.g) && actual.g !== actual.g : Math.round(actual.g) === Math.round(g)) 17 | && (isNaN(b) ? isNaN(actual.b) && actual.b !== actual.b : Math.round(actual.b) === Math.round(b)) 18 | && (isNaN(opacity) ? isNaN(actual.opacity) && actual.opacity !== actual.opacity : actual.opacity === opacity) 19 | ); 20 | } 21 | export function assertHclEqual(actual, h, c, l, opacity) { 22 | assert(actual instanceof hcl 23 | && (isNaN(h) ? isNaN(actual.h) && actual.h !== actual.h : h - 1e-6 <= actual.h && actual.h <= h + 1e-6) 24 | && (isNaN(c) ? isNaN(actual.c) && actual.c !== actual.c : c - 1e-6 <= actual.c && actual.c <= c + 1e-6) 25 | && (isNaN(l) ? isNaN(actual.l) && actual.l !== actual.l : l - 1e-6 <= actual.l && actual.l <= l + 1e-6) 26 | && (isNaN(opacity) ? isNaN(actual.opacity) && actual.opacity !== actual.opacity : actual.opacity === opacity) 27 | ); 28 | } 29 | 30 | export function assertHslEqual(actual, h, s, l, opacity) { 31 | assert(actual instanceof hsl 32 | && (isNaN(h) ? isNaN(actual.h) && actual.h !== actual.h : h - 1e-6 <= actual.h && actual.h <= h + 1e-6) 33 | && (isNaN(s) ? isNaN(actual.s) && actual.s !== actual.s : s - 1e-6 <= actual.s && actual.s <= s + 1e-6) 34 | && (isNaN(l) ? isNaN(actual.l) && actual.l !== actual.l : l - 1e-6 <= actual.l && actual.l <= l + 1e-6) 35 | && (isNaN(opacity) ? isNaN(actual.opacity) && actual.opacity !== actual.opacity : actual.opacity === opacity) 36 | ); 37 | } 38 | 39 | export function assertLabEqual(actual, l, a, b, opacity) { 40 | assert(actual instanceof lab 41 | && (isNaN(l) ? isNaN(actual.l) && actual.l !== actual.l : l - 1e-6 <= actual.l && actual.l <= l + 1e-6) 42 | && (isNaN(a) ? isNaN(actual.a) && actual.a !== actual.a : a - 1e-6 <= actual.a && actual.a <= a + 1e-6) 43 | && (isNaN(b) ? isNaN(actual.b) && actual.b !== actual.b : b - 1e-6 <= actual.b && actual.b <= b + 1e-6) 44 | && (isNaN(opacity) ? isNaN(actual.opacity) && actual.opacity !== actual.opacity : actual.opacity === opacity) 45 | ); 46 | } 47 | -------------------------------------------------------------------------------- /src/lab.js: -------------------------------------------------------------------------------- 1 | import define, {extend} from "./define.js"; 2 | import {Color, rgbConvert, Rgb} from "./color.js"; 3 | import {degrees, radians} from "./math.js"; 4 | 5 | // https://observablehq.com/@mbostock/lab-and-rgb 6 | const K = 18, 7 | Xn = 0.96422, 8 | Yn = 1, 9 | Zn = 0.82521, 10 | t0 = 4 / 29, 11 | t1 = 6 / 29, 12 | t2 = 3 * t1 * t1, 13 | t3 = t1 * t1 * t1; 14 | 15 | function labConvert(o) { 16 | if (o instanceof Lab) return new Lab(o.l, o.a, o.b, o.opacity); 17 | if (o instanceof Hcl) return hcl2lab(o); 18 | if (!(o instanceof Rgb)) o = rgbConvert(o); 19 | var r = rgb2lrgb(o.r), 20 | g = rgb2lrgb(o.g), 21 | b = rgb2lrgb(o.b), 22 | y = xyz2lab((0.2225045 * r + 0.7168786 * g + 0.0606169 * b) / Yn), x, z; 23 | if (r === g && g === b) x = z = y; else { 24 | x = xyz2lab((0.4360747 * r + 0.3850649 * g + 0.1430804 * b) / Xn); 25 | z = xyz2lab((0.0139322 * r + 0.0971045 * g + 0.7141733 * b) / Zn); 26 | } 27 | return new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity); 28 | } 29 | 30 | export function gray(l, opacity) { 31 | return new Lab(l, 0, 0, opacity == null ? 1 : opacity); 32 | } 33 | 34 | export default function lab(l, a, b, opacity) { 35 | return arguments.length === 1 ? labConvert(l) : new Lab(l, a, b, opacity == null ? 1 : opacity); 36 | } 37 | 38 | export function Lab(l, a, b, opacity) { 39 | this.l = +l; 40 | this.a = +a; 41 | this.b = +b; 42 | this.opacity = +opacity; 43 | } 44 | 45 | define(Lab, lab, extend(Color, { 46 | brighter(k) { 47 | return new Lab(this.l + K * (k == null ? 1 : k), this.a, this.b, this.opacity); 48 | }, 49 | darker(k) { 50 | return new Lab(this.l - K * (k == null ? 1 : k), this.a, this.b, this.opacity); 51 | }, 52 | rgb() { 53 | var y = (this.l + 16) / 116, 54 | x = isNaN(this.a) ? y : y + this.a / 500, 55 | z = isNaN(this.b) ? y : y - this.b / 200; 56 | x = Xn * lab2xyz(x); 57 | y = Yn * lab2xyz(y); 58 | z = Zn * lab2xyz(z); 59 | return new Rgb( 60 | lrgb2rgb( 3.1338561 * x - 1.6168667 * y - 0.4906146 * z), 61 | lrgb2rgb(-0.9787684 * x + 1.9161415 * y + 0.0334540 * z), 62 | lrgb2rgb( 0.0719453 * x - 0.2289914 * y + 1.4052427 * z), 63 | this.opacity 64 | ); 65 | } 66 | })); 67 | 68 | function xyz2lab(t) { 69 | return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0; 70 | } 71 | 72 | function lab2xyz(t) { 73 | return t > t1 ? t * t * t : t2 * (t - t0); 74 | } 75 | 76 | function lrgb2rgb(x) { 77 | return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055); 78 | } 79 | 80 | function rgb2lrgb(x) { 81 | return (x /= 255) <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4); 82 | } 83 | 84 | function hclConvert(o) { 85 | if (o instanceof Hcl) return new Hcl(o.h, o.c, o.l, o.opacity); 86 | if (!(o instanceof Lab)) o = labConvert(o); 87 | if (o.a === 0 && o.b === 0) return new Hcl(NaN, 0 < o.l && o.l < 100 ? 0 : NaN, o.l, o.opacity); 88 | var h = Math.atan2(o.b, o.a) * degrees; 89 | return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l, o.opacity); 90 | } 91 | 92 | export function lch(l, c, h, opacity) { 93 | return arguments.length === 1 ? hclConvert(l) : new Hcl(h, c, l, opacity == null ? 1 : opacity); 94 | } 95 | 96 | export function hcl(h, c, l, opacity) { 97 | return arguments.length === 1 ? hclConvert(h) : new Hcl(h, c, l, opacity == null ? 1 : opacity); 98 | } 99 | 100 | export function Hcl(h, c, l, opacity) { 101 | this.h = +h; 102 | this.c = +c; 103 | this.l = +l; 104 | this.opacity = +opacity; 105 | } 106 | 107 | function hcl2lab(o) { 108 | if (isNaN(o.h)) return new Lab(o.l, 0, 0, o.opacity); 109 | var h = o.h * radians; 110 | return new Lab(o.l, Math.cos(h) * o.c, Math.sin(h) * o.c, o.opacity); 111 | } 112 | 113 | define(Hcl, hcl, extend(Color, { 114 | brighter(k) { 115 | return new Hcl(this.h, this.c, this.l + K * (k == null ? 1 : k), this.opacity); 116 | }, 117 | darker(k) { 118 | return new Hcl(this.h, this.c, this.l - K * (k == null ? 1 : k), this.opacity); 119 | }, 120 | rgb() { 121 | return hcl2lab(this).rgb(); 122 | } 123 | })); 124 | -------------------------------------------------------------------------------- /test/color-test.js: -------------------------------------------------------------------------------- 1 | import assert from "assert"; 2 | import {color} from "../src/index.js"; 3 | import {assertHslEqual, assertRgbApproxEqual, assertRgbEqual} from "./asserts.js"; 4 | 5 | it("color(format) parses CSS color names (e.g., \"rebeccapurple\")", () => { 6 | assertRgbApproxEqual(color("moccasin"), 255, 228, 181, 1); 7 | assertRgbApproxEqual(color("aliceblue"), 240, 248, 255, 1); 8 | assertRgbApproxEqual(color("yellow"), 255, 255, 0, 1); 9 | assertRgbApproxEqual(color("moccasin"), 255, 228, 181, 1); 10 | assertRgbApproxEqual(color("aliceblue"), 240, 248, 255, 1); 11 | assertRgbApproxEqual(color("yellow"), 255, 255, 0, 1); 12 | assertRgbApproxEqual(color("rebeccapurple"), 102, 51, 153, 1); 13 | assertRgbApproxEqual(color("transparent"), NaN, NaN, NaN, 0); 14 | }); 15 | 16 | it("color(format) parses 6-digit hexadecimal (e.g., \"#abcdef\")", () => { 17 | assertRgbApproxEqual(color("#abcdef"), 171, 205, 239, 1); 18 | }); 19 | 20 | it("color(format) parses 3-digit hexadecimal (e.g., \"#abc\")", () => { 21 | assertRgbApproxEqual(color("#abc"), 170, 187, 204, 1); 22 | }); 23 | 24 | it("color(format) does not parse 7-digit hexadecimal (e.g., \"#abcdef3\")", () => { 25 | assert.strictEqual(color("#abcdef3"), null); 26 | }); 27 | 28 | it("color(format) parses 8-digit hexadecimal (e.g., \"#abcdef33\")", () => { 29 | assertRgbApproxEqual(color("#abcdef33"), 171, 205, 239, 0.2); 30 | }); 31 | 32 | it("color(format) parses 4-digit hexadecimal (e.g., \"#abc3\")", () => { 33 | assertRgbApproxEqual(color("#abc3"), 170, 187, 204, 0.2); 34 | }); 35 | 36 | it("color(format) parses RGB integer format (e.g., \"rgb(12,34,56)\")", () => { 37 | assertRgbApproxEqual(color("rgb(12,34,56)"), 12, 34, 56, 1); 38 | }); 39 | 40 | it("color(format) parses RGBA integer format (e.g., \"rgba(12,34,56,0.4)\")", () => { 41 | assertRgbApproxEqual(color("rgba(12,34,56,0.4)"), 12, 34, 56, 0.4); 42 | }); 43 | 44 | it("color(format) parses RGB percentage format (e.g., \"rgb(12%,34%,56%)\")", () => { 45 | assertRgbApproxEqual(color("rgb(12%,34%,56%)"), 31, 87, 143, 1); 46 | assertRgbEqual(color("rgb(100%,100%,100%)"), 255, 255, 255, 1); 47 | }); 48 | 49 | it("color(format) parses RGBA percentage format (e.g., \"rgba(12%,34%,56%,0.4)\")", () => { 50 | assertRgbApproxEqual(color("rgba(12%,34%,56%,0.4)"), 31, 87, 143, 0.4); 51 | assertRgbEqual(color("rgba(100%,100%,100%,0.4)"), 255, 255, 255, 0.4); 52 | }); 53 | 54 | it("color(format) parses HSL format (e.g., \"hsl(60,100%,20%)\")", () => { 55 | assertHslEqual(color("hsl(60,100%,20%)"), 60, 1, 0.2, 1); 56 | }); 57 | 58 | it("color(format) parses HSLA format (e.g., \"hsla(60,100%,20%,0.4)\")", () => { 59 | assertHslEqual(color("hsla(60,100%,20%,0.4)"), 60, 1, 0.2, 0.4); 60 | }); 61 | 62 | it("color(format) ignores leading and trailing whitespace", () => { 63 | assertRgbApproxEqual(color(" aliceblue\t\n"), 240, 248, 255, 1); 64 | assertRgbApproxEqual(color(" #abc\t\n"), 170, 187, 204, 1); 65 | assertRgbApproxEqual(color(" #aabbcc\t\n"), 170, 187, 204, 1); 66 | assertRgbApproxEqual(color(" rgb(120,30,50)\t\n"), 120, 30, 50, 1); 67 | assertHslEqual(color(" hsl(120,30%,50%)\t\n"), 120, 0.3, 0.5, 1); 68 | }); 69 | 70 | it("color(format) ignores whitespace between numbers", () => { 71 | assertRgbApproxEqual(color(" rgb( 120 , 30 , 50 ) "), 120, 30, 50, 1); 72 | assertHslEqual(color(" hsl( 120 , 30% , 50% ) "), 120, 0.3, 0.5, 1); 73 | assertRgbApproxEqual(color(" rgba( 12 , 34 , 56 , 0.4 ) "), 12, 34, 56, 0.4); 74 | assertRgbApproxEqual(color(" rgba( 12% , 34% , 56% , 0.4 ) "), 31, 87, 143, 0.4); 75 | assertHslEqual(color(" hsla( 60 , 100% , 20% , 0.4 ) "), 60, 1, 0.2, 0.4); 76 | }); 77 | 78 | it("color(format) allows number signs", () => { 79 | assertRgbApproxEqual(color("rgb(+120,+30,+50)"), 120, 30, 50, 1); 80 | assertHslEqual(color("hsl(+120,+30%,+50%)"), 120, 0.3, 0.5, 1); 81 | assertRgbApproxEqual(color("rgb(-120,-30,-50)"), -120, -30, -50, 1); 82 | assertHslEqual(color("hsl(-120,-30%,-50%)"), NaN, NaN, -0.5, 1); 83 | assertRgbApproxEqual(color("rgba(12,34,56,+0.4)"), 12, 34, 56, 0.4); 84 | assertRgbApproxEqual(color("rgba(12,34,56,-0.4)"), NaN, NaN, NaN, -0.4); 85 | assertRgbApproxEqual(color("rgba(12%,34%,56%,+0.4)"), 31, 87, 143, 0.4); 86 | assertRgbApproxEqual(color("rgba(12%,34%,56%,-0.4)"), NaN, NaN, NaN, -0.4); 87 | assertHslEqual(color("hsla(60,100%,20%,+0.4)"), 60, 1, 0.2, 0.4); 88 | assertHslEqual(color("hsla(60,100%,20%,-0.4)"), NaN, NaN, NaN, -0.4); 89 | }); 90 | 91 | it("color(format) allows decimals for non-integer values", () => { 92 | assertRgbApproxEqual(color("rgb(20.0%,30.4%,51.2%)"), 51, 78, 131, 1); 93 | assertHslEqual(color("hsl(20.0,30.4%,51.2%)"), 20, 0.304, 0.512, 1); 94 | }); 95 | 96 | it("color(format) allows leading decimal for hue, opacity and percentages", () => { 97 | assertHslEqual(color("hsl(.9,.3%,.5%)"), 0.9, 0.003, 0.005, 1); 98 | assertHslEqual(color("hsla(.9,.3%,.5%,.5)"), 0.9, 0.003, 0.005, 0.5); 99 | assertRgbApproxEqual(color("rgb(.1%,.2%,.3%)"), 0, 1, 1, 1); 100 | assertRgbApproxEqual(color("rgba(120,30,50,.5)"), 120, 30, 50, 0.5); 101 | }); 102 | 103 | it("color(format) allows exponential format for hue, opacity and percentages", () => { 104 | assertHslEqual(color("hsl(1e1,2e1%,3e1%)"), 10, 0.2, 0.3, 1); 105 | assertHslEqual(color("hsla(9e-1,3e-1%,5e-1%,5e-1)"), 0.9, 0.003, 0.005, 0.5); 106 | assertRgbApproxEqual(color("rgb(1e-1%,2e-1%,3e-1%)"), 0, 1, 1, 1); 107 | assertRgbApproxEqual(color("rgba(120,30,50,1e-1)"), 120, 30, 50, 0.1); 108 | }); 109 | 110 | it("color(format) does not allow decimals for integer values", () => { 111 | assert.strictEqual(color("rgb(120.5,30,50)"), null); 112 | }); 113 | 114 | it("color(format) does not allow empty decimals", () => { 115 | assert.strictEqual(color("rgb(120.,30,50)"), null); 116 | assert.strictEqual(color("rgb(120.%,30%,50%)"), null); 117 | assert.strictEqual(color("rgba(120,30,50,1.)"), null); 118 | assert.strictEqual(color("rgba(12%,30%,50%,1.)"), null); 119 | assert.strictEqual(color("hsla(60,100%,20%,1.)"), null); 120 | }); 121 | 122 | it("color(format) does not allow made-up names", () => { 123 | assert.strictEqual(color("bostock"), null); 124 | }); 125 | 126 | it("color(format) allows achromatic colors", () => { 127 | assertRgbApproxEqual(color("rgba(0,0,0,0)"), NaN, NaN, NaN, 0); 128 | assertRgbApproxEqual(color("#0000"), NaN, NaN, NaN, 0); 129 | assertRgbApproxEqual(color("#00000000"), NaN, NaN, NaN, 0); 130 | }); 131 | 132 | it("color(format) does not allow whitespace before open paren or percent sign", () => { 133 | assert.strictEqual(color("rgb (120,30,50)"), null); 134 | assert.strictEqual(color("rgb (12%,30%,50%)"), null); 135 | assert.strictEqual(color("hsl (120,30%,50%)"), null); 136 | assert.strictEqual(color("hsl(120,30 %,50%)"), null); 137 | assert.strictEqual(color("rgba (120,30,50,1)"), null); 138 | assert.strictEqual(color("rgba (12%,30%,50%,1)"), null); 139 | assert.strictEqual(color("hsla (120,30%,50%,1)"), null); 140 | }); 141 | 142 | it("color(format) is case-insensitive", () => { 143 | assertRgbApproxEqual(color("aLiCeBlUE"), 240, 248, 255, 1); 144 | assertRgbApproxEqual(color("transPARENT"), NaN, NaN, NaN, 0); 145 | assertRgbApproxEqual(color(" #aBc\t\n"), 170, 187, 204, 1); 146 | assertRgbApproxEqual(color(" #aaBBCC\t\n"), 170, 187, 204, 1); 147 | assertRgbApproxEqual(color(" rGB(120,30,50)\t\n"), 120, 30, 50, 1); 148 | assertHslEqual(color(" HSl(120,30%,50%)\t\n"), 120, 0.3, 0.5, 1); 149 | }); 150 | 151 | it("color(format) returns undefined RGB channel values for unknown formats", () => { 152 | assert.strictEqual(color("invalid"), null); 153 | assert.strictEqual(color("hasOwnProperty"), null); 154 | assert.strictEqual(color("__proto__"), null); 155 | assert.strictEqual(color("#ab"), null); 156 | }); 157 | 158 | it("color(format).hex() returns a hexadecimal string", () => { 159 | assert.strictEqual(color("rgba(12%,34%,56%,0.4)").hex(), "#1f578f"); 160 | }); 161 | -------------------------------------------------------------------------------- /test/lab-test.js: -------------------------------------------------------------------------------- 1 | import assert from "assert"; 2 | import {color, hcl, hsl, lab, rgb} from "../src/index.js"; 3 | import {assertLabEqual, assertRgbApproxEqual} from "./asserts.js"; 4 | 5 | it("lab(…) returns an instance of lab and color", () => { 6 | const c = lab(120, 40, 50); 7 | assert(c instanceof lab); 8 | assert(c instanceof color); 9 | }); 10 | 11 | it("lab(…) exposes l, a and b channel values and opacity", () => { 12 | assertLabEqual(lab("rgba(170, 187, 204, 0.4)"), 74.96879980931759, -3.398998724348956, -10.696507207853333, 0.4); 13 | }); 14 | 15 | it("lab.toString() converts to RGB and formats as rgb(…) or rgba(…)", () => { 16 | assert.strictEqual(lab("#abcdef") + "", "rgb(171, 205, 239)"); 17 | assert.strictEqual(lab("moccasin") + "", "rgb(255, 228, 181)"); 18 | assert.strictEqual(lab("hsl(60, 100%, 20%)") + "", "rgb(102, 102, 0)"); 19 | assert.strictEqual(lab("hsla(60, 100%, 20%, 0.4)") + "", "rgba(102, 102, 0, 0.4)"); 20 | assert.strictEqual(lab("rgb(12, 34, 56)") + "", "rgb(12, 34, 56)"); 21 | assert.strictEqual(lab(rgb(12, 34, 56)) + "", "rgb(12, 34, 56)"); 22 | assert.strictEqual(lab(hsl(60, 1, 0.2)) + "", "rgb(102, 102, 0)"); 23 | assert.strictEqual(lab(hsl(60, 1, 0.2, 0.4)) + "", "rgba(102, 102, 0, 0.4)"); 24 | }); 25 | 26 | it("lab.toString() reflects l, a and b channel values and opacity", () => { 27 | const c = lab("#abc"); 28 | c.l += 10, c.a -= 10, c.b += 10, c.opacity = 0.4; 29 | assert.strictEqual(c + "", "rgba(184, 220, 213, 0.4)"); 30 | }); 31 | 32 | it("lab.toString() treats undefined channel values as 0", () => { 33 | assert.strictEqual(lab("invalid") + "", "rgb(0, 0, 0)"); 34 | assert.strictEqual(lab(NaN, 0, 0) + "", "rgb(0, 0, 0)"); 35 | assert.strictEqual(lab(50, NaN, 0) + "", "rgb(119, 119, 119)"); 36 | assert.strictEqual(lab(50, 0, NaN) + "", "rgb(119, 119, 119)"); 37 | assert.strictEqual(lab(50, NaN, NaN) + "", "rgb(119, 119, 119)"); 38 | }); 39 | 40 | it("lab.toString() treats undefined opacity as 1", () => { 41 | const c = lab("#abc"); 42 | c.opacity = NaN; 43 | assert.strictEqual(c + "", "rgb(170, 187, 204)"); 44 | }); 45 | 46 | it("lab(l, a, b) does not clamp l channel value", () => { 47 | assertLabEqual(lab(-10, 1, 2), -10, 1, 2, 1); 48 | assertLabEqual(lab(0, 1, 2), 0, 1, 2, 1); 49 | assertLabEqual(lab(100, 1, 2), 100, 1, 2, 1); 50 | assertLabEqual(lab(110, 1, 2), 110, 1, 2, 1); 51 | }); 52 | 53 | it("lab(l, a, b, opacity) does not clamp opacity to [0,1]", () => { 54 | assertLabEqual(lab(50, 10, 20, -0.2), 50, 10, 20, -0.2); 55 | assertLabEqual(lab(50, 10, 20, 1.2), 50, 10, 20, 1.2); 56 | }); 57 | 58 | it("lab(l, a, b) coerces channel values to numbers", () => { 59 | assertLabEqual(lab("50", "4", "-5"), 50, 4, -5, 1); 60 | }); 61 | 62 | it("lab(l, a, b, opacity) coerces opacity to number", () => { 63 | assertLabEqual(lab(50, 4, -5, "0.2"), 50, 4, -5, 0.2); 64 | }); 65 | 66 | it("lab(l, a, b) allows undefined channel values", () => { 67 | assertLabEqual(lab(undefined, NaN, "foo"), NaN, NaN, NaN, 1); 68 | assertLabEqual(lab(undefined, 4, -5), NaN, 4, -5, 1); 69 | assertLabEqual(lab(42, undefined, -5), 42, NaN, -5, 1); 70 | assertLabEqual(lab(42, 4, undefined), 42, 4, NaN, 1); 71 | }); 72 | 73 | it("lab(l, a, b, opacity) converts undefined opacity to 1", () => { 74 | assertLabEqual(lab(10, 20, 30, null), 10, 20, 30, 1); 75 | assertLabEqual(lab(10, 20, 30, undefined), 10, 20, 30, 1); 76 | }); 77 | 78 | it("lab(format) parses the specified format and converts to Lab", () => { 79 | assertLabEqual(lab("#abcdef"), 80.77135418262527, -5.957098328496224, -20.785782794739237, 1); 80 | assertLabEqual(lab("#abc"), 74.96879980931759, -3.398998724348956, -10.696507207853333, 1); 81 | assertLabEqual(lab("rgb(12, 34, 56)"), 12.404844123471648, -2.159950219712034, -17.168132391132946, 1); 82 | assertLabEqual(lab("rgb(12%, 34%, 56%)"), 35.48300043476593, -2.507637675606522, -36.95112983195855, 1); 83 | assertLabEqual(lab("rgba(12%, 34%, 56%, 0.4)"), 35.48300043476593, -2.507637675606522, -36.95112983195855, 0.4); 84 | assertLabEqual(lab("hsl(60,100%,20%)"), 41.97125732118659, -8.03835128380484, 47.65411917854332, 1); 85 | assertLabEqual(lab("hsla(60,100%,20%,0.4)"), 41.97125732118659, -8.03835128380484, 47.65411917854332, 0.4); 86 | assertLabEqual(lab("aliceblue"), 97.12294991108756, -1.773836604137824, -4.332680308569969, 1); 87 | }); 88 | 89 | it("lab(format) returns undefined channel values for unknown formats", () => { 90 | assertLabEqual(lab("invalid"), NaN, NaN, NaN, NaN); 91 | }); 92 | 93 | it("lab(lab) copies a Lab color", () => { 94 | const c1 = lab(50, 4, -5, 0.4); 95 | const c2 = lab(c1); 96 | assertLabEqual(c1, 50, 4, -5, 0.4); 97 | c1.l = c1.a = c1.b = c1.opacity = 0; 98 | assertLabEqual(c1, 0, 0, 0, 0); 99 | assertLabEqual(c2, 50, 4, -5, 0.4); 100 | }); 101 | 102 | it("lab(hcl(lab)) doesn’t lose a and b channels if luminance is zero", () => { 103 | assertLabEqual(lab(hcl(lab(0, 10, 0))), 0, 10, 0, 1); 104 | }); 105 | 106 | it("lab(rgb) converts from RGB", () => { 107 | assertLabEqual(lab(rgb(255, 0, 0, 0.4)), 54.29173376861782, 80.8124553179771, 69.88504032350531, 0.4); 108 | }); 109 | 110 | it("lab(color) converts from another colorspace via rgb()", () => { 111 | function TestColor() {} 112 | TestColor.prototype = Object.create(color.prototype); 113 | TestColor.prototype.rgb = function() { return rgb(12, 34, 56, 0.4); }; 114 | TestColor.prototype.toString = function() { throw new Error("should use rgb, not toString"); }; 115 | assertLabEqual(lab(new TestColor), 12.404844123471648, -2.159950219712034, -17.168132391132946, 0.4); 116 | }); 117 | 118 | it("lab.brighter(k) returns a brighter color if k > 0", () => { 119 | const c = lab("rgba(165, 42, 42, 0.4)"); 120 | assertLabEqual(c.brighter(0.5), 47.149667346714935, 50.388769337115, 31.834059255569358, 0.4); 121 | assertLabEqual(c.brighter(1), 56.149667346714935, 50.388769337115, 31.834059255569358, 0.4); 122 | assertLabEqual(c.brighter(2), 74.14966734671493, 50.388769337115, 31.834059255569358, 0.4); 123 | }); 124 | 125 | it("lab.brighter(k) returns a copy", () => { 126 | const c1 = lab("rgba(70, 130, 180, 0.4)"); 127 | const c2 = c1.brighter(1); 128 | assertLabEqual(c1, 51.98624890550498, -8.362792037014344, -32.832699449697685, 0.4); 129 | assertLabEqual(c2, 69.98624890550498, -8.362792037014344, -32.832699449697685, 0.4); 130 | }); 131 | 132 | it("lab.brighter() is equivalent to lab.brighter(1)", () => { 133 | const c1 = lab("rgba(70, 130, 180, 0.4)"); 134 | const c2 = c1.brighter(); 135 | const c3 = c1.brighter(1); 136 | assertLabEqual(c2, c3.l, c3.a, c3.b, 0.4); 137 | }); 138 | 139 | it("lab.brighter(k) is equivalent to lab.darker(-k)", () => { 140 | const c1 = lab("rgba(70, 130, 180, 0.4)"); 141 | const c2 = c1.brighter(1.5); 142 | const c3 = c1.darker(-1.5); 143 | assertLabEqual(c2, c3.l, c3.a, c3.b, 0.4); 144 | }); 145 | 146 | it("lab.darker(k) returns a darker color if k > 0", () => { 147 | const c = lab("rgba(165, 42, 42, 0.4)"); 148 | assertLabEqual(c.darker(0.5), 29.149667346714935, 50.388769337115, 31.834059255569358, 0.4); 149 | assertLabEqual(c.darker(1), 20.149667346714935, 50.388769337115, 31.834059255569358, 0.4); 150 | assertLabEqual(c.darker(2), 2.149667346714935, 50.388769337115, 31.834059255569358, 0.4); 151 | }); 152 | 153 | it("lab.darker(k) returns a copy", () => { 154 | const c1 = lab("rgba(70, 130, 180, 0.4)"); 155 | const c2 = c1.darker(1); 156 | assertLabEqual(c1, 51.98624890550498, -8.362792037014344, -32.832699449697685, 0.4); 157 | assertLabEqual(c2, 33.98624890550498, -8.362792037014344, -32.832699449697685, 0.4); 158 | }); 159 | 160 | it("lab.darker() is equivalent to lab.darker(1)", () => { 161 | const c1 = lab("rgba(70, 130, 180, 0.4)"); 162 | const c2 = c1.darker(); 163 | const c3 = c1.darker(1); 164 | assertLabEqual(c2, c3.l, c3.a, c3.b, 0.4); 165 | }); 166 | 167 | it("lab.darker(k) is equivalent to lab.brighter(-k)", () => { 168 | const c1 = lab("rgba(70, 130, 180, 0.4)"); 169 | const c2 = c1.darker(1.5); 170 | const c3 = c1.brighter(-1.5); 171 | assertLabEqual(c2, c3.l, c3.a, c3.b, 0.4); 172 | }); 173 | 174 | it("lab.rgb() converts to RGB", () => { 175 | const c = lab(50, 4, -5, 0.4); 176 | assertRgbApproxEqual(c.rgb(), 123, 117, 128, 0.4); 177 | }); 178 | -------------------------------------------------------------------------------- /test/hcl-test.js: -------------------------------------------------------------------------------- 1 | import assert from "assert"; 2 | import {assertHclEqual, assertRgbApproxEqual} from "./asserts.js"; 3 | import {color, hcl, hsl, lab, rgb} from "../src/index.js"; 4 | 5 | it("hcl(…) returns an instance of hcl and color", () => { 6 | const c = hcl(120, 40, 50); 7 | assert(c instanceof hcl); 8 | assert(c instanceof color); 9 | }); 10 | 11 | it("hcl(…) exposes h, c, and l channel values", () => { 12 | assertHclEqual(hcl("#abc"), 252.37145234745182, 11.223567114593477, 74.96879980931759, 1); 13 | }); 14 | 15 | it("hcl(…) returns defined hue and undefined chroma for black and white", () => { 16 | assertHclEqual(hcl("black"), NaN, NaN, 0, 1); 17 | assertHclEqual(hcl("#000"), NaN, NaN, 0, 1); 18 | assertHclEqual(hcl(lab("#000")), NaN, NaN, 0, 1); 19 | assertHclEqual(hcl("white"), NaN, NaN, 100, 1); 20 | assertHclEqual(hcl("#fff"), NaN, NaN, 100, 1); 21 | assertHclEqual(hcl(lab("#fff")), NaN, NaN, 100, 1); 22 | }); 23 | 24 | it("hcl(…) returns undefined hue and zero chroma for gray", () => { 25 | assertHclEqual(hcl("gray"), NaN, 0, 53.585013, 1); 26 | assertHclEqual(hcl(lab("gray")), NaN, 0, 53.585013, 1); 27 | }); 28 | 29 | it("hcl.toString() converts to RGB and formats as hexadecimal", () => { 30 | assert.strictEqual(hcl("#abcdef") + "", "rgb(171, 205, 239)"); 31 | assert.strictEqual(hcl("moccasin") + "", "rgb(255, 228, 181)"); 32 | assert.strictEqual(hcl("hsl(60, 100%, 20%)") + "", "rgb(102, 102, 0)"); 33 | assert.strictEqual(hcl("rgb(12, 34, 56)") + "", "rgb(12, 34, 56)"); 34 | assert.strictEqual(hcl(rgb(12, 34, 56)) + "", "rgb(12, 34, 56)"); 35 | assert.strictEqual(hcl(hsl(60, 1, 0.2)) + "", "rgb(102, 102, 0)"); 36 | }); 37 | 38 | it("hcl.toString() reflects h, c and l channel values", () => { 39 | const c = hcl("#abc"); 40 | c.h += 10, c.c += 1, c.l -= 1; 41 | assert.strictEqual(c + "", "rgb(170, 183, 204)"); 42 | }); 43 | 44 | it("hcl.toString() treats undefined opacity as 1", () => { 45 | const c = hcl("#abc"); 46 | c.opacity = NaN; 47 | assert.strictEqual(c + "", "rgb(170, 187, 204)"); 48 | }); 49 | 50 | it("hcl.toString() treats undefined channel values as 0", () => { 51 | assert.strictEqual(hcl("invalid") + "", "rgb(0, 0, 0)"); 52 | assert.strictEqual(hcl("#000") + "", "rgb(0, 0, 0)"); 53 | assert.strictEqual(hcl("#ccc") + "", "rgb(204, 204, 204)"); 54 | assert.strictEqual(hcl("#fff") + "", "rgb(255, 255, 255)"); 55 | assert.strictEqual(hcl(NaN, 20, 40) + "", "rgb(94, 94, 94)"); // equivalent to hcl(*, *, 40) 56 | assert.strictEqual(hcl(120, NaN, 40) + "", "rgb(94, 94, 94)"); 57 | assert.strictEqual(hcl(0, NaN, 40) + "", "rgb(94, 94, 94)"); 58 | assert.strictEqual(hcl(120, 50, NaN) + "", "rgb(0, 0, 0)"); // equivalent to hcl(*, *, 0) 59 | assert.strictEqual(hcl(0, 50, NaN) + "", "rgb(0, 0, 0)"); 60 | assert.strictEqual(hcl(120, 0, NaN) + "", "rgb(0, 0, 0)"); 61 | }); 62 | 63 | it("hcl(yellow) is displayable", () => { 64 | assert.strictEqual(hcl("yellow").displayable(), true); 65 | assert.strictEqual(hcl("yellow") + "", "rgb(255, 255, 0)"); 66 | }); 67 | 68 | it("hcl(h, c, l) does not wrap hue to [0,360)", () => { 69 | assertHclEqual(hcl(-10, 40, 50), -10, 40, 50, 1); 70 | assertHclEqual(hcl(0, 40, 50), 0, 40, 50, 1); 71 | assertHclEqual(hcl(360, 40, 50), 360, 40, 50, 1); 72 | assertHclEqual(hcl(370, 40, 50), 370, 40, 50, 1); 73 | }); 74 | 75 | it("hcl(h, c, l) does not clamp l channel value", () => { 76 | assertHclEqual(hcl(120, 20, -10), 120, 20, -10, 1); 77 | assertHclEqual(hcl(120, 20, 0), 120, 20, 0, 1); 78 | assertHclEqual(hcl(120, 20, 100), 120, 20, 100, 1); 79 | assertHclEqual(hcl(120, 20, 110), 120, 20, 110, 1); 80 | }); 81 | 82 | it("hcl(h, c, l, opacity) does not clamp opacity to [0,1]", () => { 83 | assertHclEqual(hcl(120, 20, 100, -0.2), 120, 20, 100, -0.2); 84 | assertHclEqual(hcl(120, 20, 110, 1.2), 120, 20, 110, 1.2); 85 | }); 86 | 87 | it("hcl(h, c, l) coerces channel values to numbers", () => { 88 | assertHclEqual(hcl("120", "40", "50"), 120, 40, 50, 1); 89 | }); 90 | 91 | it("hcl(h, c, l, opacity) coerces opacity to number", () => { 92 | assertHclEqual(hcl(120, 40, 50, "0.2"), 120, 40, 50, 0.2); 93 | }); 94 | 95 | it("hcl(h, c, l) allows undefined channel values", () => { 96 | assertHclEqual(hcl(undefined, NaN, "foo"), NaN, NaN, NaN, 1); 97 | assertHclEqual(hcl(undefined, 40, 50), NaN, 40, 50, 1); 98 | assertHclEqual(hcl(42, undefined, 50), 42, NaN, 50, 1); 99 | assertHclEqual(hcl(42, 40, undefined), 42, 40, NaN, 1); 100 | }); 101 | 102 | it("hcl(h, c, l, opacity) converts undefined opacity to 1", () => { 103 | assertHclEqual(hcl(10, 20, 30, null), 10, 20, 30, 1); 104 | assertHclEqual(hcl(10, 20, 30, undefined), 10, 20, 30, 1); 105 | }); 106 | 107 | it("hcl(format) parses the specified format and converts to HCL", () => { 108 | assertHclEqual(hcl("#abcdef"), 254.0079700170605, 21.62257586147983, 80.77135418262527, 1); 109 | assertHclEqual(hcl("#abc"), 252.37145234745182, 11.223567114593477, 74.96879980931759, 1); 110 | assertHclEqual(hcl("rgb(12, 34, 56)"), 262.8292023352897, 17.30347233219686, 12.404844123471648, 1); 111 | assertHclEqual(hcl("rgb(12%, 34%, 56%)"), 266.117653326772, 37.03612078188506, 35.48300043476593, 1); 112 | assertHclEqual(hcl("rgba(12%, 34%, 56%, 0.4)"), 266.117653326772, 37.03612078188506, 35.48300043476593, 0.4); 113 | assertHclEqual(hcl("hsl(60,100%,20%)"), 99.57458688693686, 48.327323183108916, 41.97125732118659, 1); 114 | assertHclEqual(hcl("hsla(60,100%,20%,0.4)"), 99.57458688693686, 48.327323183108916, 41.97125732118659, 0.4); 115 | assertHclEqual(hcl("aliceblue"), 247.7353849904697, 4.681732046417135, 97.12294991108756, 1); 116 | }); 117 | 118 | it("hcl(format) returns undefined channel values for unknown formats", () => { 119 | assertHclEqual(hcl("invalid"), NaN, NaN, NaN, NaN); 120 | }); 121 | 122 | it("hcl(hcl) copies an HCL color", () => { 123 | const c1 = hcl(120, 30, 50, 0.4); 124 | const c2 = hcl(c1); 125 | assertHclEqual(c1, 120, 30, 50, 0.4); 126 | c1.h = c1.c = c1.l = c1.opacity = 0; 127 | assertHclEqual(c1, 0, 0, 0, 0); 128 | assertHclEqual(c2, 120, 30, 50, 0.4); 129 | }); 130 | 131 | it("hcl(lab) returns h = NaN if a and b are zero", () => { 132 | assertHclEqual(hcl(lab(0, 0, 0)), NaN, NaN, 0, 1); 133 | assertHclEqual(hcl(lab(50, 0, 0)), NaN, 0, 50, 1); 134 | assertHclEqual(hcl(lab(100, 0, 0)), NaN, NaN, 100, 1); 135 | assertHclEqual(hcl(lab(0, 10, 0)), 0, 10, 0, 1); 136 | assertHclEqual(hcl(lab(50, 10, 0)), 0, 10, 50, 1); 137 | assertHclEqual(hcl(lab(100, 10, 0)), 0, 10, 100, 1); 138 | assertHclEqual(hcl(lab(0, 0, 10)), 90, 10, 0, 1); 139 | assertHclEqual(hcl(lab(50, 0, 10)), 90, 10, 50, 1); 140 | assertHclEqual(hcl(lab(100, 0, 10)), 90, 10, 100, 1); 141 | }); 142 | 143 | it("hcl(rgb) converts from RGB", () => { 144 | assertHclEqual(hcl(rgb(255, 0, 0, 0.4)), 40.85261277607024, 106.83899941284552, 54.29173376861782, 0.4); 145 | }); 146 | 147 | it("hcl(color) converts from another colorspace via rgb()", () => { 148 | function TestColor() {} 149 | TestColor.prototype = Object.create(color.prototype); 150 | TestColor.prototype.rgb = function() { return rgb(12, 34, 56, 0.4); }; 151 | TestColor.prototype.toString = function() { throw new Error("should use rgb, not toString"); }; 152 | assertHclEqual(hcl(new TestColor), 262.8292023352897, 17.30347233219686, 12.404844123471648, 0.4); 153 | }); 154 | 155 | it("hcl.brighter(k) returns a brighter color if k > 0", () => { 156 | const c = hcl("rgba(165, 42, 42, 0.4)"); 157 | assertHclEqual(c.brighter(0.5), 32.28342524928155, 59.60231039142763, 47.149667346714935, 0.4); 158 | assertHclEqual(c.brighter(1), 32.28342524928155, 59.60231039142763, 56.149667346714935, 0.4); 159 | assertHclEqual(c.brighter(2), 32.28342524928155, 59.60231039142763, 74.14966734671493, 0.4); 160 | }); 161 | 162 | it("hcl.brighter(k) returns a copy", () => { 163 | const c1 = hcl("rgba(70, 130, 180, 0.4)"); 164 | const c2 = c1.brighter(1); 165 | assertHclEqual(c1, 255.71009124439382, 33.88100417355615, 51.98624890550498, 0.4); 166 | assertHclEqual(c2, 255.71009124439382, 33.88100417355615, 69.98624890550498, 0.4); 167 | }); 168 | 169 | it("hcl.brighter() is equivalent to hcl.brighter(1)", () => { 170 | const c1 = hcl("rgba(70, 130, 180, 0.4)"); 171 | const c2 = c1.brighter(); 172 | const c3 = c1.brighter(1); 173 | assertHclEqual(c2, c3.h, c3.c, c3.l, 0.4); 174 | }); 175 | 176 | it("hcl.brighter(k) is equivalent to hcl.darker(-k)", () => { 177 | const c1 = hcl("rgba(70, 130, 180, 0.4)"); 178 | const c2 = c1.brighter(1.5); 179 | const c3 = c1.darker(-1.5); 180 | assertHclEqual(c2, c3.h, c3.c, c3.l, 0.4); 181 | }); 182 | 183 | it("hcl.darker(k) returns a darker color if k > 0", () => { 184 | const c = hcl("rgba(165, 42, 42, 0.4)"); 185 | assertHclEqual(c.darker(0.5), 32.28342524928155, 59.60231039142763, 29.149667346714935, 0.4); 186 | assertHclEqual(c.darker(1), 32.28342524928155, 59.60231039142763, 20.149667346714935, 0.4); 187 | assertHclEqual(c.darker(2), 32.28342524928155, 59.60231039142763, 2.149667346714935, 0.4); 188 | }); 189 | 190 | it("hcl.darker(k) returns a copy", () => { 191 | const c1 = hcl("rgba(70, 130, 180, 0.4)"); 192 | const c2 = c1.darker(1); 193 | assertHclEqual(c1, 255.71009124439382, 33.88100417355615, 51.98624890550498, 0.4); 194 | assertHclEqual(c2, 255.71009124439382, 33.88100417355615, 33.98624890550498, 0.4); 195 | }); 196 | 197 | it("hcl.darker() is equivalent to hcl.darker(1)", () => { 198 | const c1 = hcl("rgba(70, 130, 180, 0.4)"); 199 | const c2 = c1.darker(); 200 | const c3 = c1.darker(1); 201 | assertHclEqual(c2, c3.h, c3.c, c3.l, 0.4); 202 | }); 203 | 204 | it("hcl.darker(k) is equivalent to hcl.brighter(-k)", () => { 205 | const c1 = hcl("rgba(70, 130, 180, 0.4)"); 206 | const c2 = c1.darker(1.5); 207 | const c3 = c1.brighter(-1.5); 208 | assertHclEqual(c2, c3.h, c3.c, c3.l, 0.4); 209 | }); 210 | 211 | it("hcl.rgb() converts to RGB", () => { 212 | const c = hcl(120, 30, 50, 0.4); 213 | assertRgbApproxEqual(c.rgb(), 105, 126, 73, 0.4); 214 | }); 215 | -------------------------------------------------------------------------------- /test/rgb-test.js: -------------------------------------------------------------------------------- 1 | import assert from "assert"; 2 | import {color, hsl, rgb} from "../src/index.js"; 3 | import {assertRgbApproxEqual, assertRgbEqual} from "./asserts.js"; 4 | 5 | it("rgb(…) returns an instance of rgb and color", () => { 6 | const c = rgb(70, 130, 180); 7 | assert(c instanceof rgb); 8 | assert(c instanceof color); 9 | }); 10 | 11 | it("rgb(…) exposes r, g and b channel values and opacity", () => { 12 | assertRgbApproxEqual(rgb("#abc"), 170, 187, 204, 1); 13 | assertRgbApproxEqual(rgb("rgba(170, 187, 204, 0.4)"), 170, 187, 204, 0.4); 14 | }); 15 | 16 | it("rgb.toString() formats as rgb(…) or rgba(…)", () => { 17 | assert.strictEqual(rgb("#abcdef") + "", "rgb(171, 205, 239)"); 18 | assert.strictEqual(rgb("moccasin") + "", "rgb(255, 228, 181)"); 19 | assert.strictEqual(rgb("hsl(60, 100%, 20%)") + "", "rgb(102, 102, 0)"); 20 | assert.strictEqual(rgb("rgb(12, 34, 56)") + "", "rgb(12, 34, 56)"); 21 | assert.strictEqual(rgb(rgb(12, 34, 56)) + "", "rgb(12, 34, 56)"); 22 | assert.strictEqual(rgb(hsl(60, 1, 0.2)) + "", "rgb(102, 102, 0)"); 23 | assert.strictEqual(rgb("rgba(12, 34, 56, 0.4)") + "", "rgba(12, 34, 56, 0.4)"); 24 | assert.strictEqual(rgb("rgba(12%, 34%, 56%, 0.4)") + "", "rgba(31, 87, 143, 0.4)"); 25 | assert.strictEqual(rgb("hsla(60, 100%, 20%, 0.4)") + "", "rgba(102, 102, 0, 0.4)"); 26 | }); 27 | 28 | it("rgb.formatRgb() formats as rgb(…) or rgba(…)", () => { 29 | assert.strictEqual(rgb("#abcdef").formatRgb(), "rgb(171, 205, 239)"); 30 | assert.strictEqual(rgb("hsl(60, 100%, 20%)").formatRgb(), "rgb(102, 102, 0)"); 31 | assert.strictEqual(rgb("rgba(12%, 34%, 56%, 0.4)").formatRgb(), "rgba(31, 87, 143, 0.4)"); 32 | assert.strictEqual(rgb("hsla(60, 100%, 20%, 0.4)").formatRgb(), "rgba(102, 102, 0, 0.4)"); 33 | }); 34 | 35 | it("rgb.formatHsl() formats as hsl(…) or hsla(…)", () => { 36 | assert.strictEqual(rgb("#abcdef").formatHsl(), "hsl(210, 68%, 80.3921568627451%)"); 37 | assert.strictEqual(rgb("hsl(60, 100%, 20%)").formatHsl(), "hsl(60, 100%, 20%)"); 38 | assert.strictEqual(rgb("rgba(12%, 34%, 56%, 0.4)").formatHsl(), "hsla(210, 64.70588235294117%, 34%, 0.4)"); 39 | assert.strictEqual(rgb("hsla(60, 100%, 20%, 0.4)").formatHsl(), "hsla(60, 100%, 20%, 0.4)"); 40 | }); 41 | 42 | it("rgb.formatHex() formats as #rrggbb", () => { 43 | assert.strictEqual(rgb("#abcdef").formatHex(), "#abcdef"); 44 | assert.strictEqual(rgb("hsl(60, 100%, 20%)").formatHex(), "#666600"); 45 | assert.strictEqual(rgb("rgba(12%, 34%, 56%, 0.4)").formatHex(), "#1f578f"); 46 | assert.strictEqual(rgb("hsla(60, 100%, 20%, 0.4)").formatHex(), "#666600"); 47 | }); 48 | 49 | it("rgb.formatHex8() formats as #rrggbbaa", () => { 50 | assert.strictEqual(rgb("#abcdef").formatHex8(), "#abcdefff"); 51 | assert.strictEqual(rgb("hsl(60, 100%, 20%)").formatHex8(), "#666600ff"); 52 | assert.strictEqual(rgb("rgba(12%, 34%, 56%, 0.4)").formatHex8(), "#1f578f66"); 53 | assert.strictEqual(rgb("hsla(60, 100%, 20%, 0.4)").formatHex8(), "#66660066"); 54 | }); 55 | 56 | it("rgb.hex() is an alias for rgb.formatHex()", () => { 57 | assert.strictEqual(color.prototype.hex, color.prototype.formatHex); 58 | assert.strictEqual(rgb.prototype.hex, rgb.prototype.formatHex); 59 | }); 60 | 61 | it("rgb.toString() reflects r, g and b channel values and opacity", () => { 62 | const c = rgb("#abc"); 63 | ++c.r, ++c.g, ++c.b, c.opacity = 0.5; 64 | assert.strictEqual(c + "", "rgba(171, 188, 205, 0.5)"); 65 | }); 66 | 67 | it("rgb.toString() treats undefined channel values as 0", () => { 68 | assert.strictEqual(rgb("invalid") + "", "rgb(0, 0, 0)"); 69 | assert.strictEqual(rgb(NaN, 12, 34) + "", "rgb(0, 12, 34)"); 70 | }); 71 | 72 | it("rgb.toString() treats undefined opacity as 1", () => { 73 | const c = rgb("#abc"); 74 | ++c.r, ++c.g, ++c.b, c.opacity = NaN; 75 | assert.strictEqual(c + "", "rgb(171, 188, 205)"); 76 | }); 77 | 78 | it("rgb.toString() clamps r, g, b and opacity channel values", () => { 79 | assert.strictEqual(rgb(-1, 2, 3) + "", "rgb(0, 2, 3)"); 80 | assert.strictEqual(rgb( 2, -1, 3) + "", "rgb(2, 0, 3)"); 81 | assert.strictEqual(rgb( 2, 3, -1) + "", "rgb(2, 3, 0)"); 82 | assert.strictEqual(rgb( 2, 3, -1, -0.2) + "", "rgba(2, 3, 0, 0)"); 83 | assert.strictEqual(rgb( 2, 3, -1, 1.2) + "", "rgb(2, 3, 0)"); 84 | }); 85 | 86 | it("rgb.toString() rounds r, g and b channel values", () => { 87 | assert.strictEqual(rgb(0.5, 2.0, 3.0) + "", "rgb(1, 2, 3)"); 88 | assert.strictEqual(rgb(2.0, 0.5, 3.0) + "", "rgb(2, 1, 3)"); 89 | assert.strictEqual(rgb(2.0, 3.0, 0.5) + "", "rgb(2, 3, 1)"); 90 | }); 91 | 92 | it("rgb(r, g, b) does not round channel values", () => { 93 | assertRgbEqual(rgb(1.2, 2.6, 42.9), 1.2, 2.6, 42.9, 1); 94 | }); 95 | 96 | it("rgb(r, g, b) does not clamp channel values", () => { 97 | assertRgbApproxEqual(rgb(-10, -20, -30), -10, -20, -30, 1); 98 | assertRgbApproxEqual(rgb(300, 400, 500), 300, 400, 500, 1); 99 | }); 100 | 101 | it("rgb(r, g, b).clamp() rounds and clamps channel values", () => { 102 | assertRgbApproxEqual(rgb(-10, -20, -30).clamp(), 0, 0, 0, 1); 103 | assertRgbApproxEqual(rgb(10.5, 20.5, 30.5).clamp(), 11, 21, 31, 1); 104 | assertRgbApproxEqual(rgb(300, 400, 500).clamp(), 255, 255, 255, 1); 105 | assert.strictEqual(rgb(10.5, 20.5, 30.5, -1).clamp().opacity, 0); 106 | assert.strictEqual(rgb(10.5, 20.5, 30.5, 0.5).clamp().opacity, 0.5); 107 | assert.strictEqual(rgb(10.5, 20.5, 30.5, 2).clamp().opacity, 1); 108 | assert.strictEqual(rgb(10.5, 20.5, 30.5, NaN).clamp().opacity, 1); 109 | }); 110 | 111 | it("rgb(r, g, b, opacity) does not clamp opacity", () => { 112 | assertRgbApproxEqual(rgb(-10, -20, -30, -0.2), -10, -20, -30, -0.2); 113 | assertRgbApproxEqual(rgb(300, 400, 500, 1.2), 300, 400, 500, 1.2); 114 | }); 115 | 116 | it("rgb(r, g, b) coerces channel values to numbers", () => { 117 | assertRgbApproxEqual(rgb("12", "34", "56"), 12, 34, 56, 1); 118 | assertRgbApproxEqual(rgb(null, null, null), 0, 0, 0, 1); 119 | }); 120 | 121 | it("rgb(r, g, b, opacity) coerces opacity to number", () => { 122 | assertRgbEqual(rgb(-10, -20, -30, "-0.2"), -10, -20, -30, -0.2); 123 | assertRgbEqual(rgb(300, 400, 500, "1.2"), 300, 400, 500, 1.2); 124 | }); 125 | 126 | it("rgb(r, g, b) allows undefined channel values", () => { 127 | assertRgbApproxEqual(rgb(undefined, NaN, "foo"), NaN, NaN, NaN, 1); 128 | assertRgbApproxEqual(rgb(undefined, 42, 56), NaN, 42, 56, 1); 129 | assertRgbApproxEqual(rgb(42, undefined, 56), 42, NaN, 56, 1); 130 | assertRgbApproxEqual(rgb(42, 56, undefined), 42, 56, NaN, 1); 131 | }); 132 | 133 | it("rgb(r, g, b, opacity) converts undefined opacity to 1", () => { 134 | assertRgbApproxEqual(rgb(10, 20, 30, null), 10, 20, 30, 1); 135 | assertRgbApproxEqual(rgb(10, 20, 30, undefined), 10, 20, 30, 1); 136 | }); 137 | 138 | it("rgb(format) parses the specified format and converts to RGB", () => { 139 | assertRgbApproxEqual(rgb("#abcdef"), 171, 205, 239, 1); 140 | assertRgbApproxEqual(rgb("#abc"), 170, 187, 204, 1); 141 | assertRgbApproxEqual(rgb("rgb(12, 34, 56)"), 12, 34, 56, 1); 142 | assertRgbApproxEqual(rgb("rgb(12%, 34%, 56%)"), 31, 87, 143, 1); 143 | assertRgbApproxEqual(rgb("hsl(60,100%,20%)"), 102, 102, 0, 1); 144 | assertRgbApproxEqual(rgb("aliceblue"), 240, 248, 255, 1); 145 | assertRgbApproxEqual(rgb("hsla(60,100%,20%,0.4)"), 102, 102, 0, 0.4); 146 | }); 147 | 148 | it("rgb(format) ignores all channels if the alpha is <= 0", () => { 149 | assertRgbApproxEqual(rgb("rgba(12,34,45,0)"), NaN, NaN, NaN, 0); 150 | assertRgbApproxEqual(rgb("rgba(12,34,45,-0.1)"), NaN, NaN, NaN, -0.1); 151 | }); 152 | 153 | it("rgb(format) returns undefined channel values for unknown formats", () => { 154 | assertRgbApproxEqual(rgb("invalid"), NaN, NaN, NaN, NaN); 155 | }); 156 | 157 | it("rgb(rgb) copies an RGB color", () => { 158 | const c1 = rgb("rgba(70, 130, 180, 0.4)"); 159 | const c2 = rgb(c1); 160 | assertRgbApproxEqual(c1, 70, 130, 180, 0.4); 161 | c1.r = c1.g = c1.b = c1.opacity = 0; 162 | assertRgbApproxEqual(c1, 0, 0, 0, 0); 163 | assertRgbApproxEqual(c2, 70, 130, 180, 0.4); 164 | }); 165 | 166 | it("rgb(hsl) converts from HSL", () => { 167 | assertRgbApproxEqual(rgb(hsl(0, 1, 0.5)), 255, 0, 0, 1); 168 | assertRgbApproxEqual(rgb(hsl(0, 1, 0.5, 0.4)), 255, 0, 0, 0.4); 169 | }); 170 | 171 | it("rgb(color) converts from another colorspace via rgb()", () => { 172 | function TestColor() {} 173 | TestColor.prototype = Object.create(color.prototype); 174 | TestColor.prototype.rgb = function() { return rgb(12, 34, 56, 0.4); }; 175 | TestColor.prototype.toString = function() { throw new Error("should use rgb, not toString"); }; 176 | assertRgbApproxEqual(rgb(new TestColor), 12, 34, 56, 0.4); 177 | }); 178 | 179 | it("rgb.displayable() returns true if the color is within the RGB gamut and opacity is in [0,1]", () => { 180 | assert.strictEqual(rgb("white").displayable(), true); 181 | assert.strictEqual(rgb("red").displayable(), true); 182 | assert.strictEqual(rgb("black").displayable(), true); 183 | assert.strictEqual(rgb("invalid").displayable(), false); 184 | assert.strictEqual(rgb(-1, 0, 0).displayable(), false); 185 | assert.strictEqual(rgb(0, -1, 0).displayable(), false); 186 | assert.strictEqual(rgb(0, 0, -1).displayable(), false); 187 | assert.strictEqual(rgb(256, 0, 0).displayable(), false); 188 | assert.strictEqual(rgb(0, 256, 0).displayable(), false); 189 | assert.strictEqual(rgb(0, 0, 256).displayable(), false); 190 | assert.strictEqual(rgb(0, 0, 255, 0).displayable(), true); 191 | assert.strictEqual(rgb(0, 0, 255, 1.2).displayable(), false); 192 | assert.strictEqual(rgb(0, 0, 255, -0.2).displayable(), false); 193 | }); 194 | 195 | it("rgb.brighter(k) returns a brighter color if k > 0", () => { 196 | const c = rgb("rgba(165, 42, 42, 0.4)"); 197 | assertRgbApproxEqual(c.brighter(0.5), 197, 50, 50, 0.4); 198 | assertRgbApproxEqual(c.brighter(1), 236, 60, 60, 0.4); 199 | assertRgbApproxEqual(c.brighter(2), 337, 86, 86, 0.4); 200 | }); 201 | 202 | it("rgb.brighter(k) returns a copy", () => { 203 | const c1 = rgb("rgba(70, 130, 180, 0.4)"); 204 | const c2 = c1.brighter(1); 205 | assertRgbApproxEqual(c1, 70, 130, 180, 0.4); 206 | assertRgbApproxEqual(c2, 100, 186, 257, 0.4); 207 | }); 208 | 209 | it("rgb.brighter() is equivalent to rgb.brighter(1)", () => { 210 | const c1 = rgb("rgba(70, 130, 180, 0.4)"); 211 | const c2 = c1.brighter(); 212 | const c3 = c1.brighter(1); 213 | assertRgbApproxEqual(c2, c3.r, c3.g, c3.b, 0.4); 214 | }); 215 | 216 | it("rgb.brighter(k) is equivalent to rgb.darker(-k)", () => { 217 | const c1 = rgb("rgba(70, 130, 180, 0.4)"); 218 | const c2 = c1.brighter(1.5); 219 | const c3 = c1.darker(-1.5); 220 | assertRgbApproxEqual(c2, c3.r, c3.g, c3.b, 0.4); 221 | }); 222 | 223 | it("rgb(\"black\").brighter() still returns black", () => { 224 | const c1 = rgb("black"); 225 | const c2 = c1.brighter(1); 226 | assertRgbApproxEqual(c1, 0, 0, 0, 1); 227 | assertRgbApproxEqual(c2, 0, 0, 0, 1); 228 | }); 229 | 230 | it("rgb.darker(k) returns a darker color if k > 0", () => { 231 | const c = rgb("rgba(165, 42, 42, 0.4)"); 232 | assertRgbApproxEqual(c.darker(0.5), 138, 35, 35, 0.4); 233 | assertRgbApproxEqual(c.darker(1), 115, 29, 29, 0.4); 234 | assertRgbApproxEqual(c.darker(2), 81, 21, 21, 0.4); 235 | }); 236 | 237 | it("rgb.darker(k) returns a copy", () => { 238 | const c1 = rgb("rgba(70, 130, 180, 0.4)"); 239 | const c2 = c1.darker(1); 240 | assertRgbApproxEqual(c1, 70, 130, 180, 0.4); 241 | assertRgbApproxEqual(c2, 49, 91, 126, 0.4); 242 | }); 243 | 244 | it("rgb.darker() is equivalent to rgb.darker(1)", () => { 245 | const c1 = rgb("rgba(70, 130, 180, 0.4)"); 246 | const c2 = c1.darker(); 247 | const c3 = c1.darker(1); 248 | assertRgbApproxEqual(c2, c3.r, c3.g, c3.b, 0.4); 249 | }); 250 | 251 | it("rgb.darker(k) is equivalent to rgb.brighter(-k)", () => { 252 | const c1 = rgb("rgba(70, 130, 180, 0.4)"); 253 | const c2 = c1.darker(1.5); 254 | const c3 = c1.brighter(-1.5); 255 | assertRgbApproxEqual(c2, c3.r, c3.g, c3.b, 0.4); 256 | }); 257 | 258 | it("rgb.rgb() returns this", () => { 259 | const c = rgb(70, 130, 180); 260 | assert.strictEqual(c.rgb(), c); 261 | }); 262 | 263 | it("rgb.copy(…) returns a new rgb with the specified channel values", () => { 264 | const c = rgb(70, 130, 180); 265 | assert.strictEqual(c.copy() instanceof rgb, true); 266 | assert.strictEqual(c.copy() + "", "rgb(70, 130, 180)"); 267 | assert.strictEqual(c.copy({opacity: 0.2}) + "", "rgba(70, 130, 180, 0.2)"); 268 | assert.strictEqual(c.copy({r: 20}) + "", "rgb(20, 130, 180)"); 269 | assert.strictEqual(c.copy({r: 20, g: 40}) + "", "rgb(20, 40, 180)"); 270 | }); 271 | -------------------------------------------------------------------------------- /src/color.js: -------------------------------------------------------------------------------- 1 | import define, {extend} from "./define.js"; 2 | 3 | export function Color() {} 4 | 5 | export var darker = 0.7; 6 | export var brighter = 1 / darker; 7 | 8 | var reI = "\\s*([+-]?\\d+)\\s*", 9 | reN = "\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)\\s*", 10 | reP = "\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)%\\s*", 11 | reHex = /^#([0-9a-f]{3,8})$/, 12 | reRgbInteger = new RegExp(`^rgb\\(${reI},${reI},${reI}\\)$`), 13 | reRgbPercent = new RegExp(`^rgb\\(${reP},${reP},${reP}\\)$`), 14 | reRgbaInteger = new RegExp(`^rgba\\(${reI},${reI},${reI},${reN}\\)$`), 15 | reRgbaPercent = new RegExp(`^rgba\\(${reP},${reP},${reP},${reN}\\)$`), 16 | reHslPercent = new RegExp(`^hsl\\(${reN},${reP},${reP}\\)$`), 17 | reHslaPercent = new RegExp(`^hsla\\(${reN},${reP},${reP},${reN}\\)$`); 18 | 19 | var named = { 20 | aliceblue: 0xf0f8ff, 21 | antiquewhite: 0xfaebd7, 22 | aqua: 0x00ffff, 23 | aquamarine: 0x7fffd4, 24 | azure: 0xf0ffff, 25 | beige: 0xf5f5dc, 26 | bisque: 0xffe4c4, 27 | black: 0x000000, 28 | blanchedalmond: 0xffebcd, 29 | blue: 0x0000ff, 30 | blueviolet: 0x8a2be2, 31 | brown: 0xa52a2a, 32 | burlywood: 0xdeb887, 33 | cadetblue: 0x5f9ea0, 34 | chartreuse: 0x7fff00, 35 | chocolate: 0xd2691e, 36 | coral: 0xff7f50, 37 | cornflowerblue: 0x6495ed, 38 | cornsilk: 0xfff8dc, 39 | crimson: 0xdc143c, 40 | cyan: 0x00ffff, 41 | darkblue: 0x00008b, 42 | darkcyan: 0x008b8b, 43 | darkgoldenrod: 0xb8860b, 44 | darkgray: 0xa9a9a9, 45 | darkgreen: 0x006400, 46 | darkgrey: 0xa9a9a9, 47 | darkkhaki: 0xbdb76b, 48 | darkmagenta: 0x8b008b, 49 | darkolivegreen: 0x556b2f, 50 | darkorange: 0xff8c00, 51 | darkorchid: 0x9932cc, 52 | darkred: 0x8b0000, 53 | darksalmon: 0xe9967a, 54 | darkseagreen: 0x8fbc8f, 55 | darkslateblue: 0x483d8b, 56 | darkslategray: 0x2f4f4f, 57 | darkslategrey: 0x2f4f4f, 58 | darkturquoise: 0x00ced1, 59 | darkviolet: 0x9400d3, 60 | deeppink: 0xff1493, 61 | deepskyblue: 0x00bfff, 62 | dimgray: 0x696969, 63 | dimgrey: 0x696969, 64 | dodgerblue: 0x1e90ff, 65 | firebrick: 0xb22222, 66 | floralwhite: 0xfffaf0, 67 | forestgreen: 0x228b22, 68 | fuchsia: 0xff00ff, 69 | gainsboro: 0xdcdcdc, 70 | ghostwhite: 0xf8f8ff, 71 | gold: 0xffd700, 72 | goldenrod: 0xdaa520, 73 | gray: 0x808080, 74 | green: 0x008000, 75 | greenyellow: 0xadff2f, 76 | grey: 0x808080, 77 | honeydew: 0xf0fff0, 78 | hotpink: 0xff69b4, 79 | indianred: 0xcd5c5c, 80 | indigo: 0x4b0082, 81 | ivory: 0xfffff0, 82 | khaki: 0xf0e68c, 83 | lavender: 0xe6e6fa, 84 | lavenderblush: 0xfff0f5, 85 | lawngreen: 0x7cfc00, 86 | lemonchiffon: 0xfffacd, 87 | lightblue: 0xadd8e6, 88 | lightcoral: 0xf08080, 89 | lightcyan: 0xe0ffff, 90 | lightgoldenrodyellow: 0xfafad2, 91 | lightgray: 0xd3d3d3, 92 | lightgreen: 0x90ee90, 93 | lightgrey: 0xd3d3d3, 94 | lightpink: 0xffb6c1, 95 | lightsalmon: 0xffa07a, 96 | lightseagreen: 0x20b2aa, 97 | lightskyblue: 0x87cefa, 98 | lightslategray: 0x778899, 99 | lightslategrey: 0x778899, 100 | lightsteelblue: 0xb0c4de, 101 | lightyellow: 0xffffe0, 102 | lime: 0x00ff00, 103 | limegreen: 0x32cd32, 104 | linen: 0xfaf0e6, 105 | magenta: 0xff00ff, 106 | maroon: 0x800000, 107 | mediumaquamarine: 0x66cdaa, 108 | mediumblue: 0x0000cd, 109 | mediumorchid: 0xba55d3, 110 | mediumpurple: 0x9370db, 111 | mediumseagreen: 0x3cb371, 112 | mediumslateblue: 0x7b68ee, 113 | mediumspringgreen: 0x00fa9a, 114 | mediumturquoise: 0x48d1cc, 115 | mediumvioletred: 0xc71585, 116 | midnightblue: 0x191970, 117 | mintcream: 0xf5fffa, 118 | mistyrose: 0xffe4e1, 119 | moccasin: 0xffe4b5, 120 | navajowhite: 0xffdead, 121 | navy: 0x000080, 122 | oldlace: 0xfdf5e6, 123 | olive: 0x808000, 124 | olivedrab: 0x6b8e23, 125 | orange: 0xffa500, 126 | orangered: 0xff4500, 127 | orchid: 0xda70d6, 128 | palegoldenrod: 0xeee8aa, 129 | palegreen: 0x98fb98, 130 | paleturquoise: 0xafeeee, 131 | palevioletred: 0xdb7093, 132 | papayawhip: 0xffefd5, 133 | peachpuff: 0xffdab9, 134 | peru: 0xcd853f, 135 | pink: 0xffc0cb, 136 | plum: 0xdda0dd, 137 | powderblue: 0xb0e0e6, 138 | purple: 0x800080, 139 | rebeccapurple: 0x663399, 140 | red: 0xff0000, 141 | rosybrown: 0xbc8f8f, 142 | royalblue: 0x4169e1, 143 | saddlebrown: 0x8b4513, 144 | salmon: 0xfa8072, 145 | sandybrown: 0xf4a460, 146 | seagreen: 0x2e8b57, 147 | seashell: 0xfff5ee, 148 | sienna: 0xa0522d, 149 | silver: 0xc0c0c0, 150 | skyblue: 0x87ceeb, 151 | slateblue: 0x6a5acd, 152 | slategray: 0x708090, 153 | slategrey: 0x708090, 154 | snow: 0xfffafa, 155 | springgreen: 0x00ff7f, 156 | steelblue: 0x4682b4, 157 | tan: 0xd2b48c, 158 | teal: 0x008080, 159 | thistle: 0xd8bfd8, 160 | tomato: 0xff6347, 161 | turquoise: 0x40e0d0, 162 | violet: 0xee82ee, 163 | wheat: 0xf5deb3, 164 | white: 0xffffff, 165 | whitesmoke: 0xf5f5f5, 166 | yellow: 0xffff00, 167 | yellowgreen: 0x9acd32 168 | }; 169 | 170 | define(Color, color, { 171 | copy(channels) { 172 | return Object.assign(new this.constructor, this, channels); 173 | }, 174 | displayable() { 175 | return this.rgb().displayable(); 176 | }, 177 | hex: color_formatHex, // Deprecated! Use color.formatHex. 178 | formatHex: color_formatHex, 179 | formatHex8: color_formatHex8, 180 | formatHsl: color_formatHsl, 181 | formatRgb: color_formatRgb, 182 | toString: color_formatRgb 183 | }); 184 | 185 | function color_formatHex() { 186 | return this.rgb().formatHex(); 187 | } 188 | 189 | function color_formatHex8() { 190 | return this.rgb().formatHex8(); 191 | } 192 | 193 | function color_formatHsl() { 194 | return hslConvert(this).formatHsl(); 195 | } 196 | 197 | function color_formatRgb() { 198 | return this.rgb().formatRgb(); 199 | } 200 | 201 | export default function color(format) { 202 | var m, l; 203 | format = (format + "").trim().toLowerCase(); 204 | return (m = reHex.exec(format)) ? (l = m[1].length, m = parseInt(m[1], 16), l === 6 ? rgbn(m) // #ff0000 205 | : l === 3 ? new Rgb((m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1) // #f00 206 | : l === 8 ? rgba(m >> 24 & 0xff, m >> 16 & 0xff, m >> 8 & 0xff, (m & 0xff) / 0xff) // #ff000000 207 | : l === 4 ? rgba((m >> 12 & 0xf) | (m >> 8 & 0xf0), (m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), (((m & 0xf) << 4) | (m & 0xf)) / 0xff) // #f000 208 | : null) // invalid hex 209 | : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0) 210 | : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%) 211 | : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1) 212 | : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1) 213 | : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%) 214 | : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1) 215 | : named.hasOwnProperty(format) ? rgbn(named[format]) // eslint-disable-line no-prototype-builtins 216 | : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0) 217 | : null; 218 | } 219 | 220 | function rgbn(n) { 221 | return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1); 222 | } 223 | 224 | function rgba(r, g, b, a) { 225 | if (a <= 0) r = g = b = NaN; 226 | return new Rgb(r, g, b, a); 227 | } 228 | 229 | export function rgbConvert(o) { 230 | if (!(o instanceof Color)) o = color(o); 231 | if (!o) return new Rgb; 232 | o = o.rgb(); 233 | return new Rgb(o.r, o.g, o.b, o.opacity); 234 | } 235 | 236 | export function rgb(r, g, b, opacity) { 237 | return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity); 238 | } 239 | 240 | export function Rgb(r, g, b, opacity) { 241 | this.r = +r; 242 | this.g = +g; 243 | this.b = +b; 244 | this.opacity = +opacity; 245 | } 246 | 247 | define(Rgb, rgb, extend(Color, { 248 | brighter(k) { 249 | k = k == null ? brighter : Math.pow(brighter, k); 250 | return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); 251 | }, 252 | darker(k) { 253 | k = k == null ? darker : Math.pow(darker, k); 254 | return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); 255 | }, 256 | rgb() { 257 | return this; 258 | }, 259 | clamp() { 260 | return new Rgb(clampi(this.r), clampi(this.g), clampi(this.b), clampa(this.opacity)); 261 | }, 262 | displayable() { 263 | return (-0.5 <= this.r && this.r < 255.5) 264 | && (-0.5 <= this.g && this.g < 255.5) 265 | && (-0.5 <= this.b && this.b < 255.5) 266 | && (0 <= this.opacity && this.opacity <= 1); 267 | }, 268 | hex: rgb_formatHex, // Deprecated! Use color.formatHex. 269 | formatHex: rgb_formatHex, 270 | formatHex8: rgb_formatHex8, 271 | formatRgb: rgb_formatRgb, 272 | toString: rgb_formatRgb 273 | })); 274 | 275 | function rgb_formatHex() { 276 | return `#${hex(this.r)}${hex(this.g)}${hex(this.b)}`; 277 | } 278 | 279 | function rgb_formatHex8() { 280 | return `#${hex(this.r)}${hex(this.g)}${hex(this.b)}${hex((isNaN(this.opacity) ? 1 : this.opacity) * 255)}`; 281 | } 282 | 283 | function rgb_formatRgb() { 284 | const a = clampa(this.opacity); 285 | return `${a === 1 ? "rgb(" : "rgba("}${clampi(this.r)}, ${clampi(this.g)}, ${clampi(this.b)}${a === 1 ? ")" : `, ${a})`}`; 286 | } 287 | 288 | function clampa(opacity) { 289 | return isNaN(opacity) ? 1 : Math.max(0, Math.min(1, opacity)); 290 | } 291 | 292 | function clampi(value) { 293 | return Math.max(0, Math.min(255, Math.round(value) || 0)); 294 | } 295 | 296 | function hex(value) { 297 | value = clampi(value); 298 | return (value < 16 ? "0" : "") + value.toString(16); 299 | } 300 | 301 | function hsla(h, s, l, a) { 302 | if (a <= 0) h = s = l = NaN; 303 | else if (l <= 0 || l >= 1) h = s = NaN; 304 | else if (s <= 0) h = NaN; 305 | return new Hsl(h, s, l, a); 306 | } 307 | 308 | export function hslConvert(o) { 309 | if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity); 310 | if (!(o instanceof Color)) o = color(o); 311 | if (!o) return new Hsl; 312 | if (o instanceof Hsl) return o; 313 | o = o.rgb(); 314 | var r = o.r / 255, 315 | g = o.g / 255, 316 | b = o.b / 255, 317 | min = Math.min(r, g, b), 318 | max = Math.max(r, g, b), 319 | h = NaN, 320 | s = max - min, 321 | l = (max + min) / 2; 322 | if (s) { 323 | if (r === max) h = (g - b) / s + (g < b) * 6; 324 | else if (g === max) h = (b - r) / s + 2; 325 | else h = (r - g) / s + 4; 326 | s /= l < 0.5 ? max + min : 2 - max - min; 327 | h *= 60; 328 | } else { 329 | s = l > 0 && l < 1 ? 0 : h; 330 | } 331 | return new Hsl(h, s, l, o.opacity); 332 | } 333 | 334 | export function hsl(h, s, l, opacity) { 335 | return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity); 336 | } 337 | 338 | function Hsl(h, s, l, opacity) { 339 | this.h = +h; 340 | this.s = +s; 341 | this.l = +l; 342 | this.opacity = +opacity; 343 | } 344 | 345 | define(Hsl, hsl, extend(Color, { 346 | brighter(k) { 347 | k = k == null ? brighter : Math.pow(brighter, k); 348 | return new Hsl(this.h, this.s, this.l * k, this.opacity); 349 | }, 350 | darker(k) { 351 | k = k == null ? darker : Math.pow(darker, k); 352 | return new Hsl(this.h, this.s, this.l * k, this.opacity); 353 | }, 354 | rgb() { 355 | var h = this.h % 360 + (this.h < 0) * 360, 356 | s = isNaN(h) || isNaN(this.s) ? 0 : this.s, 357 | l = this.l, 358 | m2 = l + (l < 0.5 ? l : 1 - l) * s, 359 | m1 = 2 * l - m2; 360 | return new Rgb( 361 | hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2), 362 | hsl2rgb(h, m1, m2), 363 | hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2), 364 | this.opacity 365 | ); 366 | }, 367 | clamp() { 368 | return new Hsl(clamph(this.h), clampt(this.s), clampt(this.l), clampa(this.opacity)); 369 | }, 370 | displayable() { 371 | return (0 <= this.s && this.s <= 1 || isNaN(this.s)) 372 | && (0 <= this.l && this.l <= 1) 373 | && (0 <= this.opacity && this.opacity <= 1); 374 | }, 375 | formatHsl() { 376 | const a = clampa(this.opacity); 377 | return `${a === 1 ? "hsl(" : "hsla("}${clamph(this.h)}, ${clampt(this.s) * 100}%, ${clampt(this.l) * 100}%${a === 1 ? ")" : `, ${a})`}`; 378 | } 379 | })); 380 | 381 | function clamph(value) { 382 | value = (value || 0) % 360; 383 | return value < 0 ? value + 360 : value; 384 | } 385 | 386 | function clampt(value) { 387 | return Math.max(0, Math.min(1, value || 0)); 388 | } 389 | 390 | /* From FvD 13.37, CSS Color Module Level 3 */ 391 | function hsl2rgb(h, m1, m2) { 392 | return (h < 60 ? m1 + (m2 - m1) * h / 60 393 | : h < 180 ? m2 394 | : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60 395 | : m1) * 255; 396 | } 397 | -------------------------------------------------------------------------------- /test/hsl-test.js: -------------------------------------------------------------------------------- 1 | import assert from "assert"; 2 | import {color, hsl, rgb} from "../src/index.js"; 3 | import {assertHslEqual, assertRgbApproxEqual} from "./asserts.js"; 4 | 5 | it("hsl(…) returns an instance of hsl and color", () => { 6 | const c = hsl(120, 0.4, 0.5); 7 | assert(c instanceof hsl); 8 | assert(c instanceof color); 9 | }); 10 | 11 | it("hsl(…) exposes h, s, and l channel values and opacity", () => { 12 | assertHslEqual(hsl("#abc"), 210, 0.25, 0.7333333, 1); 13 | assertHslEqual(hsl("hsla(60, 100%, 20%, 0.4)"), 60, 1, 0.2, 0.4); 14 | }); 15 | 16 | it("hsl.toString() converts to RGB and formats as rgb(…) or rgba(…)", () => { 17 | assert.strictEqual(hsl("#abcdef") + "", "rgb(171, 205, 239)"); 18 | assert.strictEqual(hsl("moccasin") + "", "rgb(255, 228, 181)"); 19 | assert.strictEqual(hsl("hsl(60, 100%, 20%)") + "", "rgb(102, 102, 0)"); 20 | assert.strictEqual(hsl("hsla(60, 100%, 20%, 0.4)") + "", "rgba(102, 102, 0, 0.4)"); 21 | assert.strictEqual(hsl("rgb(12, 34, 56)") + "", "rgb(12, 34, 56)"); 22 | assert.strictEqual(hsl(rgb(12, 34, 56)) + "", "rgb(12, 34, 56)"); 23 | assert.strictEqual(hsl(hsl(60, 1, 0.2)) + "", "rgb(102, 102, 0)"); 24 | assert.strictEqual(hsl(hsl(60, 1, 0.2, 0.4)) + "", "rgba(102, 102, 0, 0.4)"); 25 | }); 26 | 27 | it("hsl.formatRgb() formats as rgb(…) or rgba(…)", () => { 28 | assert.strictEqual(hsl("#abcdef").formatRgb(), "rgb(171, 205, 239)"); 29 | assert.strictEqual(hsl("hsl(60, 100%, 20%)").formatRgb(), "rgb(102, 102, 0)"); 30 | assert.strictEqual(hsl("rgba(12%, 34%, 56%, 0.4)").formatRgb(), "rgba(31, 87, 143, 0.4)"); 31 | assert.strictEqual(hsl("hsla(60, 100%, 20%, 0.4)").formatRgb(), "rgba(102, 102, 0, 0.4)"); 32 | }); 33 | 34 | it("hsl.formatHsl() formats as hsl(…) or hsla(…)", () => { 35 | assert.strictEqual(hsl("#abcdef").formatHsl(), "hsl(210, 68%, 80.3921568627451%)"); 36 | assert.strictEqual(hsl("hsl(60, 100%, 20%)").formatHsl(), "hsl(60, 100%, 20%)"); 37 | assert.strictEqual(hsl("rgba(12%, 34%, 56%, 0.4)").formatHsl(), "hsla(210, 64.70588235294117%, 34%, 0.4)"); 38 | assert.strictEqual(hsl("hsla(60, 100%, 20%, 0.4)").formatHsl(), "hsla(60, 100%, 20%, 0.4)"); 39 | }); 40 | 41 | it("hsl.formatHsl() clamps to the expected range", () => { 42 | assert.strictEqual(hsl(180, -100, -50).formatHsl(), "hsl(180, 0%, 0%)"); 43 | assert.strictEqual(hsl(180, 150, 200).formatHsl(), "hsl(180, 100%, 100%)"); 44 | assert.strictEqual(hsl(-90, 50, 50).formatHsl(), "hsl(270, 100%, 100%)"); 45 | assert.strictEqual(hsl(420, 50, 50).formatHsl(), "hsl(60, 100%, 100%)"); 46 | }); 47 | 48 | it("hsl.formatHex() formats as #rrggbb", () => { 49 | assert.strictEqual(hsl("#abcdef").formatHex(), "#abcdef"); 50 | assert.strictEqual(hsl("hsl(60, 100%, 20%)").formatHex(), "#666600"); 51 | assert.strictEqual(hsl("rgba(12%, 34%, 56%, 0.4)").formatHex(), "#1f578f"); 52 | assert.strictEqual(hsl("hsla(60, 100%, 20%, 0.4)").formatHex(), "#666600"); 53 | }); 54 | 55 | it("hsl.toString() reflects h, s and l channel values and opacity", () => { 56 | const c = hsl("#abc"); 57 | c.h += 10, c.s += 0.01, c.l -= 0.01, c.opacity = 0.4; 58 | assert.strictEqual(c + "", "rgba(166, 178, 203, 0.4)"); 59 | }); 60 | 61 | it("hsl.toString() treats undefined channel values as 0", () => { 62 | assert.strictEqual(hsl("invalid") + "", "rgb(0, 0, 0)"); 63 | assert.strictEqual(hsl("#000") + "", "rgb(0, 0, 0)"); 64 | assert.strictEqual(hsl("#ccc") + "", "rgb(204, 204, 204)"); 65 | assert.strictEqual(hsl("#fff") + "", "rgb(255, 255, 255)"); 66 | assert.strictEqual(hsl(NaN, 0.5, 0.4) + "", "rgb(102, 102, 102)"); // equivalent to hsl(*, 0, 0.4) 67 | assert.strictEqual(hsl(120, NaN, 0.4) + "", "rgb(102, 102, 102)"); 68 | assert.strictEqual(hsl(NaN, NaN, 0.4) + "", "rgb(102, 102, 102)"); 69 | assert.strictEqual(hsl(120, 0.5, NaN) + "", "rgb(0, 0, 0)"); // equivalent to hsl(120, 0.5, 0) 70 | }); 71 | 72 | it("hsl.toString() treats undefined opacity as 1", () => { 73 | const c = hsl("#abc"); 74 | c.opacity = NaN; 75 | assert.strictEqual(c + "", "rgb(170, 187, 204)"); 76 | }); 77 | 78 | it("hsl(h, s, l) does not wrap hue to [0,360)", () => { 79 | assertHslEqual(hsl(-10, 0.4, 0.5), -10, 0.4, 0.5, 1); 80 | assertHslEqual(hsl(0, 0.4, 0.5), 0, 0.4, 0.5, 1); 81 | assertHslEqual(hsl(360, 0.4, 0.5), 360, 0.4, 0.5, 1); 82 | assertHslEqual(hsl(370, 0.4, 0.5), 370, 0.4, 0.5, 1); 83 | }); 84 | 85 | it("hsl(h, s, l) does not clamp s and l channel values to [0,1]", () => { 86 | assertHslEqual(hsl(120, -0.1, 0.5), 120, -0.1, 0.5, 1); 87 | assertHslEqual(hsl(120, 1.1, 0.5), 120, 1.1, 0.5, 1); 88 | assertHslEqual(hsl(120, 0.2, -0.1), 120, 0.2, -0.1, 1); 89 | assertHslEqual(hsl(120, 0.2, 1.1), 120, 0.2, 1.1, 1); 90 | }); 91 | 92 | it("hsl(h, s, l).clamp() clamps channel values", () => { 93 | assertHslEqual(hsl(120, -0.1, -0.2).clamp(), 120, 0, 0, 1); 94 | assertHslEqual(hsl(120, 1.1, 1.2).clamp(), 120, 1, 1, 1); 95 | assertHslEqual(hsl(120, 2.1, 2.2).clamp(), 120, 1, 1, 1); 96 | assertHslEqual(hsl(420, -0.1, -0.2).clamp(), 60, 0, 0, 1); 97 | assertHslEqual(hsl(-420, -0.1, -0.2).clamp(), 300, 0, 0, 1); 98 | assert.strictEqual(hsl(-420, -0.1, -0.2, NaN).clamp().opacity, 1); 99 | assert.strictEqual(hsl(-420, -0.1, -0.2, 0.5).clamp().opacity, 0.5); 100 | assert.strictEqual(hsl(-420, -0.1, -0.2, -1).clamp().opacity, 0); 101 | assert.strictEqual(hsl(-420, -0.1, -0.2, 2).clamp().opacity, 1); 102 | }); 103 | 104 | it("hsl(h, s, l, opacity) does not clamp opacity to [0,1]", () => { 105 | assertHslEqual(hsl(120, 0.1, 0.5, -0.2), 120, 0.1, 0.5, -0.2); 106 | assertHslEqual(hsl(120, 0.9, 0.5, 1.2), 120, 0.9, 0.5, 1.2); 107 | }); 108 | 109 | it("hsl(h, s, l) coerces channel values to numbers", () => { 110 | assertHslEqual(hsl("120", ".4", ".5"), 120, 0.4, 0.5, 1); 111 | }); 112 | 113 | it("hsl(h, s, l, opacity) coerces opacity to number", () => { 114 | assertHslEqual(hsl(120, 0.1, 0.5, "0.2"), 120, 0.1, 0.5, 0.2); 115 | assertHslEqual(hsl(120, 0.9, 0.5, "0.9"), 120, 0.9, 0.5, 0.9); 116 | }); 117 | 118 | it("hsl(h, s, l) allows undefined channel values", () => { 119 | assertHslEqual(hsl(undefined, NaN, "foo"), NaN, NaN, NaN, 1); 120 | assertHslEqual(hsl(undefined, 0.4, 0.5), NaN, 0.4, 0.5, 1); 121 | assertHslEqual(hsl(42, undefined, 0.5), 42, NaN, 0.5, 1); 122 | assertHslEqual(hsl(42, 0.4, undefined), 42, 0.4, NaN, 1); 123 | }); 124 | 125 | it("hsl(h, s, l, opacity) converts undefined opacity to 1", () => { 126 | assertHslEqual(hsl(10, 0.2, 0.3, null), 10, 0.2, 0.3, 1); 127 | assertHslEqual(hsl(10, 0.2, 0.3, undefined), 10, 0.2, 0.3, 1); 128 | }); 129 | 130 | it("hsl(h, s, l) preserves explicit hue, even for grays", () => { 131 | assertHslEqual(hsl(0, 0, 0), 0, 0, 0, 1); 132 | assertHslEqual(hsl(42, 0, 0.5), 42, 0, 0.5, 1); 133 | assertHslEqual(hsl(118, 0, 1), 118, 0, 1, 1); 134 | }); 135 | 136 | it("hsl(h, s, l) preserves explicit saturation, even for white or black", () => { 137 | assertHslEqual(hsl(0, 0, 0), 0, 0, 0, 1); 138 | assertHslEqual(hsl(0, 0.18, 0), 0, 0.18, 0, 1); 139 | assertHslEqual(hsl(0, 0.42, 1), 0, 0.42, 1, 1); 140 | assertHslEqual(hsl(0, 1, 1), 0, 1, 1, 1); 141 | }); 142 | 143 | it("hsl(format) parses the specified format and converts to HSL", () => { 144 | assertHslEqual(hsl("#abcdef"), 210, 0.68, 0.8039215, 1); 145 | assertHslEqual(hsl("#abc"), 210, 0.25, 0.733333333, 1); 146 | assertHslEqual(hsl("rgb(12, 34, 56)"), 210, 0.647058, 0.1333333, 1); 147 | assertHslEqual(hsl("rgb(12%, 34%, 56%)"), 210, 0.647058, 0.34, 1); 148 | assertHslEqual(hsl("hsl(60,100%,20%)"), 60, 1, 0.2, 1); 149 | assertHslEqual(hsl("hsla(60,100%,20%,0.4)"), 60, 1, 0.2, 0.4); 150 | assertHslEqual(hsl("aliceblue"), 208, 1, 0.9705882, 1); 151 | assertHslEqual(hsl("transparent"), NaN, NaN, NaN, 0); 152 | }); 153 | 154 | it("hsl(format) ignores the hue if the saturation is <= 0", () => { 155 | assertHslEqual(hsl("hsl(120,0%,20%)"), NaN, 0, 0.2, 1); 156 | assertHslEqual(hsl("hsl(120,-10%,20%)"), NaN, -0.1, 0.2, 1); 157 | }); 158 | 159 | it("hsl(format) ignores the hue and saturation if the lightness is <= 0 or >= 1", () => { 160 | assertHslEqual(hsl("hsl(120,20%,-10%)"), NaN, NaN, -0.1, 1); 161 | assertHslEqual(hsl("hsl(120,20%,0%)"), NaN, NaN, 0.0, 1); 162 | assertHslEqual(hsl("hsl(120,20%,100%)"), NaN, NaN, 1.0, 1); 163 | assertHslEqual(hsl("hsl(120,20%,120%)"), NaN, NaN, 1.2, 1); 164 | }); 165 | 166 | it("hsl(format) ignores all channels if the alpha is <= 0", () => { 167 | assertHslEqual(hsl("hsla(120,20%,10%,0)"), NaN, NaN, NaN, 0); 168 | assertHslEqual(hsl("hsla(120,20%,10%,-0.1)"), NaN, NaN, NaN, -0.1); 169 | }); 170 | 171 | it("hsl(format) does not lose precision when parsing HSL formats", () => { 172 | assertHslEqual(hsl("hsl(325,50%,40%)"), 325, 0.5, 0.4, 1); 173 | }); 174 | 175 | it("hsl(format) returns undefined channel values for unknown formats", () => { 176 | assertHslEqual(hsl("invalid"), NaN, NaN, NaN, NaN); 177 | }); 178 | 179 | it("hsl(hsl) copies an HSL color", () => { 180 | const c1 = hsl("hsla(120,30%,50%,0.4)"); 181 | const c2 = hsl(c1); 182 | assertHslEqual(c1, 120, 0.3, 0.5, 0.4); 183 | c1.h = c1.s = c1.l = c1.opacity = 0; 184 | assertHslEqual(c1, 0, 0, 0, 0); 185 | assertHslEqual(c2, 120, 0.3, 0.5, 0.4); 186 | }); 187 | 188 | it("hsl(rgb) converts from RGB", () => { 189 | assertHslEqual(hsl(rgb(255, 0, 0, 0.4)), 0, 1, 0.5, 0.4); 190 | }); 191 | 192 | it("hsl(color) returns undefined hue and zero saturation for grays (but not white and black)", () => { 193 | assertHslEqual(hsl("gray"), NaN, 0, 0.5019608, 1); 194 | assertHslEqual(hsl("#ccc"), NaN, 0, 0.8, 1); 195 | assertHslEqual(hsl(rgb("gray")), NaN, 0, 0.5019608, 1); 196 | }); 197 | 198 | it("hsl(color) returns undefined hue and saturation for black and white", () => { 199 | assertHslEqual(hsl("black"), NaN, NaN, 0, 1); 200 | assertHslEqual(hsl("#000"), NaN, NaN, 0, 1); 201 | assertHslEqual(hsl("white"), NaN, NaN, 1, 1); 202 | assertHslEqual(hsl("#fff"), NaN, NaN, 1, 1); 203 | assertHslEqual(hsl(rgb("#fff")), NaN, NaN, 1, 1); 204 | }); 205 | 206 | it("hsl(color) converts from another colorspace via rgb()", () => { 207 | function TestColor() {} 208 | TestColor.prototype = Object.create(color.prototype); 209 | TestColor.prototype.rgb = function() { return rgb(12, 34, 56, 0.4); }; 210 | TestColor.prototype.toString = function() { throw new Error("should use rgb, not toString"); }; 211 | assertHslEqual(hsl(new TestColor), 210, 0.6470588, 0.1333334, 0.4); 212 | }); 213 | 214 | it("hsl.displayable() returns true if the color is within the RGB gamut and the opacity is in [0,1]", () => { 215 | assert.strictEqual(hsl("white").displayable(), true); 216 | assert.strictEqual(hsl("red").displayable(), true); 217 | assert.strictEqual(hsl("black").displayable(), true); 218 | assert.strictEqual(hsl("invalid").displayable(), false); 219 | assert.strictEqual(hsl(NaN, NaN, 1).displayable(), true); 220 | assert.strictEqual(hsl(NaN, NaN, 1.5).displayable(), false); 221 | assert.strictEqual(hsl(120, -0.5, 0).displayable(), false); 222 | assert.strictEqual(hsl(120, 1.5, 0).displayable(), false); 223 | assert.strictEqual(hsl(0, 1, 1, 0).displayable(), true); 224 | assert.strictEqual(hsl(0, 1, 1, 1).displayable(), true); 225 | assert.strictEqual(hsl(0, 1, 1, -0.2).displayable(), false); 226 | assert.strictEqual(hsl(0, 1, 1, 1.2).displayable(), false); 227 | }); 228 | 229 | it("hsl.brighter(k) returns a brighter color if k > 0", () => { 230 | const c = hsl("rgba(165, 42, 42, 0.4)"); 231 | assertHslEqual(c.brighter(0.5), 0, 0.5942028, 0.4851222, 0.4); 232 | assertHslEqual(c.brighter(1), 0, 0.5942028, 0.5798319, 0.4); 233 | assertHslEqual(c.brighter(2), 0, 0.5942028, 0.8283313, 0.4); 234 | }); 235 | 236 | it("hsl.brighter(k) returns a copy", () => { 237 | const c1 = hsl("rgba(70, 130, 180, 0.4)"); 238 | const c2 = c1.brighter(1); 239 | assertHslEqual(c1, 207.272727, 0.44, 0.4901961, 0.4); 240 | assertHslEqual(c2, 207.272727, 0.44, 0.7002801, 0.4); 241 | }); 242 | 243 | it("hsl.brighter() is equivalent to hsl.brighter(1)", () => { 244 | const c1 = hsl("rgba(70, 130, 180, 0.4)"); 245 | const c2 = c1.brighter(); 246 | const c3 = c1.brighter(1); 247 | assertHslEqual(c2, c3.h, c3.s, c3.l, 0.4); 248 | }); 249 | 250 | it("hsl.brighter(k) is equivalent to hsl.darker(-k)", () => { 251 | const c1 = hsl("rgba(70, 130, 180, 0.4)"); 252 | const c2 = c1.brighter(1.5); 253 | const c3 = c1.darker(-1.5); 254 | assertHslEqual(c2, c3.h, c3.s, c3.l, 0.4); 255 | }); 256 | 257 | it("hsl(\"black\").brighter() still returns black", () => { 258 | const c1 = hsl("black"); 259 | const c2 = c1.brighter(1); 260 | assertHslEqual(c1, NaN, NaN, 0, 1); 261 | assertHslEqual(c2, NaN, NaN, 0, 1); 262 | }); 263 | 264 | it("hsl.darker(k) returns a darker color if k > 0", () => { 265 | const c = hsl("rgba(165, 42, 42, 0.4)"); 266 | assertHslEqual(c.darker(0.5), 0, 0.5942029, 0.3395855, 0.4); 267 | assertHslEqual(c.darker(1), 0, 0.5942029, 0.2841176, 0.4); 268 | assertHslEqual(c.darker(2), 0, 0.5942029, 0.1988823, 0.4); 269 | }); 270 | 271 | it("hsl.darker(k) returns a copy", () => { 272 | const c1 = hsl("rgba(70, 130, 180, 0.4)"); 273 | const c2 = c1.darker(1); 274 | assertHslEqual(c1, 207.272727, 0.44, 0.4901961, 0.4); 275 | assertHslEqual(c2, 207.272727, 0.44, 0.3431373, 0.4); 276 | }); 277 | 278 | it("hsl.darker() is equivalent to hsl.darker(1)", () => { 279 | const c1 = hsl("rgba(70, 130, 180, 0.4)"); 280 | const c2 = c1.darker(); 281 | const c3 = c1.darker(1); 282 | assertHslEqual(c2, c3.h, c3.s, c3.l, 0.4); 283 | }); 284 | 285 | it("hsl.darker(k) is equivalent to hsl.brighter(-k)", () => { 286 | const c1 = hsl("rgba(70, 130, 180, 0.4)"); 287 | const c2 = c1.darker(1.5); 288 | const c3 = c1.brighter(-1.5); 289 | assertHslEqual(c2, c3.h, c3.s, c3.l, 0.4); 290 | }); 291 | 292 | it("hsl.rgb() converts to RGB", () => { 293 | const c = hsl(120, 0.3, 0.5, 0.4); 294 | assertRgbApproxEqual(c.rgb(), 89, 166, 89, 0.4); 295 | }); 296 | 297 | it("hsl.copy(…) returns a new hsl with the specified channel values", () => { 298 | const c = hsl(120, 0.3, 0.5, 0.4); 299 | assert.strictEqual(c.copy() instanceof hsl, true); 300 | assert.strictEqual(c.copy().formatHsl(), "hsla(120, 30%, 50%, 0.4)"); 301 | assert.strictEqual(c.copy({opacity: 1}).formatHsl(), "hsl(120, 30%, 50%)"); 302 | assert.strictEqual(c.copy({h: 20}).formatHsl(), "hsla(20, 30%, 50%, 0.4)"); 303 | assert.strictEqual(c.copy({h: 20, s: 0.4}).formatHsl(), "hsla(20, 40%, 50%, 0.4)"); 304 | }); 305 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@babel/code-frame@^7.10.4": 6 | version "7.16.7" 7 | resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" 8 | integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== 9 | dependencies: 10 | "@babel/highlight" "^7.16.7" 11 | 12 | "@babel/helper-validator-identifier@^7.16.7": 13 | version "7.16.7" 14 | resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" 15 | integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== 16 | 17 | "@babel/highlight@^7.16.7": 18 | version "7.16.10" 19 | resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.10.tgz#744f2eb81579d6eea753c227b0f570ad785aba88" 20 | integrity sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw== 21 | dependencies: 22 | "@babel/helper-validator-identifier" "^7.16.7" 23 | chalk "^2.0.0" 24 | js-tokens "^4.0.0" 25 | 26 | "@eslint/eslintrc@^1.2.1": 27 | version "1.2.1" 28 | resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.2.1.tgz#8b5e1c49f4077235516bc9ec7d41378c0f69b8c6" 29 | integrity sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ== 30 | dependencies: 31 | ajv "^6.12.4" 32 | debug "^4.3.2" 33 | espree "^9.3.1" 34 | globals "^13.9.0" 35 | ignore "^5.2.0" 36 | import-fresh "^3.2.1" 37 | js-yaml "^4.1.0" 38 | minimatch "^3.0.4" 39 | strip-json-comments "^3.1.1" 40 | 41 | "@humanwhocodes/config-array@^0.9.2": 42 | version "0.9.5" 43 | resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.5.tgz#2cbaf9a89460da24b5ca6531b8bbfc23e1df50c7" 44 | integrity sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw== 45 | dependencies: 46 | "@humanwhocodes/object-schema" "^1.2.1" 47 | debug "^4.1.1" 48 | minimatch "^3.0.4" 49 | 50 | "@humanwhocodes/object-schema@^1.2.1": 51 | version "1.2.1" 52 | resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" 53 | integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== 54 | 55 | "@types/node@*": 56 | version "17.0.23" 57 | resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.23.tgz#3b41a6e643589ac6442bdbd7a4a3ded62f33f7da" 58 | integrity sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw== 59 | 60 | "@ungap/promise-all-settled@1.1.2": 61 | version "1.1.2" 62 | resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" 63 | integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== 64 | 65 | acorn-jsx@^5.3.1: 66 | version "5.3.2" 67 | resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" 68 | integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== 69 | 70 | acorn@^8.5.0, acorn@^8.7.0: 71 | version "8.7.0" 72 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" 73 | integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== 74 | 75 | ajv@^6.10.0, ajv@^6.12.4: 76 | version "6.12.6" 77 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" 78 | integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== 79 | dependencies: 80 | fast-deep-equal "^3.1.1" 81 | fast-json-stable-stringify "^2.0.0" 82 | json-schema-traverse "^0.4.1" 83 | uri-js "^4.2.2" 84 | 85 | ansi-colors@4.1.1: 86 | version "4.1.1" 87 | resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" 88 | integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== 89 | 90 | ansi-regex@^5.0.1: 91 | version "5.0.1" 92 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" 93 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 94 | 95 | ansi-styles@^3.2.1: 96 | version "3.2.1" 97 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 98 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== 99 | dependencies: 100 | color-convert "^1.9.0" 101 | 102 | ansi-styles@^4.0.0, ansi-styles@^4.1.0: 103 | version "4.3.0" 104 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 105 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 106 | dependencies: 107 | color-convert "^2.0.1" 108 | 109 | anymatch@~3.1.2: 110 | version "3.1.2" 111 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" 112 | integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== 113 | dependencies: 114 | normalize-path "^3.0.0" 115 | picomatch "^2.0.4" 116 | 117 | argparse@^2.0.1: 118 | version "2.0.1" 119 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" 120 | integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== 121 | 122 | balanced-match@^1.0.0: 123 | version "1.0.2" 124 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 125 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 126 | 127 | binary-extensions@^2.0.0: 128 | version "2.2.0" 129 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" 130 | integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== 131 | 132 | brace-expansion@^1.1.7: 133 | version "1.1.11" 134 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 135 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 136 | dependencies: 137 | balanced-match "^1.0.0" 138 | concat-map "0.0.1" 139 | 140 | braces@~3.0.2: 141 | version "3.0.2" 142 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" 143 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 144 | dependencies: 145 | fill-range "^7.0.1" 146 | 147 | browser-stdout@1.3.1: 148 | version "1.3.1" 149 | resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" 150 | integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== 151 | 152 | buffer-from@^1.0.0: 153 | version "1.1.2" 154 | resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" 155 | integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== 156 | 157 | callsites@^3.0.0: 158 | version "3.1.0" 159 | resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" 160 | integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== 161 | 162 | camelcase@^6.0.0: 163 | version "6.3.0" 164 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" 165 | integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== 166 | 167 | chalk@^2.0.0: 168 | version "2.4.2" 169 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" 170 | integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== 171 | dependencies: 172 | ansi-styles "^3.2.1" 173 | escape-string-regexp "^1.0.5" 174 | supports-color "^5.3.0" 175 | 176 | chalk@^4.0.0, chalk@^4.1.0: 177 | version "4.1.2" 178 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" 179 | integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== 180 | dependencies: 181 | ansi-styles "^4.1.0" 182 | supports-color "^7.1.0" 183 | 184 | chokidar@3.5.3: 185 | version "3.5.3" 186 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" 187 | integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== 188 | dependencies: 189 | anymatch "~3.1.2" 190 | braces "~3.0.2" 191 | glob-parent "~5.1.2" 192 | is-binary-path "~2.1.0" 193 | is-glob "~4.0.1" 194 | normalize-path "~3.0.0" 195 | readdirp "~3.6.0" 196 | optionalDependencies: 197 | fsevents "~2.3.2" 198 | 199 | cliui@^7.0.2: 200 | version "7.0.4" 201 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" 202 | integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== 203 | dependencies: 204 | string-width "^4.2.0" 205 | strip-ansi "^6.0.0" 206 | wrap-ansi "^7.0.0" 207 | 208 | color-convert@^1.9.0: 209 | version "1.9.3" 210 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 211 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== 212 | dependencies: 213 | color-name "1.1.3" 214 | 215 | color-convert@^2.0.1: 216 | version "2.0.1" 217 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 218 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 219 | dependencies: 220 | color-name "~1.1.4" 221 | 222 | color-name@1.1.3: 223 | version "1.1.3" 224 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 225 | integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= 226 | 227 | color-name@~1.1.4: 228 | version "1.1.4" 229 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 230 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 231 | 232 | commander@^2.20.0: 233 | version "2.20.3" 234 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" 235 | integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== 236 | 237 | concat-map@0.0.1: 238 | version "0.0.1" 239 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 240 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 241 | 242 | cross-spawn@^7.0.2: 243 | version "7.0.3" 244 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" 245 | integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== 246 | dependencies: 247 | path-key "^3.1.0" 248 | shebang-command "^2.0.0" 249 | which "^2.0.1" 250 | 251 | debug@4.3.3: 252 | version "4.3.3" 253 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" 254 | integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== 255 | dependencies: 256 | ms "2.1.2" 257 | 258 | debug@^4.1.1, debug@^4.3.2: 259 | version "4.3.4" 260 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" 261 | integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== 262 | dependencies: 263 | ms "2.1.2" 264 | 265 | decamelize@^4.0.0: 266 | version "4.0.0" 267 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" 268 | integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== 269 | 270 | deep-is@^0.1.3: 271 | version "0.1.4" 272 | resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" 273 | integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== 274 | 275 | diff@5.0.0: 276 | version "5.0.0" 277 | resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" 278 | integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== 279 | 280 | doctrine@^3.0.0: 281 | version "3.0.0" 282 | resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" 283 | integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== 284 | dependencies: 285 | esutils "^2.0.2" 286 | 287 | emoji-regex@^8.0.0: 288 | version "8.0.0" 289 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 290 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 291 | 292 | escalade@^3.1.1: 293 | version "3.1.1" 294 | resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" 295 | integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== 296 | 297 | escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: 298 | version "4.0.0" 299 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" 300 | integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== 301 | 302 | escape-string-regexp@^1.0.5: 303 | version "1.0.5" 304 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 305 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= 306 | 307 | eslint-scope@^7.1.1: 308 | version "7.1.1" 309 | resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642" 310 | integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== 311 | dependencies: 312 | esrecurse "^4.3.0" 313 | estraverse "^5.2.0" 314 | 315 | eslint-utils@^3.0.0: 316 | version "3.0.0" 317 | resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" 318 | integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== 319 | dependencies: 320 | eslint-visitor-keys "^2.0.0" 321 | 322 | eslint-visitor-keys@^2.0.0: 323 | version "2.1.0" 324 | resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" 325 | integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== 326 | 327 | eslint-visitor-keys@^3.3.0: 328 | version "3.3.0" 329 | resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" 330 | integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== 331 | 332 | eslint@8: 333 | version "8.12.0" 334 | resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.12.0.tgz#c7a5bd1cfa09079aae64c9076c07eada66a46e8e" 335 | integrity sha512-it1oBL9alZg1S8UycLm5YDMAkIhtH6FtAzuZs6YvoGVldWjbS08BkAdb/ymP9LlAyq8koANu32U7Ib/w+UNh8Q== 336 | dependencies: 337 | "@eslint/eslintrc" "^1.2.1" 338 | "@humanwhocodes/config-array" "^0.9.2" 339 | ajv "^6.10.0" 340 | chalk "^4.0.0" 341 | cross-spawn "^7.0.2" 342 | debug "^4.3.2" 343 | doctrine "^3.0.0" 344 | escape-string-regexp "^4.0.0" 345 | eslint-scope "^7.1.1" 346 | eslint-utils "^3.0.0" 347 | eslint-visitor-keys "^3.3.0" 348 | espree "^9.3.1" 349 | esquery "^1.4.0" 350 | esutils "^2.0.2" 351 | fast-deep-equal "^3.1.3" 352 | file-entry-cache "^6.0.1" 353 | functional-red-black-tree "^1.0.1" 354 | glob-parent "^6.0.1" 355 | globals "^13.6.0" 356 | ignore "^5.2.0" 357 | import-fresh "^3.0.0" 358 | imurmurhash "^0.1.4" 359 | is-glob "^4.0.0" 360 | js-yaml "^4.1.0" 361 | json-stable-stringify-without-jsonify "^1.0.1" 362 | levn "^0.4.1" 363 | lodash.merge "^4.6.2" 364 | minimatch "^3.0.4" 365 | natural-compare "^1.4.0" 366 | optionator "^0.9.1" 367 | regexpp "^3.2.0" 368 | strip-ansi "^6.0.1" 369 | strip-json-comments "^3.1.0" 370 | text-table "^0.2.0" 371 | v8-compile-cache "^2.0.3" 372 | 373 | espree@^9.3.1: 374 | version "9.3.1" 375 | resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.1.tgz#8793b4bc27ea4c778c19908e0719e7b8f4115bcd" 376 | integrity sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ== 377 | dependencies: 378 | acorn "^8.7.0" 379 | acorn-jsx "^5.3.1" 380 | eslint-visitor-keys "^3.3.0" 381 | 382 | esquery@^1.4.0: 383 | version "1.4.0" 384 | resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" 385 | integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== 386 | dependencies: 387 | estraverse "^5.1.0" 388 | 389 | esrecurse@^4.3.0: 390 | version "4.3.0" 391 | resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" 392 | integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== 393 | dependencies: 394 | estraverse "^5.2.0" 395 | 396 | estraverse@^5.1.0, estraverse@^5.2.0: 397 | version "5.3.0" 398 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" 399 | integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== 400 | 401 | esutils@^2.0.2: 402 | version "2.0.3" 403 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" 404 | integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== 405 | 406 | fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: 407 | version "3.1.3" 408 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" 409 | integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== 410 | 411 | fast-json-stable-stringify@^2.0.0: 412 | version "2.1.0" 413 | resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" 414 | integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== 415 | 416 | fast-levenshtein@^2.0.6: 417 | version "2.0.6" 418 | resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" 419 | integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= 420 | 421 | file-entry-cache@^6.0.1: 422 | version "6.0.1" 423 | resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" 424 | integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== 425 | dependencies: 426 | flat-cache "^3.0.4" 427 | 428 | fill-range@^7.0.1: 429 | version "7.0.1" 430 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" 431 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 432 | dependencies: 433 | to-regex-range "^5.0.1" 434 | 435 | find-up@5.0.0: 436 | version "5.0.0" 437 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" 438 | integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== 439 | dependencies: 440 | locate-path "^6.0.0" 441 | path-exists "^4.0.0" 442 | 443 | flat-cache@^3.0.4: 444 | version "3.0.4" 445 | resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" 446 | integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== 447 | dependencies: 448 | flatted "^3.1.0" 449 | rimraf "^3.0.2" 450 | 451 | flat@^5.0.2: 452 | version "5.0.2" 453 | resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" 454 | integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== 455 | 456 | flatted@^3.1.0: 457 | version "3.2.5" 458 | resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" 459 | integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== 460 | 461 | fs.realpath@^1.0.0: 462 | version "1.0.0" 463 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 464 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 465 | 466 | fsevents@~2.3.2: 467 | version "2.3.2" 468 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" 469 | integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== 470 | 471 | functional-red-black-tree@^1.0.1: 472 | version "1.0.1" 473 | resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" 474 | integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= 475 | 476 | get-caller-file@^2.0.5: 477 | version "2.0.5" 478 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" 479 | integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== 480 | 481 | glob-parent@^6.0.1: 482 | version "6.0.2" 483 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" 484 | integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== 485 | dependencies: 486 | is-glob "^4.0.3" 487 | 488 | glob-parent@~5.1.2: 489 | version "5.1.2" 490 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" 491 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 492 | dependencies: 493 | is-glob "^4.0.1" 494 | 495 | glob@7.2.0, glob@^7.1.3: 496 | version "7.2.0" 497 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" 498 | integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== 499 | dependencies: 500 | fs.realpath "^1.0.0" 501 | inflight "^1.0.4" 502 | inherits "2" 503 | minimatch "^3.0.4" 504 | once "^1.3.0" 505 | path-is-absolute "^1.0.0" 506 | 507 | globals@^13.6.0, globals@^13.9.0: 508 | version "13.13.0" 509 | resolved "https://registry.yarnpkg.com/globals/-/globals-13.13.0.tgz#ac32261060d8070e2719dd6998406e27d2b5727b" 510 | integrity sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A== 511 | dependencies: 512 | type-fest "^0.20.2" 513 | 514 | growl@1.10.5: 515 | version "1.10.5" 516 | resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" 517 | integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== 518 | 519 | has-flag@^3.0.0: 520 | version "3.0.0" 521 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 522 | integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= 523 | 524 | has-flag@^4.0.0: 525 | version "4.0.0" 526 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" 527 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 528 | 529 | he@1.2.0: 530 | version "1.2.0" 531 | resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" 532 | integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== 533 | 534 | ignore@^5.2.0: 535 | version "5.2.0" 536 | resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" 537 | integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== 538 | 539 | import-fresh@^3.0.0, import-fresh@^3.2.1: 540 | version "3.3.0" 541 | resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" 542 | integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== 543 | dependencies: 544 | parent-module "^1.0.0" 545 | resolve-from "^4.0.0" 546 | 547 | imurmurhash@^0.1.4: 548 | version "0.1.4" 549 | resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" 550 | integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= 551 | 552 | inflight@^1.0.4: 553 | version "1.0.6" 554 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 555 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 556 | dependencies: 557 | once "^1.3.0" 558 | wrappy "1" 559 | 560 | inherits@2: 561 | version "2.0.4" 562 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 563 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 564 | 565 | is-binary-path@~2.1.0: 566 | version "2.1.0" 567 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" 568 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== 569 | dependencies: 570 | binary-extensions "^2.0.0" 571 | 572 | is-extglob@^2.1.1: 573 | version "2.1.1" 574 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 575 | integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= 576 | 577 | is-fullwidth-code-point@^3.0.0: 578 | version "3.0.0" 579 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 580 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 581 | 582 | is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: 583 | version "4.0.3" 584 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" 585 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== 586 | dependencies: 587 | is-extglob "^2.1.1" 588 | 589 | is-number@^7.0.0: 590 | version "7.0.0" 591 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" 592 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 593 | 594 | is-plain-obj@^2.1.0: 595 | version "2.1.0" 596 | resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" 597 | integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== 598 | 599 | is-unicode-supported@^0.1.0: 600 | version "0.1.0" 601 | resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" 602 | integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== 603 | 604 | isexe@^2.0.0: 605 | version "2.0.0" 606 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 607 | integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= 608 | 609 | jest-worker@^26.2.1: 610 | version "26.6.2" 611 | resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" 612 | integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== 613 | dependencies: 614 | "@types/node" "*" 615 | merge-stream "^2.0.0" 616 | supports-color "^7.0.0" 617 | 618 | js-tokens@^4.0.0: 619 | version "4.0.0" 620 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" 621 | integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== 622 | 623 | js-yaml@4.1.0, js-yaml@^4.1.0: 624 | version "4.1.0" 625 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" 626 | integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== 627 | dependencies: 628 | argparse "^2.0.1" 629 | 630 | json-schema-traverse@^0.4.1: 631 | version "0.4.1" 632 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" 633 | integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== 634 | 635 | json-stable-stringify-without-jsonify@^1.0.1: 636 | version "1.0.1" 637 | resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" 638 | integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= 639 | 640 | levn@^0.4.1: 641 | version "0.4.1" 642 | resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" 643 | integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== 644 | dependencies: 645 | prelude-ls "^1.2.1" 646 | type-check "~0.4.0" 647 | 648 | locate-path@^6.0.0: 649 | version "6.0.0" 650 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" 651 | integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== 652 | dependencies: 653 | p-locate "^5.0.0" 654 | 655 | lodash.merge@^4.6.2: 656 | version "4.6.2" 657 | resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" 658 | integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== 659 | 660 | log-symbols@4.1.0: 661 | version "4.1.0" 662 | resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" 663 | integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== 664 | dependencies: 665 | chalk "^4.1.0" 666 | is-unicode-supported "^0.1.0" 667 | 668 | merge-stream@^2.0.0: 669 | version "2.0.0" 670 | resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" 671 | integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== 672 | 673 | minimatch@4.2.1: 674 | version "4.2.1" 675 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-4.2.1.tgz#40d9d511a46bdc4e563c22c3080cde9c0d8299b4" 676 | integrity sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g== 677 | dependencies: 678 | brace-expansion "^1.1.7" 679 | 680 | minimatch@^3.0.4: 681 | version "3.1.2" 682 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" 683 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== 684 | dependencies: 685 | brace-expansion "^1.1.7" 686 | 687 | mocha@9: 688 | version "9.2.2" 689 | resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.2.tgz#d70db46bdb93ca57402c809333e5a84977a88fb9" 690 | integrity sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g== 691 | dependencies: 692 | "@ungap/promise-all-settled" "1.1.2" 693 | ansi-colors "4.1.1" 694 | browser-stdout "1.3.1" 695 | chokidar "3.5.3" 696 | debug "4.3.3" 697 | diff "5.0.0" 698 | escape-string-regexp "4.0.0" 699 | find-up "5.0.0" 700 | glob "7.2.0" 701 | growl "1.10.5" 702 | he "1.2.0" 703 | js-yaml "4.1.0" 704 | log-symbols "4.1.0" 705 | minimatch "4.2.1" 706 | ms "2.1.3" 707 | nanoid "3.3.1" 708 | serialize-javascript "6.0.0" 709 | strip-json-comments "3.1.1" 710 | supports-color "8.1.1" 711 | which "2.0.2" 712 | workerpool "6.2.0" 713 | yargs "16.2.0" 714 | yargs-parser "20.2.4" 715 | yargs-unparser "2.0.0" 716 | 717 | ms@2.1.2: 718 | version "2.1.2" 719 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 720 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 721 | 722 | ms@2.1.3: 723 | version "2.1.3" 724 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" 725 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== 726 | 727 | nanoid@3.3.1: 728 | version "3.3.1" 729 | resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" 730 | integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== 731 | 732 | natural-compare@^1.4.0: 733 | version "1.4.0" 734 | resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" 735 | integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= 736 | 737 | normalize-path@^3.0.0, normalize-path@~3.0.0: 738 | version "3.0.0" 739 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" 740 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 741 | 742 | once@^1.3.0: 743 | version "1.4.0" 744 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 745 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 746 | dependencies: 747 | wrappy "1" 748 | 749 | optionator@^0.9.1: 750 | version "0.9.1" 751 | resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" 752 | integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== 753 | dependencies: 754 | deep-is "^0.1.3" 755 | fast-levenshtein "^2.0.6" 756 | levn "^0.4.1" 757 | prelude-ls "^1.2.1" 758 | type-check "^0.4.0" 759 | word-wrap "^1.2.3" 760 | 761 | p-limit@^3.0.2: 762 | version "3.1.0" 763 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" 764 | integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== 765 | dependencies: 766 | yocto-queue "^0.1.0" 767 | 768 | p-locate@^5.0.0: 769 | version "5.0.0" 770 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" 771 | integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== 772 | dependencies: 773 | p-limit "^3.0.2" 774 | 775 | parent-module@^1.0.0: 776 | version "1.0.1" 777 | resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" 778 | integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== 779 | dependencies: 780 | callsites "^3.0.0" 781 | 782 | path-exists@^4.0.0: 783 | version "4.0.0" 784 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" 785 | integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== 786 | 787 | path-is-absolute@^1.0.0: 788 | version "1.0.1" 789 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 790 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 791 | 792 | path-key@^3.1.0: 793 | version "3.1.1" 794 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" 795 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 796 | 797 | picomatch@^2.0.4, picomatch@^2.2.1: 798 | version "2.3.1" 799 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" 800 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== 801 | 802 | prelude-ls@^1.2.1: 803 | version "1.2.1" 804 | resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" 805 | integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== 806 | 807 | punycode@^2.1.0: 808 | version "2.1.1" 809 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" 810 | integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== 811 | 812 | randombytes@^2.1.0: 813 | version "2.1.0" 814 | resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" 815 | integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== 816 | dependencies: 817 | safe-buffer "^5.1.0" 818 | 819 | readdirp@~3.6.0: 820 | version "3.6.0" 821 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" 822 | integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== 823 | dependencies: 824 | picomatch "^2.2.1" 825 | 826 | regexpp@^3.2.0: 827 | version "3.2.0" 828 | resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" 829 | integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== 830 | 831 | require-directory@^2.1.1: 832 | version "2.1.1" 833 | resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" 834 | integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= 835 | 836 | resolve-from@^4.0.0: 837 | version "4.0.0" 838 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" 839 | integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== 840 | 841 | rimraf@^3.0.2: 842 | version "3.0.2" 843 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" 844 | integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== 845 | dependencies: 846 | glob "^7.1.3" 847 | 848 | rollup-plugin-terser@7: 849 | version "7.0.2" 850 | resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz#e8fbba4869981b2dc35ae7e8a502d5c6c04d324d" 851 | integrity sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ== 852 | dependencies: 853 | "@babel/code-frame" "^7.10.4" 854 | jest-worker "^26.2.1" 855 | serialize-javascript "^4.0.0" 856 | terser "^5.0.0" 857 | 858 | rollup@2: 859 | version "2.70.1" 860 | resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.70.1.tgz#824b1f1f879ea396db30b0fc3ae8d2fead93523e" 861 | integrity sha512-CRYsI5EuzLbXdxC6RnYhOuRdtz4bhejPMSWjsFLfVM/7w/85n2szZv6yExqUXsBdz5KT8eoubeyDUDjhLHEslA== 862 | optionalDependencies: 863 | fsevents "~2.3.2" 864 | 865 | safe-buffer@^5.1.0: 866 | version "5.2.1" 867 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 868 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 869 | 870 | serialize-javascript@6.0.0: 871 | version "6.0.0" 872 | resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" 873 | integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== 874 | dependencies: 875 | randombytes "^2.1.0" 876 | 877 | serialize-javascript@^4.0.0: 878 | version "4.0.0" 879 | resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" 880 | integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== 881 | dependencies: 882 | randombytes "^2.1.0" 883 | 884 | shebang-command@^2.0.0: 885 | version "2.0.0" 886 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" 887 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== 888 | dependencies: 889 | shebang-regex "^3.0.0" 890 | 891 | shebang-regex@^3.0.0: 892 | version "3.0.0" 893 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" 894 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 895 | 896 | source-map-support@~0.5.20: 897 | version "0.5.21" 898 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" 899 | integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== 900 | dependencies: 901 | buffer-from "^1.0.0" 902 | source-map "^0.6.0" 903 | 904 | source-map@^0.6.0: 905 | version "0.6.1" 906 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" 907 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== 908 | 909 | source-map@~0.7.2: 910 | version "0.7.3" 911 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" 912 | integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== 913 | 914 | string-width@^4.1.0, string-width@^4.2.0: 915 | version "4.2.3" 916 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" 917 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 918 | dependencies: 919 | emoji-regex "^8.0.0" 920 | is-fullwidth-code-point "^3.0.0" 921 | strip-ansi "^6.0.1" 922 | 923 | strip-ansi@^6.0.0, strip-ansi@^6.0.1: 924 | version "6.0.1" 925 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" 926 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 927 | dependencies: 928 | ansi-regex "^5.0.1" 929 | 930 | strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: 931 | version "3.1.1" 932 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" 933 | integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== 934 | 935 | supports-color@8.1.1: 936 | version "8.1.1" 937 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" 938 | integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== 939 | dependencies: 940 | has-flag "^4.0.0" 941 | 942 | supports-color@^5.3.0: 943 | version "5.5.0" 944 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 945 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== 946 | dependencies: 947 | has-flag "^3.0.0" 948 | 949 | supports-color@^7.0.0, supports-color@^7.1.0: 950 | version "7.2.0" 951 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" 952 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== 953 | dependencies: 954 | has-flag "^4.0.0" 955 | 956 | terser@^5.0.0: 957 | version "5.12.1" 958 | resolved "https://registry.yarnpkg.com/terser/-/terser-5.12.1.tgz#4cf2ebed1f5bceef5c83b9f60104ac4a78b49e9c" 959 | integrity sha512-NXbs+7nisos5E+yXwAD+y7zrcTkMqb0dEJxIGtSKPdCBzopf7ni4odPul2aechpV7EXNvOudYOX2bb5tln1jbQ== 960 | dependencies: 961 | acorn "^8.5.0" 962 | commander "^2.20.0" 963 | source-map "~0.7.2" 964 | source-map-support "~0.5.20" 965 | 966 | text-table@^0.2.0: 967 | version "0.2.0" 968 | resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" 969 | integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= 970 | 971 | to-regex-range@^5.0.1: 972 | version "5.0.1" 973 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" 974 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 975 | dependencies: 976 | is-number "^7.0.0" 977 | 978 | type-check@^0.4.0, type-check@~0.4.0: 979 | version "0.4.0" 980 | resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" 981 | integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== 982 | dependencies: 983 | prelude-ls "^1.2.1" 984 | 985 | type-fest@^0.20.2: 986 | version "0.20.2" 987 | resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" 988 | integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== 989 | 990 | uri-js@^4.2.2: 991 | version "4.4.1" 992 | resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" 993 | integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== 994 | dependencies: 995 | punycode "^2.1.0" 996 | 997 | v8-compile-cache@^2.0.3: 998 | version "2.3.0" 999 | resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" 1000 | integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== 1001 | 1002 | which@2.0.2, which@^2.0.1: 1003 | version "2.0.2" 1004 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" 1005 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 1006 | dependencies: 1007 | isexe "^2.0.0" 1008 | 1009 | word-wrap@^1.2.3: 1010 | version "1.2.3" 1011 | resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" 1012 | integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== 1013 | 1014 | workerpool@6.2.0: 1015 | version "6.2.0" 1016 | resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.0.tgz#827d93c9ba23ee2019c3ffaff5c27fccea289e8b" 1017 | integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A== 1018 | 1019 | wrap-ansi@^7.0.0: 1020 | version "7.0.0" 1021 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" 1022 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== 1023 | dependencies: 1024 | ansi-styles "^4.0.0" 1025 | string-width "^4.1.0" 1026 | strip-ansi "^6.0.0" 1027 | 1028 | wrappy@1: 1029 | version "1.0.2" 1030 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1031 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 1032 | 1033 | y18n@^5.0.5: 1034 | version "5.0.8" 1035 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" 1036 | integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== 1037 | 1038 | yargs-parser@20.2.4: 1039 | version "20.2.4" 1040 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" 1041 | integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== 1042 | 1043 | yargs-parser@^20.2.2: 1044 | version "20.2.9" 1045 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" 1046 | integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== 1047 | 1048 | yargs-unparser@2.0.0: 1049 | version "2.0.0" 1050 | resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" 1051 | integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== 1052 | dependencies: 1053 | camelcase "^6.0.0" 1054 | decamelize "^4.0.0" 1055 | flat "^5.0.2" 1056 | is-plain-obj "^2.1.0" 1057 | 1058 | yargs@16.2.0: 1059 | version "16.2.0" 1060 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" 1061 | integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== 1062 | dependencies: 1063 | cliui "^7.0.2" 1064 | escalade "^3.1.1" 1065 | get-caller-file "^2.0.5" 1066 | require-directory "^2.1.1" 1067 | string-width "^4.2.0" 1068 | y18n "^5.0.5" 1069 | yargs-parser "^20.2.2" 1070 | 1071 | yocto-queue@^0.1.0: 1072 | version "0.1.0" 1073 | resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" 1074 | integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== 1075 | --------------------------------------------------------------------------------