├── .github
└── dependabot.yml
├── .gitignore
├── .taskcluster.yml
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── package.json
├── src
├── index.d.ts
├── index.js
└── slugid.js
├── test
└── slugid_test.js
└── yarn.lock
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # To get started with Dependabot version updates, you'll need to specify which
2 | # package ecosystems to update and where the package manifests are located.
3 | # Please see the documentation for all configuration options:
4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5 |
6 | version: 2
7 | updates:
8 | - package-ecosystem: "npm"
9 | directory: "/"
10 | schedule:
11 | interval: "monthly"
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
--------------------------------------------------------------------------------
/.taskcluster.yml:
--------------------------------------------------------------------------------
1 | version: 1
2 | policy:
3 | pullRequests: public
4 | tasks:
5 | $let:
6 | head_rev:
7 | $if: tasks_for == "github-pull-request"
8 | then: ${event.pull_request.head.sha}
9 | else: ${event.after}
10 | repository:
11 | $if: tasks_for == "github-pull-request"
12 | then: ${event.pull_request.head.repo.html_url}
13 | else: ${event.repository.html_url}
14 | environments:
15 | - image: node:18
16 | description: Run tests with node v18
17 | command: yarn test
18 | - image: node:latest
19 | description: Run tests with latest node
20 | command: yarn test
21 | - image: node:latest
22 | description: Run tests with latest node without Buffer
23 | command: yarn run test-nobuffer
24 | in:
25 | $if: tasks_for == "github-pull-request" && event["action"] in ["opened","reopened","synchronize"]
26 | then:
27 | $map: {$eval: environments}
28 | each(env):
29 | taskId: {$eval: as_slugid(env.image + ":tests")}
30 | deadline:
31 | $fromNow: 1 day
32 | taskQueueId: proj-taskcluster/ci
33 | metadata:
34 | name: ${env.image} tests
35 | description: ${env.description}
36 | owner: ${event.sender.login}@users.noreply.github.com
37 | source: ${event.repository.url}
38 | payload:
39 | maxRunTime: 3600
40 | image: ${env.image}
41 | command:
42 | - /bin/bash
43 | - '--login'
44 | - '-c'
45 | - >-
46 | set -o xtrace &&
47 | git --version &&
48 | node -v &&
49 | yarn -v &&
50 | git clone --no-progress ${repository} repo &&
51 | cd repo &&
52 | git config advice.detachedHead false &&
53 | git checkout --no-progress ${head_rev} &&
54 | yarn install &&
55 | ${env.command}
56 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog for slugid
2 |
3 | ## v3.1.0 (2022-09-05)
4 |
5 | * Buffer usage is [optional](https://github.com/taskcluster/slugid/pull/24) for browsers
6 |
7 | ## v3.0.0 (2021-08-06)
8 |
9 | * Drop support for node 4 (Node v6.17.1 is the earliest tested release)
10 | * Add support for node 12, 14, and 16
11 | * Remove unmaintained [uuid-parse](https://www.npmjs.com/package/uuid-parse)
12 | * Update to [uuid](https://www.npmjs.com/package/uuid) 8.3.2, which now
13 | includes UUID parsing functions (again)
14 | * Use ``Buffer.from(bytes)`` instead of the
15 | [insecure](https://nodejs.org/en/docs/guides/buffer-constructor-deprecation/)
16 | ``new Buffer(bytes)``
17 | * Switch from TravisCI to Taskcluster for testing pull requests
18 | * Add Code of Conduct, Contributing Guide, and Changelog
19 |
20 | ## v2.0.0 (2018-05-07)
21 |
22 | * Drop support for node 0.10, 0.11
23 | * Add support for node 4, 6, 8, and 10
24 | * Update to [uuid](https://www.npmjs.com/package/uuid) 3.2.1
25 | * Add [uuid-parse](https://www.npmjs.com/package/uuid-parse) 1.0.0 to parse
26 | UUIDs (instead of ``uuid``)
27 |
28 | ## v1.1.0 (2015-08-27)
29 |
30 | * Add `slugid.nice()`, which ensures the first letter of the slug begins with a
31 | letter, allowing it to be used in more contexts
32 | * Update to [uuid](https://www.npmjs.com/package/uuid) 2.0.1
33 |
34 | ## v1.0.3 (2014-10-06)
35 |
36 | * Remove extra files not needed for the browser variant built with Browserify
37 |
38 | ## v1.0.2 (2014-08-19)
39 |
40 | * Add a variant that runs in a browser using [Browserify](https://browserify.org/) 5.9.1
41 |
42 | ## v1.0.1 (2014-03-28)
43 |
44 | * Add ``index.js`` with proper exports.
45 |
46 | ## v1.0.0 (2014-03-27)
47 |
48 | * Initial release of code ported from Taskcluster
49 |
50 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Community Participation Guidelines
2 |
3 | This repository is governed by Mozilla's code of conduct and etiquette guidelines.
4 | For more details, please read the
5 | [Mozilla Community Participation Guidelines](https://www.mozilla.org/about/governance/policies/participation/).
6 |
7 | ## How to Report
8 | For more information on how to report violations of the Community Participation Guidelines, please read our '[How to Report](https://www.mozilla.org/about/governance/policies/participation/reporting/)' page.
9 |
10 |
16 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # How to Contribute
2 |
3 | We welcome pull requests from everyone. We do expect everyone to adhere to the [Mozilla Community Participation Guidelines][participation].
4 |
5 | If you're trying to figure out what to work on, here are some places to find suitable projects:
6 | * [Good first bugs][goodfirstbug]: these are scoped to make it easy for first-time contributors to get their feet wet with Taskcluster code.
7 | * [Mentored bugs][bugsahoy]: these are slightly more involved projects that may require insight or guidance from someone on the Taskcluster team.
8 | * [Full list of open issues][issues]: everything else
9 |
10 | If the project you're interested in working on isn't covered by a bug or issue, or you're unsure about how to proceed on an existing issue, it's a good idea to talk to someone on the Taskcluster team before you go too far down a particular path. You can find us in the #taskcluster channel on [Mozilla's IRC server][irc] to discuss. You can also simply add a comment to the issue or bug.
11 |
12 | Once you've found an issue to work on and written a patch, submit a pull request. Some things that will increase the chance that your pull request is accepted:
13 |
14 | * Follow our [best practices][bestpractices].
15 | * This includes [writing or updating tests][testing].
16 | * Write a [good commit message][commit].
17 |
18 | Welcome to the team!
19 |
20 | [participation]: https://www.mozilla.org/en-US/about/governance/policies/participation/
21 | [issues]: ../../issues
22 | [bugsahoy]: https://www.joshmatthews.net/bugsahoy/?taskcluster=1
23 | [goodfirstbug]: http://www.joshmatthews.net/bugsahoy/?taskcluster=1&simple=1
24 | [irc]: https://wiki.mozilla.org/IRC
25 | [bestpractices]: https://docs.taskcluster.net/docs/manual/design/devel/best-practices
26 | [testing]: https://docs.taskcluster.net/docs/manual/design/devel/best-practices/testing
27 | [commit]: https://docs.taskcluster.net/docs/manual/design/devel/best-practices/commits
28 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Jonas Finnemann Jensen
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # slugid - Compressed UUIDs for Node.js
4 |
5 | A node.js module for generating v4 UUIDs and encoding them into 22 character
6 | URL-safe base64 slug representation (see [RFC 4648 sec.
7 | 5](http://tools.ietf.org/html/rfc4648#section-5)).
8 |
9 | Slugs are url-safe base64 encoded v4 uuids, stripped of base64 `=` padding.
10 | They are generated with the [uuid package](https://www.npmjs.com/package/uuid) which
11 | is careful to use a cryptographically strong random number generator on platforms
12 | that make one available.
13 |
14 | There are two methods for generating slugs - `slugid.v4()` and `slugid.nice()`.
15 |
16 | The `slugid.v4()` method returns a slug from a randomly generated v4 uuid. The
17 | `slugid.nice()` method returns a v4 slug which conforms to a set of "nice"
18 | properties. At the moment the only "nice" property is that the slug starts with
19 | [A-Za-f], which in turn implies that the first (most significant) but of its
20 | associated uuid is set to 0.
21 |
22 | The purpose of the `slugid.nice()` method is to support having slugids which
23 | can be used in more contexts safely. Regular slugids can safely be used in
24 | urls, and for example in AMQP routing keys. However, slugs beginning with `-`
25 | may cause problems when used as command line parameters.
26 |
27 | In contrast, slugids generated by the `slugid.nice()` method can safely be used
28 | as command line parameters. This comes at a cost to entropy (121 bits vs 122
29 | bits for regular v4 slugs).
30 |
31 | Slug consumers should consider carefully which of these two slug generation
32 | methods to call. Is it more important to have maximum entropy, or to have
33 | slugids that do not need special treatment when used as command line
34 | parameters? This is especially important if you are providing a service which
35 | supplies slugs to unexpecting tool developers downstream, who may not realise
36 | the risks of using your regular v4 slugs as command line parameters, especially
37 | since this would arise only as an intermittent issue (one time in 64).
38 |
39 | Generated slugs take the form `[A-Za-z0-9_-]{22}`, or more precisely:
40 |
41 | * `slugid.v4()` slugs conform to
42 | `[A-Za-z0-9_-]{8}[Q-T][A-Za-z0-9_-][CGKOSWaeimquy26-][A-Za-z0-9_-]{10}[AQgw]`
43 |
44 | * `slugid.nice()` slugs conform to
45 | `[A-Za-f][A-Za-z0-9_-]{7}[Q-T][A-Za-z0-9_-][CGKOSWaeimquy26-][A-Za-z0-9_-]{10}[AQgw]`
46 |
47 | RFC 4122 defines the setting of 6 bits of the v4 UUID which determines these
48 | regular expressions.
49 |
50 | ```js
51 | const slugid = require('slugid');
52 |
53 | // Generate "nice" URL-safe base64 encoded UUID version 4 (random)
54 | const slug = slugid.nice(); // a8_YezW8T7e1jLxG7evy-A
55 | ```
56 |
57 | Encode / Decode
58 | ---------------
59 | ```js
60 | const slugid = require('slugid');
61 |
62 | // Generate URL-safe base64 encoded UUID version 4 (random)
63 | const slug = slugid.v4();
64 |
65 | // Get UUID on the form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
66 | const uuid = slugid.decode(slug);
67 |
68 | // Compress to slug again
69 | assert(slug == slugid.encode(uuid));
70 | ```
71 |
72 | License
73 | -------
74 | The `slugid` library is released on the MIT license, see the `LICENSE` for
75 | complete license.
76 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "slugid",
3 | "version": "5.0.1",
4 | "author": "Jonas Finnemann Jensen ",
5 | "description": "URL-safe base64 UUID encoder for generating 22 character slugs",
6 | "license": "MIT",
7 | "main": "./src/index.js",
8 | "files": [
9 | "src"
10 | ],
11 | "scripts": {
12 | "test": "mocha",
13 | "test-nobuffer": "NO_BUFFER=1 yarn test"
14 | },
15 | "repository": {
16 | "type": "git",
17 | "url": "git+https://github.com/taskcluster/slugid.git"
18 | },
19 | "types": "./src/index.d.ts",
20 | "bugs": {
21 | "url": "https://github.com/taskcluster/slugid/issues"
22 | },
23 | "engines": {
24 | "node": ">=18"
25 | },
26 | "dependencies": {
27 | "uuid": "^9.0.0"
28 | },
29 | "devDependencies": {
30 | "mocha": "^10.2.0"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/index.d.ts:
--------------------------------------------------------------------------------
1 | export function decode(slug: string): string;
2 | export function encode(uuid: string): string;
3 | export function v4(): string;
4 | export function nice(): string;
5 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2014 Jonas Finnemann Jensen
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | module.exports = require('./slugid');
24 |
--------------------------------------------------------------------------------
/src/slugid.js:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2014 Jonas Finnemann Jensen
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | const uuid = require('uuid');
24 |
25 | /** @type {(bytes: Uint8Array) => string} */
26 | const toBase64 = (() => {
27 | if (typeof Buffer !== 'undefined') {
28 | return (bytes) => Buffer.from(bytes).toString('base64');
29 | }
30 | return (bytes) => btoa(String.fromCharCode(...bytes));
31 | })();
32 |
33 | /** @type {(base64: string) => Uint8Array | Buffer} */
34 | const fromBase64 = (() => {
35 | if (typeof Buffer !== 'undefined') {
36 | return (base64) => Buffer.from(base64, 'base64');
37 | }
38 | return (base64) => Uint8Array.from(atob(base64), c => c.charCodeAt(0));
39 | })();
40 |
41 | /**
42 | * Returns the given uuid as a 22 character slug. This can be a regular v4
43 | * slug or a "nice" slug.
44 | */
45 | exports.encode = function(uuid_) {
46 | const bytes = uuid.parse(uuid_);
47 | const base64 = toBase64(bytes);
48 | const slug = base64
49 | .replace(/\+/g, '-') // Replace + with - (see RFC 4648, sec. 5)
50 | .replace(/\//g, '_') // Replace / with _ (see RFC 4648, sec. 5)
51 | .substring(0, 22); // Drop '==' padding
52 | return slug;
53 | };
54 |
55 | /**
56 | * Returns the uuid represented by the given v4 or "nice" slug
57 | */
58 | exports.decode = function(slug) {
59 | const base64 = slug
60 | .replace(/-/g, '+')
61 | .replace(/_/g, '/')
62 | + '==';
63 | return uuid.stringify(fromBase64(base64));
64 | };
65 |
66 | /**
67 | * Returns a randomly generated uuid v4 compliant slug
68 | */
69 | exports.v4 = function() {
70 | const bytes = uuid.v4(null, new Uint8Array(16));
71 | const base64 = toBase64(bytes);
72 | const slug = base64
73 | .replace(/\+/g, '-') // Replace + with - (see RFC 4648, sec. 5)
74 | .replace(/\//g, '_') // Replace / with _ (see RFC 4648, sec. 5)
75 | .substring(0, 22); // Drop '==' padding
76 | return slug;
77 | };
78 |
79 | /**
80 | * Returns a randomly generated uuid v4 compliant slug which conforms to a set
81 | * of "nice" properties, at the cost of some entropy. Currently this means one
82 | * extra fixed bit (the first bit of the uuid is set to 0) which guarantees the
83 | * slug will begin with [A-Za-f]. For example such slugs don't require special
84 | * handling when used as command line parameters (whereas non-nice slugs may
85 | * start with `-` which can confuse command line tools).
86 | *
87 | * Potentially other "nice" properties may be added in future to further
88 | * restrict the range of potential uuids that may be generated.
89 | */
90 | exports.nice = function() {
91 | const bytes = uuid.v4(null, new Uint8Array(16));
92 | bytes[0] = bytes[0] & 0x7f; // unset first bit to ensure [A-Za-f] first char
93 | const base64 = toBase64(bytes);
94 | const slug = base64
95 | .replace(/\+/g, '-') // Replace + with - (see RFC 4648, sec. 5)
96 | .replace(/\//g, '_') // Replace / with _ (see RFC 4648, sec. 5)
97 | .substring(0, 22); // Drop '==' padding
98 | return slug;
99 | };
100 |
--------------------------------------------------------------------------------
/test/slugid_test.js:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2014 Jonas Finnemann Jensen
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | // Allows the tests to be run in environments with and without `Buffer`.
24 | if (process.env.NO_BUFFER === "1") {
25 | delete global.Buffer;
26 | console.log('\x1b[33m' + 'Removed `Buffer` from globalThis.' + '\x1b[0m');
27 | }
28 |
29 | const assert = require('assert');
30 | const slugid = require('../src/slugid');
31 | const uuidv4 = require('uuid').v4;
32 |
33 | describe('slugid', function () {
34 | describe('encode', function () {
35 | /**
36 | * Test that we can correctly encode a "non-nice" uuid (with first bit set) to
37 | * its known slug. The specific uuid was chosen since it has a slug which
38 | * contains both `-` and `_` characters.
39 | */
40 | it('should correctly encode a "non-nce" uuid', function () {
41 | // 10000000010011110011111111001000110111111100101101001011000001101000100111111011101011101111101011010101111000011000011101010100....
42 | // <8 ><0 ><4 ><3 ><8 ><4 ><0 ><6 ><8 ><9 ><5 ><1 ><8 ><7 ><5 ><4 >
43 | // < g >< E >< 8 >< _ >< y >< N >< _ >< L >< S >< w >< a >< J >< - >< 6 >< 7 >< 6 >< 1 >< e >< G >< H >< V >< A >
44 | const uuid_ = '804f3fc8-dfcb-4b06-89fb-aefad5e18754';
45 | const expectedSlug = "gE8_yN_LSwaJ-6761eGHVA";
46 |
47 | // Encode
48 | const actualSlug = slugid.encode(uuid_);
49 |
50 | // Test that it encoded correctly
51 | assert(expectedSlug == actualSlug, "UUID not correctly encoded into slug: '" + expectedSlug + "' != '" + actualSlug + "'");
52 | });
53 | });
54 |
55 | describe('decode', function () {
56 | /**
57 | * Test that we can decode a "non-nice" slug (first bit of uuid is set) that
58 | * begins with `-`
59 | */
60 | it('should correctly decode a "non-nice" slug', function () {
61 | // 11111011111011111011111011111011111011111011111001000011111011111011111111111111111111111111111111111111111111111111111111111101....
62 | // <4 ><3 >
63 | // < - >< - >< - >< - >< - >< - >< - >< - >< Q >< - >< - >< - >< _ >< _ >< _ >< _ >< _ >< _ >< _ >< _ >< _ >< Q >
64 | const slug = '--------Q--__________Q';
65 | const expectedUuid = "fbefbefb-efbe-43ef-bfff-fffffffffffd";
66 |
67 | // Decode
68 | const actualUuid = slugid.decode(slug);
69 |
70 | // Test that it is decoded correctly
71 | assert(expectedUuid == actualUuid, "Slug not correctly decoded into uuid: '" + expectedUuid + "' != '" + actualUuid + "'");
72 | });
73 | });
74 |
75 | describe('encode and decode', function () {
76 | /**
77 | * Test that 100 v4 uuids are unchanged after encoding and then decoding them
78 | */
79 | it('should correctly encode and decode 100 v4 uuids', function () {
80 | for (let i = 0; i < 100; i++) {
81 | // Generate uuid
82 | const uuid_ = uuidv4();
83 |
84 | // Encode
85 | const slug = slugid.encode(uuid_);
86 |
87 | // Test that decode uuid matches original
88 | assert(slugid.decode(slug) == uuid_, "Encode and decode isn't identity");
89 | };
90 | });
91 |
92 | /**
93 | * Test that 100 v4 slugs are unchanged after decoding and then encoding them.
94 | */
95 | it('should correctly decode and encode 100 v4 slugs', function () {
96 | for (let i = 0; i < 100; i++) {
97 | // Generate slug
98 | const slug1 = slugid.v4();
99 |
100 | // Decode
101 | const uuid_ = slugid.decode(slug1);
102 |
103 | // Encode
104 | const slug2 = slugid.encode(uuid_);
105 |
106 | // Test that decode uuid matches original
107 | assert(slug1 == slug2, "Decode and encode isn't identity");
108 | };
109 | });
110 | });
111 |
112 | describe('spread', function () {
113 | /**
114 | * Test: Make sure that all allowed characters can appear in all allowed
115 | * positions within the "nice" slug. In this test we generate over a thousand
116 | * slugids, and make sure that every possible allowed character per position
117 | * appears at least once in the sample of all slugids generated. We also make
118 | * sure that no other characters appear in positions in which they are not
119 | * allowed.
120 | *
121 | * base 64 encoding char -> value:
122 | * ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_
123 | * 0 1 2 3 4 5 6
124 | * 0123456789012345678901234567890123456789012345678901234567890123
125 | *
126 | * e.g. from this we can see 'j' represents 35 in base64
127 | *
128 | * The following comments show the 128 bits of the v4 uuid in binary, hex and
129 | * base 64 encodings. The 6 fixed bits (`0`/`1`) according to RFC 4122, plus
130 | * the first (most significant) fixed bit (`0`) are shown among the 121
131 | * arbitrary value bits (`.`/`x`). The `x` means the same as `.` but just
132 | * highlights which bits are grouped together for the respective encoding.
133 | *
134 | * schema:
135 | * <..........time_low............><...time_mid...><.....................node.....................>
136 | *
137 | * bin: 0xxx............................................0100............10xx............................................................
138 | * hex: $A <01><02><03><04><05><06><07><08><09><10><11> 4 <13><14><15> $B <17><18><19><20><21><22><23><24><25><26><27><28><29><30><31>
139 | *
140 | * => $A in {0, 1, 2, 3, 4, 5, 6, 7} (0b0xxx)
141 | * => $B in {8, 9, A, B} (0b10xx)
142 | *
143 | * bin: 0xxxxx..........................................0100xx......xxxx10............................................................xx0000
144 | * b64: $C < 01 >< 02 >< 03 >< 04 >< 05 >< 06 >< 07 > $D < 09 > $E < 11 >< 12 >< 13 >< 14 >< 15 >< 16 >< 17 >< 18 >< 19 >< 20 > $F
145 | *
146 | * => $C in {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, a, b, c, d, e, f} (0b0xxxxx)
147 | * => $D in {Q, R, S, T} (0b0100xx)
148 | * => $E in {C, G, K, O, S, W, a, e, i, m, q, u, y, 2, 6, -} (0bxxxx10)
149 | * => $F in {A, Q, g, w} (0bxx0000)
150 | */
151 | it('should have allowed characters in all allowed positions within the "nice" slug', function () {
152 | const charsAll = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".split('').sort().join('');
153 | // 0 - 31: 0b0xxxxx
154 | const charsC = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef".split('').sort().join('');
155 | // 16, 17, 18, 19: 0b0100xx
156 | const charsD = "QRST".split('').sort().join('');
157 | // 2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46, 50, 54, 58, 62: 0bxxxx10
158 | const charsE = "CGKOSWaeimquy26-".split('').sort().join('');
159 | // 0, 16, 32, 48: 0bxx0000
160 | const charsF = "AQgw".split('').sort().join('');
161 | const expected = [charsC, charsAll, charsAll, charsAll, charsAll, charsAll, charsAll, charsAll, charsD, charsAll, charsE, charsAll, charsAll, charsAll, charsAll, charsAll, charsAll, charsAll, charsAll, charsAll, charsAll, charsF];
162 | spreadTest(
163 | function() {
164 | return slugid.nice();
165 | },
166 | expected
167 | );
168 | });
169 |
170 | /**
171 | * This test is the same as niceSpreadTest but for slugid.v4() rather than
172 | * slugid.nice(). The only difference is that a v4() slug can start with any of
173 | * the base64 characters since the first six bits of the uuid are random.
174 | */
175 | it('should have allowed characters in all allowed positions within the "v4" slug', function () {
176 | const charsAll = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".split('').sort().join('');
177 | // 16, 17, 18, 19: 0b0100xx
178 | const charsD = "QRST".split('').sort().join('');
179 | // 2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46, 50, 54, 58, 62: 0bxxxx10
180 | const charsE = "CGKOSWaeimquy26-".split('').sort().join('');
181 | // 0, 16, 32, 48: 0bxx0000
182 | const charsF = "AQgw".split('').sort().join('');
183 | const expected = [charsAll, charsAll, charsAll, charsAll, charsAll, charsAll, charsAll, charsAll, charsD, charsAll, charsE, charsAll, charsAll, charsAll, charsAll, charsAll, charsAll, charsAll, charsAll, charsAll, charsAll, charsF];
184 | spreadTest(
185 | function() {
186 | return slugid.v4();
187 | },
188 | expected
189 | );
190 | });
191 | });
192 | });
193 |
194 | /**
195 | * `spreadTest` runs a test against the `generator` function, to check that
196 | * when calling it 64*40 times, the range of characters per string position it
197 | * returns matches the array `expected`, where each entry in `expected` is a
198 | * string of all possible characters that should appear in that position in the
199 | * string, at least once in the sample of 64*40 responses from the `generator`
200 | * function */
201 | function spreadTest(generator, expected) {
202 | // k records which characters were found at which positions. It has one entry
203 | // per slugid character, therefore 22 entries. Each entry is an object with
204 | // a property for each character found, where the value of that property is
205 | // the number of times that character appeared at that position in the slugid
206 | // in the large sample of slugids generated in this test.
207 | let k = [[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []];
208 |
209 | // Generate a large sample of slugids, and record what characters appeared
210 | // where... A monte-carlo test has demonstrated that with 64 * 20
211 | // iterations, no failure occurred in 1000 simulations, so 64 * 40 should be
212 | // suitably large to rule out false positives.
213 | for (let i = 0; i < 64 * 40; i++) {
214 | let slug = generator();
215 | for (let j = 0; j < slug.length; j++) {
216 | if (k[j][slug.charAt(j)] === undefined) {
217 | k[j][slug.charAt(j)] = 1
218 | } else {
219 | k[j][slug.charAt(j)]++;
220 | }
221 | }
222 | }
223 |
224 | // Compose results into an array `actual`, for comparison with `expected`
225 | let actual = [];
226 | for (let j = 0; j < k.length; j++) {
227 | const a = Object.keys(k[j])
228 | actual[j] = ""
229 | for (const el of a) {
230 | if (k[j][el] > 0) {
231 | actual[j] += el
232 | }
233 | }
234 | // sort for easy comparison
235 | actual[j] = actual[j].split('').sort().join('');
236 | }
237 |
238 | assert(arraysEqual(expected, actual), "In a large sample of generated slugids, the range of characters found per character position in the sample did not match expected results.\n\nExpected: " + expected + "\n\nActual: " + actual);
239 | }
240 |
241 | /**
242 | * `arraysEqual` checks arrays `a` and `b` for equality
243 | */
244 | function arraysEqual(a, b) {
245 | if (a === b) return true;
246 | if (a == null || b == null) return false;
247 | if (a.length != b.length) return false;
248 | for (let i = 0; i < a.length; ++i) {
249 | if (a[i] !== b[i]) return false;
250 | }
251 | return true;
252 | }
253 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | ansi-colors@4.1.1:
6 | version "4.1.1"
7 | resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348"
8 | integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==
9 |
10 | ansi-regex@^5.0.1:
11 | version "5.0.1"
12 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
13 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
14 |
15 | ansi-styles@^4.0.0, ansi-styles@^4.1.0:
16 | version "4.3.0"
17 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
18 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
19 | dependencies:
20 | color-convert "^2.0.1"
21 |
22 | anymatch@~3.1.2:
23 | version "3.1.3"
24 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e"
25 | integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==
26 | dependencies:
27 | normalize-path "^3.0.0"
28 | picomatch "^2.0.4"
29 |
30 | argparse@^2.0.1:
31 | version "2.0.1"
32 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
33 | integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
34 |
35 | balanced-match@^1.0.0:
36 | version "1.0.2"
37 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
38 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
39 |
40 | binary-extensions@^2.0.0:
41 | version "2.2.0"
42 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
43 | integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
44 |
45 | brace-expansion@^2.0.1:
46 | version "2.0.1"
47 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
48 | integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
49 | dependencies:
50 | balanced-match "^1.0.0"
51 |
52 | braces@~3.0.2:
53 | version "3.0.3"
54 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789"
55 | integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==
56 | dependencies:
57 | fill-range "^7.1.1"
58 |
59 | browser-stdout@1.3.1:
60 | version "1.3.1"
61 | resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60"
62 | integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==
63 |
64 | camelcase@^6.0.0:
65 | version "6.3.0"
66 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a"
67 | integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
68 |
69 | chalk@^4.1.0:
70 | version "4.1.2"
71 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
72 | integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
73 | dependencies:
74 | ansi-styles "^4.1.0"
75 | supports-color "^7.1.0"
76 |
77 | chokidar@3.5.3:
78 | version "3.5.3"
79 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
80 | integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
81 | dependencies:
82 | anymatch "~3.1.2"
83 | braces "~3.0.2"
84 | glob-parent "~5.1.2"
85 | is-binary-path "~2.1.0"
86 | is-glob "~4.0.1"
87 | normalize-path "~3.0.0"
88 | readdirp "~3.6.0"
89 | optionalDependencies:
90 | fsevents "~2.3.2"
91 |
92 | cliui@^7.0.2:
93 | version "7.0.4"
94 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f"
95 | integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==
96 | dependencies:
97 | string-width "^4.2.0"
98 | strip-ansi "^6.0.0"
99 | wrap-ansi "^7.0.0"
100 |
101 | color-convert@^2.0.1:
102 | version "2.0.1"
103 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
104 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
105 | dependencies:
106 | color-name "~1.1.4"
107 |
108 | color-name@~1.1.4:
109 | version "1.1.4"
110 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
111 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
112 |
113 | debug@4.3.4:
114 | version "4.3.4"
115 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
116 | integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
117 | dependencies:
118 | ms "2.1.2"
119 |
120 | decamelize@^4.0.0:
121 | version "4.0.0"
122 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837"
123 | integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==
124 |
125 | diff@5.0.0:
126 | version "5.0.0"
127 | resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b"
128 | integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==
129 |
130 | emoji-regex@^8.0.0:
131 | version "8.0.0"
132 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
133 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
134 |
135 | escalade@^3.1.1:
136 | version "3.1.1"
137 | resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
138 | integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
139 |
140 | escape-string-regexp@4.0.0:
141 | version "4.0.0"
142 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
143 | integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
144 |
145 | fill-range@^7.1.1:
146 | version "7.1.1"
147 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292"
148 | integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==
149 | dependencies:
150 | to-regex-range "^5.0.1"
151 |
152 | find-up@5.0.0:
153 | version "5.0.0"
154 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc"
155 | integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==
156 | dependencies:
157 | locate-path "^6.0.0"
158 | path-exists "^4.0.0"
159 |
160 | flat@^5.0.2:
161 | version "5.0.2"
162 | resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241"
163 | integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==
164 |
165 | fs.realpath@^1.0.0:
166 | version "1.0.0"
167 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
168 | integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
169 |
170 | fsevents@~2.3.2:
171 | version "2.3.2"
172 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
173 | integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
174 |
175 | get-caller-file@^2.0.5:
176 | version "2.0.5"
177 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
178 | integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
179 |
180 | glob-parent@~5.1.2:
181 | version "5.1.2"
182 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
183 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
184 | dependencies:
185 | is-glob "^4.0.1"
186 |
187 | glob@8.1.0:
188 | version "8.1.0"
189 | resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e"
190 | integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==
191 | dependencies:
192 | fs.realpath "^1.0.0"
193 | inflight "^1.0.4"
194 | inherits "2"
195 | minimatch "^5.0.1"
196 | once "^1.3.0"
197 |
198 | has-flag@^4.0.0:
199 | version "4.0.0"
200 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
201 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
202 |
203 | he@1.2.0:
204 | version "1.2.0"
205 | resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
206 | integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
207 |
208 | inflight@^1.0.4:
209 | version "1.0.6"
210 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
211 | integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==
212 | dependencies:
213 | once "^1.3.0"
214 | wrappy "1"
215 |
216 | inherits@2:
217 | version "2.0.4"
218 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
219 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
220 |
221 | is-binary-path@~2.1.0:
222 | version "2.1.0"
223 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
224 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
225 | dependencies:
226 | binary-extensions "^2.0.0"
227 |
228 | is-extglob@^2.1.1:
229 | version "2.1.1"
230 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
231 | integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
232 |
233 | is-fullwidth-code-point@^3.0.0:
234 | version "3.0.0"
235 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
236 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
237 |
238 | is-glob@^4.0.1, is-glob@~4.0.1:
239 | version "4.0.3"
240 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
241 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
242 | dependencies:
243 | is-extglob "^2.1.1"
244 |
245 | is-number@^7.0.0:
246 | version "7.0.0"
247 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
248 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
249 |
250 | is-plain-obj@^2.1.0:
251 | version "2.1.0"
252 | resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287"
253 | integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==
254 |
255 | is-unicode-supported@^0.1.0:
256 | version "0.1.0"
257 | resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7"
258 | integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==
259 |
260 | js-yaml@4.1.0:
261 | version "4.1.0"
262 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
263 | integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
264 | dependencies:
265 | argparse "^2.0.1"
266 |
267 | locate-path@^6.0.0:
268 | version "6.0.0"
269 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286"
270 | integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==
271 | dependencies:
272 | p-locate "^5.0.0"
273 |
274 | log-symbols@4.1.0:
275 | version "4.1.0"
276 | resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503"
277 | integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==
278 | dependencies:
279 | chalk "^4.1.0"
280 | is-unicode-supported "^0.1.0"
281 |
282 | minimatch@5.0.1:
283 | version "5.0.1"
284 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b"
285 | integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==
286 | dependencies:
287 | brace-expansion "^2.0.1"
288 |
289 | minimatch@^5.0.1:
290 | version "5.1.6"
291 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96"
292 | integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==
293 | dependencies:
294 | brace-expansion "^2.0.1"
295 |
296 | mocha@^10.2.0:
297 | version "10.4.0"
298 | resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.4.0.tgz#ed03db96ee9cfc6d20c56f8e2af07b961dbae261"
299 | integrity sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==
300 | dependencies:
301 | ansi-colors "4.1.1"
302 | browser-stdout "1.3.1"
303 | chokidar "3.5.3"
304 | debug "4.3.4"
305 | diff "5.0.0"
306 | escape-string-regexp "4.0.0"
307 | find-up "5.0.0"
308 | glob "8.1.0"
309 | he "1.2.0"
310 | js-yaml "4.1.0"
311 | log-symbols "4.1.0"
312 | minimatch "5.0.1"
313 | ms "2.1.3"
314 | serialize-javascript "6.0.0"
315 | strip-json-comments "3.1.1"
316 | supports-color "8.1.1"
317 | workerpool "6.2.1"
318 | yargs "16.2.0"
319 | yargs-parser "20.2.4"
320 | yargs-unparser "2.0.0"
321 |
322 | ms@2.1.2:
323 | version "2.1.2"
324 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
325 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
326 |
327 | ms@2.1.3:
328 | version "2.1.3"
329 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
330 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
331 |
332 | normalize-path@^3.0.0, normalize-path@~3.0.0:
333 | version "3.0.0"
334 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
335 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
336 |
337 | once@^1.3.0:
338 | version "1.4.0"
339 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
340 | integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
341 | dependencies:
342 | wrappy "1"
343 |
344 | p-limit@^3.0.2:
345 | version "3.1.0"
346 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
347 | integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==
348 | dependencies:
349 | yocto-queue "^0.1.0"
350 |
351 | p-locate@^5.0.0:
352 | version "5.0.0"
353 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834"
354 | integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==
355 | dependencies:
356 | p-limit "^3.0.2"
357 |
358 | path-exists@^4.0.0:
359 | version "4.0.0"
360 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
361 | integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
362 |
363 | picomatch@^2.0.4, picomatch@^2.2.1:
364 | version "2.3.1"
365 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
366 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
367 |
368 | randombytes@^2.1.0:
369 | version "2.1.0"
370 | resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
371 | integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==
372 | dependencies:
373 | safe-buffer "^5.1.0"
374 |
375 | readdirp@~3.6.0:
376 | version "3.6.0"
377 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
378 | integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
379 | dependencies:
380 | picomatch "^2.2.1"
381 |
382 | require-directory@^2.1.1:
383 | version "2.1.1"
384 | resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
385 | integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
386 |
387 | safe-buffer@^5.1.0:
388 | version "5.2.1"
389 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
390 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
391 |
392 | serialize-javascript@6.0.0:
393 | version "6.0.0"
394 | resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8"
395 | integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==
396 | dependencies:
397 | randombytes "^2.1.0"
398 |
399 | string-width@^4.1.0, string-width@^4.2.0:
400 | version "4.2.3"
401 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
402 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
403 | dependencies:
404 | emoji-regex "^8.0.0"
405 | is-fullwidth-code-point "^3.0.0"
406 | strip-ansi "^6.0.1"
407 |
408 | strip-ansi@^6.0.0, strip-ansi@^6.0.1:
409 | version "6.0.1"
410 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
411 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
412 | dependencies:
413 | ansi-regex "^5.0.1"
414 |
415 | strip-json-comments@3.1.1:
416 | version "3.1.1"
417 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
418 | integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
419 |
420 | supports-color@8.1.1:
421 | version "8.1.1"
422 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
423 | integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
424 | dependencies:
425 | has-flag "^4.0.0"
426 |
427 | supports-color@^7.1.0:
428 | version "7.2.0"
429 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
430 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
431 | dependencies:
432 | has-flag "^4.0.0"
433 |
434 | to-regex-range@^5.0.1:
435 | version "5.0.1"
436 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
437 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
438 | dependencies:
439 | is-number "^7.0.0"
440 |
441 | uuid@^9.0.0:
442 | version "9.0.1"
443 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30"
444 | integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==
445 |
446 | workerpool@6.2.1:
447 | version "6.2.1"
448 | resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343"
449 | integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==
450 |
451 | wrap-ansi@^7.0.0:
452 | version "7.0.0"
453 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
454 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
455 | dependencies:
456 | ansi-styles "^4.0.0"
457 | string-width "^4.1.0"
458 | strip-ansi "^6.0.0"
459 |
460 | wrappy@1:
461 | version "1.0.2"
462 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
463 | integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
464 |
465 | y18n@^5.0.5:
466 | version "5.0.8"
467 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
468 | integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
469 |
470 | yargs-parser@20.2.4:
471 | version "20.2.4"
472 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54"
473 | integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==
474 |
475 | yargs-parser@^20.2.2:
476 | version "20.2.9"
477 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"
478 | integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==
479 |
480 | yargs-unparser@2.0.0:
481 | version "2.0.0"
482 | resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb"
483 | integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==
484 | dependencies:
485 | camelcase "^6.0.0"
486 | decamelize "^4.0.0"
487 | flat "^5.0.2"
488 | is-plain-obj "^2.1.0"
489 |
490 | yargs@16.2.0:
491 | version "16.2.0"
492 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
493 | integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==
494 | dependencies:
495 | cliui "^7.0.2"
496 | escalade "^3.1.1"
497 | get-caller-file "^2.0.5"
498 | require-directory "^2.1.1"
499 | string-width "^4.2.0"
500 | y18n "^5.0.5"
501 | yargs-parser "^20.2.2"
502 |
503 | yocto-queue@^0.1.0:
504 | version "0.1.0"
505 | resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
506 | integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
507 |
--------------------------------------------------------------------------------