pax_global_header00006660000000000000000000000064142032743310014511gustar00rootroot0000000000000052 comment=ec6f809b1210ad27568753a91a8312a164c62674 nanoid-3.3.1/000077500000000000000000000000001420327433100127655ustar00rootroot00000000000000nanoid-3.3.1/.editorconfig000066400000000000000000000002231420327433100154370ustar00rootroot00000000000000root = true [*] indent_style = space indent_size = 2 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true nanoid-3.3.1/.github/000077500000000000000000000000001420327433100143255ustar00rootroot00000000000000nanoid-3.3.1/.github/FUNDING.yml000066400000000000000000000000251420327433100161370ustar00rootroot00000000000000tidelift: npm/nanoid nanoid-3.3.1/.github/workflows/000077500000000000000000000000001420327433100163625ustar00rootroot00000000000000nanoid-3.3.1/.github/workflows/test.yml000066400000000000000000000046771420327433100201020ustar00rootroot00000000000000name: Test on: push: branches: - main pull_request: jobs: full: name: Node.js 17 Full runs-on: ubuntu-latest steps: - name: Checkout the repository uses: actions/checkout@v2 - name: Install pnpm uses: pnpm/action-setup@v2 with: version: latest - name: Install Node.js uses: actions/setup-node@v2 with: node-version: 17 cache: pnpm - name: Install dependencies run: pnpm install --frozen-lockfile --ignore-scripts - name: Run tests run: pnpm test env: FORCE_COLOR: 2 short: runs-on: ubuntu-latest strategy: matrix: node-version: - 16 - 14 - 12 name: Node.js ${{ matrix.node-version }} Quick steps: - name: Checkout the repository uses: actions/checkout@v2 - name: Install pnpm uses: pnpm/action-setup@v2 with: version: latest - name: Install Node.js ${{ matrix.node-version }} uses: actions/setup-node@v2 with: node-version: ${{ matrix.node-version }} cache: pnpm - name: Install dependencies run: pnpm install --frozen-lockfile --ignore-scripts - name: Run unit tests run: pnpm unit env: FORCE_COLOR: 2 old: runs-on: ubuntu-latest name: Node.js 10 Quick steps: - name: Checkout the repository uses: actions/checkout@v2 - name: Install pnpm uses: pnpm/action-setup@v1 with: version: 3 env: ACTIONS_ALLOW_UNSECURE_COMMANDS: true - name: Install Node.js 10 uses: actions/setup-node@v2 with: node-version: 10 - name: Install dependencies run: pnpm install --frozen-lockfile --ignore-scripts - name: Run unit tests run: pnpm unit env: FORCE_COLOR: 2 benchmark: name: Benchmark runs-on: ubuntu-latest steps: - name: Checkout the repository uses: actions/checkout@v2 - name: Install pnpm uses: pnpm/action-setup@v2 with: version: latest - name: Install Node.js uses: actions/setup-node@v2 with: node-version: 16 cache: pnpm - name: Install dependencies run: pnpm install --frozen-lockfile --ignore-scripts - name: Run benchmark run: node ./test/benchmark.js nanoid-3.3.1/.gitignore000066400000000000000000000000311420327433100147470ustar00rootroot00000000000000node_modules/ coverage/ nanoid-3.3.1/.npmignore000066400000000000000000000000441420327433100147620ustar00rootroot00000000000000test/ tsconfig.json coverage/ img/ nanoid-3.3.1/CHANGELOG.md000066400000000000000000000136631420327433100146070ustar00rootroot00000000000000# Change Log This project adheres to [Semantic Versioning](http://semver.org/). ## 3.3.1 * Reduced package size. ## 3.3 * Added `size` argument to function from `customAlphabet` (by Stefan Sundin). ## 3.2 * Added `--size` and `--alphabet` arguments to binary (by Vitaly Baev). ## 3.1.32 * Reduced `async` exports size (by Artyom Arutyunyan). * Moved from Jest to uvu (by Vitaly Baev). ## 3.1.31 * Fixed collision vulnerability on object in `size` (by Artyom Arutyunyan). ## 3.1.30 * Reduced size for project with `brotli` compression (by Anton Khlynovskiy). ## 3.1.29 * Reduced npm package size. ## 3.1.28 * Reduced npm package size. ## 3.1.27 * Cleaned `dependencies` from development tools. ## 3.1.26 * Improved performance (by Eitan Har-Shoshanim). * Reduced npm package size. ## 3.1.25 * Fixed `browserify` support. ## 3.1.24 * Fixed `browserify` support (by Artur Paikin). ## 3.1.23 * Fixed `esbuild` support. ## 3.1.22 * Added `default` and `browser.default` to `package.exports`. ## 3.1.21 * Reduced npm package size. ## 3.1.20 * Fix ES modules support. ## 3.1.19 * Reduced `customAlphabet` size (by Enrico Scherlies). ## 3.1.18 * Fixed `package.exports`. ## 3.1.17 * Added files without `process`. ## 3.1.16 * Speeded up Nano ID 4 times (by Peter Boyer). ## 3.1.15 * Fixed `package.types` path. ## 3.1.14 * Added `package.types`. ## 3.1.13 * Removed Node.js 15.0.0 with `randomFillSync` regression from `engines.node`. ## 3.1.12 * Improved IE 11 docs. ## 3.1.11 * Fixed asynchronous `customAlphabet` in browser (by @LoneRifle). ## 3.1.10 * Fix ES modules support. ## 3.1.9 * Try to fix React Native Expo support. ## 3.1.8 * Add React Native Expo support. ## 3.1.7 * Clean up code. ## 3.1.6 * Avoid `self` using. ## 3.1.5 * Improve IE docs and warning. ## 3.1.4 * Restrict old Node.js 13 by `engines.node` (by Cansin Yildiz). ## 3.1.3 * Fix ES modules issue with CLI. ## 3.1.2 * Add shebang to CLI. ## 3.1.1 * Fix CLI. ## 3.1 * Add `npx nanoid` CLI. ## 3.0.2 * Fix docs (by Dylan Irlbeck ). ## 3.0.1 * Fix React Native warning on `non-secure` import (by Jia Huang). ## 3.0 **Migration guide:** * Move to ES2016 syntax. You need to use Babel for IE 11. * Move to named exports `import { nanoid } from 'nanoid'`. * Move `import url from 'nanoid/url'` to `import { urlAlphabet } from 'nanoid'`. * Replace `format()` to `customRandom()`. * Replace `generate()` to `customAlphabet()`. * Remove `async/format`. * Remove React Native support for `nanoid/async`. * Add `nanoid.js` to use directly in browser from CDN. * Add TypeScript type definitions. * Add ES modules support for bundlers, Node.js, and React Native. * Fix React Native support. * Reduce size. * Improve docs (by Dair Aidarkhanov). ## 2.1.11 * Reduce size (by Anton Evzhakov). ## 2.1.10 * Reduce size by 10% (by Anton Khlynovskiy). ## 2.1.9 * Reduce `format` and `async/format` size (by Dair Aidarkhanov). ## 2.1.8 * Improve React docs (by Nahum Zsilva). ## 2.1.7 * Reduce `index`, `async` and `non-secure` size (by @polemius). ## 2.1.6 * Reduce size (by Stas Lashmanov). * Return fast mask for Node.js. ## 2.1.5 * Reduce size (by Max Graey). * Fix IE support. ## 2.1.4 * Reduce `generate` size (by Vsevolod Rodionov). * Reduce `format` and `format` size (by Victor). * Reduce `async`, `non-secure` and `non-secure/generate` size. * Speed up `format` and `async/format` (by Max Graey). * Improve development process on Windows (by Stanislav Lashmanov). ## 2.1.3 * Improve performance (by Stephen Richardson). * Reduce size (by Stephen Richardson). ## 2.1.2 * Improve docs. ## 2.1.1 * Fix React Native support (by Shawn Hwei). ## 2.1 * Improve React Native support (by Sebastian Werner). ## 2.0.4 * Improve error text for React Native (by Sebastian Werner). ## 2.0.3 * Fix freeze on string in ID length. ## 2.0.2 * Improve docs (by Sylvanus Kateile and Mark Stosberg). ## 2.0.1 * Reduce npm package size. * Mark package as not having side effects (by @xiaody). ## 2.0 * Use `-` instead of `~` in default alphabet to by file name safe. * Add `nanoid/non-secure/generate`. ## 1.3.4 * Reduce `non-secure` size. * Add `async` callback type check. ## 1.3.3 * Fix `nanoid/async` performance regression. * Fix old Node.js `not seeded` issue in synchronous version too. ## 1.3.2 * Fix random generator `not seeded` issue of old Node.js. ## 1.3.1 * Reduce library size. ## 1.3 * Add `nanoid/async/format` and `nanoid/async/generate`. * Improve synchronous API performance. * Reduce `url` size (by Daniil Poroshin). * Improve React Native docs (by joelgetaction). ## 1.2.6 * Reduce library size (by rqrqrqrq). ## 1.2.5 * Fix Node.js 6.11.1 support (by Andrey Belym). ## 1.2.4 * Speed up Node.js secure generators (by Dmitriy Tsvettsikh). ## 1.2.3 * Fix JSDoc (by Hendry Sadrak). ## 1.2.2 * Fix distribution in `nanoid/non-secure` (by Eatall). ## 1.2.1 * Fix old Node.js support. ## 1.2 * Add `nanoid/async`. * Fix `nanoid/non-secure` JSDoc. * Add Chinese documentation (by Wenliang Dai). * Speed up and reduce size of `nanoid/non-secure` (by Ori Livni). ## 1.1.1 * Improve performance and reduce size of non-secure ID generator. ## 1.1 * Add non-secure ID generator. * Suggest to use non-secure ID generator for React Native developers. * Reduce size. ## 1.0.7 * Fix documentation. ## 1.0.6 * Fix documentation. ## 1.0.5 * Reduce `nanoid/index` size (by Anton Khlynovskiy). ## 1.0.4 * Reduce npm package size. ## 1.0.3 * Reduce npm package size. ## 1.0.2 * Fix Web Workers support (by Zachary Golba). ## 1.0.1 * Reduce `nanoid/index` size (by Anton Khlynovskiy). ## 1.0 * Use 21 symbols by default (by David Klebanoff). ## 0.2.2 * Reduce `nanoid/generate` size (by Anton Khlynovskiy). * Speed up Node.js random generator. ## 0.2.1 * Fix documentation (by Piper Chester). ## 0.2 * Add `size` argument to `nanoid()`. * Improve performance by 50%. * Reduce library size by 26% (by Vsevolod Rodionov and Oleg Mokhov). ## 0.1.1 * Reduce library size by 5%. ## 0.1 * Initial release. nanoid-3.3.1/LICENSE000066400000000000000000000021071420327433100137720ustar00rootroot00000000000000The MIT License (MIT) Copyright 2017 Andrey Sitnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. nanoid-3.3.1/README.id-ID.md000066400000000000000000000406421420327433100151370ustar00rootroot00000000000000# Nano ID Logo Nano ID oleh Anton Lovchikov [English](./README.md) | [Русский](./README.ru.md) | [简体中文](./README.zh-CN.md) | **Bahasa Indonesia** Sebuah generator ID yang unik dalam bentuk string yang ringan, aman, serta _URL-friendly_ untuk JavaScript. > "Sebuah tingkat kesempurnaan yang luar biasa, > yang mana tidak mungkin untuk tidak dihormati." - **Ringan.** Hanya 130 bytes (diperkecil dan gzipped). Tidak ada ketergantungan (dependencies) apapun. [Size Limit](https://github.com/ai/size-limit) mengatur ukuran dari generator ini. - **Cepat.** Nano ID dua kali lipat lebih cepat dibanding UUID. - **Aman.** Nano ID menggunakan RNG yang terdapat pada perangkat keras. Dapat digunakan dalam lingkungan seperti klaster. - **ID yang pendek.** Nano ID menggunakan alfabet yang lebih banyak ketimbang UUID (`A-Za-z0-9_-`), karenanya ukuran ID menjadi berkurang dari 36 menjadi 21 simbol. - **Portabel.** Nano ID telah dimigrasi untuk [20 bahasa pemrograman lainnya](#bahasa-pemrograman-lainnya). ```js import { nanoid } from 'nanoid' model.id = nanoid() //=> "V1StGXR8_Z5jdHi6B-myT" ``` Mendukung penjelajah (browser) modern, IE [dengan Babel](https://developer.epages.com/blog/coding/how-to-transpile-node-modules-with-babel-and-webpack-in-a-monorepo/), Node.js, dan React Native. Disponsori oleh Evil Martians ## Table of Contents - [Perbandingan dengan UUID](#perbandingan-dengan-uuid) - [Benchmark](#benchmark) - [Keamanan](#keamanan) - [Instalasi](#instalasi) - [API](#api) - [Blocking](#blocking) - [Async](#async) - [Non-Secure](#non-secure) - [Alfabet dan Ukuran (Custom)](#alfabet-dan-ukuran-penyesuaian) - [Generasi Random Bytes (Custom)](#generasi-random-bytes-custom) - [Penggunaan](#penggunaan) - [IE](#ie) - [React](#react) - [React Native](#react-native) - [Rollup](#rollup) - [PouchDB dan CouchDB](#pouchdb-dan-couchdb) - [Mongoose](#mongoose) - [Web Workers](#web-workers) - [CLI](#cli) - [Bahasa Pemrograman Lainnya](#bahasa-pemrograman-lainnya) - [Alat](#alat) ## Perbandingan dengan UUID Nano ID dapat dibandingkan dengan UUID v4 (yang berbasis acak / _randomly generated_). Nano ID dan UUID v4 memiliki jumlah bita yang mirip pada ID yang dihasilkan (126 bita pada NanoID dan 122 bita pada UUID), karenanya ia memiliki probabilitas _collision_ (konflik / tabrakan) yang hampir serupa: > Agar timbul kemungkinan collison / duplikasi ID satu dalam satu miliar, perlu dihasilkan 103 triliun UUID v4. Ada tiga buah perbedaan antara Nano ID dan UUID v4: 1. Nano ID menggunakan alfabet yang lebih lebar, karenanya jumlah bita acak dapat 'dikemas' dalam 21 simbol, bukan 36 simbol. 2. Kode sumber Nano ID **empat kali lebih kecil** ketimbang `uuid/v4`: 130 bytes dibanding 483 bytes. 3. Karena menggunakan trik alokasi memori, Nano ID **dua kali lebih cepat** ketimbang UUID. ## Benchmark ```rust $ node ./test/benchmark.js crypto.randomUUID 25,603,857 ops/sec @napi-rs/uuid 9,973,819 ops/sec uid/secure 8,234,798 ops/sec @lukeed/uuid 7,464,706 ops/sec nanoid 5,616,592 ops/sec customAlphabet 3,115,207 ops/sec uuid v4 1,535,753 ops/sec secure-random-string 388,226 ops/sec uid-safe.sync 363,489 ops/sec cuid 187,343 ops/sec shortid 45,758 ops/sec Async: nanoid/async 96,094 ops/sec async customAlphabet 97,184 ops/sec async secure-random-string 92,794 ops/sec uid-safe 90,684 ops/sec Non-secure: uid 67,376,692 ops/sec nanoid/non-secure 2,849,639 ops/sec rndm 2,674,806 ops/sec ``` Konfigurasi pengujian: ThinkPad X1 Carbon Gen 9, Fedora 34, Node.js 16.10. ## Keamanan _Lihat artikel yang informatif tentang teori angka acak: [Nilai acak yang aman dalam Node.js (English)](https://gist.github.com/joepie91/7105003c3b26e65efcea63f3db82dfba)_. - **Ketidakpastian.** Sebagai ganti untuk penggunaan `Math.random()`, Nano ID menggunakan modul `crypto` yang ada di dalam Nodejs dan/atau Web Crypto API dalam penjelajah (_browser_). Modul-modul ini menggunakan generator acak berbasis perangkat keras yang tidak bisa diprediksi untuk mendapatkan nilai-nilai yang tidak pasti yang aman secara kriptografis. - **Keseragaman.** Pembagian dengan rumus `random % alphabet` adalah kesalahan yang seringkali dilakukan ketika merancang sebuah generator ID. Distribusi dari nilai-nilai tersebut tidak akan seimbang; dalam artian ada kesempatan untuk beberapa simbol untuk muncul dibandingkan dengan simbol yang lain. Ini memiliki dampak yang kurang baik, yakni mengurangi jumlah percobaan ketika seseorang mencoba untuk melakukan _brute-force attacks_. Nano ID menggunakan [algoritma yang lebih baik](https://github.com/ai/nanoid/blob/main/index.js) dan sudah diuji untuk keseragamannya. Nano ID uniformity - **Terdokumentasi secara baik.** Seluruh algoritma Nano ID sudah terdokumentasi. Lihat komentar di [kode sumber](https://github.com/ai/nanoid/blob/main/index.js). - **Kerentanan.** Untuk melaporkan sebuah _security vulnerability_ atau kerentanan, mohon menggunakan [Tidelift Security Contact](https://tidelift.com/security). Tidelift akan mengkoordinasikan pembetulan dan penyingkapan dari kerentanan tersebut. ## Instalasi ```bash npm install --save nanoid ``` Apabila ingin 'coba-coba' terlebih dahulu, dapat digunakan Nano ID melalui CDN. Hal ini tidak direkomendasikan untuk digunakan pada lingkungan produksi karena performa pemuatan (_loading_) yang berkurang. ```js import { nanoid } from 'https://cdn.jsdelivr.net/npm/nanoid/nanoid.js' ``` Nano ID tersedia dalam bentuk ES modules. Tidak perlu melakukan konfigurasi apapun apabila menggunakan Nano ID dalam bentuk ESM di webpack, Rollup, Parcel, atau Node.js. ```js import { nanoid } from 'nanoid' ``` Dalam Node.js, dapat digunakan gaya _import_ ala CommonJS: ```js const { nanoid } = require('nanoid') ``` ## API Nano ID memiliki tiga buah API: normal (_blocking_), asinkronus (_asynchronous_), dan _non-secure_. Bawaannya, Nano ID menggunakan simbol yang _URL-friendly_ (`A-Za-z0-9_-`) dan mengembalikan ID dengan 21 karakter (untuk memiliki probabilitas collision / tabrakan yang mirip dengan UUID v4). ### Blocking Penggunaan Nano ID yang aman dan yang paling mudah. Dalam kasus langka, fungsi ini dapat menghambat CPU untuk melakukan proses yang lain ketika dalam proses 'noise-collection' untuk generasi nilai acak (yang dilakukan pada perangkat keras). ```js import { nanoid } from 'nanoid' model.id = nanoid() //=> "V1StGXR8_Z5jdHi6B-myT" ``` Apabila ingin mengurangi ukuran ID (dan meningkatkan probabilitas collision), dapat dimasukkan `size` sebagai argumen dari fungsi `nanoid()`. ```js nanoid(10) //=> "IRFa-VaY2b" ``` Jangan lupa memeriksa tingkat keamanan dari ukuran ID dalam situs [ID collision probability calculator](https://zelark.github.io/nano-id-cc/). Dapat digunakan pula [custom alphabet](#custom-alphabet-or-size) atau [random generator](#custom-random-bytes-generator) yang lain. ### Async Untuk menghasilkan bytes yang acak dan aman secara kriptografis, CPU mengumpulkan noise elektromagnetik. Umumnya, entropi sudah dikumpulkan terlebih dahulu. Dalam API sinkronus, pada saat CPU mengumpulkan noise elektromagnetik, CPU berada dalam situasi 'busy' dan tidak dapat melakukan proses yang lain (contohnya yakni memorses permintaan HTTP). Ketika menggunakan API asinkronus dari Nano ID, proses lain dapat berjalan ketika CPU sedang mengumpulkan noise elektromagnetik. ```js import { nanoid } from 'nanoid/async' async function createUser() { user.id = await nanoid() } ``` Referensi lebih lanjut tentang entropi dapat dilihat pada dokumentasi fungsi [`crypto.randomBytes`](https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback) milik Node.js. Sayangnya, keuntungan Web Crypto API akan hilang di browser apabila menggunakan API asinkronus ini. Untuk sekarang, browser dibatasi hanya menggunakan API sinkronus (untuk keamanan) atau API asinkronus (lebih cepat, tetapi karena keuntungan Web Crypto hilang, keamanannya sedikit lebih rendah ketimbang penggunaan API sinkronus). ### Non-Secure Konfigurasi bawaan Nano ID menggunakan random bytes generator yang berasal dari perangkat keras untuk keamanan dan probabilitas collision yang rendah. Apabila tidak terlalu memikirkan soal keamanan, dapat pula menggunakan non-secure generator yang lebih cepat. ```js import { nanoid } from 'nanoid/non-secure' const id = nanoid() //=> "Uakgb_J5m9g-0JDMbcJqLJ" ``` ### Alfabet dan Ukuran (Custom) `customAlphabet` digunakan untuk membuat Nano ID dengan alfabet dan ukuran ID yang sesuai dengan kebutuhan (dapat dikustomisasi). ```js import { customAlphabet } from 'nanoid' const nanoid = customAlphabet('1234567890abcdef', 10) model.id = nanoid() //=> "4f90d13a42" ``` Ketika menggunakan fungsi ini, jangan lupa untuk memeriksa keamanan alfabet dan ukuran ID dalam [ID collision probability calculator](https://alex7kom.github.io/nano-nanoid-cc/). Untuk lebih banyak alfabet, dapat menggunakan [`nanoid-dictionary`](https://github.com/CyberAP/nanoid-dictionary). Alfabet harus terbentuk dari 256 simbol atau lebih kecil. Selain itu, keamanan algoritma generasi yang berada di dalam library ini tidak dijamin aman. API asinkronus dan non-secure yang dapat dikustomisasi dengan `customAlphabet` pun tersedia disini: ```js import { customAlphabet } from 'nanoid/async' const nanoid = customAlphabet('1234567890abcdef', 10) async function createUser() { user.id = await nanoid() } ``` ```js import { customAlphabet } from 'nanoid/non-secure' const nanoid = customAlphabet('1234567890abcdef', 10) user.id = nanoid() ``` ### Generasi Random Bytes (Custom) `customRandom` digunakan untuk membuat Nano ID yang mengganti alfabet dan algoritma _random bytes generator_ yang telah diimplementasikan pada versi bawaan (dalam artian menggunakan algoritma sendiri untuk mendapatkan random bytes). Pada contoh berikut, digunakan _seed-based generator_: ```js import { customRandom } from 'nanoid' const rng = seedrandom(seed) const nanoid = customRandom('abcdef', 10, size => { return new Uint8Array(size).map(() => 256 * rng()) }) nanoid() //=> "fbaefaadeb" ``` Fungsi _callback_ pada `random` harus menerima ukuran array dan mengembalikan sebuah array dengan angka acak. Apabila ingin menggunakan alfabet bawaan NanoID pada fungsi `customRandom`, dapat menggunakan konstanta `urlAlphabet` seperti berikut: ```js const { customRandom, urlAlphabet } = require('nanoid') const nanoid = customRandom(urlAlphabet, 10, random) ``` API asinkronus dan non-secure tidak tersedia untuk fungsi `customRandom`. ## Penggunaan ### IE Apabila mengimplementasikan di Internet Explorer, dibutuhkan untuk melakukan [transpile pada `node_modules`](https://developer.epages.com/blog/coding/how-to-transpile-node-modules-with-babel-and-webpack-in-a-monorepo/) dengan Babel dan menambahkan alias untuk `crypto` seperti berikut: ```js // polyfills.js if (!window.crypto) { window.crypto = window.msCrypto } ``` ```js import './polyfills.js' import { nanoid } from 'nanoid' ``` ### React Dalam React, tidak ada cara yang benar bila ingin menggunakan Nano ID untuk prop `key`, karena `key` tersebut harus konsisten dalam setiap proses render yang terjadi. ```jsx function Todos({ todos }) { return ( ) } ``` Karena hal tersebut, disarankan untuk menggunakan ID yang stabil pada setiap objek yang di-render oleh React. ```jsx const todoItems = todos.map(todo =>
  • {todo.text}
  • ) ``` Apabila tidak memiliki ID yang stabil pada setiap _item_ yang di-render pada React, lebih baik menggunakan indeks sebuah array sebagai `key` ketimbang menggunakan fungsi `nanoid()`, seperti berikut: ```jsx const todoItems = todos.map((text, index) => ( /* Tetap tidak direkomendasikan, tetapi lebih disarankan dari 'nanoid()'. Lakukan ini apabila setiap objek / item dalam list tidak ada ID yang stabil. */
  • {text}
  • )) ``` ### React Native React Native tidak memiliki _built-in random generator_. Digunakan polyfill seperti berikut yang berjalan untuk React Native dan Expo yang bermula dari versi `39.x`. 1. Periksa dokumentasi [`react-native-get-random-values`](https://github.com/LinusU/react-native-get-random-values) dan install di aplikasi. 2. Import library tersebut sebelum Nano ID. ```js import 'react-native-get-random-values' import { nanoid } from 'nanoid' ``` ### Rollup Untuk Rollup, dibutuhkan [`@rollup/plugin-node-resolve`](https://github.com/rollup/plugins/tree/master/packages/node-resolve) untuk versi browser. ```js plugins: [ nodeResolve({ browser: true }) ] ``` ### PouchDB dan CouchDB Dalam PouchDB dan CouchDB, ID tidak bisa dimulai dengan underscore `_`. Sebuah _prefix_ dibutuhkan untuk mencegah hal ini terjadi, karena Nano ID mungkin menggunakan `_` sebagai karakter pertama dari ID yang dihasilkan. ID bawaan dapat diubah dengan opsi berikut: ```js db.put({ _id: 'id' + nanoid(), … }) ``` ### Mongoose ```js const mySchema = new Schema({ _id: { type: String, default: () => nanoid() } }) ``` ### Web Workers Web Workers tidak memiliki akses untuk secure random generator. Keamanan sangat penting pada ID yang mana setiap ID harus memiliki sifat tidak bisa diprediksi, seperti pada contoh use-case generasi link pada "access by URL". Apabila tidak memerlukan ID yang tidak bisa diprediksi, tetapi ingin/harus menggunakan Web Workers, dapat digunakan NanoID dengan API non-secure. ```js import { nanoid } from 'nanoid/non-secure' nanoid() //=> "Uakgb_J5m9g-0JDMbcJqLJ" ``` Perhatian: ID yang dihasilkan dari non-secure dapat lebih mudah tabrakan / memiliki probabilitas collision yang lebih besar. ### CLI Nano ID dapat didapatkan dengan cara menggunakan `npx nanoid` pada Terminal. Hanya diperlukan Node.js untuk ini, dan tidak perlu mengunduh dan menginstall Nano ID dalam sistem. ```sh $ npx nanoid npx: installed 1 in 0.63s LZfXLFzPPR4NNrgjlWDxn ``` Bila ingin mengganti alfabet atau ukuran ID, dapat menggunakan [`nanoid-cli`](https://github.com/twhitbeck/nanoid-cli). ### Bahasa Pemrograman Lainnya Nano ID telah bermigrasi ke berbagai macam bahasa. Seluruh versi dapat digunakan untuk mendapatkan ID generator yang sama pada sisi klien dan sisi penyedia layanan (_client-side_ dan _server-side_). - [C#](https://github.com/codeyu/nanoid-net) - [C++](https://github.com/mcmikecreations/nanoid_cpp) - [Clojure and ClojureScript](https://github.com/zelark/nano-id) - [ColdFusion/CFML](https://github.com/JamoCA/cfml-nanoid) - [Crystal](https://github.com/mamantoha/nanoid.cr) - [Dart & Flutter](https://github.com/pd4d10/nanoid-dart) - [Deno](https://github.com/ianfabs/nanoid) - [Go](https://github.com/matoous/go-nanoid) - [Elixir](https://github.com/railsmechanic/nanoid) - [Haskell](https://github.com/MichelBoucey/NanoID) - [Janet](https://sr.ht/~statianzo/janet-nanoid/) - [Java](https://github.com/aventrix/jnanoid) - [Nim](https://github.com/icyphox/nanoid.nim) - [OCaml](https://github.com/routineco/ocaml-nanoid) - [Perl](https://github.com/tkzwtks/Nanoid-perl) - [PHP](https://github.com/hidehalo/nanoid-php) - [Python](https://github.com/puyuan/py-nanoid) with [dictionaries](https://pypi.org/project/nanoid-dictionary) - [Ruby](https://github.com/radeno/nanoid.rb) - [Rust](https://github.com/nikolay-govorov/nanoid) - [Swift](https://github.com/antiflasher/NanoID) - [Unison](https://share.unison-lang.org/latest/namespaces/hojberg/nanoid) - [V](https://github.com/invipal/nanoid) Untuk environment lainnya, [CLI](#cli) tersedia untuk melakukan generasi ID dari command line / Terminal. ## Alat - [ID Size Calculator](https://zelark.github.io/nano-id-cc/) menunjukkan probabilitas collision ketika melakukan konfigurasi alfabet dan ukuran. - [`nanoid-dictionary`](https://github.com/CyberAP/nanoid-dictionary) untuk menggunakan alfabet popular dalam fungsi [`customAlphabet`](#custom-alphabet-or-size) - [`nanoid-good`](https://github.com/y-gagar1n/nanoid-good) untuk meyakinkan bahwa ID yang di-generasi tidak memiliki kata-kata yang kurang baik (kasar, tidak sopan, dsb.). nanoid-3.3.1/README.md000066400000000000000000000357541420327433100142620ustar00rootroot00000000000000# Nano ID Nano ID logo by Anton Lovchikov **English** | [Русский](./README.ru.md) | [简体中文](./README.zh-CN.md) | [Bahasa Indonesia](./README.id-ID.md) A tiny, secure, URL-friendly, unique string ID generator for JavaScript. > “An amazing level of senseless perfectionism, > which is simply impossible not to respect.” * **Small.** 130 bytes (minified and gzipped). No dependencies. [Size Limit] controls the size. * **Fast.** It is 2 times faster than UUID. * **Safe.** It uses hardware random generator. Can be used in clusters. * **Short IDs.** It uses a larger alphabet than UUID (`A-Za-z0-9_-`). So ID size was reduced from 36 to 21 symbols. * **Portable.** Nano ID was ported to [20 programming languages](#other-programming-languages). ```js import { nanoid } from 'nanoid' model.id = nanoid() //=> "V1StGXR8_Z5jdHi6B-myT" ``` Supports modern browsers, IE [with Babel], Node.js and React Native. [online tool]: https://gitpod.io/#https://github.com/ai/nanoid/ [with Babel]: https://developer.epages.com/blog/coding/how-to-transpile-node-modules-with-babel-and-webpack-in-a-monorepo/ [Size Limit]: https://github.com/ai/size-limit Sponsored by Evil Martians ## Table of Contents * [Comparison with UUID](#comparison-with-uuid) * [Benchmark](#benchmark) * [Security](#security) * [API](#api) * [Blocking](#blocking) * [Async](#async) * [Non-Secure](#non-secure) * [Custom Alphabet or Size](#custom-alphabet-or-size) * [Custom Random Bytes Generator](#custom-random-bytes-generator) * [Usage](#usage) * [IE](#ie) * [React](#react) * [React Native](#react-native) * [Rollup](#rollup) * [PouchDB and CouchDB](#pouchdb-and-couchdb) * [Mongoose](#mongoose) * [Web Workers](#web-workers) * [CLI](#cli) * [Other Programming Languages](#other-programming-languages) * [Tools](#tools) ## Comparison with UUID Nano ID is quite comparable to UUID v4 (random-based). It has a similar number of random bits in the ID (126 in Nano ID and 122 in UUID), so it has a similar collision probability: > For there to be a one in a billion chance of duplication, > 103 trillion version 4 IDs must be generated. There are three main differences between Nano ID and UUID v4: 1. Nano ID uses a bigger alphabet, so a similar number of random bits are packed in just 21 symbols instead of 36. 2. Nano ID code is **4 times less** than `uuid/v4` package: 130 bytes instead of 483. 3. Because of memory allocation tricks, Nano ID is **2 times** faster than UUID. ## Benchmark ```rust $ node ./test/benchmark.js crypto.randomUUID 25,603,857 ops/sec @napi-rs/uuid 9,973,819 ops/sec uid/secure 8,234,798 ops/sec @lukeed/uuid 7,464,706 ops/sec nanoid 5,616,592 ops/sec customAlphabet 3,115,207 ops/sec uuid v4 1,535,753 ops/sec secure-random-string 388,226 ops/sec uid-safe.sync 363,489 ops/sec cuid 187,343 ops/sec shortid 45,758 ops/sec Async: nanoid/async 96,094 ops/sec async customAlphabet 97,184 ops/sec async secure-random-string 92,794 ops/sec uid-safe 90,684 ops/sec Non-secure: uid 67,376,692 ops/sec nanoid/non-secure 2,849,639 ops/sec rndm 2,674,806 ops/sec ``` Test configuration: ThinkPad X1 Carbon Gen 9, Fedora 34, Node.js 16.10. ## Security *See a good article about random generators theory: [Secure random values (in Node.js)]* * **Unpredictability.** Instead of using the unsafe `Math.random()`, Nano ID uses the `crypto` module in Node.js and the Web Crypto API in browsers. These modules use unpredictable hardware random generator. * **Uniformity.** `random % alphabet` is a popular mistake to make when coding an ID generator. The distribution will not be even; there will be a lower chance for some symbols to appear compared to others. So, it will reduce the number of tries when brute-forcing. Nano ID uses a [better algorithm] and is tested for uniformity. Nano ID uniformity * **Well-documented:** all Nano ID hacks are documented. See comments in [the source]. * **Vulnerabilities:** to report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure. [Secure random values (in Node.js)]: https://gist.github.com/joepie91/7105003c3b26e65efcea63f3db82dfba [better algorithm]: https://github.com/ai/nanoid/blob/main/index.js [the source]: https://github.com/ai/nanoid/blob/main/index.js ## Install ```bash npm install --save nanoid ``` For quick hacks, you can load Nano ID from CDN. Though, it is not recommended to be used in production because of the lower loading performance. ```js import { nanoid } from 'https://cdn.jsdelivr.net/npm/nanoid/nanoid.js' ``` Nano ID provides ES modules. You do not need to do anything to use Nano ID as ESM in webpack, Rollup, Parcel, or Node.js. ```js import { nanoid } from 'nanoid' ``` In Node.js you can use CommonJS import: ```js const { nanoid } = require('nanoid') ``` ## API Nano ID has 3 APIs: normal (blocking), asynchronous, and non-secure. By default, Nano ID uses URL-friendly symbols (`A-Za-z0-9_-`) and returns an ID with 21 characters (to have a collision probability similar to UUID v4). ### Blocking The safe and easiest way to use Nano ID. In rare cases could block CPU from other work while noise collection for hardware random generator. ```js import { nanoid } from 'nanoid' model.id = nanoid() //=> "V1StGXR8_Z5jdHi6B-myT" ``` If you want to reduce the ID size (and increase collisions probability), you can pass the size as an argument. ```js nanoid(10) //=> "IRFa-VaY2b" ``` Don’t forget to check the safety of your ID size in our [ID collision probability] calculator. You can also use a [custom alphabet](#custom-alphabet-or-size) or a [random generator](#custom-random-bytes-generator). [ID collision probability]: https://zelark.github.io/nano-id-cc/ ### Async To generate hardware random bytes, CPU collects electromagnetic noise. For most cases, entropy will be already collected. In the synchronous API during the noise collection, the CPU is busy and cannot do anything useful (for instance, process another HTTP request). Using the asynchronous API of Nano ID, another code can run during the entropy collection. ```js import { nanoid } from 'nanoid/async' async function createUser () { user.id = await nanoid() } ``` Read more about entropy collection in [`crypto.randomBytes`] docs. Unfortunately, you will lose Web Crypto API advantages in a browser if you use the asynchronous API. So, currently, in the browser, you are limited with either security (`nanoid`), asynchronous behavior (`nanoid/async`), or non-secure behavior (`nanoid/non-secure`) that will be explained in the next part of the documentation. [`crypto.randomBytes`]: https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback ### Non-Secure By default, Nano ID uses hardware random bytes generation for security and low collision probability. If you are not so concerned with security, you can use the faster non-secure generator. ```js import { nanoid } from 'nanoid/non-secure' const id = nanoid() //=> "Uakgb_J5m9g-0JDMbcJqLJ" ``` ### Custom Alphabet or Size `customAlphabet` allows you to create `nanoid` with your own alphabet and ID size. ```js import { customAlphabet } from 'nanoid' const nanoid = customAlphabet('1234567890abcdef', 10) model.id = nanoid() //=> "4f90d13a42" ``` ```js import { customAlphabet } from 'nanoid/async' const nanoid = customAlphabet('1234567890abcdef', 10) async function createUser () { user.id = await nanoid() } ``` ```js import { customAlphabet } from 'nanoid/non-secure' const nanoid = customAlphabet('1234567890abcdef', 10) user.id = nanoid() ``` Check the safety of your custom alphabet and ID size in our [ID collision probability] calculator. For more alphabets, check out the options in [`nanoid-dictionary`]. Alphabet must contain 256 symbols or less. Otherwise, the security of the internal generator algorithm is not guaranteed. In addition to setting a default size, you can change the ID size when calling the function: ```js import { customAlphabet } from 'nanoid' const nanoid = customAlphabet('1234567890abcdef', 10) model.id = nanoid(5) //=> "f01a2" ``` [ID collision probability]: https://alex7kom.github.io/nano-nanoid-cc/ [`nanoid-dictionary`]: https://github.com/CyberAP/nanoid-dictionary ### Custom Random Bytes Generator `customRandom` allows you to create a `nanoid` and replace alphabet and the default random bytes generator. In this example, a seed-based generator is used: ```js import { customRandom } from 'nanoid' const rng = seedrandom(seed) const nanoid = customRandom('abcdef', 10, size => { return (new Uint8Array(size)).map(() => 256 * rng()) }) nanoid() //=> "fbaefaadeb" ``` `random` callback must accept the array size and return an array with random numbers. If you want to use the same URL-friendly symbols with `customRandom`, you can get the default alphabet using the `urlAlphabet`. ```js const { customRandom, urlAlphabet } = require('nanoid') const nanoid = customRandom(urlAlphabet, 10, random) ``` Asynchronous and non-secure APIs are not available for `customRandom`. Note, that between Nano ID versions we may change random generator call sequence. If you are using seed-based generators, we do not guarantee the same result. ## Usage ### IE If you support IE, you need to [transpile `node_modules`] by Babel and add `crypto` alias: ```js // polyfills.js if (!window.crypto) { window.crypto = window.msCrypto } ``` ```js import './polyfills.js' import { nanoid } from 'nanoid' ``` [transpile `node_modules`]: https://developer.epages.com/blog/coding/how-to-transpile-node-modules-with-babel-and-webpack-in-a-monorepo/ ### React There’s no correct way to use Nano ID for React `key` prop since it should be consistent among renders. ```jsx function Todos({todos}) { return ( ) } ``` You should rather try to reach for stable ID inside your list item. ```jsx const todoItems = todos.map((todo) =>
  • {todo.text}
  • ) ``` In case you don’t have stable IDs you'd rather use index as `key` instead of `nanoid()`: ```jsx const todoItems = todos.map((text, index) =>
  • /* Still not recommended but preferred over nanoid(). Only do this if items have no stable IDs. */ {text}
  • ) ``` ### React Native React Native does not have built-in random generator. The following polyfill works for plain React Native and Expo starting with `39.x`. 1. Check [`react-native-get-random-values`] docs and install it. 2. Import it before Nano ID. ```js import 'react-native-get-random-values' import { nanoid } from 'nanoid' ``` [`react-native-get-random-values`]: https://github.com/LinusU/react-native-get-random-values ### Rollup For Rollup you will need [`@rollup/plugin-node-resolve`] to bundle browser version of this library.: ```js plugins: [ nodeResolve({ browser: true }) ] ``` [`@rollup/plugin-node-resolve`]: https://github.com/rollup/plugins/tree/master/packages/node-resolve ### PouchDB and CouchDB In PouchDB and CouchDB, IDs can’t start with an underscore `_`. A prefix is required to prevent this issue, as Nano ID might use a `_` at the start of the ID by default. Override the default ID with the following option: ```js db.put({ _id: 'id' + nanoid(), … }) ``` ### Mongoose ```js const mySchema = new Schema({ _id: { type: String, default: () => nanoid() } }) ``` ### Web Workers Web Workers do not have access to a secure random generator. Security is important in IDs when IDs should be unpredictable. For instance, in "access by URL" link generation. If you do not need unpredictable IDs, but you need to use Web Workers, you can use the non‑secure ID generator. ```js import { nanoid } from 'nanoid/non-secure' nanoid() //=> "Uakgb_J5m9g-0JDMbcJqLJ" ``` Note: non-secure IDs are more prone to collision attacks. ### CLI You can get unique ID in terminal by calling `npx nanoid`. You need only Node.js in the system. You do not need Nano ID to be installed anywhere. ```sh $ npx nanoid npx: installed 1 in 0.63s LZfXLFzPPR4NNrgjlWDxn ``` Size of generated ID can be specified with `--size` (or `-s`) option: ```sh $ npx nanoid --size 10 L3til0JS4z ``` Custom alphabet can be specified with `--alphabet` (or `-a`) option (note that in this case `--size` is required): ```sh $ npx nanoid --alphabet abc --size 15 bccbcabaabaccab ``` ### Other Programming Languages Nano ID was ported to many languages. You can use these ports to have the same ID generator on the client and server side. * [C#](https://github.com/codeyu/nanoid-net) * [C++](https://github.com/mcmikecreations/nanoid_cpp) * [Clojure and ClojureScript](https://github.com/zelark/nano-id) * [ColdFusion/CFML](https://github.com/JamoCA/cfml-nanoid) * [Crystal](https://github.com/mamantoha/nanoid.cr) * [Dart & Flutter](https://github.com/pd4d10/nanoid-dart) * [Deno](https://github.com/ianfabs/nanoid) * [Go](https://github.com/matoous/go-nanoid) * [Elixir](https://github.com/railsmechanic/nanoid) * [Haskell](https://github.com/MichelBoucey/NanoID) * [Janet](https://sr.ht/~statianzo/janet-nanoid/) * [Java](https://github.com/aventrix/jnanoid) * [Nim](https://github.com/icyphox/nanoid.nim) * [OCaml](https://github.com/routineco/ocaml-nanoid) * [Perl](https://github.com/tkzwtks/Nanoid-perl) * [PHP](https://github.com/hidehalo/nanoid-php) * [Python](https://github.com/puyuan/py-nanoid) with [dictionaries](https://pypi.org/project/nanoid-dictionary) * [Ruby](https://github.com/radeno/nanoid.rb) * [Rust](https://github.com/nikolay-govorov/nanoid) * [Swift](https://github.com/antiflasher/NanoID) * [Unison](https://share.unison-lang.org/latest/namespaces/hojberg/nanoid) * [V](https://github.com/invipal/nanoid) For other environments, [CLI] is available to generate IDs from a command line. [CLI]: #cli ## Tools * [ID size calculator] shows collision probability when adjusting the ID alphabet or size. * [`nanoid-dictionary`] with popular alphabets to use with [`customAlphabet`]. * [`nanoid-good`] to be sure that your ID doesn’t contain any obscene words. [`nanoid-dictionary`]: https://github.com/CyberAP/nanoid-dictionary [ID size calculator]: https://zelark.github.io/nano-id-cc/ [`customAlphabet`]: #custom-alphabet-or-size [`nanoid-good`]: https://github.com/y-gagar1n/nanoid-good nanoid-3.3.1/README.ru.md000066400000000000000000000520731420327433100147000ustar00rootroot00000000000000# Nano ID Логотип Nano ID от Антона Ловчикова [English](./README.md) | **Русский** | [简体中文](./README.zh-CN.md) | [Bahasa Indonesia](./README.id-ID.md) Генератор уникальных ID для JavaScript — лёгкий, безопасный, ID можно применять в URL. > «Поразительный уровень бессмысленного перфекционизма, > который просто невозможно не уважать» - **Лёгкий.** 130 байт (после минификации и gzip). Без зависимостей. [Size Limit] следит за размером. - **Быстрый.** В 2 раза быстрее UUID. - **Безопасный.** Использует аппаратный генератор случайных чисел. Можно использовать в кластерах машин. - **Короткие ID.** Используется больший алфавит, чем у UUID (`A-Za-z0-9_-`). Поэтому длина ID уменьшена с 36 до 21 символа. - **Работает везде.** Nano ID уже портировали на [20 языков программирования](#другие-языки-программирования). ```js import { nanoid } from 'nanoid' model.id = nanoid() //=> "V1StGXR8_Z5jdHi6B-myT" ``` Поддерживает современные браузеры, IE ([с Babel]), Node.js и React Native. [online tool]: https://gitpod.io/#https://github.com/ai/nanoid/ [с babel]: https://developer.epages.com/blog/coding/how-to-transpile-node-modules-with-babel-and-webpack-in-a-monorepo/ [size limit]: https://github.com/ai/size-limit При поддержке Злых марсиан ## Оглавление - [Сравнение с UUID](#сравнение-с-uuid) - [Сравнение производительности](#сравнение-производительности) - [Безопасность](#безопасность) - [Подключение](#подключение) - [API](#api) - [Блокирующий](#блокирующий) - [Асинхронный](#асинхронный) - [Небезопасный](#небезопасный) - [Смена алфавита или длины](#смена-алфавита-или-длины) - [Смена генератора случайных чисел](#смена-генератора-случайных-чисел) - [Руководство](#руководство) - [IE](#ie) - [React](#react) - [React Native](#react-native) - [Rollup](#rollup) - [PouchDB и CouchDB](#pouchdb-и-couchdb) - [Mongoose](#mongoose) - [Веб-воркеры](#веб-воркеры) - [Терминал](#терминал) - [Другие языки программирования](#другие-языки-программирования) - [Инструменты](#инструменты) ## Сравнение с UUID Nano ID похож на UUID v4 (случайный). У них сравнимое число битов случайности в ID (126 у Nano ID против 122 у UUID), поэтому они обладают похожей вероятностью возникновения коллизий (повторной генерации ранее выданных ID): > Чтобы вероятность повтора приблизилась к 1 на миллиард, > нужно сгенерировать 103 триллиона ID. Но между ними есть 3 важных отличия: 1. Nano ID использует более широкий алфавит, и сравнимое количество битов случайности будут упакованы в более короткую строку (21 символ, против 36 у UUID). 2. Код Nano ID **в 4 раз меньше**, чем у `uuid/v4` — 130 байт против 483. 3. Благодаря оптимизациям с выделением памяти, Nano ID **в 2 раза быстрее** UUID. ## Сравнение производительности ```rust $ node ./test/benchmark.js crypto.randomUUID 25,603,857 ops/sec @napi-rs/uuid 9,973,819 ops/sec uid/secure 8,234,798 ops/sec @lukeed/uuid 7,464,706 ops/sec nanoid 5,616,592 ops/sec customAlphabet 3,115,207 ops/sec uuid v4 1,535,753 ops/sec secure-random-string 388,226 ops/sec uid-safe.sync 363,489 ops/sec cuid 187,343 ops/sec shortid 45,758 ops/sec Async: nanoid/async 96,094 ops/sec async customAlphabet 97,184 ops/sec async secure-random-string 92,794 ops/sec uid-safe 90,684 ops/sec Non-secure: uid 67,376,692 ops/sec nanoid/non-secure 2,849,639 ops/sec rndm 2,674,806 ops/sec ``` Среда сравнения: ThinkPad X1 Carbon Gen 9, Fedora 34, Node.js 16.10. ## Безопасность _См. также хорошую статью о теориях генераторов случайных чисел: [Secure random values (in Node.js)]_ - **Непредсказуемость.** Вместо предсказуемого `Math.random()`, Nano ID использует модуль `crypto` в Node.js и Web Crypto API в браузере. Эти модули дают доступ к аппаратному генератору случайных чисел. - **Равномерность.** Например, существует популярная ошибка `random % alphabet`, которую часто допускают при разработке генератора ID. Распределение вероятности для каждого символа может не быть одинаковым. Из-за неравномерности использования пространства алфавита, на перебор ID потребуется меньше времени, чем ожидается. Nano ID использует [более совершенный алгоритм], а равномерность распределения символов покрыта тестами. Распределение Nano ID - **Документация:** все хитрости Nano ID хорошо документированы — смотрите комментарии [в исходниках]. - **Уязвимости:** если вы нашли уязвимость в Nano ID, свяжитесь с [командой безопасности Tidelift](https://tidelift.com/security). Они проконтролируют исправление и проинформируют пользователей. [secure random values (in node.js)]: https://gist.github.com/joepie91/7105003c3b26e65efcea63f3db82dfba [более совершенный алгоритм]: https://github.com/ai/nanoid/blob/main/index.js [в исходниках]: https://github.com/ai/nanoid/blob/main/index.js ## Подключение ```bash npm install --save nanoid ``` Для быстрого прототипирования вы можете подключить Nano ID с CDN без установки. Не используйте этот способ на реальном сайте, так как он сильно бьёт по скорости загрузки сайта. ```js import { nanoid } from 'https://cdn.jsdelivr.net/npm/nanoid/nanoid.js' ``` Nano ID поддерживает ES-модули. Вам не надо ничего делать, чтобы ES-импорты работали в webpack, Rollup, Parcel, или Node.js. ```js import { nanoid } from 'nanoid' ``` Для Node.js также поддерживается CommonJS-импорт: ```js const { nanoid } = require('nanoid') ``` ## API Nano ID разделён на три модуля: стандартный (блокирующий), асинхронный и небезопасный. По умолчанию используются символы, безопасные для URL (`A-Za-z0-9_-`). Длина ID по умолчанию — 21 символ (чтобы вероятность коллизий была соизмеримой с UUID v4). ### Блокирующий Безопасный и простой в использовании способ использования Nano ID. Из-за особенностей работы генератора случайных чисел при использовании этого способа ЦПУ может иногда простаивать без работы. ```js import { nanoid } from 'nanoid' model.id = nanoid() //=> "V1StGXR8_Z5jdHi6B-myT" ``` Функция также принимает необязательный аргумент, задающий длину ID: ```js nanoid(10) //=> "IRFa-VaY2b" ``` При изменении размера, всегда проверяйте риски в нашем [калькуляторе коллизий](https://zelark.github.io/nano-id-cc/). ### Асинхронный Для аппаратной генерации случайных чисел процессор накапливает электромагнитные шумы. Обычно они накоплены заранее, и получение случайных чисел происходит быстро. Но могут быть ситуации, когда системе требуется время на накопление энтропии. При использовании синхронного API процесс заблокируется во время накопления энтропии. Например, веб-сервер не сможет обрабатывать запрос следующего посетителя, пока не сгенерирует ID для предыдущего. Но если использовать асинхронный API у Nano ID, то процесс будет работать более эффективно: во время накопления шума сможет выполняться другая задача. ```js import { nanoid } from 'nanoid/async' async function createUser() { user.id = await nanoid() } ``` Про ожидание накопления энтропии можно почитать в описании метода `crypto.randomBytes` в [документации Node.js]. К сожалению, эта оптимизация имеет смысл только для Node.js. Web Crypto API в браузерах не имеет асинхронной версии. [документации node.js]: https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback ### Небезопасный По умолчанию, Nano ID использует аппаратный генератор случайных чисел для получения непредсказуемых ID и минимизации риска возникновения коллизий (повторной генерации ранее выданных ID). Но если вам не требуется устойчивость к подбору ID, то вы можете перейти на небезопасный генератор. ```js import { nanoid } from 'nanoid/non-secure' const id = nanoid() //=> "Uakgb_J5m9g-0JDMbcJqLJ" ``` Но учтите, что предсказуемость ID может быть использована для атаки на систему. ### Смена алфавита или длины Функция `customAlphabet` позволяет создать свою функцию `nanoid` с нужным вам алфавитом и длиной ID. ```js import { customAlphabet } from 'nanoid' const nanoid = customAlphabet('1234567890abcdef', 10) user.id = nanoid() //=> "4f90d13a42" ``` ```js import { customAlphabet } from 'nanoid/async' const nanoid = customAlphabet('1234567890abcdef', 10) async function createUser() { user.id = await nanoid() } ``` ```js import { customAlphabet } from 'nanoid/non-secure' const nanoid = customAlphabet('1234567890abcdef', 10) user.id = nanoid() ``` Не забудьте проверить риски коллизии вашего алфавита и длины [на нашем калькуляторе]. [`nanoid-dictionary`] содержит много популярных примеров альтернативных алфавитов. Алфавит должен содержать ≤256 символов. Иначе мы не сможем гарантировать непредсказуемость ID. Длину ID можно менять не только в `customAlphabet()`, но и при вызове генератора, который она вернёт: ```js import { customAlphabet } from 'nanoid' const nanoid = customAlphabet('1234567890abcdef', 10) model.id = nanoid(5) //=> "f01a2" ``` [на нашем калькуляторе]: https://alex7kom.github.io/nano-nanoid-cc/ [`nanoid-dictionary`]: https://github.com/CyberAP/nanoid-dictionary ### Смена генератора случайных чисел Функция `customRandom` позволяет создать свою функцию `nanoid` со своими генераторами случайных чисел, алфавитом и длинной ID. Например, можно использовать генератор c seed для повторяемости тестов. ```js import { customRandom } from 'nanoid' const rng = seedrandom(seed) const nanoid = customRandom('abcdef', 10, size => { return new Uint8Array(size).map(() => 256 * rng()) }) nanoid() //=> "fbaefaadeb" ``` Функция в третьем аргументе `customRandom` должна принимать длину массива и возвращать нужный массив со случайными числами Если вы хотите заменить только генератор случайных чисел, но оставить URL-совместимый алфавит, то стандартный алфавит доступен в экспорте `urlAlphabet`. ```js const { customRandom, urlAlphabet } = require('nanoid') const nanoid = customRandom(urlAlphabet, 10, random) ``` У асинхронной и небезопасной версий нет `customRandom`. ## Руководство ### IE Если вам нужна поддержка IE, потребуется включить [компиляцию `node_modules`] с помощью Babel и вручную убрать вендорный префикс у `crypto`. ```js // polyfills.js if (!window.crypto) { window.crypto = window.msCrypto } ``` ```js import './polyfills.js' import { nanoid } from 'nanoid' ``` [компиляцию `node_modules`]: https://developer.epages.com/blog/coding/how-to-transpile-node-modules-with-babel-and-webpack-in-a-monorepo/ ### React Не используйте Nano ID для генерации свойства `key` в JSX. При каждом рендере `key` будет разный, что плохо скажется на производительности. ```jsx function Todos({ todos }) { return ( ) } ``` Подробнее об использовании свойства `key` читайте в [официальной документации React](https://ru.reactjs.org/docs/lists-and-keys.html#keys). ### React Native React Native не имеет встроенного аппаратного генератора случайных чисел. Полифил ниже работает в чистом React Native и в Expo начиная с версии 39. 1. Прочитайте документацию [`react-native-get-random-values`] и установите его. 2. Импортируйте эту библиотеку до импорта Nano ID. ```js import 'react-native-get-random-values' import { nanoid } from 'nanoid' ``` [`react-native-get-random-values`]: https://github.com/LinusU/react-native-get-random-values ### Rollup Для Rollup понадобятся плагины [`@rollup/plugin-node-resolve`]. ```js plugins: [ nodeResolve({ browser: true }) ] ``` [`@rollup/plugin-node-resolve`]: https://github.com/rollup/plugins/tree/master/packages/node-resolve ### PouchDB и CouchDB В PouchDB и CouchDB, ID не могут начинаться с `_`. Добавьте к ID префикс, так как иногда Nano ID может сгенерировать ID начинающийся с `_`. Изменить стандартный ID можно через следующую опцию: ```js db.put({ _id: 'id' + nanoid(), … }) ``` ### Mongoose ```js const mySchema = new Schema({ _id: { type: String, default: () => nanoid() } }) ``` ### Веб-воркеры Веб-воркеры не имеют доступа к аппаратному генератору случайных чисел. Аппаратный генератор нужен, в том числе, для непредсказуемости ID. Например, когда доступ к секретному документу защищён ссылкой с уникальным ID. Если вам не нужна непредсказуемость ID, то в Веб-воркере можно использовать небезопасный генератор ID. ```js import { nanoid } from 'nanoid/non-secure' nanoid() //=> "Uakgb_J5m9g-0JDMbcJqLJ" ``` ### Терминал Можно сгенерировать уникальный ID прямо из терминала, вызвав `npx nanoid`. Для этого в системе должна быть только Node.js. `npx` сама скачает Nano ID, если его нет в системе. ```sh $ npx nanoid npx: installed 1 in 0.63s LZfXLFzPPR4NNrgjlWDxn ``` Длину генерируемых ID можно передать в аргументе `--size` (или `-s`): ```sh $ npx nanoid --size 10 L3til0JS4z ``` Изменить алфавит можно при помощи аргумента `--alphabet` (ли `-a`) (в этом случае `--size` обязателен): ```sh $ npx nanoid --alphabet abc --size 15 bccbcabaabaccab ``` ### Другие языки программирования Nano ID был портирован на множество языков. Это полезно, чтобы сервер и клиент генерировали ID по одной схеме. - [C#](https://github.com/codeyu/nanoid-net) - [C++](https://github.com/mcmikecreations/nanoid_cpp) - [Clojure и ClojureScript](https://github.com/zelark/nano-id) - [ColdFusion/CFML](https://github.com/JamoCA/cfml-nanoid) - [Crystal](https://github.com/mamantoha/nanoid.cr) - [Dart и Flutter](https://github.com/pd4d10/nanoid-dart) - [Deno](https://github.com/ianfabs/nanoid) - [Go](https://github.com/matoous/go-nanoid) - [Elixir](https://github.com/railsmechanic/nanoid) - [Haskell](https://github.com/MichelBoucey/NanoID) - [Janet](https://sr.ht/~statianzo/janet-nanoid/) - [Java](https://github.com/aventrix/jnanoid) - [Nim](https://github.com/icyphox/nanoid.nim) - [Perl](https://github.com/tkzwtks/Nanoid-perl) - [PHP](https://github.com/hidehalo/nanoid-php) - [Python](https://github.com/puyuan/py-nanoid) со [словарями](https://pypi.org/project/nanoid-dictionary) - [Ruby](https://github.com/radeno/nanoid.rb) - [Rust](https://github.com/nikolay-govorov/nanoid) - [Swift](https://github.com/antiflasher/NanoID) * [Unison](https://share.unison-lang.org/latest/namespaces/hojberg/nanoid) - [V](https://github.com/invipal/nanoid) Для остальных сред можно использовать Nano ID [для терминала]. [для терминала]: #терминал ## Инструменты - [Калькулятор длины ID] поможет подобрать оптимальную длину ID, в зависимости от частоты выдачи ID и нужной надёжности системы. - [`nanoid-dictionary`] с популярными алфавитами для [`customAlphabet`]. - [`nanoid-good`] гарантирует, что в случайном ID не будет матерных слов. [калькулятор длины id]: https://zelark.github.io/nano-id-cc/ [`nanoid-dictionary`]: https://github.com/CyberAP/nanoid-dictionary [`customalphabet`]: #смена-алфавита-или-длины [`nanoid-good`]: https://github.com/y-gagar1n/nanoid-good nanoid-3.3.1/README.zh-CN.md000066400000000000000000000333771420327433100151770ustar00rootroot00000000000000# Nano ID Nano ID logo by Anton Lovchikov [English](./README.md) | [Русский](./README.ru.md) | **简体中文** | [Bahasa Indonesia](./README.id-ID.md) 一个小巧、安全、URL友好、唯一的 JavaScript 字符串ID生成器。 > “一个惊人的无意义的完美主义水平, > 这简直让人无法不敬佩。” * **小巧.** 130 bytes (已压缩和 gzipped)。 没有依赖。 [Size Limit] 控制大小。 * **快速.** 它比 UUID 快 60%。 * **安全.** 它使用加密的强随机 API。可在集群中使用。 * **紧凑.** 它使用比 UUID(`A-Za-z0-9_-`)更大的字母表。 因此,ID 大小从36个符号减少到21个符号。 * **易用.** Nano ID 已被移植到 [20种编程语言](#其他编程语言)。 ```js import { nanoid } from 'nanoid' model.id = nanoid() //=> "V1StGXR8_Z5jdHi6B-myT" ``` 支持现代浏览器、IE [使用 Babel]、Node.js 和 React Native。 [在线工具]: https://gitpod.io/#https://github.com/ai/nanoid/ [使用 Babel]: https://developer.epages.com/blog/coding/how-to-transpile-node-modules-with-babel-and-webpack-in-a-monorepo/ [Size Limit]: https://github.com/ai/size-limit Sponsored by Evil Martians ## 目录 * [与 UUID 的比较](#与-uuid-的比较) * [基准值](#基准值) * [安全性](#安全性) * [API](#api) * [阻塞](#阻塞) * [异步](#异步) * [不安全](#不安全) * [自定义字母或大小](#自定义字母或大小) * [自定义随机字节生成器](#自定义随机字节生成器) * [用法](#用法) * [IE](#ie) * [React](#react) * [React Native](#react-native) * [Rollup](#rollup) * [PouchDB and CouchDB](#pouchdb-and-couchdb) * [Mongoose](#mongoose) * [Web Workers](#web-workers) * [CLI](#cli) * [其他编程语言](#other-programming-languages) * [工具](#工具) ## 与 UUID 的比较 Nano ID 与 UUID v4 (基于随机) 相当。 它们在 ID 中有相似数量的随机位 (Nano ID 为126,UUID 为122),因此它们的冲突概率相似:: > 要想有十亿分之一的重复机会, > 必须产生103万亿个版本4的ID. Nano ID 和 UUID v4之间有三个主要区别: 1. Nano ID 使用更大的字母表,所以类似数量的随机位 被包装在21个符号中,而不是36个。 2. Nano ID 代码比 `uuid/v4` 包少 **4倍**: 130字节而不是483字节. 3. 由于内存分配的技巧,Nano ID 比 UUID 快 **60%**。 ## 基准值 ```rust $ node ./test/benchmark.js crypto.randomUUID 25,603,857 ops/sec @napi-rs/uuid 9,973,819 ops/sec uid/secure 8,234,798 ops/sec @lukeed/uuid 7,464,706 ops/sec nanoid 5,616,592 ops/sec customAlphabet 3,115,207 ops/sec uuid v4 1,535,753 ops/sec secure-random-string 388,226 ops/sec uid-safe.sync 363,489 ops/sec cuid 187,343 ops/sec shortid 45,758 ops/sec Async: nanoid/async 96,094 ops/sec async customAlphabet 97,184 ops/sec async secure-random-string 92,794 ops/sec uid-safe 90,684 ops/sec Non-secure: uid 67,376,692 ops/sec nanoid/non-secure 2,849,639 ops/sec rndm 2,674,806 ops/sec ``` 测试配置: ThinkPad X1 Carbon Gen 9, Fedora 34, Node.js 16.10. ## 安全性 *请看一篇关于随机生成器理论的好文章: [安全的随机值 (在 Node.js 中)]* * **不可预测性.** 不使用不安全的 `Math.random()`, Nano ID 使用 Node.js 的 `crypto` 模块和浏览器的 Web Crypto API。 这些模块使用不可预测的硬件随机生成器。 * **统一性.** `随机 % 字母表` 是编写ID生成器时常犯的一个错误。 符号的分布是不均匀的; 有些符号出现的几率会比其他符号低。因此, 它将减少刷新时的尝试次数。 Nano ID 使用了一种 [更好的算法],并进行了一致性测试。 Nano ID uniformity * **有据可查:** 所有的 Nano ID 的行为都有记录。 见 [源代码] 中的注释。 * **漏洞:** 报告安全漏洞,请使用 [安全联系人 Tidelift](https://tidelift.com/security). Tidelift 将协调修复和披露。 [安全的随机值 (在 Node.js 中)]: https://gist.github.com/joepie91/7105003c3b26e65efcea63f3db82dfba [更好的算法]: https://github.com/ai/nanoid/blob/main/index.js [源代码]: https://github.com/ai/nanoid/blob/main/index.js ## 安装 ```bash npm install --save nanoid ``` 对于快速的骇客用法,你可以从 CDN 加载 Nano ID。但是,它不建议 在生产中使用,因为它的加载性能较低。 ```js import { nanoid } from 'https://cdn.jsdelivr.net/npm/nanoid/nanoid.js' ``` Nano ID提供ES模块。在 webpack、Rollup、Parcel 或 Node.js 中 你不需要做任何事情来使用 Nano ID ```js import { nanoid } from 'nanoid' ``` 在 Node.js 中,你可以使用 CommonJS 导入: ```js const { nanoid } = require('nanoid') ``` ## API Nano ID 有3个 API:正常(阻塞),异步,和不安全。 默认情况下,Nano ID 使用 URL 友好的符号(`A-Za-z0-9_-`)并返回一个 有21个字符(类似UUID v4的冲突概率)的ID。 ### 阻塞 使用 Nano ID 最安全、最简单的方法 在极少数情况下,噪声收集时可能会阻止CPU执行其他工作 用于硬件随机发生器。 ```js import { nanoid } from 'nanoid' model.id = nanoid() //=> "V1StGXR8_Z5jdHi6B-myT" ``` 如果你想要减小ID size(但是会增加冲突概率), 可以将 size 作为参数传递 ```js nanoid(10) //=> "IRFa-VaY2b" ``` 别忘了检查你的ID size 的安全性 在我们的 [ID 冲突概率] 计算器. 您也可以使用 [自定义字母表](#自定义字母或大小) 或者是 [自定义生成器](#自定义随机字节生成器). [ID 冲突概率]: https://alex7kom.github.io/nano-nanoid-cc/ ### 异步 为了生成硬件随机字节,CPU收集电磁噪声。 在大多数情况下,熵已经被收集。 在噪声收集期间的同步API中,CPU忙且 无法执行任何有用的操作(例如,处理另一个HTTP请求)。 使用Nano ID的异步API,可以在熵收集期间 运行另一个代码。 ```js import { nanoid } from 'nanoid/async' async function createUser () { user.id = await nanoid() } ``` 阅读更多有关熵收集的信息 [`crypto.randomBytes`] 文档. 不幸的是,您将在浏览器中失去 Web Crypto API 的优势 如果您使用异步 API。那么,目前在浏览器中, 您将受到安全性或异步行为的限制。 [`crypto.randomBytes`]: https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback ### 不安全 默认情况下,Nano ID 使用硬件随机字节生成器来实现安全性 冲突概率低。如果你不那么关心安全 更关心性能的话,您可以使用更快的非安全生成器. ```js import { nanoid } from 'nanoid/non-secure' const id = nanoid() //=> "Uakgb_J5m9g-0JDMbcJqLJ" ``` ### 自定义字母或大小 `customAlphabet` 允许您使用自己的字母表创建 `nanoid` 和 ID size。 ```js import { customAlphabet } from 'nanoid' const nanoid = customAlphabet('1234567890abcdef', 10) model.id = nanoid() //=> "4f90d13a42" ``` 在我们的中 [ID 冲突概率] 计算器检查您的自定义字母表和 ID size 的安全性。 有关更多字母表, 请在 [`nanoid-dictionary`] 查看选项. 字母表必须包含256个或更少的符号。 否则,无法保证内部生成器算法的安全性。 还提供了可定制的异步和非安全API: ```js import { customAlphabet } from 'nanoid/async' const nanoid = customAlphabet('1234567890abcdef', 10) async function createUser () { user.id = await nanoid() } ``` ```js import { customAlphabet } from 'nanoid/non-secure' const nanoid = customAlphabet('1234567890abcdef', 10) user.id = nanoid() ``` [`nanoid-dictionary`]: https://github.com/CyberAP/nanoid-dictionary ### 自定义随机字节生成器 `customRandom` 允许您创建一个 `nanoid` 并替换字母表 和默认的随机字节生成器。 在此示例中,使用基于种子的生成器: ```js import { customRandom } from 'nanoid' const rng = seedrandom(seed) const nanoid = customRandom('abcdef', 10, size => { return (new Uint8Array(size)).map(() => 256 * rng()) }) nanoid() //=> "fbaefaadeb" ``` `random` 回调必须接受数组大小并返回随机数的数组。 如果要使用与 `customRandom` 相同的URL友好符号, 您可以使用 `urlAlphabet` 获取默认字母表。 ```js const { customRandom, urlAlphabet } = require('nanoid') const nanoid = customRandom(urlAlphabet, 10, random) ``` 异步和非安全 API 不适用于 `customRandom`。 ## 用法 ### IE 如果你需要支持 IE, 则需要使用 Babel [转换 `node_modules`] 并添加 `crypto` 别名: ```js // polyfills.js if (!window.crypto) { window.crypto = window.msCrypto } ``` ```js import './polyfills.js' import { nanoid } from 'nanoid' ``` [转换 `node_modules`]: https://developer.epages.com/blog/coding/how-to-transpile-node-modules-with-babel-and-webpack-in-a-monorepo/ ### React 目前还没有将 nanoid 用于 React `key` prop 的正确方法 因为它在不同的渲染中应该是一致的。 ```jsx function Todos({todos}) { return ( ) } ``` 您应该尝试在列表项中找到稳定的 id。 ```jsx const todoItems = todos.map((todo) =>
  • {todo.text}
  • ) ``` 如果您没有稳定的 ID,您最好使用索引作为 `键` 而不是 `nanoid()`: ```jsx const todoItems = todos.map((text, index) =>
  • /* 仍然不推荐,但优于 nanoid()。 仅当项目没有稳定ID时才执行此操作。 */ {text}
  • ) ``` ### React Native React Native 没有内置的随机生成器。下面的 polyfill 适用于普通 React Native 和从 `39.x` 开始的 Expo。 1. 检查 [`react-native-get-random-values`] 文档并安装它。 2. 在 Nano ID 之前导入它。 ```js import 'react-native-get-random-values' import { nanoid } from 'nanoid' ``` [`react-native-get-random-values`]: https://github.com/LinusU/react-native-get-random-values ### Rollup 对于 Rollup 来说,你需要 [`@rollup/plugin-node-resolve`] 来绑定浏览器版本。 ```js plugins: [ nodeResolve({ browser: true }) ] ``` [`@rollup/plugin-node-resolve`]: https://github.com/rollup/plugins/tree/master/packages/node-resolve ### PouchDB and CouchDB 在 PouchDB 和 CouchDB 中,ID 不能以下划线 `_` 开头。 需要一个前缀来防止这个问题,因为 Nano ID 可能在默认情况下使用 `_` 作为 ID 的开头。 在默认情况下,在 ID 的开头使用 `_`。 用下面的选项覆盖默认的 ID。 ```js db.put({ _id: 'id' + nanoid(), … }) ``` ### Mongoose ```js const mySchema = new Schema({ _id: { type: String, default: () => nanoid() } }) ``` ### Web Workers Web Workers 无法访问安全的随机生成器. 当ID应该是不可预测的时候,安全性对ID很重要。 例如,在 "按 URL 访问"的链接生成中。 如果你不需要不可预测的 ID,但你需要使用 Web Workers。 你可以使用非安全的 ID 生成器。 ```js import { nanoid } from 'nanoid/non-secure' nanoid() //=> "Uakgb_J5m9g-0JDMbcJqLJ" ``` ### CLI 你可以通过调用 `npx nanoid` 在终端获得唯一的 ID。你只需要 在系统中安装了 Node.js。你不需要把 Nano ID 安装在任何地方。 ```sh $ npx nanoid npx: installed 1 in 0.63s LZfXLFzPPR4NNrgjlWDxn ``` 如果你想改变字母或 ID size,你应该使用 [`nanoid-cli`]。 [`nanoid-cli`]: https://github.com/twhitbeck/nanoid-cli ### 其他编程语言 Nano ID 已被移植到许多语言。 你可以使用下面这些移植,获取在客户端和服务器端相同的ID生成器。 * [C#](https://github.com/codeyu/nanoid-net) * [C++](https://github.com/mcmikecreations/nanoid_cpp) * [Clojure and ClojureScript](https://github.com/zelark/nano-id) * [ColdFusion/CFML](https://github.com/JamoCA/cfml-nanoid) * [Crystal](https://github.com/mamantoha/nanoid.cr) * [Dart & Flutter](https://github.com/pd4d10/nanoid-dart) * [Deno](https://github.com/ianfabs/nanoid) * [Go](https://github.com/matoous/go-nanoid) * [Elixir](https://github.com/railsmechanic/nanoid) * [Haskell](https://github.com/MichelBoucey/NanoID) * [Janet](https://sr.ht/~statianzo/janet-nanoid/) * [Java](https://github.com/aventrix/jnanoid) * [Nim](https://github.com/icyphox/nanoid.nim) * [Perl](https://github.com/tkzwtks/Nanoid-perl) * [PHP](https://github.com/hidehalo/nanoid-php) * [Python](https://github.com/puyuan/py-nanoid) with [dictionaries](https://pypi.org/project/nanoid-dictionary) * [Ruby](https://github.com/radeno/nanoid.rb) * [Rust](https://github.com/nikolay-govorov/nanoid) * [Swift](https://github.com/antiflasher/NanoID) * [Unison](https://share.unison-lang.org/latest/namespaces/hojberg/nanoid) * [V](https://github.com/invipal/nanoid) 此外,[CLI] 还可用于从命令行生成 ID。 [CLI]: #cli ## 工具 * [ID size 计算器] 显示调整时的冲突概率 ID的字母或size。 * [`nanoid-dictionary`] 与常用的字母一起使用 [`自定义字母`]。 * [`nanoid-good`] 以确保你的ID不包含任何淫秽词汇。 [`nanoid-dictionary`]: https://github.com/CyberAP/nanoid-dictionary [ID size 计算器]: https://zelark.github.io/nano-id-cc/ [`自定义字母`]: #自定义字母或大小 [`nanoid-good`]: https://github.com/y-gagar1n/nanoid-good nanoid-3.3.1/async/000077500000000000000000000000001420327433100141025ustar00rootroot00000000000000nanoid-3.3.1/async/index.browser.js000066400000000000000000000051711420327433100172350ustar00rootroot00000000000000let random = async bytes => crypto.getRandomValues(new Uint8Array(bytes)) let customAlphabet = (alphabet, defaultSize = 21) => { // First, a bitmask is necessary to generate the ID. The bitmask makes bytes // values closer to the alphabet size. The bitmask calculates the closest // `2^31 - 1` number, which exceeds the alphabet size. // For example, the bitmask for the alphabet size 30 is 31 (00011111). // `Math.clz32` is not used, because it is not available in browsers. let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 1 // Though, the bitmask solution is not perfect since the bytes exceeding // the alphabet size are refused. Therefore, to reliably generate the ID, // the random bytes redundancy has to be satisfied. // Note: every hardware random generator call is performance expensive, // because the system call for entropy collection takes a lot of time. // So, to avoid additional system calls, extra bytes are requested in advance. // Next, a step determines how many random bytes to generate. // The number of random bytes gets decided upon the ID size, mask, // alphabet size, and magic number 1.6 (using 1.6 peaks at performance // according to benchmarks). // `-~f => Math.ceil(f)` if f is a float // `-~i => i + 1` if i is an integer let step = -~((1.6 * mask * defaultSize) / alphabet.length) return async (size = defaultSize) => { let id = '' while (true) { let bytes = crypto.getRandomValues(new Uint8Array(step)) // A compact alternative for `for (var i = 0; i < step; i++)`. let i = step while (i--) { // Adding `|| ''` refuses a random byte that exceeds the alphabet size. id += alphabet[bytes[i] & mask] || '' if (id.length === size) return id } } } } let nanoid = async (size = 21) => { let id = '' let bytes = crypto.getRandomValues(new Uint8Array(size)) // A compact alternative for `for (var i = 0; i < step; i++)`. while (size--) { // It is incorrect to use bytes exceeding the alphabet size. // The following mask reduces the random byte in the 0-255 value // range to the 0-63 value range. Therefore, adding hacks, such // as empty string fallback or magic numbers, is unneccessary because // the bitmask trims bytes down to the alphabet size. let byte = bytes[size] & 63 if (byte < 36) { // `0-9a-z` id += byte.toString(36) } else if (byte < 62) { // `A-Z` id += (byte - 26).toString(36).toUpperCase() } else if (byte < 63) { id += '_' } else { id += '-' } } return id } module.exports = { nanoid, customAlphabet, random } nanoid-3.3.1/async/index.d.ts000066400000000000000000000027411420327433100160070ustar00rootroot00000000000000/** * Generate secure URL-friendly unique ID. The non-blocking version. * * By default, the ID will have 21 symbols to have a collision probability * similar to UUID v4. * * ```js * import { nanoid } from 'nanoid/async' * nanoid().then(id => { * model.id = id * }) * ``` * * @param size Size of the ID. The default size is 21. * @returns A promise with a random string. */ export function nanoid(size?: number): Promise /** * A low-level function. * Generate secure unique ID with custom alphabet. The non-blocking version. * * Alphabet must contain 256 symbols or less. Otherwise, the generator * will not be secure. * * @param alphabet Alphabet used to generate the ID. * @param defaultSize Size of the ID. The default size is 21. * @returns A function that returns a promise with a random string. * * ```js * import { customAlphabet } from 'nanoid/async' * const nanoid = customAlphabet('0123456789абвгдеё', 5) * nanoid().then(id => { * model.id = id //=> "8ё56а" * }) * ``` */ export function customAlphabet( alphabet: string, defaultSize?: number ): (size?: number) => Promise /** * Generate an array of random bytes collected from hardware noise. * * ```js * import { random } from 'nanoid/async' * random(5).then(bytes => { * bytes //=> [10, 67, 212, 67, 89] * }) * ``` * * @param bytes Size of the array. * @returns A promise with a random bytes array. */ export function random(bytes: number): Promise nanoid-3.3.1/async/index.js000066400000000000000000000054461420327433100155600ustar00rootroot00000000000000let crypto = require('crypto') let { urlAlphabet } = require('../url-alphabet') // `crypto.randomFill()` is a little faster than `crypto.randomBytes()`, // because it is possible to use in combination with `Buffer.allocUnsafe()`. let random = bytes => new Promise((resolve, reject) => { // `Buffer.allocUnsafe()` is faster because it doesn’t flush the memory. // Memory flushing is unnecessary since the buffer allocation itself resets // the memory with the new bytes. crypto.randomFill(Buffer.allocUnsafe(bytes), (err, buf) => { if (err) { reject(err) } else { resolve(buf) } }) }) let customAlphabet = (alphabet, defaultSize = 21) => { // First, a bitmask is necessary to generate the ID. The bitmask makes bytes // values closer to the alphabet size. The bitmask calculates the closest // `2^31 - 1` number, which exceeds the alphabet size. // For example, the bitmask for the alphabet size 30 is 31 (00011111). let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1 // Though, the bitmask solution is not perfect since the bytes exceeding // the alphabet size are refused. Therefore, to reliably generate the ID, // the random bytes redundancy has to be satisfied. // Note: every hardware random generator call is performance expensive, // because the system call for entropy collection takes a lot of time. // So, to avoid additional system calls, extra bytes are requested in advance. // Next, a step determines how many random bytes to generate. // The number of random bytes gets decided upon the ID size, mask, // alphabet size, and magic number 1.6 (using 1.6 peaks at performance // according to benchmarks). let step = Math.ceil((1.6 * mask * defaultSize) / alphabet.length) let tick = (id, size = defaultSize) => random(step).then(bytes => { // A compact alternative for `for (var i = 0; i < step; i++)`. let i = step while (i--) { // Adding `|| ''` refuses a random byte that exceeds the alphabet size. id += alphabet[bytes[i] & mask] || '' if (id.length === size) return id } return tick(id, size) }) return size => tick('', size) } let nanoid = (size = 21) => random(size).then(bytes => { let id = '' // A compact alternative for `for (var i = 0; i < step; i++)`. while (size--) { // It is incorrect to use bytes exceeding the alphabet size. // The following mask reduces the random byte in the 0-255 value // range to the 0-63 value range. Therefore, adding hacks, such // as empty string fallback or magic numbers, is unneccessary because // the bitmask trims bytes down to the alphabet size. id += urlAlphabet[bytes[size] & 63] } return id }) module.exports = { nanoid, customAlphabet, random } nanoid-3.3.1/async/index.native.js000066400000000000000000000044511420327433100170400ustar00rootroot00000000000000let { getRandomBytesAsync } = require('expo-random') let { urlAlphabet } = require('../url-alphabet') let random = getRandomBytesAsync let customAlphabet = (alphabet, defaultSize = 21) => { // First, a bitmask is necessary to generate the ID. The bitmask makes bytes // values closer to the alphabet size. The bitmask calculates the closest // `2^31 - 1` number, which exceeds the alphabet size. // For example, the bitmask for the alphabet size 30 is 31 (00011111). let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1 // Though, the bitmask solution is not perfect since the bytes exceeding // the alphabet size are refused. Therefore, to reliably generate the ID, // the random bytes redundancy has to be satisfied. // Note: every hardware random generator call is performance expensive, // because the system call for entropy collection takes a lot of time. // So, to avoid additional system calls, extra bytes are requested in advance. // Next, a step determines how many random bytes to generate. // The number of random bytes gets decided upon the ID size, mask, // alphabet size, and magic number 1.6 (using 1.6 peaks at performance // according to benchmarks). let step = Math.ceil((1.6 * mask * defaultSize) / alphabet.length) let tick = (id, size = defaultSize) => random(step).then(bytes => { // A compact alternative for `for (var i = 0; i < step; i++)`. let i = step while (i--) { // Adding `|| ''` refuses a random byte that exceeds the alphabet size. id += alphabet[bytes[i] & mask] || '' if (id.length === size) return id } return tick(id, size) }) return size => tick('', size) } let nanoid = (size = 21) => random(size).then(bytes => { let id = '' // A compact alternative for `for (var i = 0; i < step; i++)`. while (size--) { // It is incorrect to use bytes exceeding the alphabet size. // The following mask reduces the random byte in the 0-255 value // range to the 0-63 value range. Therefore, adding hacks, such // as empty string fallback or magic numbers, is unneccessary because // the bitmask trims bytes down to the alphabet size. id += urlAlphabet[bytes[size] & 63] } return id }) module.exports = { nanoid, customAlphabet, random } nanoid-3.3.1/bin/000077500000000000000000000000001420327433100135355ustar00rootroot00000000000000nanoid-3.3.1/bin/nanoid.cjs000077500000000000000000000021451420327433100155130ustar00rootroot00000000000000#!/usr/bin/env node let { nanoid, customAlphabet } = require('..') function print(msg) { process.stdout.write(msg + '\n') } function error(msg) { process.stderr.write(msg + '\n') process.exit(1) } if (process.argv.includes('--help') || process.argv.includes('-h')) { print(` Usage $ nanoid [options] Options -s, --size Generated ID size -a, --alphabet Alphabet to use -h, --help Show this help Examples $ nano --s 15 S9sBF77U6sDB8Yg $ nano --size 10 --alphabet abc bcabababca`) process.exit() } let alphabet, size for (let i = 2; i < process.argv.length; i++) { let arg = process.argv[i] if (arg === '--size' || arg === '-s') { size = Number(process.argv[i + 1]) i += 1 if (Number.isNaN(size) || size <= 0) { error('Size must be positive integer') } } else if (arg === '--alphabet' || arg === '-a') { alphabet = process.argv[i + 1] i += 1 } else { error('Unknown argument ' + arg) } } if (alphabet) { let customNanoid = customAlphabet(alphabet, size) print(customNanoid()) } else { print(nanoid(size)) } nanoid-3.3.1/img/000077500000000000000000000000001420327433100135415ustar00rootroot00000000000000nanoid-3.3.1/img/distribution.png000066400000000000000000000311261420327433100167710ustar00rootroot00000000000000PNG  IHDR2IDATx7a@l 4NÔDVa,rュ=#qaa p?~p?~~p?~ީjXu5~wI$e5f,5~wyxx8==~hjU|>_t:v ^Pv{\,dnizyyBh41n;J8'u:k6mۻڶm۶Q:m7w>_s_Ϟ=S/^ؿEZZZr-Z֮Ù.\@Z/Rȁu`̘1yA h *T񎎎PۊIWXk׮[ >+V d6^x???8F^[[,' ;88hh YF9rǓ4^^^\j2l2Fk׮r$n{|TRufZ̙3>O,ƍud!_O@Z{?ڲ~HhJll=Ľ{*1E働7Y !9MY=b&MLv܉HT ?w\YD:"rU(@^9 :d߼yG $$D_xA'Oo߾m ֩SG F? nL2eޏCd_!5eӦM) K,1N#EG5z?!~B~4 4U5k{X&ڵ;s۷_d3)<>}QǗ# 7l{kMucҥu G ,0F:z?!zΝL:U9a޼y&{chPߑva>}*ʆϟ?O1ee+L~ h#a"ݻwF;y#@'O(CwtA4A֭TV ڟꁈ%JL4 5㣝ݣGȾ}vU!h?@?B'BȢ9*ŋ;wθ`Ei~hO .'O1 oݺuׯfwnq έ3VqQP`/ Dp?~p?~p?8(!_`aggU9zoR\9^c~g?~g?~g?~;;g?~g?~g?~`?~`?~g?~g?~g?~(g?~g?_¹Y79 Yfލ1x !R.dF{FW7Ҩ%y25 սMF])=WJ%'S|EX~iV+MbQOQ/tL_12uNQizlf~b_F7ʰn39(ؿex]'FO\oWxPvJt‡W[_bhv}%4~ff{IhM2T]tTG$/x+!V^`f|؏x) IYHJ:XZޛe?T//9̫*S霈 ŽdT]`:^*ÏmN#*)=OMYWm)="Ch~f )7o(]I!N2ːZilr&jCg:=4$,͋c]4د`}jgZ2m®a# ]j.Dэ\i)ҏJNB]~j=ɶϳ)Ǖx|BhڬUnP`hM^KofZAl?j1az;ƽ4UzĐSV?YG"f6gH0Z3Er 7<_IN+čɘ?2y9]L%P6+W_ni~UC2b̟fOƇi`1x8YSZ{b;Pΐ 1J'jߵ\yPŎ8ϻ ^gĎhM5'AN>%f?4h3+/谿Na"pSz aњOgddve?ӑ!eav)꓁|| }[EkIsIs~(/x&׫Z}Tc?ETw},̣%,. /:ϙ?0N$iC~g?ؾ>[S*>QaB}\ 5s& B&/ a͋H6u1/u؟+Zv1kk=7[Fgz>ƍU*:o$- <7IRď wjRĥ_O]%#Ҋ[7f5? aWϼ'VԀ۬Җط6ŭCk`'^gf^g`Nĩ _S~<@v1`E*ݮa њ$"}Ԡ`b4~Éi!횳1Z3[v.H?S ƶQ٣~X/<-$wr5B|?@|KX{w*/qó$q$l^91^nx@4Բ30Unq> M]9M[,!o#P$1KU^Ef G҃Z{ G^bLҺg?BD1ljlj괠ɂfُ:m-\ʤN7x>_n'BĨSlq1P?PFׄ3R^rDjnfmR1sz{Չ)TٟSG>izHg?mI?Q~V*qdW]_k1 $Xi~H/]4V_1QU$~gݡVB촨d:A~dBZO4.% 'VuI0PIoVr.yO`J+ G}vYUӹ]SztFxn2܀2 {b/a ~0CUIaYi_`v&k:n|E%7@fY7@h]>b6G%<ȠMV^rڒ$ _VB' Atx]u_D PIJRk/R}:`τHwF>a?ߪ 5*/$۷SU_O4_Eۿkߵ:ofsK9?Q#?'ɷso% 1jB6mٯ-so/7QlOTŘ}F%P?#ȤvSխ67'~|~b|hk1`fw@0^+q*5xe߯okkkkkkkk~hkkk~hkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk;;~~~wvگگگگگگ@@~@~@~@@~@~@~@@~h?h?h?twU^dw@r('f`FQ,Ŭ39,/uUk'ff(;ӹ55eef?k~bC]|9}l2L~TJzǏ`۷oG=̴iӢm=K.18TF珍yXh_jժXqo2|͇~!ܹso۶_5B ϲCtΰcwM&cdLڵoɒ%ˑ#Ǎ7~鿊&ӥKݻO{?!v…;wos[n~: N_ ի%#v%2gĉmʔ)1;/^dx1k׮]~=Cytȓ L8铞&cwOʏ?[o$Id{2elݺcðaի2eJi/BիW[ W_M x≆ Il 2&^xlC'=?Eٲe;ݭ[7Qp´* &~oܸOнH"K*1AVX񩧞2{+Z&nݺTQpd͚5β5i͢+XVT[&Ma9 p2 9sĂHX_~}&'qNZ-ψ[d>g̘o ӧOO;>qœ.]T~!Ɖ,Xqt)-[/o2E~*쬤3]m{[hvZ]J'OXw؏=zTÇcDv p鲜>}ZU _|9Bkv@#UӃF"r\&[<5d@K+L0^j5,`䁱Rڛ7o8`-։(8gr(@h]vqdɒ޽{|4zh%#:UV^j N_5.b&dGEV6qh֬Y-Ƀ?,PKk|ر0 ;ng3!_^tWvr6%A>DY }wSAƏ?:g}̙@<*R$qkΞ=y)"}|-7lg?s`FJ8>Ӹq5 L~k&'`C$a?~'m{= [,,~<"vx<})-@YfH> AzĈZ[G_U`0y!yOnޱIV~2Js蕚:u~\4r1^_=b'{hcou;u_IVepչsg)uIYݼy_t@K۶m%, D5ag-.uIK2L={$MG2=PMϕE0G:8-yp/^YTHxFX;Ϙ1's{SStiӦȏM&cj9rHڴiiFx_[E~yP텗VNK*~'foF|[1tVaMɓ'3yjXkJBR\aL;nw^`>'N$;$0~Y̙A=z̉~&-5@@p[o2L&QYf؍z46 /.+Y&MT~>vXďRG6(@>ACFFEpcƌ%Kp 9ϘG@zviTG#Q26 .t42#XfϞJa?`,ı#jc~-[A(#Gҭ6Ї.Ah\2,z}.wܩT=kwJ?e+G+ẀXǎ&ds [G~BsΟv9 eiB~Wau}wC UЅǩrP]ke?.m8ͨ@#e6fv )_U~B&d&?M#fp;ʆ"e?!@`&^%i?.8ȋ.y31^,UGe{5 t C'7z ϰ;A)h,!CFOy Kt#KN[b]&d(̚@"+nLFϳXbTe\ἅCiu/%O14rvB}T vSQAh ~-B t.?)~)U|J=脮'U~#t`xi@tgͭHc'7r `xGχURTuXd7Q~t@94D~UqhXOW:ϟĻ8WK6"Rt)np2w;8=;Ąa- m $g?Tf  TOq3_C9s&מ d8FICdCtTg,r<_9?*e2M,Xq.m=kD|(K=A`Jmp+2Oz:/gqYBi*R>Nk^ /w@ ɢٜ^%~h?h?M ~@~@~@~@Յ 1@7lz_㧵n^C:DjF.s5RMgCn ~g?~g?~g?~(b?~(b?~g?~g?~g?~g?~7g?~߀g?~g?~wm,w 1VB 33sb̖T۳~p*%KwT]ӿ]*s*UWٿ -5ٿ"M >=43B3B{1F`uӉ'4;D4t2ZyP){iMH3Wٯ_e~ZY%O`'MӴ >Ikϐc,=NiP/j5;LvܘR d~*R4ui^ UW_r֒]#@ivn,%Pٟ6QٿhUg*c#$OdDkA 6$5Iq=i`BevQ?64 `?8 X, aehmy Q$EpHo y[P;D!It7kFُ))BS د_edRphT&iA=07؄Xh '~DTR)N2>aʳmhaZt@5I?dz$2m( цжa5(_I@s"t8^ &6[(dCgRVic7p6c]Mh' 2<>DіT`aF{"\1?oM3#V!"*ru  hǀ%h>S^c)Y56#~,3ISK>;~D3\)Kp29(D{DZ3`Tj/?$͛d*Sgus/(y4ƱrZV?Ehe2m?G4J*{K+"Dn x/Mj ̫7R777]יVF/ Jrnk!gW 3rsg{4 XZ9(~gm=[NN+kasؼZ^Nm~ B3 " TrN6gEi8pKhO|Q 7`廴Y H ٽ|Gc2KC7~`bLyU.ye*d\]Oo(iA$g"LrS"L2t_3BA-7yQvlإY!gFd~tUCX<8~,Go0g9F"Iz <țǢ_oЮ߅EôUOK@ m%;m7aVHf~?&oh5 T?,i^D~f #J['SNDX;K[63~[9aϭ44+N<-~J(3~$ڎ_h_UҬ9 MExC2=PDؿ,L(Š#ۡ'Jj0*4#@sX!ϳKoKˏs39VBC[ ߾G-?y~g#,z&p]~ <|埢'.Ԁ(i{|/ +mK"_ueV{%IG:3~}w1{_rXY~"w؏d~0,6k.j͵D9C=L4o"/QCQ8 ̪R~OQK͊lf>3[nږO\ge,ӟqk?4 ;LuR~a#s&])RY~-f$~LcneUG#~G{gTgLYlg#9'l;p?-_{Fr۰΃"斳e'?Щ` inВThם_7>f?+y@&a?sڅH_iq2ؐ`W~/7i >j!(E-:V?}[EEv٦AYa`&8C]t1Wf=!}Шiv9`8 ?r@\rxQ)s _.x2~|퍲Ma+OR>aMi+ʝbg7 8{'q|;vv2ϊ 1R̋_/Y*}"SVsSmz~v[ Ys9e!Πf$u>j$C(c8؏PĆM M͊JSV`w4ϳ+C֝$ P zg/aIh0!spdU$!fm\^CZh^aX߽/o71#EIOcL$KV}4EvErl/6۽Vٟ(Ym4oBe?C /`Z >O/?ߥ~.×g?~ g?~g?~g?~g?~g?~g?~g?~g?~g?~g?~g?~g?~_~gW{u@k-p?p?~p?~@"d)IENDB`nanoid-3.3.1/img/icon.svg000066400000000000000000000005241420327433100152130ustar00rootroot00000000000000nanoid-3.3.1/img/logo.svg000066400000000000000000000061271420327433100152300ustar00rootroot00000000000000 nanoid-3.3.1/index.browser.js000066400000000000000000000055521420327433100161230ustar00rootroot00000000000000// This file replaces `index.js` in bundlers like webpack or Rollup, // according to `browser` config in `package.json`. let { urlAlphabet } = require('./url-alphabet') let random = bytes => crypto.getRandomValues(new Uint8Array(bytes)) let customRandom = (alphabet, defaultSize, getRandom) => { // First, a bitmask is necessary to generate the ID. The bitmask makes bytes // values closer to the alphabet size. The bitmask calculates the closest // `2^31 - 1` number, which exceeds the alphabet size. // For example, the bitmask for the alphabet size 30 is 31 (00011111). // `Math.clz32` is not used, because it is not available in browsers. let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 1 // Though, the bitmask solution is not perfect since the bytes exceeding // the alphabet size are refused. Therefore, to reliably generate the ID, // the random bytes redundancy has to be satisfied. // Note: every hardware random generator call is performance expensive, // because the system call for entropy collection takes a lot of time. // So, to avoid additional system calls, extra bytes are requested in advance. // Next, a step determines how many random bytes to generate. // The number of random bytes gets decided upon the ID size, mask, // alphabet size, and magic number 1.6 (using 1.6 peaks at performance // according to benchmarks). // `-~f => Math.ceil(f)` if f is a float // `-~i => i + 1` if i is an integer let step = -~((1.6 * mask * defaultSize) / alphabet.length) return (size = defaultSize) => { let id = '' while (true) { let bytes = getRandom(step) // A compact alternative for `for (var i = 0; i < step; i++)`. let j = step while (j--) { // Adding `|| ''` refuses a random byte that exceeds the alphabet size. id += alphabet[bytes[j] & mask] || '' if (id.length === size) return id } } } } let customAlphabet = (alphabet, size = 21) => customRandom(alphabet, size, random) let nanoid = (size = 21) => { let id = '' let bytes = crypto.getRandomValues(new Uint8Array(size)) // A compact alternative for `for (var i = 0; i < step; i++)`. while (size--) { // It is incorrect to use bytes exceeding the alphabet size. // The following mask reduces the random byte in the 0-255 value // range to the 0-63 value range. Therefore, adding hacks, such // as empty string fallback or magic numbers, is unneccessary because // the bitmask trims bytes down to the alphabet size. let byte = bytes[size] & 63 if (byte < 36) { // `0-9a-z` id += byte.toString(36) } else if (byte < 62) { // `A-Z` id += (byte - 26).toString(36).toUpperCase() } else if (byte < 63) { id += '_' } else { id += '-' } } return id } module.exports = { nanoid, customAlphabet, customRandom, urlAlphabet, random } nanoid-3.3.1/index.d.ts000066400000000000000000000043141420327433100146700ustar00rootroot00000000000000/** * Generate secure URL-friendly unique ID. * * By default, the ID will have 21 symbols to have a collision probability * similar to UUID v4. * * ```js * import { nanoid } from 'nanoid' * model.id = nanoid() //=> "Uakgb_J5m9g-0JDMbcJqL" * ``` * * @param size Size of the ID. The default size is 21. * @returns A random string. */ export function nanoid(size?: number): string /** * Generate secure unique ID with custom alphabet. * * Alphabet must contain 256 symbols or less. Otherwise, the generator * will not be secure. * * @param alphabet Alphabet used to generate the ID. * @param defaultSize Size of the ID. The default size is 21. * @returns A random string generator. * * ```js * const { customAlphabet } = require('nanoid') * const nanoid = customAlphabet('0123456789абвгдеё', 5) * nanoid() //=> "8ё56а" * ``` */ export function customAlphabet( alphabet: string, defaultSize?: number ): (size?: number) => string /** * Generate unique ID with custom random generator and alphabet. * * Alphabet must contain 256 symbols or less. Otherwise, the generator * will not be secure. * * ```js * import { customRandom } from 'nanoid/format' * * const nanoid = customRandom('abcdef', 5, size => { * const random = [] * for (let i = 0; i < size; i++) { * random.push(randomByte()) * } * return random * }) * * nanoid() //=> "fbaef" * ``` * * @param alphabet Alphabet used to generate a random string. * @param size Size of the random string. * @param random A random bytes generator. * @returns A random string generator. */ export function customRandom( alphabet: string, size: number, random: (bytes: number) => Uint8Array ): () => string /** * URL safe symbols. * * ```js * import { urlAlphabet } from 'nanoid' * const nanoid = customAlphabet(urlAlphabet, 10) * nanoid() //=> "Uakgb_J5m9" * ``` */ export const urlAlphabet: string /** * Generate an array of random bytes collected from hardware noise. * * ```js * import { customRandom, random } from 'nanoid' * const nanoid = customRandom("abcdef", 5, random) * ``` * * @param bytes Size of the array. * @returns An array of random bytes. */ export function random(bytes: number): Uint8Array nanoid-3.3.1/index.js000066400000000000000000000063571420327433100144450ustar00rootroot00000000000000let crypto = require('crypto') let { urlAlphabet } = require('./url-alphabet') // It is best to make fewer, larger requests to the crypto module to // avoid system call overhead. So, random numbers are generated in a // pool. The pool is a Buffer that is larger than the initial random // request size by this multiplier. The pool is enlarged if subsequent // requests exceed the maximum buffer size. const POOL_SIZE_MULTIPLIER = 128 let pool, poolOffset let fillPool = bytes => { if (!pool || pool.length < bytes) { pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER) crypto.randomFillSync(pool) poolOffset = 0 } else if (poolOffset + bytes > pool.length) { crypto.randomFillSync(pool) poolOffset = 0 } poolOffset += bytes } let random = bytes => { // `-=` convert `bytes` to number to prevent `valueOf` abusing fillPool((bytes -= 0)) return pool.subarray(poolOffset - bytes, poolOffset) } let customRandom = (alphabet, defaultSize, getRandom) => { // First, a bitmask is necessary to generate the ID. The bitmask makes bytes // values closer to the alphabet size. The bitmask calculates the closest // `2^31 - 1` number, which exceeds the alphabet size. // For example, the bitmask for the alphabet size 30 is 31 (00011111). let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1 // Though, the bitmask solution is not perfect since the bytes exceeding // the alphabet size are refused. Therefore, to reliably generate the ID, // the random bytes redundancy has to be satisfied. // Note: every hardware random generator call is performance expensive, // because the system call for entropy collection takes a lot of time. // So, to avoid additional system calls, extra bytes are requested in advance. // Next, a step determines how many random bytes to generate. // The number of random bytes gets decided upon the ID size, mask, // alphabet size, and magic number 1.6 (using 1.6 peaks at performance // according to benchmarks). let step = Math.ceil((1.6 * mask * defaultSize) / alphabet.length) return (size = defaultSize) => { let id = '' while (true) { let bytes = getRandom(step) // A compact alternative for `for (let i = 0; i < step; i++)`. let i = step while (i--) { // Adding `|| ''` refuses a random byte that exceeds the alphabet size. id += alphabet[bytes[i] & mask] || '' if (id.length === size) return id } } } } let customAlphabet = (alphabet, size = 21) => customRandom(alphabet, size, random) let nanoid = (size = 21) => { // `-=` convert `size` to number to prevent `valueOf` abusing fillPool((size -= 0)) let id = '' // We are reading directly from the random pool to avoid creating new array for (let i = poolOffset - size; i < poolOffset; i++) { // It is incorrect to use bytes exceeding the alphabet size. // The following mask reduces the random byte in the 0-255 value // range to the 0-63 value range. Therefore, adding hacks, such // as empty string fallback or magic numbers, is unneccessary because // the bitmask trims bytes down to the alphabet size. id += urlAlphabet[pool[i] & 63] } return id } module.exports = { nanoid, customAlphabet, customRandom, urlAlphabet, random } nanoid-3.3.1/nanoid.js000066400000000000000000000002761420327433100146000ustar00rootroot00000000000000export let nanoid=(t=21)=>{let e="",r=crypto.getRandomValues(new Uint8Array(t));for(;t--;){let n=63&r[t];e+=n<36?n.toString(36):n<62?(n-26).toString(36).toUpperCase():n<63?"_":"-"}return e};nanoid-3.3.1/non-secure/000077500000000000000000000000001420327433100150435ustar00rootroot00000000000000nanoid-3.3.1/non-secure/index.d.ts000066400000000000000000000017271420327433100167530ustar00rootroot00000000000000/** * Generate URL-friendly unique ID. This method uses the non-secure * predictable random generator with bigger collision probability. * * ```js * import { nanoid } from 'nanoid/non-secure' * model.id = nanoid() //=> "Uakgb_J5m9g-0JDMbcJqL" * ``` * * @param size Size of the ID. The default size is 21. * @returns A random string. */ export function nanoid(size?: number): string /** * Generate a unique ID based on a custom alphabet. * This method uses the non-secure predictable random generator * with bigger collision probability. * * @param alphabet Alphabet used to generate the ID. * @param defaultSize Size of the ID. The default size is 21. * @returns A random string generator. * * ```js * import { customAlphabet } from 'nanoid/non-secure' * const nanoid = customAlphabet('0123456789абвгдеё', 5) * model.id = //=> "8ё56а" * ``` */ export function customAlphabet( alphabet: string, defaultSize?: number ): (size?: number) => string nanoid-3.3.1/non-secure/index.js000066400000000000000000000021221420327433100165050ustar00rootroot00000000000000// This alphabet uses `A-Za-z0-9_-` symbols. // The order of characters is optimized for better gzip and brotli compression. // References to the same file (works both for gzip and brotli): // `'use`, `andom`, and `rict'` // References to the brotli default dictionary: // `-26T`, `1983`, `40px`, `75px`, `bush`, `jack`, `mind`, `very`, and `wolf` let urlAlphabet = 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict' let customAlphabet = (alphabet, defaultSize = 21) => { return (size = defaultSize) => { let id = '' // A compact alternative for `for (var i = 0; i < step; i++)`. let i = size while (i--) { // `| 0` is more compact and faster than `Math.floor()`. id += alphabet[(Math.random() * alphabet.length) | 0] } return id } } let nanoid = (size = 21) => { let id = '' // A compact alternative for `for (var i = 0; i < step; i++)`. let i = size while (i--) { // `| 0` is more compact and faster than `Math.floor()`. id += urlAlphabet[(Math.random() * 64) | 0] } return id } module.exports = { nanoid, customAlphabet } nanoid-3.3.1/package.json000066400000000000000000000076751420327433100152720ustar00rootroot00000000000000{ "name": "nanoid", "version": "3.3.1", "description": "A tiny (130 bytes), secure URL-friendly unique string ID generator", "keywords": [ "uuid", "random", "id", "url" ], "scripts": { "clean": "rm -R coverage", "unit": "uvu . .test.js$", "test": "c8 pnpm unit && eslint . && pnpm clean && size-limit", "start": "vite test/demo/ --open" }, "engines": { "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" }, "author": "Andrey Sitnik ", "license": "MIT", "repository": "ai/nanoid", "browser": { "./index.js": "./index.browser.js", "./async/index.js": "./async/index.browser.js", "./async/index.cjs": "./async/index.browser.cjs" }, "react-native": { "./async/index.js": "./async/index.native.js" }, "bin": "./bin/nanoid.cjs", "sideEffects": false, "types": "./index.d.ts", "devDependencies": { "@babel/core": "^7.17.4", "@logux/eslint-config": "^46.1.1", "@lukeed/uuid": "^2.0.0", "@originjs/vite-plugin-commonjs": "^1.0.3", "@size-limit/dual-publish": "^7.0.8", "@size-limit/file": "^7.0.8", "@size-limit/webpack": "^7.0.8", "@types/node": "^17.0.18", "benchmark": "^2.1.4", "c8": "^7.11.0", "cuid": "^2.1.8", "dual-publish": "^3.0.0", "eslint": "^8.9.0", "eslint-config-standard": "^16.0.3", "eslint-plugin-import": "^2.25.4", "eslint-plugin-node": "^11.1.0", "eslint-plugin-prefer-let": "^3.0.1", "eslint-plugin-promise": "^6.0.0", "nanospy": "^0.5.0", "picocolors": "^1.0.0", "postcss": "^8.4.6", "rndm": "^1.2.0", "secure-random-string": "^1.1.3", "shortid": "^2.2.16", "size-limit": "^7.0.8", "terser": "^5.10.0", "uid": "^2.0.0", "uid-safe": "^2.1.5", "uuid": "^8.3.2", "uvu": "^0.5.3", "vite": "^2.8.3" }, "size-limit": [ { "name": "nanoid", "import": "{ nanoid }", "limit": "130 B" }, { "name": "customAlphabet", "import": "{ customAlphabet }", "limit": "174 B" }, { "name": "urlAlphabet", "import": "{ urlAlphabet }", "limit": "61 B" }, { "name": "non-secure nanoid", "import": "{ nanoid }", "path": "non-secure/index.js", "limit": "118 B" }, { "name": "non-secure customAlphabet", "import": "{ customAlphabet }", "path": "non-secure/index.js", "limit": "69 B" }, { "name": "async nanoid", "import": "{ nanoid }", "path": "async/index.js", "limit": "136 B" }, { "name": "async customAlphabet", "import": "{ customAlphabet }", "path": "async/index.js", "limit": "157 B" }, { "name": "Brotli all", "brotli": true, "import": "{ nanoid, customAlphabet, urlAlphabet }", "limit": "271 B" }, { "name": "Brotli non-secure", "brotli": true, "import": "{ nanoid, customAlphabet }", "path": "non-secure/index.js", "limit": "116 B" }, { "name": "Brotli async", "brotli": true, "import": "{ nanoid, customAlphabet }", "path": "async/index.js", "limit": "211 B" } ], "eslintConfig": { "extends": "@logux/eslint-config", "rules": { "consistent-return": "off", "func-style": "off", "yoda": "off" }, "overrides": [ { "files": "*.native.js", "rules": { "node/no-missing-require": "off", "global-require": "off" } } ] }, "eslintIgnore": [ "test/demo/build", "nanoid.js", "**/errors.ts" ], "prettier": { "arrowParens": "avoid", "jsxSingleQuote": false, "quoteProps": "consistent", "semi": false, "singleQuote": true, "trailingComma": "none" }, "clean-publish": { "cleanDocs": true, "cleanComments": true }, "c8": { "exclude": [ "**/*.test.*" ], "lines": 100, "reporter": "lcov", "check-coverage": true } } nanoid-3.3.1/pnpm-lock.yaml000066400000000000000000002657111420327433100155650ustar00rootroot00000000000000lockfileVersion: 5.3 specifiers: '@babel/core': ^7.17.4 '@logux/eslint-config': ^46.1.1 '@lukeed/uuid': ^2.0.0 '@originjs/vite-plugin-commonjs': ^1.0.3 '@size-limit/dual-publish': ^7.0.8 '@size-limit/file': ^7.0.8 '@size-limit/webpack': ^7.0.8 '@types/node': ^17.0.18 benchmark: ^2.1.4 c8: ^7.11.0 cuid: ^2.1.8 dual-publish: ^3.0.0 eslint: ^8.9.0 eslint-config-standard: ^16.0.3 eslint-plugin-import: ^2.25.4 eslint-plugin-node: ^11.1.0 eslint-plugin-prefer-let: ^3.0.1 eslint-plugin-promise: ^6.0.0 nanospy: ^0.5.0 picocolors: ^1.0.0 postcss: ^8.4.6 rndm: ^1.2.0 secure-random-string: ^1.1.3 shortid: ^2.2.16 size-limit: ^7.0.8 terser: ^5.10.0 uid: ^2.0.0 uid-safe: ^2.1.5 uuid: ^8.3.2 uvu: ^0.5.3 vite: ^2.8.3 devDependencies: '@babel/core': 7.17.4 '@logux/eslint-config': 46.1.1_cd7f45d1cba51a736d2df3e99513a1a4 '@lukeed/uuid': 2.0.0 '@originjs/vite-plugin-commonjs': 1.0.3 '@size-limit/dual-publish': 7.0.8_24c433b8572c6d8a3a69f812fcb06aa8 '@size-limit/file': 7.0.8_size-limit@7.0.8 '@size-limit/webpack': 7.0.8_size-limit@7.0.8 '@types/node': 17.0.18 benchmark: 2.1.4 c8: 7.11.0 cuid: 2.1.8 dual-publish: 3.0.0 eslint: 8.9.0 eslint-config-standard: 16.0.3_3dc95bbf26a1efd07c4db3385b7c7e02 eslint-plugin-import: 2.25.4_eslint@8.9.0 eslint-plugin-node: 11.1.0_eslint@8.9.0 eslint-plugin-prefer-let: 3.0.1 eslint-plugin-promise: 6.0.0_eslint@8.9.0 nanospy: 0.5.0 picocolors: 1.0.0 postcss: 8.4.6 rndm: 1.2.0 secure-random-string: 1.1.3 shortid: 2.2.16 size-limit: 7.0.8 terser: 5.10.0 uid: 2.0.0 uid-safe: 2.1.5 uuid: 8.3.2 uvu: 0.5.3 vite: 2.8.3 packages: /@ampproject/remapping/2.1.2: resolution: {integrity: sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg==} engines: {node: '>=6.0.0'} dependencies: '@jridgewell/trace-mapping': 0.3.4 dev: true /@babel/code-frame/7.16.7: resolution: {integrity: sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==} engines: {node: '>=6.9.0'} dependencies: '@babel/highlight': 7.16.10 dev: true /@babel/compat-data/7.17.0: resolution: {integrity: sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng==} engines: {node: '>=6.9.0'} dev: true /@babel/core/7.17.4: resolution: {integrity: sha512-R9x5r4t4+hBqZTmioSnkrW+I6NmbojwjGT8p4G2Gw1thWbXIHGDnmGdLdFw0/7ljucdIrNRp7Npgb4CyBYzzJg==} engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.1.2 '@babel/code-frame': 7.16.7 '@babel/generator': 7.17.3 '@babel/helper-compilation-targets': 7.16.7_@babel+core@7.17.4 '@babel/helper-module-transforms': 7.16.7 '@babel/helpers': 7.17.2 '@babel/parser': 7.17.3 '@babel/template': 7.16.7 '@babel/traverse': 7.17.3 '@babel/types': 7.17.0 convert-source-map: 1.8.0 debug: 4.3.3 gensync: 1.0.0-beta.2 json5: 2.2.0 semver: 6.3.0 transitivePeerDependencies: - supports-color dev: true /@babel/generator/7.17.3: resolution: {integrity: sha512-+R6Dctil/MgUsZsZAkYgK+ADNSZzJRRy0TvY65T71z/CR854xHQ1EweBYXdfT+HNeN7w0cSJJEzgxZMv40pxsg==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.17.0 jsesc: 2.5.2 source-map: 0.5.7 dev: true /@babel/helper-compilation-targets/7.16.7_@babel+core@7.17.4: resolution: {integrity: sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: '@babel/compat-data': 7.17.0 '@babel/core': 7.17.4 '@babel/helper-validator-option': 7.16.7 browserslist: 4.19.1 semver: 6.3.0 dev: true /@babel/helper-environment-visitor/7.16.7: resolution: {integrity: sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.17.0 dev: true /@babel/helper-function-name/7.16.7: resolution: {integrity: sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-get-function-arity': 7.16.7 '@babel/template': 7.16.7 '@babel/types': 7.17.0 dev: true /@babel/helper-get-function-arity/7.16.7: resolution: {integrity: sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.17.0 dev: true /@babel/helper-hoist-variables/7.16.7: resolution: {integrity: sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.17.0 dev: true /@babel/helper-module-imports/7.16.7: resolution: {integrity: sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.17.0 dev: true /@babel/helper-module-transforms/7.16.7: resolution: {integrity: sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-environment-visitor': 7.16.7 '@babel/helper-module-imports': 7.16.7 '@babel/helper-simple-access': 7.16.7 '@babel/helper-split-export-declaration': 7.16.7 '@babel/helper-validator-identifier': 7.16.7 '@babel/template': 7.16.7 '@babel/traverse': 7.17.3 '@babel/types': 7.17.0 transitivePeerDependencies: - supports-color dev: true /@babel/helper-simple-access/7.16.7: resolution: {integrity: sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.17.0 dev: true /@babel/helper-split-export-declaration/7.16.7: resolution: {integrity: sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.17.0 dev: true /@babel/helper-validator-identifier/7.16.7: resolution: {integrity: sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==} engines: {node: '>=6.9.0'} dev: true /@babel/helper-validator-option/7.16.7: resolution: {integrity: sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==} engines: {node: '>=6.9.0'} dev: true /@babel/helpers/7.17.2: resolution: {integrity: sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==} engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.16.7 '@babel/traverse': 7.17.3 '@babel/types': 7.17.0 transitivePeerDependencies: - supports-color dev: true /@babel/highlight/7.16.10: resolution: {integrity: sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-validator-identifier': 7.16.7 chalk: 2.4.2 js-tokens: 4.0.0 dev: true /@babel/parser/7.17.3: resolution: {integrity: sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA==} engines: {node: '>=6.0.0'} hasBin: true dev: true /@babel/template/7.16.7: resolution: {integrity: sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==} engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.16.7 '@babel/parser': 7.17.3 '@babel/types': 7.17.0 dev: true /@babel/traverse/7.17.3: resolution: {integrity: sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==} engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.16.7 '@babel/generator': 7.17.3 '@babel/helper-environment-visitor': 7.16.7 '@babel/helper-function-name': 7.16.7 '@babel/helper-hoist-variables': 7.16.7 '@babel/helper-split-export-declaration': 7.16.7 '@babel/parser': 7.17.3 '@babel/types': 7.17.0 debug: 4.3.3 globals: 11.12.0 transitivePeerDependencies: - supports-color dev: true /@babel/types/7.17.0: resolution: {integrity: sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-validator-identifier': 7.16.7 to-fast-properties: 2.0.0 dev: true /@bcoe/v8-coverage/0.2.3: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} dev: true /@eslint/eslintrc/1.1.0: resolution: {integrity: sha512-C1DfL7XX4nPqGd6jcP01W9pVM1HYCuUkFk1432D7F0v3JSlUIeOYn9oCoi3eoLZ+iwBSb29BMFxxny0YrrEZqg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 debug: 4.3.3 espree: 9.3.1 globals: 13.12.1 ignore: 4.0.6 import-fresh: 3.3.0 js-yaml: 4.1.0 minimatch: 3.1.2 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color dev: true /@humanwhocodes/config-array/0.9.3: resolution: {integrity: sha512-3xSMlXHh03hCcCmFc0rbKp3Ivt2PFEJnQUJDDMTJQ2wkECZWdq4GePs2ctc5H8zV+cHPaq8k2vU8mrQjA6iHdQ==} engines: {node: '>=10.10.0'} dependencies: '@humanwhocodes/object-schema': 1.2.1 debug: 4.3.3 minimatch: 3.1.2 transitivePeerDependencies: - supports-color dev: true /@humanwhocodes/object-schema/1.2.1: resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} dev: true /@istanbuljs/schema/0.1.3: resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} engines: {node: '>=8'} dev: true /@jridgewell/resolve-uri/3.0.5: resolution: {integrity: sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==} engines: {node: '>=6.0.0'} dev: true /@jridgewell/sourcemap-codec/1.4.11: resolution: {integrity: sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==} dev: true /@jridgewell/trace-mapping/0.3.4: resolution: {integrity: sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==} dependencies: '@jridgewell/resolve-uri': 3.0.5 '@jridgewell/sourcemap-codec': 1.4.11 dev: true /@logux/eslint-config/46.1.1_cd7f45d1cba51a736d2df3e99513a1a4: resolution: {integrity: sha512-FSSiEj6yGGmoI+ccK8ET093OL2G9ar1izQtixB62SWGouas096VpqQoz+FuFW8f4iCb4wuYrXYuv0uOLuvc+LA==} engines: {node: '>=10.0.0'} peerDependencies: eslint: ^8.5.0 eslint-config-standard: ^16.0.3 eslint-plugin-import: ^2.25.3 eslint-plugin-node: ^11.1.0 eslint-plugin-prefer-let: ^3.0.1 eslint-plugin-promise: ^6.0.0 dependencies: eslint: 8.9.0 eslint-config-standard: 16.0.3_3dc95bbf26a1efd07c4db3385b7c7e02 eslint-plugin-import: 2.25.4_eslint@8.9.0 eslint-plugin-node: 11.1.0_eslint@8.9.0 eslint-plugin-prefer-let: 3.0.1 eslint-plugin-promise: 6.0.0_eslint@8.9.0 dev: true /@lukeed/csprng/1.0.1: resolution: {integrity: sha512-uSvJdwQU5nK+Vdf6zxcWAY2A8r7uqe+gePwLWzJ+fsQehq18pc0I2hJKwypZ2aLM90+Er9u1xn4iLJPZ+xlL4g==} engines: {node: '>=8'} dev: true /@lukeed/uuid/2.0.0: resolution: {integrity: sha512-dUz8OmYvlY5A9wXaroHIMSPASpSYRLCqbPvxGSyHguhtTQIy24lC+EGxQlwv71AhRCO55WOtgwhzQLpw27JaJQ==} engines: {node: '>=8'} dependencies: '@lukeed/csprng': 1.0.1 dev: true /@nodelib/fs.scandir/2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} dependencies: '@nodelib/fs.stat': 2.0.5 run-parallel: 1.2.0 dev: true /@nodelib/fs.stat/2.0.5: resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} engines: {node: '>= 8'} dev: true /@nodelib/fs.walk/1.2.8: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} dependencies: '@nodelib/fs.scandir': 2.1.5 fastq: 1.13.0 dev: true /@originjs/vite-plugin-commonjs/1.0.3: resolution: {integrity: sha512-KuEXeGPptM2lyxdIEJ4R11+5ztipHoE7hy8ClZt3PYaOVQ/pyngd2alaSrPnwyFeOW1UagRBaQ752aA1dTMdOQ==} dependencies: esbuild: 0.14.21 dev: true /@size-limit/dual-publish/7.0.8_24c433b8572c6d8a3a69f812fcb06aa8: resolution: {integrity: sha512-TiupMMHp4Lm7TwATJ4k5tErQ38qdX2+7F4yo1FqpHEYaYKo2qj1FtNi1Smn066faIUNJ6iVDZ2V9hM64eTsLig==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} peerDependencies: dual-publish: '> 0.6.0' size-limit: 7.0.8 dependencies: dual-publish: 3.0.0 size-limit: 7.0.8 dev: true /@size-limit/file/7.0.8_size-limit@7.0.8: resolution: {integrity: sha512-1KeFQuMXIXAH/iELqIX7x+YNYDFvzIvmxcp9PrdwEoSNL0dXdaDIo9WE/yz8xvOmUcKaLfqbWkL75DM0k91WHQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} peerDependencies: size-limit: 7.0.8 dependencies: semver: 7.3.5 size-limit: 7.0.8 dev: true /@size-limit/webpack/7.0.8_size-limit@7.0.8: resolution: {integrity: sha512-69YuY0o4geRNJDb55Vri+bNPs9+WZlK0pzcziip1p4uajCFMFQE0K8pKj3vsIOUADdTcimfypHciriCY/qrnJQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} peerDependencies: size-limit: 7.0.8 dependencies: escape-string-regexp: 4.0.0 nanoid: 3.3.0 size-limit: 7.0.8 webpack: 5.69.0 transitivePeerDependencies: - '@swc/core' - esbuild - uglify-js - webpack-cli dev: true /@types/eslint-scope/3.7.3: resolution: {integrity: sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==} dependencies: '@types/eslint': 8.4.1 '@types/estree': 0.0.51 dev: true /@types/eslint/8.4.1: resolution: {integrity: sha512-GE44+DNEyxxh2Kc6ro/VkIj+9ma0pO0bwv9+uHSyBrikYOHr8zYcdPvnBOp1aw8s+CjRvuSx7CyWqRrNFQ59mA==} dependencies: '@types/estree': 0.0.51 '@types/json-schema': 7.0.9 dev: true /@types/estree/0.0.51: resolution: {integrity: sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==} dev: true /@types/istanbul-lib-coverage/2.0.4: resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} dev: true /@types/json-schema/7.0.9: resolution: {integrity: sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==} dev: true /@types/json5/0.0.29: resolution: {integrity: sha1-7ihweulOEdK4J7y+UnC86n8+ce4=} dev: true /@types/node/17.0.18: resolution: {integrity: sha512-eKj4f/BsN/qcculZiRSujogjvp5O/k4lOW5m35NopjZM/QwLOR075a8pJW5hD+Rtdm2DaCVPENS6KtSQnUD6BA==} dev: true /@webassemblyjs/ast/1.11.1: resolution: {integrity: sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==} dependencies: '@webassemblyjs/helper-numbers': 1.11.1 '@webassemblyjs/helper-wasm-bytecode': 1.11.1 dev: true /@webassemblyjs/floating-point-hex-parser/1.11.1: resolution: {integrity: sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==} dev: true /@webassemblyjs/helper-api-error/1.11.1: resolution: {integrity: sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==} dev: true /@webassemblyjs/helper-buffer/1.11.1: resolution: {integrity: sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==} dev: true /@webassemblyjs/helper-numbers/1.11.1: resolution: {integrity: sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==} dependencies: '@webassemblyjs/floating-point-hex-parser': 1.11.1 '@webassemblyjs/helper-api-error': 1.11.1 '@xtuc/long': 4.2.2 dev: true /@webassemblyjs/helper-wasm-bytecode/1.11.1: resolution: {integrity: sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==} dev: true /@webassemblyjs/helper-wasm-section/1.11.1: resolution: {integrity: sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==} dependencies: '@webassemblyjs/ast': 1.11.1 '@webassemblyjs/helper-buffer': 1.11.1 '@webassemblyjs/helper-wasm-bytecode': 1.11.1 '@webassemblyjs/wasm-gen': 1.11.1 dev: true /@webassemblyjs/ieee754/1.11.1: resolution: {integrity: sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==} dependencies: '@xtuc/ieee754': 1.2.0 dev: true /@webassemblyjs/leb128/1.11.1: resolution: {integrity: sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==} dependencies: '@xtuc/long': 4.2.2 dev: true /@webassemblyjs/utf8/1.11.1: resolution: {integrity: sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==} dev: true /@webassemblyjs/wasm-edit/1.11.1: resolution: {integrity: sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==} dependencies: '@webassemblyjs/ast': 1.11.1 '@webassemblyjs/helper-buffer': 1.11.1 '@webassemblyjs/helper-wasm-bytecode': 1.11.1 '@webassemblyjs/helper-wasm-section': 1.11.1 '@webassemblyjs/wasm-gen': 1.11.1 '@webassemblyjs/wasm-opt': 1.11.1 '@webassemblyjs/wasm-parser': 1.11.1 '@webassemblyjs/wast-printer': 1.11.1 dev: true /@webassemblyjs/wasm-gen/1.11.1: resolution: {integrity: sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==} dependencies: '@webassemblyjs/ast': 1.11.1 '@webassemblyjs/helper-wasm-bytecode': 1.11.1 '@webassemblyjs/ieee754': 1.11.1 '@webassemblyjs/leb128': 1.11.1 '@webassemblyjs/utf8': 1.11.1 dev: true /@webassemblyjs/wasm-opt/1.11.1: resolution: {integrity: sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==} dependencies: '@webassemblyjs/ast': 1.11.1 '@webassemblyjs/helper-buffer': 1.11.1 '@webassemblyjs/wasm-gen': 1.11.1 '@webassemblyjs/wasm-parser': 1.11.1 dev: true /@webassemblyjs/wasm-parser/1.11.1: resolution: {integrity: sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==} dependencies: '@webassemblyjs/ast': 1.11.1 '@webassemblyjs/helper-api-error': 1.11.1 '@webassemblyjs/helper-wasm-bytecode': 1.11.1 '@webassemblyjs/ieee754': 1.11.1 '@webassemblyjs/leb128': 1.11.1 '@webassemblyjs/utf8': 1.11.1 dev: true /@webassemblyjs/wast-printer/1.11.1: resolution: {integrity: sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==} dependencies: '@webassemblyjs/ast': 1.11.1 '@xtuc/long': 4.2.2 dev: true /@xtuc/ieee754/1.2.0: resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} dev: true /@xtuc/long/4.2.2: resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} dev: true /acorn-import-assertions/1.8.0_acorn@8.7.0: resolution: {integrity: sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==} peerDependencies: acorn: ^8 dependencies: acorn: 8.7.0 dev: true /acorn-jsx/5.3.2_acorn@8.7.0: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: acorn: 8.7.0 dev: true /acorn/8.7.0: resolution: {integrity: sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==} engines: {node: '>=0.4.0'} hasBin: true dev: true /ajv-keywords/3.5.2_ajv@6.12.6: resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} peerDependencies: ajv: ^6.9.1 dependencies: ajv: 6.12.6 dev: true /ajv/6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} dependencies: fast-deep-equal: 3.1.3 fast-json-stable-stringify: 2.1.0 json-schema-traverse: 0.4.1 uri-js: 4.4.1 dev: true /ansi-regex/5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} dev: true /ansi-styles/3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} dependencies: color-convert: 1.9.3 dev: true /ansi-styles/4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} dependencies: color-convert: 2.0.1 dev: true /anymatch/3.1.2: resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==} engines: {node: '>= 8'} dependencies: normalize-path: 3.0.0 picomatch: 2.3.1 dev: true /argparse/2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} dev: true /array-includes/3.1.4: resolution: {integrity: sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==} engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.2 define-properties: 1.1.3 es-abstract: 1.19.1 get-intrinsic: 1.1.1 is-string: 1.0.7 dev: true /array-union/2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} dev: true /array.prototype.flat/1.2.5: resolution: {integrity: sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==} engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.2 define-properties: 1.1.3 es-abstract: 1.19.1 dev: true /balanced-match/1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} dev: true /benchmark/2.1.4: resolution: {integrity: sha1-CfPeMckWQl1JjMLuVloOvzwqVik=} dependencies: lodash: 4.17.21 platform: 1.3.6 dev: true /binary-extensions/2.2.0: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} engines: {node: '>=8'} dev: true /brace-expansion/1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 dev: true /braces/3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} engines: {node: '>=8'} dependencies: fill-range: 7.0.1 dev: true /browserslist/4.19.1: resolution: {integrity: sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: caniuse-lite: 1.0.30001312 electron-to-chromium: 1.4.71 escalade: 3.1.1 node-releases: 2.0.2 picocolors: 1.0.0 dev: true /buffer-from/1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} dev: true /bytes-iec/3.1.1: resolution: {integrity: sha512-fey6+4jDK7TFtFg/klGSvNKJctyU7n2aQdnM+CO0ruLPbqqMOM8Tio0Pc+deqUeVKX1tL5DQep1zQ7+37aTAsA==} engines: {node: '>= 0.8'} dev: true /c8/7.11.0: resolution: {integrity: sha512-XqPyj1uvlHMr+Y1IeRndC2X5P7iJzJlEJwBpCdBbq2JocXOgJfr+JVfJkyNMGROke5LfKrhSFXGFXnwnRJAUJw==} engines: {node: '>=10.12.0'} hasBin: true dependencies: '@bcoe/v8-coverage': 0.2.3 '@istanbuljs/schema': 0.1.3 find-up: 5.0.0 foreground-child: 2.0.0 istanbul-lib-coverage: 3.2.0 istanbul-lib-report: 3.0.0 istanbul-reports: 3.1.4 rimraf: 3.0.2 test-exclude: 6.0.0 v8-to-istanbul: 8.1.1 yargs: 16.2.0 yargs-parser: 20.2.9 dev: true /call-bind/1.0.2: resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} dependencies: function-bind: 1.1.1 get-intrinsic: 1.1.1 dev: true /callsites/3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} dev: true /caniuse-lite/1.0.30001312: resolution: {integrity: sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==} dev: true /chalk/2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} dependencies: ansi-styles: 3.2.1 escape-string-regexp: 1.0.5 supports-color: 5.5.0 dev: true /chalk/4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 dev: true /chokidar/3.5.3: resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} engines: {node: '>= 8.10.0'} dependencies: anymatch: 3.1.2 braces: 3.0.2 glob-parent: 5.1.2 is-binary-path: 2.1.0 is-glob: 4.0.3 normalize-path: 3.0.0 readdirp: 3.6.0 optionalDependencies: fsevents: 2.3.2 dev: true /chrome-trace-event/1.0.3: resolution: {integrity: sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==} engines: {node: '>=6.0'} dev: true /ci-job-number/1.2.2: resolution: {integrity: sha512-CLOGsVDrVamzv8sXJGaILUVI6dsuAkouJP/n6t+OxLPeeA4DDby7zn9SB6EUpa1H7oIKoE+rMmkW80zYsFfUjA==} dev: true /clean-publish/4.0.0: resolution: {integrity: sha512-PcOxJSnPgncx/ANmgPw8hj9DDtdLHTxIc6Vh/yXCX7IA9w1oUSx2POL0Vno/7omhyrKxMKTpnRh2wlzwH5zaCw==} hasBin: true dependencies: cross-spawn: 7.0.3 fast-glob: 3.2.11 lilconfig: 2.0.4 micromatch: 4.0.4 dev: true /cliui/7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} dependencies: string-width: 4.2.3 strip-ansi: 6.0.1 wrap-ansi: 7.0.0 dev: true /color-convert/1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} dependencies: color-name: 1.1.3 dev: true /color-convert/2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} dependencies: color-name: 1.1.4 dev: true /color-name/1.1.3: resolution: {integrity: sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=} dev: true /color-name/1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} dev: true /commander/2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} dev: true /concat-map/0.0.1: resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} dev: true /convert-source-map/1.8.0: resolution: {integrity: sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==} dependencies: safe-buffer: 5.1.2 dev: true /cross-spawn/7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} dependencies: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 dev: true /cuid/2.1.8: resolution: {integrity: sha512-xiEMER6E7TlTPnDxrM4eRiC6TRgjNX9xzEZ5U/Se2YJKr7Mq4pJn/2XEHjl3STcSh96GmkHPcBXLES8M29wyyg==} dev: true /debug/2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} dependencies: ms: 2.0.0 dev: true /debug/3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} dependencies: ms: 2.1.3 dev: true /debug/4.3.3: resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' peerDependenciesMeta: supports-color: optional: true dependencies: ms: 2.1.2 dev: true /deep-is/0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} dev: true /define-properties/1.1.3: resolution: {integrity: sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==} engines: {node: '>= 0.4'} dependencies: object-keys: 1.1.1 dev: true /dequal/2.0.2: resolution: {integrity: sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug==} engines: {node: '>=6'} dev: true /diff/5.0.0: resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} engines: {node: '>=0.3.1'} dev: true /dir-glob/3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} dependencies: path-type: 4.0.0 dev: true /doctrine/2.1.0: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} dependencies: esutils: 2.0.3 dev: true /doctrine/3.0.0: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} dependencies: esutils: 2.0.3 dev: true /dual-publish/3.0.0: resolution: {integrity: sha512-Agp0jMJ4DDhkCXN+wsMYhAo3NvurwHFy2LmTbCprUDBK/3BKip9jwZHtDnnHdg4QlQJf81YKOWoxMMqeRwZtEQ==} engines: {node: '>=16.0.0'} hasBin: true dependencies: clean-publish: 4.0.0 fast-glob: 3.2.11 line-column: 1.0.2 picocolors: 1.0.0 dev: true /electron-to-chromium/1.4.71: resolution: {integrity: sha512-Hk61vXXKRb2cd3znPE9F+2pLWdIOmP7GjiTj45y6L3W/lO+hSnUSUhq+6lEaERWBdZOHbk2s3YV5c9xVl3boVw==} dev: true /emoji-regex/8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} dev: true /enhanced-resolve/5.9.0: resolution: {integrity: sha512-weDYmzbBygL7HzGGS26M3hGQx68vehdEg6VUmqSOaFzXExFqlnKuSvsEJCVGQHScS8CQMbrAqftT+AzzHNt/YA==} engines: {node: '>=10.13.0'} dependencies: graceful-fs: 4.2.9 tapable: 2.2.1 dev: true /es-abstract/1.19.1: resolution: {integrity: sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==} engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.2 es-to-primitive: 1.2.1 function-bind: 1.1.1 get-intrinsic: 1.1.1 get-symbol-description: 1.0.0 has: 1.0.3 has-symbols: 1.0.2 internal-slot: 1.0.3 is-callable: 1.2.4 is-negative-zero: 2.0.2 is-regex: 1.1.4 is-shared-array-buffer: 1.0.1 is-string: 1.0.7 is-weakref: 1.0.2 object-inspect: 1.12.0 object-keys: 1.1.1 object.assign: 4.1.2 string.prototype.trimend: 1.0.4 string.prototype.trimstart: 1.0.4 unbox-primitive: 1.0.1 dev: true /es-module-lexer/0.9.3: resolution: {integrity: sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==} dev: true /es-to-primitive/1.2.1: resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} engines: {node: '>= 0.4'} dependencies: is-callable: 1.2.4 is-date-object: 1.0.5 is-symbol: 1.0.4 dev: true /esbuild-android-arm64/0.14.21: resolution: {integrity: sha512-Bqgld1TY0wZv8TqiQmVxQFgYzz8ZmyzT7clXBDZFkOOdRybzsnj8AZuK1pwcLVA7Ya6XncHgJqIao7NFd3s0RQ==} engines: {node: '>=12'} cpu: [arm64] os: [android] requiresBuild: true dev: true optional: true /esbuild-darwin-64/0.14.21: resolution: {integrity: sha512-j+Eg+e13djzyYINVvAbOo2/zvZ2DivuJJTaBrJnJHSD7kUNuGHRkHoSfFjbI80KHkn091w350wdmXDNSgRjfYQ==} engines: {node: '>=12'} cpu: [x64] os: [darwin] requiresBuild: true dev: true optional: true /esbuild-darwin-arm64/0.14.21: resolution: {integrity: sha512-nDNTKWDPI0RuoPj5BhcSB2z5EmZJJAyRtZLIjyXSqSpAyoB8eyAKXl4lB8U2P78Fnh4Lh1le/fmpewXE04JhBQ==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] requiresBuild: true dev: true optional: true /esbuild-freebsd-64/0.14.21: resolution: {integrity: sha512-zIurkCHXhxELiDZtLGiexi8t8onQc2LtuE+S7457H/pP0g0MLRKMrsn/IN4LDkNe6lvBjuoZZi2OfelOHn831g==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] requiresBuild: true dev: true optional: true /esbuild-freebsd-arm64/0.14.21: resolution: {integrity: sha512-wdxMmkJfbwcN+q85MpeUEamVZ40FNsBa9mPq8tAszDn8TRT2HoJvVRADPIIBa9SWWwlDChIMjkDKAnS3KS/sPA==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] requiresBuild: true dev: true optional: true /esbuild-linux-32/0.14.21: resolution: {integrity: sha512-fmxvyzOPPh2xiEHojpCeIQP6pXcoKsWbz3ryDDIKLOsk4xp3GbpHIEAWP0xTeuhEbendmvBDVKbAVv3PnODXLg==} engines: {node: '>=12'} cpu: [ia32] os: [linux] requiresBuild: true dev: true optional: true /esbuild-linux-64/0.14.21: resolution: {integrity: sha512-edZyNOv1ql+kpmlzdqzzDjRQYls+tSyi4QFi+PdBhATJFUqHsnNELWA9vMSzAaInPOEaVUTA5Ml28XFChcy4DA==} engines: {node: '>=12'} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true /esbuild-linux-arm/0.14.21: resolution: {integrity: sha512-aSU5pUueK6afqmLQsbU+QcFBT62L+4G9hHMJDHWfxgid6hzhSmfRH9U/f+ymvxsSTr/HFRU4y7ox8ZyhlVl98w==} engines: {node: '>=12'} cpu: [arm] os: [linux] requiresBuild: true dev: true optional: true /esbuild-linux-arm64/0.14.21: resolution: {integrity: sha512-t5qxRkq4zdQC0zXpzSB2bTtfLgOvR0C6BXYaRE/6/k8/4SrkZcTZBeNu+xGvwCU4b5dU9ST9pwIWkK6T1grS8g==} engines: {node: '>=12'} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true /esbuild-linux-mips64le/0.14.21: resolution: {integrity: sha512-jLZLQGCNlUsmIHtGqNvBs3zN+7a4D9ckf0JZ+jQTwHdZJ1SgV9mAjbB980OFo66LoY+WeM7t3WEnq3FjI1zw4A==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] requiresBuild: true dev: true optional: true /esbuild-linux-ppc64le/0.14.21: resolution: {integrity: sha512-4TWxpK391en2UBUw6GSrukToTDu6lL9vkm3Ll40HrI08WG3qcnJu7bl8e1+GzelDsiw1QmfAY/nNvJ6iaHRpCQ==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] requiresBuild: true dev: true optional: true /esbuild-linux-riscv64/0.14.21: resolution: {integrity: sha512-fElngqOaOfTsF+u+oetDLHsPG74vB2ZaGZUqmGefAJn3a5z9Z2pNa4WpVbbKgHpaAAy5tWM1m1sbGohj6Ki6+Q==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] requiresBuild: true dev: true optional: true /esbuild-linux-s390x/0.14.21: resolution: {integrity: sha512-brleZ6R5fYv0qQ7ZBwenQmP6i9TdvJCB092c/3D3pTLQHBGHJb5zWgKxOeS7bdHzmLy6a6W7GbFk6QKpjyD6QA==} engines: {node: '>=12'} cpu: [s390x] os: [linux] requiresBuild: true dev: true optional: true /esbuild-netbsd-64/0.14.21: resolution: {integrity: sha512-nCEgsLCQ8RoFWVV8pVI+kX66ICwbPP/M9vEa0NJGIEB/Vs5sVGMqkf67oln90XNSkbc0bPBDuo4G6FxlF7PN8g==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] requiresBuild: true dev: true optional: true /esbuild-openbsd-64/0.14.21: resolution: {integrity: sha512-h9zLMyVD0T73MDTVYIb/qUTokwI6EJH9O6wESuTNq6+XpMSr6C5aYZ4fvFKdNELW+Xsod+yDS2hV2JTUAbFrLA==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] requiresBuild: true dev: true optional: true /esbuild-sunos-64/0.14.21: resolution: {integrity: sha512-Kl+7Cot32qd9oqpLdB1tEGXEkjBlijrIxMJ0+vlDFaqsODutif25on0IZlFxEBtL2Gosd4p5WCV1U7UskNQfXA==} engines: {node: '>=12'} cpu: [x64] os: [sunos] requiresBuild: true dev: true optional: true /esbuild-windows-32/0.14.21: resolution: {integrity: sha512-V7vnTq67xPBUCk/9UtlolmQ798Ecjdr1ZoI1vcSgw7M82aSSt0eZdP6bh5KAFZU8pxDcx3qoHyWQfHYr11f22A==} engines: {node: '>=12'} cpu: [ia32] os: [win32] requiresBuild: true dev: true optional: true /esbuild-windows-64/0.14.21: resolution: {integrity: sha512-kDgHjKOHwjfJDCyRGELzVxiP/RBJBTA+wyspf78MTTJQkyPuxH2vChReNdWc+dU2S4gIZFHMdP1Qrl/k22ZmaA==} engines: {node: '>=12'} cpu: [x64] os: [win32] requiresBuild: true dev: true optional: true /esbuild-windows-arm64/0.14.21: resolution: {integrity: sha512-8Sbo0zpzgwWrwjQYLmHF78f7E2xg5Ve63bjB2ng3V2aManilnnTGaliq2snYg+NOX60+hEvJHRdVnuIAHW0lVw==} engines: {node: '>=12'} cpu: [arm64] os: [win32] requiresBuild: true dev: true optional: true /esbuild/0.14.21: resolution: {integrity: sha512-7WEoNMBJdLN993dr9h0CpFHPRc3yFZD+EAVY9lg6syJJ12gc5fHq8d75QRExuhnMkT2DaRiIKFThRvDWP+fO+A==} engines: {node: '>=12'} hasBin: true requiresBuild: true optionalDependencies: esbuild-android-arm64: 0.14.21 esbuild-darwin-64: 0.14.21 esbuild-darwin-arm64: 0.14.21 esbuild-freebsd-64: 0.14.21 esbuild-freebsd-arm64: 0.14.21 esbuild-linux-32: 0.14.21 esbuild-linux-64: 0.14.21 esbuild-linux-arm: 0.14.21 esbuild-linux-arm64: 0.14.21 esbuild-linux-mips64le: 0.14.21 esbuild-linux-ppc64le: 0.14.21 esbuild-linux-riscv64: 0.14.21 esbuild-linux-s390x: 0.14.21 esbuild-netbsd-64: 0.14.21 esbuild-openbsd-64: 0.14.21 esbuild-sunos-64: 0.14.21 esbuild-windows-32: 0.14.21 esbuild-windows-64: 0.14.21 esbuild-windows-arm64: 0.14.21 dev: true /escalade/3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} dev: true /escape-string-regexp/1.0.5: resolution: {integrity: sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=} engines: {node: '>=0.8.0'} dev: true /escape-string-regexp/4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} dev: true /eslint-config-standard/16.0.3_3dc95bbf26a1efd07c4db3385b7c7e02: resolution: {integrity: sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==} peerDependencies: eslint: ^7.12.1 eslint-plugin-import: ^2.22.1 eslint-plugin-node: ^11.1.0 eslint-plugin-promise: ^4.2.1 || ^5.0.0 dependencies: eslint: 8.9.0 eslint-plugin-import: 2.25.4_eslint@8.9.0 eslint-plugin-node: 11.1.0_eslint@8.9.0 eslint-plugin-promise: 6.0.0_eslint@8.9.0 dev: true /eslint-import-resolver-node/0.3.6: resolution: {integrity: sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==} dependencies: debug: 3.2.7 resolve: 1.22.0 dev: true /eslint-module-utils/2.7.3: resolution: {integrity: sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==} engines: {node: '>=4'} dependencies: debug: 3.2.7 find-up: 2.1.0 dev: true /eslint-plugin-es/3.0.1_eslint@8.9.0: resolution: {integrity: sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==} engines: {node: '>=8.10.0'} peerDependencies: eslint: '>=4.19.1' dependencies: eslint: 8.9.0 eslint-utils: 2.1.0 regexpp: 3.2.0 dev: true /eslint-plugin-import/2.25.4_eslint@8.9.0: resolution: {integrity: sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==} engines: {node: '>=4'} peerDependencies: eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 dependencies: array-includes: 3.1.4 array.prototype.flat: 1.2.5 debug: 2.6.9 doctrine: 2.1.0 eslint: 8.9.0 eslint-import-resolver-node: 0.3.6 eslint-module-utils: 2.7.3 has: 1.0.3 is-core-module: 2.8.1 is-glob: 4.0.3 minimatch: 3.1.2 object.values: 1.1.5 resolve: 1.22.0 tsconfig-paths: 3.12.0 dev: true /eslint-plugin-node/11.1.0_eslint@8.9.0: resolution: {integrity: sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==} engines: {node: '>=8.10.0'} peerDependencies: eslint: '>=5.16.0' dependencies: eslint: 8.9.0 eslint-plugin-es: 3.0.1_eslint@8.9.0 eslint-utils: 2.1.0 ignore: 5.2.0 minimatch: 3.1.2 resolve: 1.22.0 semver: 6.3.0 dev: true /eslint-plugin-prefer-let/3.0.1: resolution: {integrity: sha512-vbznkkBSXB63d4o1o0NIm5C2ey3V5wKr/25dAvPdydQXdowAcnr69cbLgxd2YAG81IV5eddCO55Lp6gL7wSE4w==} engines: {node: '>=0.10.0'} dependencies: requireindex: 1.2.0 dev: true /eslint-plugin-promise/6.0.0_eslint@8.9.0: resolution: {integrity: sha512-7GPezalm5Bfi/E22PnQxDWH2iW9GTvAlUNTztemeHb6c1BniSyoeTrM87JkC0wYdi6aQrZX9p2qEiAno8aTcbw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 dependencies: eslint: 8.9.0 dev: true /eslint-scope/5.1.1: resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} engines: {node: '>=8.0.0'} dependencies: esrecurse: 4.3.0 estraverse: 4.3.0 dev: true /eslint-scope/7.1.1: resolution: {integrity: sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 dev: true /eslint-utils/2.1.0: resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} engines: {node: '>=6'} dependencies: eslint-visitor-keys: 1.3.0 dev: true /eslint-utils/3.0.0_eslint@8.9.0: resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} peerDependencies: eslint: '>=5' dependencies: eslint: 8.9.0 eslint-visitor-keys: 2.1.0 dev: true /eslint-visitor-keys/1.3.0: resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} engines: {node: '>=4'} dev: true /eslint-visitor-keys/2.1.0: resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} engines: {node: '>=10'} dev: true /eslint-visitor-keys/3.3.0: resolution: {integrity: sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true /eslint/8.9.0: resolution: {integrity: sha512-PB09IGwv4F4b0/atrbcMFboF/giawbBLVC7fyDamk5Wtey4Jh2K+rYaBhCAbUyEI4QzB1ly09Uglc9iCtFaG2Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: '@eslint/eslintrc': 1.1.0 '@humanwhocodes/config-array': 0.9.3 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 debug: 4.3.3 doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.1.1 eslint-utils: 3.0.0_eslint@8.9.0 eslint-visitor-keys: 3.3.0 espree: 9.3.1 esquery: 1.4.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 file-entry-cache: 6.0.1 functional-red-black-tree: 1.0.1 glob-parent: 6.0.2 globals: 13.12.1 ignore: 5.2.0 import-fresh: 3.3.0 imurmurhash: 0.1.4 is-glob: 4.0.3 js-yaml: 4.1.0 json-stable-stringify-without-jsonify: 1.0.1 levn: 0.4.1 lodash.merge: 4.6.2 minimatch: 3.1.2 natural-compare: 1.4.0 optionator: 0.9.1 regexpp: 3.2.0 strip-ansi: 6.0.1 strip-json-comments: 3.1.1 text-table: 0.2.0 v8-compile-cache: 2.3.0 transitivePeerDependencies: - supports-color dev: true /espree/9.3.1: resolution: {integrity: sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: acorn: 8.7.0 acorn-jsx: 5.3.2_acorn@8.7.0 eslint-visitor-keys: 3.3.0 dev: true /esquery/1.4.0: resolution: {integrity: sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==} engines: {node: '>=0.10'} dependencies: estraverse: 5.3.0 dev: true /esrecurse/4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} engines: {node: '>=4.0'} dependencies: estraverse: 5.3.0 dev: true /estraverse/4.3.0: resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} engines: {node: '>=4.0'} dev: true /estraverse/5.3.0: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} dev: true /esutils/2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} dev: true /events/3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} dev: true /fast-deep-equal/3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} dev: true /fast-glob/3.2.11: resolution: {integrity: sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==} engines: {node: '>=8.6.0'} dependencies: '@nodelib/fs.stat': 2.0.5 '@nodelib/fs.walk': 1.2.8 glob-parent: 5.1.2 merge2: 1.4.1 micromatch: 4.0.4 dev: true /fast-json-stable-stringify/2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} dev: true /fast-levenshtein/2.0.6: resolution: {integrity: sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=} dev: true /fastq/1.13.0: resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==} dependencies: reusify: 1.0.4 dev: true /file-entry-cache/6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} dependencies: flat-cache: 3.0.4 dev: true /fill-range/7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} engines: {node: '>=8'} dependencies: to-regex-range: 5.0.1 dev: true /find-up/2.1.0: resolution: {integrity: sha1-RdG35QbHF93UgndaK3eSCjwMV6c=} engines: {node: '>=4'} dependencies: locate-path: 2.0.0 dev: true /find-up/5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} dependencies: locate-path: 6.0.0 path-exists: 4.0.0 dev: true /flat-cache/3.0.4: resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} engines: {node: ^10.12.0 || >=12.0.0} dependencies: flatted: 3.2.5 rimraf: 3.0.2 dev: true /flatted/3.2.5: resolution: {integrity: sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==} dev: true /foreground-child/2.0.0: resolution: {integrity: sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==} engines: {node: '>=8.0.0'} dependencies: cross-spawn: 7.0.3 signal-exit: 3.0.7 dev: true /fs.realpath/1.0.0: resolution: {integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=} dev: true /fsevents/2.3.2: resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] requiresBuild: true dev: true optional: true /function-bind/1.1.1: resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} dev: true /functional-red-black-tree/1.0.1: resolution: {integrity: sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=} dev: true /gensync/1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} dev: true /get-caller-file/2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} dev: true /get-intrinsic/1.1.1: resolution: {integrity: sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==} dependencies: function-bind: 1.1.1 has: 1.0.3 has-symbols: 1.0.2 dev: true /get-symbol-description/1.0.0: resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.2 get-intrinsic: 1.1.1 dev: true /glob-parent/5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} dependencies: is-glob: 4.0.3 dev: true /glob-parent/6.0.2: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} dependencies: is-glob: 4.0.3 dev: true /glob-to-regexp/0.4.1: resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} dev: true /glob/7.2.0: resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} dependencies: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 minimatch: 3.1.2 once: 1.4.0 path-is-absolute: 1.0.1 dev: true /globals/11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} dev: true /globals/13.12.1: resolution: {integrity: sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==} engines: {node: '>=8'} dependencies: type-fest: 0.20.2 dev: true /globby/11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} dependencies: array-union: 2.1.0 dir-glob: 3.0.1 fast-glob: 3.2.11 ignore: 5.2.0 merge2: 1.4.1 slash: 3.0.0 dev: true /graceful-fs/4.2.9: resolution: {integrity: sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==} dev: true /has-bigints/1.0.1: resolution: {integrity: sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==} dev: true /has-flag/3.0.0: resolution: {integrity: sha1-tdRU3CGZriJWmfNGfloH87lVuv0=} engines: {node: '>=4'} dev: true /has-flag/4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} dev: true /has-symbols/1.0.2: resolution: {integrity: sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==} engines: {node: '>= 0.4'} dev: true /has-tostringtag/1.0.0: resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} engines: {node: '>= 0.4'} dependencies: has-symbols: 1.0.2 dev: true /has/1.0.3: resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} engines: {node: '>= 0.4.0'} dependencies: function-bind: 1.1.1 dev: true /html-escaper/2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} dev: true /ignore/4.0.6: resolution: {integrity: sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==} engines: {node: '>= 4'} dev: true /ignore/5.2.0: resolution: {integrity: sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==} engines: {node: '>= 4'} dev: true /import-fresh/3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} dependencies: parent-module: 1.0.1 resolve-from: 4.0.0 dev: true /imurmurhash/0.1.4: resolution: {integrity: sha1-khi5srkoojixPcT7a21XbyMUU+o=} engines: {node: '>=0.8.19'} dev: true /inflight/1.0.6: resolution: {integrity: sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=} dependencies: once: 1.4.0 wrappy: 1.0.2 dev: true /inherits/2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} dev: true /internal-slot/1.0.3: resolution: {integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==} engines: {node: '>= 0.4'} dependencies: get-intrinsic: 1.1.1 has: 1.0.3 side-channel: 1.0.4 dev: true /is-bigint/1.0.4: resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} dependencies: has-bigints: 1.0.1 dev: true /is-binary-path/2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} dependencies: binary-extensions: 2.2.0 dev: true /is-boolean-object/1.1.2: resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.2 has-tostringtag: 1.0.0 dev: true /is-callable/1.2.4: resolution: {integrity: sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==} engines: {node: '>= 0.4'} dev: true /is-core-module/2.8.1: resolution: {integrity: sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==} dependencies: has: 1.0.3 dev: true /is-date-object/1.0.5: resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} engines: {node: '>= 0.4'} dependencies: has-tostringtag: 1.0.0 dev: true /is-extglob/2.1.1: resolution: {integrity: sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=} engines: {node: '>=0.10.0'} dev: true /is-fullwidth-code-point/3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} dev: true /is-glob/4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} dependencies: is-extglob: 2.1.1 dev: true /is-negative-zero/2.0.2: resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} engines: {node: '>= 0.4'} dev: true /is-number-object/1.0.6: resolution: {integrity: sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==} engines: {node: '>= 0.4'} dependencies: has-tostringtag: 1.0.0 dev: true /is-number/7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} dev: true /is-regex/1.1.4: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.2 has-tostringtag: 1.0.0 dev: true /is-shared-array-buffer/1.0.1: resolution: {integrity: sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==} dev: true /is-string/1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} dependencies: has-tostringtag: 1.0.0 dev: true /is-symbol/1.0.4: resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} engines: {node: '>= 0.4'} dependencies: has-symbols: 1.0.2 dev: true /is-weakref/1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} dependencies: call-bind: 1.0.2 dev: true /isarray/1.0.0: resolution: {integrity: sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=} dev: true /isexe/2.0.0: resolution: {integrity: sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=} dev: true /isobject/2.1.0: resolution: {integrity: sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=} engines: {node: '>=0.10.0'} dependencies: isarray: 1.0.0 dev: true /istanbul-lib-coverage/3.2.0: resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} engines: {node: '>=8'} dev: true /istanbul-lib-report/3.0.0: resolution: {integrity: sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==} engines: {node: '>=8'} dependencies: istanbul-lib-coverage: 3.2.0 make-dir: 3.1.0 supports-color: 7.2.0 dev: true /istanbul-reports/3.1.4: resolution: {integrity: sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==} engines: {node: '>=8'} dependencies: html-escaper: 2.0.2 istanbul-lib-report: 3.0.0 dev: true /jest-worker/27.5.1: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} dependencies: '@types/node': 17.0.18 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true /js-tokens/4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} dev: true /js-yaml/4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true dependencies: argparse: 2.0.1 dev: true /jsesc/2.5.2: resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} engines: {node: '>=4'} hasBin: true dev: true /json-parse-better-errors/1.0.2: resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} dev: true /json-schema-traverse/0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} dev: true /json-stable-stringify-without-jsonify/1.0.1: resolution: {integrity: sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=} dev: true /json5/1.0.1: resolution: {integrity: sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==} hasBin: true dependencies: minimist: 1.2.5 dev: true /json5/2.2.0: resolution: {integrity: sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==} engines: {node: '>=6'} hasBin: true dependencies: minimist: 1.2.5 dev: true /kleur/4.1.4: resolution: {integrity: sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA==} engines: {node: '>=6'} dev: true /levn/0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} dependencies: prelude-ls: 1.2.1 type-check: 0.4.0 dev: true /lilconfig/2.0.4: resolution: {integrity: sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA==} engines: {node: '>=10'} dev: true /line-column/1.0.2: resolution: {integrity: sha1-0lryk2tvSEkXKzEuR5LR2Ye8NKI=} dependencies: isarray: 1.0.0 isobject: 2.1.0 dev: true /loader-runner/4.2.0: resolution: {integrity: sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==} engines: {node: '>=6.11.5'} dev: true /locate-path/2.0.0: resolution: {integrity: sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=} engines: {node: '>=4'} dependencies: p-locate: 2.0.0 path-exists: 3.0.0 dev: true /locate-path/6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} dependencies: p-locate: 5.0.0 dev: true /lodash.merge/4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} dev: true /lodash/4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} dev: true /lru-cache/6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} dependencies: yallist: 4.0.0 dev: true /make-dir/3.1.0: resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} engines: {node: '>=8'} dependencies: semver: 6.3.0 dev: true /merge-stream/2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} dev: true /merge2/1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} dev: true /micromatch/4.0.4: resolution: {integrity: sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==} engines: {node: '>=8.6'} dependencies: braces: 3.0.2 picomatch: 2.3.1 dev: true /mime-db/1.51.0: resolution: {integrity: sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==} engines: {node: '>= 0.6'} dev: true /mime-types/2.1.34: resolution: {integrity: sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==} engines: {node: '>= 0.6'} dependencies: mime-db: 1.51.0 dev: true /minimatch/3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: brace-expansion: 1.1.11 dev: true /minimist/1.2.5: resolution: {integrity: sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==} dev: true /mkdirp/1.0.4: resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} engines: {node: '>=10'} hasBin: true dev: true /mri/1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} dev: true /ms/2.0.0: resolution: {integrity: sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=} dev: true /ms/2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} dev: true /ms/2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} dev: true /nanoid/2.1.11: resolution: {integrity: sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==} dev: true /nanoid/3.3.0: resolution: {integrity: sha512-JzxqqT5u/x+/KOFSd7JP15DOo9nOoHpx6DYatqIHUW2+flybkm+mdcraotSQR5WcnZr+qhGVh8Ted0KdfSMxlg==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true dev: true /nanospinner/1.0.0: resolution: {integrity: sha512-14c2r2QQ9xfTmdbqdF51FKCNvww+0ZON9GeEHur+pBdOufoFvxD4CZQRaYWmFrGH3Nuv7PZ/9Q+wsV+hFSp32g==} dependencies: picocolors: 1.0.0 dev: true /nanospy/0.5.0: resolution: {integrity: sha512-QxH93ntkjRiSP+gJrBLcgOO3neU6pGhUKjPAJ7rAFag/+tJ+/0lw6dXic+iXUQ/3Cxk4Dp/FwLnf57xnQsjecQ==} engines: {node: ^8.0.0 || ^10.0.0 || ^12.0.0 || ^14.0.0 || >=16.0.0} dev: true /natural-compare/1.4.0: resolution: {integrity: sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=} dev: true /neo-async/2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} dev: true /node-releases/2.0.2: resolution: {integrity: sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==} dev: true /normalize-path/3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} dev: true /object-inspect/1.12.0: resolution: {integrity: sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==} dev: true /object-keys/1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} dev: true /object.assign/4.1.2: resolution: {integrity: sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==} engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.2 define-properties: 1.1.3 has-symbols: 1.0.2 object-keys: 1.1.1 dev: true /object.values/1.1.5: resolution: {integrity: sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==} engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.2 define-properties: 1.1.3 es-abstract: 1.19.1 dev: true /once/1.4.0: resolution: {integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=} dependencies: wrappy: 1.0.2 dev: true /optionator/0.9.1: resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==} engines: {node: '>= 0.8.0'} dependencies: deep-is: 0.1.4 fast-levenshtein: 2.0.6 levn: 0.4.1 prelude-ls: 1.2.1 type-check: 0.4.0 word-wrap: 1.2.3 dev: true /p-limit/1.3.0: resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} engines: {node: '>=4'} dependencies: p-try: 1.0.0 dev: true /p-limit/3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} dependencies: yocto-queue: 0.1.0 dev: true /p-locate/2.0.0: resolution: {integrity: sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=} engines: {node: '>=4'} dependencies: p-limit: 1.3.0 dev: true /p-locate/5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} dependencies: p-limit: 3.1.0 dev: true /p-try/1.0.0: resolution: {integrity: sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=} engines: {node: '>=4'} dev: true /parent-module/1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} dependencies: callsites: 3.1.0 dev: true /path-exists/3.0.0: resolution: {integrity: sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=} engines: {node: '>=4'} dev: true /path-exists/4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} dev: true /path-is-absolute/1.0.1: resolution: {integrity: sha1-F0uSaHNVNP+8es5r9TpanhtcX18=} engines: {node: '>=0.10.0'} dev: true /path-key/3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} dev: true /path-parse/1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} dev: true /path-type/4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} dev: true /picocolors/1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} dev: true /picomatch/2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} dev: true /platform/1.3.6: resolution: {integrity: sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==} dev: true /postcss/8.4.6: resolution: {integrity: sha512-OovjwIzs9Te46vlEx7+uXB0PLijpwjXGKXjVGGPIGubGpq7uh5Xgf6D6FiJ/SzJMBosHDp6a2hiXOS97iBXcaA==} engines: {node: ^10 || ^12 || >=14} dependencies: nanoid: 3.3.0 picocolors: 1.0.0 source-map-js: 1.0.2 dev: true /prelude-ls/1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} dev: true /punycode/2.1.1: resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==} engines: {node: '>=6'} dev: true /queue-microtask/1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} dev: true /random-bytes/1.0.0: resolution: {integrity: sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=} engines: {node: '>= 0.8'} dev: true /randombytes/2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} dependencies: safe-buffer: 5.2.1 dev: true /readdirp/3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} dependencies: picomatch: 2.3.1 dev: true /regexpp/3.2.0: resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} engines: {node: '>=8'} dev: true /require-directory/2.1.1: resolution: {integrity: sha1-jGStX9MNqxyXbiNE/+f3kqam30I=} engines: {node: '>=0.10.0'} dev: true /requireindex/1.2.0: resolution: {integrity: sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==} engines: {node: '>=0.10.5'} dev: true /resolve-from/4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} dev: true /resolve/1.22.0: resolution: {integrity: sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==} hasBin: true dependencies: is-core-module: 2.8.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 dev: true /reusify/1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} dev: true /rimraf/3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} hasBin: true dependencies: glob: 7.2.0 dev: true /rndm/1.2.0: resolution: {integrity: sha1-8z/pz7Urv9UgqhgyO8ZdsRCht2w=} dev: true /rollup/2.67.2: resolution: {integrity: sha512-hoEiBWwZtf1QdK3jZIq59L0FJj4Fiv4RplCO4pvCRC86qsoFurWB4hKQIjoRf3WvJmk5UZ9b0y5ton+62fC7Tw==} engines: {node: '>=10.0.0'} hasBin: true optionalDependencies: fsevents: 2.3.2 dev: true /run-parallel/1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: queue-microtask: 1.2.3 dev: true /sade/1.8.1: resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} engines: {node: '>=6'} dependencies: mri: 1.2.0 dev: true /safe-buffer/5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} dev: true /safe-buffer/5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} dev: true /schema-utils/3.1.1: resolution: {integrity: sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==} engines: {node: '>= 10.13.0'} dependencies: '@types/json-schema': 7.0.9 ajv: 6.12.6 ajv-keywords: 3.5.2_ajv@6.12.6 dev: true /secure-random-string/1.1.3: resolution: {integrity: sha512-298HxkJJp5mjpPhxDsN26S/2JmMaUIrQ4PxDI/F4fXKRBTOKendQ5i6JCkc+a8F8koLh0vdfwSCw8+RJkY7N6A==} dev: true /semver/6.3.0: resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} hasBin: true dev: true /semver/7.3.5: resolution: {integrity: sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==} engines: {node: '>=10'} hasBin: true dependencies: lru-cache: 6.0.0 dev: true /serialize-javascript/6.0.0: resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} dependencies: randombytes: 2.1.0 dev: true /shebang-command/2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} dependencies: shebang-regex: 3.0.0 dev: true /shebang-regex/3.0.0: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} dev: true /shortid/2.2.16: resolution: {integrity: sha512-Ugt+GIZqvGXCIItnsL+lvFJOiN7RYqlGy7QE41O3YC1xbNSeDGIRO7xg2JJXIAj1cAGnOeC1r7/T9pgrtQbv4g==} dependencies: nanoid: 2.1.11 dev: true /side-channel/1.0.4: resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} dependencies: call-bind: 1.0.2 get-intrinsic: 1.1.1 object-inspect: 1.12.0 dev: true /signal-exit/3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} dev: true /size-limit/7.0.8: resolution: {integrity: sha512-3h76c9E0e/nNhYLSR7IBI/bSoXICeo7EYkYjlyVqNIsu7KvN/PQmMbIXeyd2QKIF8iZKhaiZQoXLkGWbyPDtvQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} hasBin: true dependencies: bytes-iec: 3.1.1 chokidar: 3.5.3 ci-job-number: 1.2.2 globby: 11.1.0 lilconfig: 2.0.4 mkdirp: 1.0.4 nanospinner: 1.0.0 picocolors: 1.0.0 dev: true /slash/3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} dev: true /source-map-js/1.0.2: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} dev: true /source-map-support/0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} dependencies: buffer-from: 1.1.2 source-map: 0.6.1 dev: true /source-map/0.5.7: resolution: {integrity: sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=} engines: {node: '>=0.10.0'} dev: true /source-map/0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} dev: true /source-map/0.7.3: resolution: {integrity: sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==} engines: {node: '>= 8'} dev: true /string-width/4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} dependencies: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 dev: true /string.prototype.trimend/1.0.4: resolution: {integrity: sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==} dependencies: call-bind: 1.0.2 define-properties: 1.1.3 dev: true /string.prototype.trimstart/1.0.4: resolution: {integrity: sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==} dependencies: call-bind: 1.0.2 define-properties: 1.1.3 dev: true /strip-ansi/6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} dependencies: ansi-regex: 5.0.1 dev: true /strip-bom/3.0.0: resolution: {integrity: sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=} engines: {node: '>=4'} dev: true /strip-json-comments/3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} dev: true /supports-color/5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} dependencies: has-flag: 3.0.0 dev: true /supports-color/7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} dependencies: has-flag: 4.0.0 dev: true /supports-color/8.1.1: resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} engines: {node: '>=10'} dependencies: has-flag: 4.0.0 dev: true /supports-preserve-symlinks-flag/1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} dev: true /tapable/2.2.1: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} dev: true /terser-webpack-plugin/5.3.1_acorn@8.7.0+webpack@5.69.0: resolution: {integrity: sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g==} engines: {node: '>= 10.13.0'} peerDependencies: '@swc/core': '*' esbuild: '*' uglify-js: '*' webpack: ^5.1.0 peerDependenciesMeta: '@swc/core': optional: true esbuild: optional: true uglify-js: optional: true dependencies: jest-worker: 27.5.1 schema-utils: 3.1.1 serialize-javascript: 6.0.0 source-map: 0.6.1 terser: 5.10.0_acorn@8.7.0 webpack: 5.69.0 transitivePeerDependencies: - acorn dev: true /terser/5.10.0: resolution: {integrity: sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA==} engines: {node: '>=10'} hasBin: true peerDependencies: acorn: ^8.5.0 peerDependenciesMeta: acorn: optional: true dependencies: commander: 2.20.3 source-map: 0.7.3 source-map-support: 0.5.21 dev: true /terser/5.10.0_acorn@8.7.0: resolution: {integrity: sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA==} engines: {node: '>=10'} hasBin: true peerDependencies: acorn: ^8.5.0 peerDependenciesMeta: acorn: optional: true dependencies: acorn: 8.7.0 commander: 2.20.3 source-map: 0.7.3 source-map-support: 0.5.21 dev: true /test-exclude/6.0.0: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} engines: {node: '>=8'} dependencies: '@istanbuljs/schema': 0.1.3 glob: 7.2.0 minimatch: 3.1.2 dev: true /text-table/0.2.0: resolution: {integrity: sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=} dev: true /to-fast-properties/2.0.0: resolution: {integrity: sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=} engines: {node: '>=4'} dev: true /to-regex-range/5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} dependencies: is-number: 7.0.0 dev: true /tsconfig-paths/3.12.0: resolution: {integrity: sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==} dependencies: '@types/json5': 0.0.29 json5: 1.0.1 minimist: 1.2.5 strip-bom: 3.0.0 dev: true /type-check/0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} dependencies: prelude-ls: 1.2.1 dev: true /type-fest/0.20.2: resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} engines: {node: '>=10'} dev: true /uid-safe/2.1.5: resolution: {integrity: sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==} engines: {node: '>= 0.8'} dependencies: random-bytes: 1.0.0 dev: true /uid/2.0.0: resolution: {integrity: sha512-hFw+zKBA1szYdbZWj6FjTxZzJnKNf+wTDcsxlJaXS64MCy9LQEmJUVieGYHCKek/WRyFIcs0cEXtGIQmfvHe2A==} engines: {node: '>=8'} dependencies: '@lukeed/csprng': 1.0.1 dev: true /unbox-primitive/1.0.1: resolution: {integrity: sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==} dependencies: function-bind: 1.1.1 has-bigints: 1.0.1 has-symbols: 1.0.2 which-boxed-primitive: 1.0.2 dev: true /uri-js/4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: punycode: 2.1.1 dev: true /uuid/8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true dev: true /uvu/0.5.3: resolution: {integrity: sha512-brFwqA3FXzilmtnIyJ+CxdkInkY/i4ErvP7uV0DnUVxQcQ55reuHphorpF+tZoVHK2MniZ/VJzI7zJQoc9T9Yw==} engines: {node: '>=8'} hasBin: true dependencies: dequal: 2.0.2 diff: 5.0.0 kleur: 4.1.4 sade: 1.8.1 dev: true /v8-compile-cache/2.3.0: resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==} dev: true /v8-to-istanbul/8.1.1: resolution: {integrity: sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==} engines: {node: '>=10.12.0'} dependencies: '@types/istanbul-lib-coverage': 2.0.4 convert-source-map: 1.8.0 source-map: 0.7.3 dev: true /vite/2.8.3: resolution: {integrity: sha512-967klrEiG7HEsN7fQYYVETs5495Iu6GpI7YyxoO5yVTJCRxjV8HhWgNWKgrbazjoOB9DQuztL53/nUoNqHNsWg==} engines: {node: '>=12.2.0'} hasBin: true peerDependencies: less: '*' sass: '*' stylus: '*' peerDependenciesMeta: less: optional: true sass: optional: true stylus: optional: true dependencies: esbuild: 0.14.21 postcss: 8.4.6 resolve: 1.22.0 rollup: 2.67.2 optionalDependencies: fsevents: 2.3.2 dev: true /watchpack/2.3.1: resolution: {integrity: sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA==} engines: {node: '>=10.13.0'} dependencies: glob-to-regexp: 0.4.1 graceful-fs: 4.2.9 dev: true /webpack-sources/3.2.3: resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} engines: {node: '>=10.13.0'} dev: true /webpack/5.69.0: resolution: {integrity: sha512-E5Fqu89Gu8fR6vejRqu26h8ld/k6/dCVbeGUcuZjc+goQHDfCPU9rER71JmdtBYGmci7Ec2aFEATQ2IVXKy2wg==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: webpack-cli: '*' peerDependenciesMeta: webpack-cli: optional: true dependencies: '@types/eslint-scope': 3.7.3 '@types/estree': 0.0.51 '@webassemblyjs/ast': 1.11.1 '@webassemblyjs/wasm-edit': 1.11.1 '@webassemblyjs/wasm-parser': 1.11.1 acorn: 8.7.0 acorn-import-assertions: 1.8.0_acorn@8.7.0 browserslist: 4.19.1 chrome-trace-event: 1.0.3 enhanced-resolve: 5.9.0 es-module-lexer: 0.9.3 eslint-scope: 5.1.1 events: 3.3.0 glob-to-regexp: 0.4.1 graceful-fs: 4.2.9 json-parse-better-errors: 1.0.2 loader-runner: 4.2.0 mime-types: 2.1.34 neo-async: 2.6.2 schema-utils: 3.1.1 tapable: 2.2.1 terser-webpack-plugin: 5.3.1_acorn@8.7.0+webpack@5.69.0 watchpack: 2.3.1 webpack-sources: 3.2.3 transitivePeerDependencies: - '@swc/core' - esbuild - uglify-js dev: true /which-boxed-primitive/1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} dependencies: is-bigint: 1.0.4 is-boolean-object: 1.1.2 is-number-object: 1.0.6 is-string: 1.0.7 is-symbol: 1.0.4 dev: true /which/2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} hasBin: true dependencies: isexe: 2.0.0 dev: true /word-wrap/1.2.3: resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} engines: {node: '>=0.10.0'} dev: true /wrap-ansi/7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} dependencies: ansi-styles: 4.3.0 string-width: 4.2.3 strip-ansi: 6.0.1 dev: true /wrappy/1.0.2: resolution: {integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=} dev: true /y18n/5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} dev: true /yallist/4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} dev: true /yargs-parser/20.2.9: resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} engines: {node: '>=10'} dev: true /yargs/16.2.0: resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} engines: {node: '>=10'} dependencies: cliui: 7.0.4 escalade: 3.1.1 get-caller-file: 2.0.5 require-directory: 2.1.1 string-width: 4.2.3 y18n: 5.0.8 yargs-parser: 20.2.9 dev: true /yocto-queue/0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} dev: true nanoid-3.3.1/test/000077500000000000000000000000001420327433100137445ustar00rootroot00000000000000nanoid-3.3.1/test/async.test.js000066400000000000000000000115641420327433100164040ustar00rootroot00000000000000let { suite } = require('uvu') let { spy } = require('nanospy') let { is, match, ok } = require('uvu/assert') let crypto = require('crypto') global.crypto = { getRandomValues(array) { for (let i = 0; i < array.length; i++) { array[i] = Math.floor(Math.random() * 256) } return array } } let { urlAlphabet } = require('..') let browser = require('../async/index.browser.js') let node = require('../async/index.js') function times(size, callback) { let array = [] for (let i = 0; i < size; i++) { array.push(1) } return array.map(callback) } for (let type of ['node', 'browser']) { let { nanoid, customAlphabet, random } = type === 'node' ? node : browser function mock(callback) { crypto.randomFill = callback delete require.cache[require.resolve('../async')] nanoid = require('../async').nanoid } let nanoidSuite = suite(`${type} / nanoid`) if (type === 'node') { let originFill = crypto.randomFill nanoidSuite.after.each(() => { mock(originFill) }) } nanoidSuite('generates URL-friendly IDs', async () => { await Promise.all( times(100, async () => { let id = await nanoid() is(id.length, 21) is(typeof id, 'string') for (let char of id) { match(urlAlphabet, new RegExp(char, "g")) } }) ) }) nanoidSuite('changes ID length', async () => { let id = await nanoid(10) is(id.length, 10) }) nanoidSuite('has no collisions', async () => { let ids = await Promise.all(times(50 * 1000, () => nanoid())) ids.reduce((used, id) => { is(used[id], undefined) used[id] = true return used }, []) }) nanoidSuite('has flat distribution', async () => { let COUNT = 100 * 1000 let LENGTH = (await nanoid()).length let chars = {} await Promise.all( times(COUNT, async () => { let id = await nanoid() for (let char of id) { if (!chars[char]) chars[char] = 0 chars[char] += 1 } }) ) is(Object.keys(chars).length, urlAlphabet.length) let max = 0 let min = Number.MAX_SAFE_INTEGER for (let k in chars) { let distribution = (chars[k] * urlAlphabet.length) / (COUNT * LENGTH) if (distribution > max) max = distribution if (distribution < min) min = distribution } ok(max - min <= 0.05) }) if (type === 'node') { nanoidSuite('rejects Promise on error', async () => { let error = new Error('test') mock((buffer, callback) => { callback(error) }) let catched try { await nanoid() } catch (e) { catched = e } is(catched, error) }) } nanoidSuite.run() let randomSuite = suite(`${type} / random`) randomSuite('generates small random buffers', async () => { is((await random(10)).length, 10) }) randomSuite('generates random buffers', async () => { let numbers = {} let bytes = await random(10000) is(bytes.length, 10000) for (let byte of bytes) { if (!numbers[byte]) numbers[byte] = 0 numbers[byte] += 1 is(typeof byte, 'number') ok(byte <= 255) ok(byte >= 0) } }) randomSuite.run() let customAlphabetSuite = suite(`${type} / customAlphabet`) if (type === 'node') { let originFill = crypto.randomFill customAlphabetSuite.after.each(() => { mock(originFill) }) } customAlphabetSuite('has options', async () => { let nanoidA = customAlphabet('a', 5) let id = await nanoidA() is(id, 'aaaaa') }) customAlphabetSuite('has flat distribution', async () => { let COUNT = 50 * 1000 let LENGTH = 30 let ALPHABET = 'abcdefghijklmnopqrstuvwxy' let nanoid2 = customAlphabet(ALPHABET, LENGTH) let chars = {} await Promise.all( times(100, async () => { let id = await nanoid2() is(id.length, LENGTH) for (let char of id) { if (!chars[char]) chars[char] = 0 chars[char] += 1 } }) ) is(Object.keys(chars).length, ALPHABET.length) let max = 0 let min = Number.MAX_SAFE_INTEGER for (let k in chars) { let distribution = (chars[k] * ALPHABET.length) / (COUNT * LENGTH) if (distribution > max) max = distribution if (distribution < min) min = distribution } ok(max - min <= 0.05) }) customAlphabetSuite('changes size', async () => { let nanoidA = customAlphabet('a') let id = await nanoidA(10) is(id, 'aaaaaaaaaa') }) if (type === 'node') { customAlphabetSuite('should call random two times', async () => { let randomFillMock = spy((buffer, callback) => callback(null, [220, 215, 129, 35, 242, 202, 137, 180]) ) mock(randomFillMock) let nanoidA = customAlphabet('a', 5) let id = await nanoidA() is(randomFillMock.callCount, 2) is(id, 'aaaaa') }) } customAlphabetSuite.run() } nanoid-3.3.1/test/benchmark.js000077500000000000000000000047321420327433100162450ustar00rootroot00000000000000#!/usr/bin/env node let { uid: uidSecure } = require('uid/secure') let { v4: lukeed4 } = require('@lukeed/uuid') let { v4: uuid4 } = require('uuid') let benchmark = require('benchmark') let shortid = require('shortid') let uidSafe = require('uid-safe') let { uid } = require('uid') let crypto = require('crypto') let pico = require('picocolors') let cuid = require('cuid') let rndm = require('rndm') let srs = require('secure-random-string') let { nanoid: aNanoid, customAlphabet: aCustomAlphabet } = require('../async') let { nanoid, customAlphabet } = require('../') let { nanoid: nonSecure } = require('../non-secure') let suite = new benchmark.Suite() let nanoid2 = customAlphabet('1234567890abcdef-', 10) let asyncNanoid2 = aCustomAlphabet('1234567890abcdef-', 10) function formatNumber(number) { return String(number) .replace(/\d{3}$/, ',$&') .replace(/^(\d|\d\d)(\d{3},)/, '$1,$2') } suite .add('crypto.randomUUID', () => { crypto.randomUUID() }) .add('uid/secure', () => { uidSecure(32) }) .add('@lukeed/uuid', () => { lukeed4() }) .add('nanoid', () => { nanoid() }) .add('customAlphabet', () => { nanoid2() }) .add('uuid v4', () => { uuid4() }) .add('secure-random-string', () => { srs() }) .add('uid-safe.sync', () => { uidSafe.sync(14) }) .add('cuid', () => { cuid() }) .add('shortid', () => { shortid() }) .add('nanoid/async', { defer: true, fn(defer) { aNanoid().then(() => { defer.resolve() }) } }) .add('async customAlphabet', { defer: true, fn(defer) { asyncNanoid2().then(() => { defer.resolve() }) } }) .add('async secure-random-string', { defer: true, fn(defer) { srs(() => { defer.resolve() }) } }) .add('uid-safe', { defer: true, fn(defer) { uidSafe(14).then(() => { defer.resolve() }) } }) .add('uid', () => { uid(32) }) .add('nanoid/non-secure', () => { nonSecure() }) .add('rndm', () => { rndm(21) }) .on('cycle', event => { let name = event.target.name.padEnd('async secure-random-string'.length) let hz = formatNumber(event.target.hz.toFixed(0)).padStart(10) if (event.target.name === 'nanoid/async') { name = '\nAsync:\n' + name } else if (event.target.name === 'uid') { name = '\nNon-secure:\n' + name } process.stdout.write(`${name}${pico.bold(hz)}${pico.dim(' ops/sec')}\n`) }) .run() nanoid-3.3.1/test/bin.test.js000066400000000000000000000027171420327433100160370ustar00rootroot00000000000000let { is, match } = require('uvu/assert') let { promisify } = require('util') let { test } = require('uvu') let { join } = require('path') let child = require('child_process') let exec = promisify(child.exec) const BIN = join(__dirname, '..', 'bin', 'nanoid.cjs') test('prints unique ID', async () => { let { stdout, stderr } = await exec('node ' + BIN) is(stderr, '') match(stdout, /^[\w-]{21}\n$/) }) test('uses size', async () => { let { stdout, stderr } = await exec('node ' + BIN + ' --size 10') is(stderr, '') match(stdout, /^[\w-]{10}\n$/) }) test('uses alphabet', async () => { let { stdout, stderr } = await exec( 'node ' + BIN + ' --alphabet abc --size 15' ) is(stderr, '') match(stdout, /^[abc]{15}\n$/) }) test('shows an error on unknown argument', async () => { try { await exec('node ' + BIN + ' -test') } catch (e) { match(e, /Unknown argument -test/) } }) test('shows an error if size is not a number', async () => { try { await exec('node ' + BIN + ' -s abc') } catch (e) { match(e, /Size must be positive integer/) } }) test('requires error if size is a negative number', async () => { try { await exec('node ' + BIN + ' --size "-1"') } catch (e) { match(e, /Size must be positive integer/) } }) test('displays help', async () => { let { stdout, stderr } = await exec('node ' + BIN + ' --help') is(stderr, '') match(stdout, /Usage/) match(stdout, /\$ nanoid \[options]/) }) test.run() nanoid-3.3.1/test/demo/000077500000000000000000000000001420327433100146705ustar00rootroot00000000000000nanoid-3.3.1/test/demo/index.html000066400000000000000000000016301420327433100166650ustar00rootroot00000000000000 Nano ID nanoid-3.3.1/test/demo/index.js000066400000000000000000000045351420327433100163440ustar00rootroot00000000000000import { v4 as uuid4 } from 'uuid' import shortid from 'shortid' import nanoidExport from '../../index.browser.js' import nonSecureExport from '../../non-secure/index.js' let { nanoid, customAlphabet, random } = nanoidExport let nonSecure = nonSecureExport.nanoid const COUNT = 50 * 1000 const ALPHABET = 'abcdefghijklmnopqrstuvwxyz' const LENGTH = ALPHABET.length let nanoid2 = customAlphabet(ALPHABET, LENGTH) function print(number) { return String(Math.floor(number * 100)) .replace(/\d{6}$/, ',$&') .replace(/\d{3}$/, ',$&') } function printDistr(title, fn) { let data = calcDistr(title, fn) let keys = Object.keys(data.chars) let length = keys.length let dots = '' let average = keys.reduce((all, l) => all + data.chars[l], 0) / length for (let l of keys.sort()) { let distribution = data.chars[l] / average dots += `
    ${l}
    ` } document.body.innerHTML += `
    ${print((COUNT * 1000) / data.time)} ops/sec

    ${data.title}

    ${dots}
    ` } function calcDistr(title, fn) { let chars = {} let ids = [] let j let start = Date.now() for (j = 0; j < COUNT; j++) ids.push(fn()) let end = Date.now() for (j = 0; j < COUNT; j++) { let id = ids[j] if (title === 'uuid/v4') id = id.replace(/-./g, '') for (let char of id) { if (!chars[char]) chars[char] = 0 chars[char] += 1 } } return { title, chars, time: end - start } } let tasks = [ () => printDistr('ideal', () => { let result = [] for (let j = 0; j < LENGTH; j++) { result.push(ALPHABET[j]) } return result }), () => printDistr('nanoid', () => nanoid()), () => printDistr('nanoid2', () => nanoid2()), () => printDistr('uuid/v4', () => uuid4()), () => printDistr('shortid', () => shortid()), () => printDistr('nanoid/non-secure', () => nonSecure()), () => printDistr('random % alphabet', () => { return [...random(LENGTH)].map(i => ALPHABET[i % ALPHABET.length]) }) ] function run() { if (tasks.length === 0) return let task = tasks.shift() task() setTimeout(run, 10) } let html = '' for (let i = 0; i < 10; i++) { html += `
    ${nanoid()}
    ` } document.body.innerHTML = `
    ${html}
    ` run() nanoid-3.3.1/test/demo/vite.config.js000066400000000000000000000001561420327433100174430ustar00rootroot00000000000000import { viteCommonjs } from '@originjs/vite-plugin-commonjs' export default { plugins: [viteCommonjs()] } nanoid-3.3.1/test/index.test.js000066400000000000000000000115721420327433100163750ustar00rootroot00000000000000let { test } = require('uvu') let { is, ok, equal, match } = require('uvu/assert') let browser = require('../index.browser.js') let node = require('../index.js') test.before(() => { global.crypto = { getRandomValues(array) { for (let i = 0; i < array.length; i++) { array[i] = Math.floor(Math.random() * 256) } return array } } }) test.after(() => { delete global.crypto }) for (let type of ['node', 'browser']) { let { nanoid, customAlphabet, customRandom, random, urlAlphabet } = type === 'node' ? node : browser test(`${type} / nanoid / generates URL-friendly IDs`, () => { for (let i = 0; i < 100; i++) { let id = nanoid() is(id.length, 21) is(typeof id, 'string') for (let char of id) { match(urlAlphabet, new RegExp(char, "g")) } } }) test(`${type} / nanoid / changes ID length`, () => { is(nanoid(10).length, 10) }) test(`${type} / nanoid / accepts string`, () => { is(nanoid('10').length, 10) }) test(`${type} / nanoid / has no collisions`, () => { let used = {} for (let i = 0; i < 50 * 1000; i++) { let id = nanoid() is(used[id], undefined) used[id] = true } }) test(`${type} / nanoid / has flat distribution`, () => { let COUNT = 100 * 1000 let LENGTH = nanoid().length let chars = {} for (let i = 0; i < COUNT; i++) { let id = nanoid() for (let char of id) { if (!chars[char]) chars[char] = 0 chars[char] += 1 } } is(Object.keys(chars).length, urlAlphabet.length) let max = 0 let min = Number.MAX_SAFE_INTEGER for (let k in chars) { let distribution = (chars[k] * urlAlphabet.length) / (COUNT * LENGTH) if (distribution > max) max = distribution if (distribution < min) min = distribution } ok(max - min <= 0.05) }) test(`${type} / customAlphabet / has options`, () => { let nanoidA = customAlphabet('a', 5) is(nanoidA(), 'aaaaa') }) test(`${type} / customAlphabet / has flat distribution`, () => { let COUNT = 50 * 1000 let LENGTH = 30 let ALPHABET = 'abcdefghijklmnopqrstuvwxyz' let nanoid2 = customAlphabet(ALPHABET, LENGTH) let chars = {} for (let i = 0; i < COUNT; i++) { let id = nanoid2() for (let char of id) { if (!chars[char]) chars[char] = 0 chars[char] += 1 } } is(Object.keys(chars).length, ALPHABET.length) let max = 0 let min = Number.MAX_SAFE_INTEGER for (let k in chars) { let distribution = (chars[k] * ALPHABET.length) / (COUNT * LENGTH) if (distribution > max) max = distribution if (distribution < min) min = distribution } ok(max - min <= 0.05) }) test(`${type} / customAlphabet / changes size`, () => { let nanoidA = customAlphabet('a') is(nanoidA(10), 'aaaaaaaaaa') }) test(`${type} / customRandom / supports generator`, () => { let sequence = [2, 255, 3, 7, 7, 7, 7, 7, 0, 1] function fakeRandom(size) { let bytes = [] for (let i = 0; i < size; i += sequence.length) { bytes = bytes.concat(sequence.slice(0, size - i)) } return bytes } let nanoid4 = customRandom('abcde', 4, fakeRandom) let nanoid18 = customRandom('abcde', 18, fakeRandom) is(nanoid4(), 'adca') is(nanoid18(), 'cbadcbadcbadcbadcc') }) test(`${type} / urlAlphabet / is string`, () => { is(typeof urlAlphabet, 'string') }) test(`${type} / urlAlphabet / has no duplicates`, () => { for (let i = 0; i < urlAlphabet.length; i++) { equal(urlAlphabet.lastIndexOf(urlAlphabet[i]), i) } }) test(`${type} / random / generates small random buffers`, () => { for (let i = 0; i < urlAlphabet.length; i++) { is(random(10).length, 10) } }) test(`${type} / random / generates random buffers`, () => { let numbers = {} let bytes = random(10000) is(bytes.length, 10000) for (let byte of bytes) { if (!numbers[byte]) numbers[byte] = 0 numbers[byte] += 1 is(typeof byte, 'number') ok(byte <= 255) ok(byte >= 0) } }) if (type === 'node') { test(`${type} / proxy number / prevent collision`, () => { let makeProxyNumberToReproducePreviousID = () => { let step = 0 return { valueOf() { // "if (!pool || pool.length < bytes) {" if (step === 0) { step++ return 0 } // "} else if (poolOffset + bytes > pool.length) {" if (step === 1) { step++ return -Infinity } // "poolOffset += bytes" if (step === 2) { step++ return 0 } return 21 } } } let ID1 = nanoid() let ID2 = nanoid(makeProxyNumberToReproducePreviousID()) is.not(ID1, ID2) }) } } test.run() nanoid-3.3.1/test/non-secure.test.js000066400000000000000000000041351420327433100173410ustar00rootroot00000000000000let { test } = require('uvu') let { is, match, ok } = require('uvu/assert') let { nanoid, customAlphabet } = require('../non-secure') let { urlAlphabet } = require('..') test('nanoid / generates URL-friendly IDs', () => { for (let i = 0; i < 10; i++) { let id = nanoid() is(id.length, 21) for (let char of id) { match(urlAlphabet, new RegExp(char, "g")) } } }) test('nanoid / changes ID length', () => { is(nanoid(10).length, 10) }) test('nanoid / accepts string', () => { is(nanoid('10').length, 10) }) test('nanoid / has no collisions', () => { let used = {} for (let i = 0; i < 100 * 1000; i++) { let id = nanoid() is(used[id], undefined) used[id] = true } }) test('nanoid / has flat distribution', () => { let COUNT = 100 * 1000 let LENGTH = nanoid().length let chars = {} for (let i = 0; i < COUNT; i++) { let id = nanoid() for (let char of id) { if (!chars[char]) chars[char] = 0 chars[char] += 1 } } is(Object.keys(chars).length, urlAlphabet.length) let max = 0 let min = Number.MAX_SAFE_INTEGER for (let k in chars) { let distribution = (chars[k] * urlAlphabet.length) / (COUNT * LENGTH) if (distribution > max) max = distribution if (distribution < min) min = distribution } ok(max - min <= 0.05) }) test('customAlphabet / has options', () => { let nanoidA = customAlphabet('a', 5) is(nanoidA(), 'aaaaa') }) test('customAlphabet / has flat distribution', () => { let COUNT = 100 * 1000 let LENGTH = 5 let ALPHABET = 'abcdefghijklmnopqrstuvwxyz' let nanoid2 = customAlphabet(ALPHABET, LENGTH) let chars = {} for (let i = 0; i < COUNT; i++) { let id = nanoid2() for (let char of id) { if (!chars[char]) chars[char] = 0 chars[char] += 1 } } is(Object.keys(chars).length, ALPHABET.length) let max = 0 let min = Number.MAX_SAFE_INTEGER for (let k in chars) { let distribution = (chars[k] * ALPHABET.length) / (COUNT * LENGTH) if (distribution > max) max = distribution if (distribution < min) min = distribution } ok(max - min <= 0.05) }) test.run() nanoid-3.3.1/test/react-native-polyfill.test.js000066400000000000000000000010241420327433100214670ustar00rootroot00000000000000let { test } = require('uvu') let { is } = require('uvu/assert') test.before(() => { global.navigator = { product: 'ReactNative' } global.crypto = { getRandomValues(array) { for (let i = 0; i < array.length; i++) { array[i] = Math.floor(Math.random() * 256) } return array } } }) test.after(() => { delete global.navigator delete global.crypto }) test('works with polyfill', () => { let { nanoid } = require('../index.browser') is(typeof nanoid(), 'string') }) test.run() nanoid-3.3.1/test/update-prebuild.js000077500000000000000000000010261420327433100173720ustar00rootroot00000000000000#!/usr/bin/env node let { promisify } = require('util') let { minify } = require('terser') let { join } = require('path') let fs = require('fs') let writeFile = promisify(fs.writeFile) let readFile = promisify(fs.readFile) async function build() { let js = await readFile(join(__dirname, '..', 'index.browser.js')) let func = 'export ' + js.toString().match(/(let nanoid [\W\w]*)\s*module/)[1] let { code } = await minify(func) await writeFile(join(__dirname, '..', 'nanoid.js'), code) } build().catch(e => { throw e }) nanoid-3.3.1/url-alphabet/000077500000000000000000000000001420327433100153455ustar00rootroot00000000000000nanoid-3.3.1/url-alphabet/index.js000066400000000000000000000004301420327433100170070ustar00rootroot00000000000000// This alphabet uses `A-Za-z0-9_-` symbols. // The order of characters is optimized for better gzip and brotli compression. // Same as in non-secure/index.js let urlAlphabet = 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict' module.exports = { urlAlphabet }