diff --git a/.babelrc b/.babelrc deleted file mode 100644 index af0f0c3..0000000 --- a/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["es2015"] -} \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..b1836dd --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,26 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [18.x, 20.x, 22.x] + + steps: + - uses: actions/checkout@v4 + + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: npm + + - run: npm ci + - run: npm test diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..28b4b86 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,26 @@ +name: Publish + +on: + push: + tags: + - 'v*' + +jobs: + publish: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: '20.x' + registry-url: 'https://registry.npmjs.org' + cache: npm + + - run: npm ci + - run: npm test + - run: npm run build + - run: npm publish + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.jshintrc b/.jshintrc deleted file mode 100644 index ced8315..0000000 --- a/.jshintrc +++ /dev/null @@ -1,6 +0,0 @@ -{ - "esversion": 6, - "node": true, - "browser": true, - "mocha": true -} diff --git a/.mocharc.json b/.mocharc.json new file mode 100644 index 0000000..d91c84c --- /dev/null +++ b/.mocharc.json @@ -0,0 +1,5 @@ +{ + "require": ["ts-node/register"], + "spec": "test/**/*.ts", + "reporter": "spec" +} diff --git a/.npmignore b/.npmignore index 051daff..74ffdc2 100644 --- a/.npmignore +++ b/.npmignore @@ -68,10 +68,10 @@ typings/ out gen /.npmignore -/.jshintrc -/source/ +/src/ +/test/ /.gitignore /.editorconfig -/test/ /.travis.yml -/.babelrc +/.mocharc.json +/tsconfig.json diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 13e3c28..0000000 --- a/.travis.yml +++ /dev/null @@ -1,19 +0,0 @@ -sudo: false -language: node_js -node_js: -- '7' -- '8' -before_deploy: -- npm run build -deploy: - provider: npm - email: kevin@onelittlerobot.co.uk - api_key: - secure: T+/ooMJl0bsnMXAE9eaAMuXxHTdZpsuwQvPQ1D9HMuLYYfBR+tTDVJQ2p+mvQHUepYbGE8KFc5GEnzUevJgiAzQWmQcmebNywZWCYZRDvRav5WEL08hfilF1zht4+DSiBuLoHrZ+UaoodF/G0bYa6hq+SeWQWZZV6ih23zzExjmLOZhia2FhVLHekc4MVvfN6oPzqYrYiUBwz4rf4Qr8Bxa5PZ9L8K+kq52T8k6ryOyulW0gl+Ho3mIwb7VKwrYqbHzXCZ7afMevV9mqXM55Vv8CEQjiyaXu6iAgcreyA73mn8XjRkKYSBp5zY7dM2GIqmcJywTm7s8QlyizQTA8gdg3U1aw/xXUo/TwbbR+LSB3MZ72qSVM+UJQWb0trPTLoH8+9UocFKtGAWo/kLiPHwfQVivOh+JT/NBnOAympHQ+D4jdlDcehUzChEbWDVq0mYEAVTCqLg92QiYHwLRhvpiNmbhWy6IlFTUDX1YEI3dwr2RLX2lY0Dw7vp27O4e+2SKJoiehWk0qdPiKAB16/hyya1ZgHH0a5nN+Z1OCfCfpURW/6RetWC+d03GrH2IovJLoM64OyD1GvokypcQJR1LRsH2BsTOqi4heL9MXYyg+uQUBo4oajBiUAO/K34tTShAwEfyvoXTvGsDgutPo+iClB5kTWbtSMW5s5s+ZIxo= - on: - tags: true - repo: OneLittleRobot/resistor-data - branch: master - - - diff --git a/README.md b/README.md index 2b23d4a..ac6910b 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,103 @@ -# Resistor Data [![NPM version][npm-image]][npm-url] [![Build status][travis-image]][travis-url] +# Resistor Data [![NPM version][npm-image]][npm-url] [![CI][ci-image]][ci-url] -A simple module to calculate properties for resistors. +A simple module to calculate properties for resistors. -* convert resistor bands to standard resistor notation -* convert standard resistor notation to resistor bands -* convert a number to standard resistor notation -* convert standard resistor notation to a number +* Convert resistor bands to standard resistor notation +* Convert standard resistor notation to resistor bands +* Convert a number to standard resistor notation +* Convert standard resistor notation to a number -Install Resistor Data: +## Install ```sh npm install resistor-data ``` +## Usage + +### JavaScript + ```js -var resistorData = require('resistor-data'); +const { bandsToNotation, notationToBands, notationToValue, valueToNotation } = require('resistor-data'); + +bandsToNotation(['red', 'yellow', 'black', 'brown', 'brown']); // ['2k4', 1] +notationToBands(['2k4', 1], 5); // ['red', 'yellow', 'black', 'brown', 'brown'] + +notationToValue('2k4'); // 2400 +valueToNotation(2400); // '2k4' +``` + +### TypeScript + +```ts +import { + bandsToNotation, + notationToBands, + notationToValue, + valueToNotation, +} from 'resistor-data'; +import type { ResistorColor, ResistorTolerance, ResistorData, BandCount } from 'resistor-data'; -resistorData.bandsToNotation(['red', 'yellow', 'black', 'brown', 'brown'], 5); //['2k4', 1] -resistorData.notationToBands(['2k4', 1], 5); //['red', 'yellow', 'black', 'brown', 'brown'] +// ResistorData is [notation: string, tolerance: ResistorTolerance] +const result: ResistorData = bandsToNotation(['red', 'yellow', 'black', 'brown', 'brown']); +// result => ['2k4', 1] -resistorData.notationToValue('2k4'); //2400 -resistorData.valueToNotation(2400); //'2k4' +const bands: ResistorColor[] = notationToBands(['2k4', 1], 5); +// bands => ['red', 'yellow', 'black', 'brown', 'brown'] +const value: number = notationToValue('2k4'); // 2400 +const notation: string = valueToNotation(2400); // '2k4' ``` +## API + +### `bandsToNotation(bands: string[]): ResistorData` + +Converts an array of 4 or 5 resistor band colour names into `[notation, tolerance]`. + +```ts +bandsToNotation(['orange', 'orange', 'black', 'red', 'brown']); // ['33k', 1] +``` + +### `notationToBands(data: [string, ResistorTolerance?], bands?: BandCount): ResistorColor[]` + +Converts a `[notation, tolerance]` pair into an array of colour names. `bands` defaults to `5`. + +```ts +notationToBands(['33k', 1], 4); // ['orange', 'orange', 'orange', 'brown'] +notationToBands(['33k', 1], 5); // ['orange', 'orange', 'black', 'red', 'brown'] +``` + +### `notationToValue(notation: string): number` + +Converts standard resistor notation to a numeric value. + +```ts +notationToValue('5k'); // 5000 +notationToValue('5k5'); // 5500 +notationToValue('1M2'); // 1200000 +``` + +### `valueToNotation(value: number | string): string` + +Converts a numeric value to standard resistor notation. + +```ts +valueToNotation(3000); // '3k' +valueToNotation(3300); // '3k3' +valueToNotation(1000000); // '1m' +``` + +## Types + +| Type | Description | +|---|---| +| `ResistorColor` | Union of valid band colour strings (`'black'`, `'brown'`, `'red'`, ...) | +| `ResistorTolerance` | Union of valid tolerance values (`0.05`, `0.1`, `0.25`, `0.5`, `1`, `2`, `5`, `10`, `20`) | +| `ResistorData` | Tuple returned by `bandsToNotation`: `[notation: string, tolerance: ResistorTolerance]` | +| `BandCount` | `4 \| 5` | -[travis-url]: http://travis-ci.org/OneLittleRobot/resistor-data -[travis-image]: https://secure.travis-ci.org/OneLittleRobot/resistor-data.svg?branch=master +[ci-url]: https://github.com/OneLittleRobot/resistor-data/actions/workflows/ci.yml +[ci-image]: https://github.com/OneLittleRobot/resistor-data/actions/workflows/ci.yml/badge.svg [npm-url]: https://npmjs.org/package/resistor-data -[npm-image]: https://badge.fury.io/js/resistor-data.svg \ No newline at end of file +[npm-image]: https://badge.fury.io/js/resistor-data.svg diff --git a/index.js b/index.js deleted file mode 100644 index 2e62882..0000000 --- a/index.js +++ /dev/null @@ -1,8 +0,0 @@ -var notation = require('./lib/resistor-notation'); -var bands = require('./lib/resistor-bands'); - -exports.bandsToNotation = bands.bandsToNotation; -exports.notationToBands = bands.notationToBands; - -exports.notationToValue = notation.notationToValue; -exports.valueToNotation = notation.valueToNotation; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..4e7fe1c --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1272 @@ +{ + "name": "resistor-data", + "version": "2.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "resistor-data", + "version": "2.0.0", + "license": "ISC", + "devDependencies": { + "@types/chai": "^4.3.16", + "@types/mocha": "^10.0.7", + "@types/node": "^20.0.0", + "chai": "^4.5.0", + "mocha": "^10.7.0", + "ts-node": "^10.9.2", + "typescript": "^5.5.4" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz", + "integrity": "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/chai": { + "version": "4.3.20", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.20.tgz", + "integrity": "sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mocha": { + "version": "10.0.10", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", + "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.19.42", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.42.tgz", + "integrity": "sha512-5L7SUaFC1RyDraj2yRhyBzHTobyXHmohD100CChNtyPyleoq37Mqab5Gn8XEKI04dfN/oqPdpHk38MgcQWHbZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.5", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz", + "integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", + "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true, + "license": "ISC" + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chai": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-eql": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/diff": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.2.tgz", + "integrity": "sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/js-yaml": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz", + "integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, + "license": "ISC" + }, + "node_modules/minimatch": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", + "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha": { + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", + "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/diff": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", + "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true, + "license": "MIT" + }, + "node_modules/workerpool": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json index 6f595a0..a75b209 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,13 @@ { "name": "resistor-data", - "version": "1.1.1", + "version": "2.0.0", "description": "Tools to calculate resistor data.", - "main": "index.js", + "main": "lib/index.js", + "types": "lib/index.d.ts", "scripts": { - "test": "./node_modules/.bin/mocha --compilers js:babel-core/register --reporter spec test", - "jshint": "./node_modules/.bin/jshint ./source/**.js ./test/**.js", - "build": "./node_modules/.bin/babel ./source --out-dir ./lib" + "build": "tsc", + "test": "mocha", + "prepublishOnly": "npm run build" }, "repository": { "type": "git", @@ -23,11 +24,13 @@ }, "homepage": "https://github.com/OneLittleRobot/resistor-data", "devDependencies": { - "babel-cli": "^6.24.1", - "babel-preset-es2015": "^6.24.1", - "chai": "^4.1.1", - "jshint": "^2.9.5", - "mocha": "^3.5.0" + "@types/chai": "^4.3.16", + "@types/mocha": "^10.0.7", + "@types/node": "^20.0.0", + "chai": "^4.5.0", + "mocha": "^10.7.0", + "ts-node": "^10.9.2", + "typescript": "^5.5.4" }, "dependencies": {} } diff --git a/source/lookups.js b/source/lookups.js deleted file mode 100644 index 7ccc99f..0000000 --- a/source/lookups.js +++ /dev/null @@ -1,73 +0,0 @@ -import {makeReverseMap} from './utils'; - -const colorToValueMap = { - 'black': 0, - 'brown': 1, - 'red': 2, - 'orange': 3, - 'yellow': 4, - 'green': 5, - 'blue': 6, - 'violet': 7, - 'grey': 8, - 'white': 9, - 'gold': -1, - 'silver': -2 -}; - -const colorToTolerance = { - 'brown': 1, - 'red': 2, - 'yellow': 5, - 'green': 0.5, - 'blue': 0.25, - 'violet': 0.1, - 'grey': 0.05, - 'gold': 5, - 'silver': 10, - 'none': 20 -}; -const expToSymbolMap = { - 6: 'm', - 3: 'k', - 0: '', -}; -const symbolPowerToMap = { - 'm': Math.pow(10, 6), - 'k': Math.pow(10, 3), - 'r': Math.pow(10, 0), -}; -const valueToColourMap = makeReverseMap(colorToValueMap); -const toleranceToColourMap = makeReverseMap(colorToTolerance); - -export function getToleranceFromColor(color) { - return colorToTolerance[color]; -} - -export function getColorFromTolerance(tolerance) { - return toleranceToColourMap[tolerance]; -} - -export function getColorFromValue(value) { - return valueToColourMap[value]; -} - -export function getValueFromColor(color) { - const value = colorToValueMap[color]; - if (typeof value === 'undefined') { - throw new Error(`Invalid colour ${color}`); - } - return value; -} - -export function getSymbolFromExp(exp) { - return expToSymbolMap[exp]; -} - -export function getPowerFromSymbol(symbol) { - const value = symbolPowerToMap[symbol.toLowerCase()]; - if (typeof value === 'undefined') { - throw new Error(`Invalid symbol ${symbol}`); - } - return value; -} diff --git a/source/resistor-bands.js b/source/resistor-bands.js deleted file mode 100644 index 32d44d5..0000000 --- a/source/resistor-bands.js +++ /dev/null @@ -1,45 +0,0 @@ -import {notationToValue, valueToNotation} from './resistor-notation'; -import {getExponentialFor10} from './utils'; -import {getColorFromTolerance, getValueFromColor, getToleranceFromColor, getColorFromValue} from './lookups'; - -export const bandsToNotation = (bands = []) => { - if (!Array.isArray(bands)) { - throw new TypeError('Expected an array'); - } else if (bands.length < 4 || bands.length > 5) { - throw new Error('A resistor should have 4 or 5 bands'); - } - const clone = bands.slice(0); - const tolerance = getToleranceFromColor(clone.pop()); - const exp = getValueFromColor(clone.pop()); - - const value = clone - .reverse() - .reduce((sum, current, currentIndex) => { - return sum + (getValueFromColor(current) * Math.pow(10, currentIndex)); - }, 0) * (Math.pow(10, exp)); - - return [valueToNotation(value), tolerance]; -}; - -export const notationToBands = (data, bands = 5) => { - - if (!Array.isArray(data)) { - throw new TypeError('Expected an array'); - } - - const value = notationToValue(data[0]); - const tolerance = data[1] || 1; - const digits = (value * 1000) - .toString() - .split('') - .slice(0, bands - 2); - - const exp = getExponentialFor10(value / (digits.join(''))); - - return digits.map((item) => { - return getColorFromValue(item); - }).concat([ - getColorFromValue(exp), - getColorFromTolerance(tolerance) - ]); -}; diff --git a/source/resistor-notation.js b/source/resistor-notation.js deleted file mode 100644 index 16c56c0..0000000 --- a/source/resistor-notation.js +++ /dev/null @@ -1,42 +0,0 @@ -import {roundToStandard, getExponentialFor10} from './utils'; -import {getPowerFromSymbol, getSymbolFromExp} from './lookups'; - -const validRegex = /\d+\.?\d*\D?\d*/; -const matchRegex = /[\D]/i; - -export const notationToValue = (notation = '') => { - - if (!validRegex.test(notation)) { - throw new Error('Invalid string'); - } - let value = notation; - if (typeof notation === 'string' && notation.trim()) { - let match = matchRegex.exec(notation) || ['r']; - const symbol = match[0]; - const multiplier = getPowerFromSymbol(symbol); - value = notation.split(symbol).join('.') * multiplier; - } - return parseInt(value, 10); -}; - -export const valueToNotation = (value) => { - - if (value === '') { - throw new Error('Invalid value'); - } - - if (isNaN(value)) { - throw new Error('Invalid value'); - } - - const exp = roundToStandard(getExponentialFor10(value)); - const multiplier = Math.pow(10, exp); - const res = (value / multiplier).toString(); - let notation; - if (res.indexOf('.') == '-1') { - notation = res + getSymbolFromExp(exp); - } else { - notation = res.split('.').join(getSymbolFromExp(exp)); - } - return notation; -}; diff --git a/source/utils.js b/source/utils.js deleted file mode 100644 index 622b8be..0000000 --- a/source/utils.js +++ /dev/null @@ -1,22 +0,0 @@ -export const getExponentialFor10 = (value) => { - const strValue = Math.abs(value).toString(); - if (strValue.includes('.')) { - return -strValue.split('.')[1].length; - } else { - return strValue.length - 1; - } -}; - -export const roundToStandard = (value) => { - return Math.floor(value / 3) * 3; -}; - -export const makeReverseMap = (forwardMap) => { - const reverseMap = {}; - for (const key in forwardMap) { - if (forwardMap.hasOwnProperty(key)) { - reverseMap[forwardMap[key]] = key; - } - } - return reverseMap; -}; \ No newline at end of file diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..1473499 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,3 @@ +export type { ResistorColor, BandCount, ResistorTolerance, ResistorData } from './types'; +export { bandsToNotation, notationToBands } from './resistor-bands'; +export { notationToValue, valueToNotation } from './resistor-notation'; diff --git a/src/lookups.ts b/src/lookups.ts new file mode 100644 index 0000000..65d1487 --- /dev/null +++ b/src/lookups.ts @@ -0,0 +1,77 @@ +import type { ResistorColor, ResistorTolerance } from './types'; +import { makeReverseMap } from './utils'; + +const colorToValueMap: Record = { + black: 0, + brown: 1, + red: 2, + orange: 3, + yellow: 4, + green: 5, + blue: 6, + violet: 7, + grey: 8, + white: 9, + gold: -1, + silver: -2, +}; + +const colorToTolerance: Record = { + brown: 1, + red: 2, + yellow: 5, + green: 0.5, + blue: 0.25, + violet: 0.1, + grey: 0.05, + gold: 5, + silver: 10, + none: 20, +}; + +const expToSymbolMap: Record = { + 6: 'm', + 3: 'k', + 0: '', +}; + +const symbolPowerToMap: Record = { + m: Math.pow(10, 6), + k: Math.pow(10, 3), + r: Math.pow(10, 0), +}; + +const valueToColourMap = makeReverseMap(colorToValueMap); +const toleranceToColourMap = makeReverseMap(colorToTolerance); + +export function getToleranceFromColor(color: string): ResistorTolerance { + return colorToTolerance[color] as ResistorTolerance; +} + +export function getColorFromTolerance(tolerance: number): ResistorColor { + return toleranceToColourMap[tolerance] as ResistorColor; +} + +export function getColorFromValue(value: number): ResistorColor { + return valueToColourMap[value] as ResistorColor; +} + +export function getValueFromColor(color: string): number { + const value = colorToValueMap[color]; + if (typeof value === 'undefined') { + throw new Error(`Invalid colour ${color}`); + } + return value; +} + +export function getSymbolFromExp(exp: number): string { + return expToSymbolMap[exp] ?? ''; +} + +export function getPowerFromSymbol(symbol: string): number { + const value = symbolPowerToMap[symbol.toLowerCase()]; + if (typeof value === 'undefined') { + throw new Error(`Invalid symbol ${symbol}`); + } + return value; +} diff --git a/src/resistor-bands.ts b/src/resistor-bands.ts new file mode 100644 index 0000000..36b5135 --- /dev/null +++ b/src/resistor-bands.ts @@ -0,0 +1,45 @@ +import { notationToValue, valueToNotation } from './resistor-notation'; +import { getExponentialFor10 } from './utils'; +import { getColorFromTolerance, getValueFromColor, getToleranceFromColor, getColorFromValue } from './lookups'; +import type { ResistorColor, BandCount, ResistorTolerance, ResistorData } from './types'; + +export const bandsToNotation = (bands: string[] = []): ResistorData => { + if (!Array.isArray(bands)) { + throw new TypeError('Expected an array'); + } else if (bands.length < 4 || bands.length > 5) { + throw new Error('A resistor should have 4 or 5 bands'); + } + + const clone = [...bands]; + const tolerance = getToleranceFromColor(clone.pop()!); + const exp = getValueFromColor(clone.pop()!); + + const value = clone + .reverse() + .reduce((sum, current, currentIndex) => { + return sum + (getValueFromColor(current) * Math.pow(10, currentIndex)); + }, 0) * Math.pow(10, exp); + + return [valueToNotation(value), tolerance]; +}; + +export const notationToBands = (data: [string, ResistorTolerance?], bands: BandCount = 5): ResistorColor[] => { + if (!Array.isArray(data)) { + throw new TypeError('Expected an array'); + } + + const value = notationToValue(data[0]); + const tolerance: number = data[1] ?? 1; + const digits = (value * 1000) + .toString() + .split('') + .slice(0, bands - 2); + + const exp = getExponentialFor10(value / Number(digits.join(''))); + + return [ + ...digits.map(d => getColorFromValue(Number(d))), + getColorFromValue(exp), + getColorFromTolerance(tolerance), + ]; +}; diff --git a/src/resistor-notation.ts b/src/resistor-notation.ts new file mode 100644 index 0000000..10a8e95 --- /dev/null +++ b/src/resistor-notation.ts @@ -0,0 +1,39 @@ +import { roundToStandard, getExponentialFor10 } from './utils'; +import { getPowerFromSymbol, getSymbolFromExp } from './lookups'; + +const validRegex = /\d+\.?\d*\D?\d*/; +const matchRegex = /[\D]/i; + +export const notationToValue = (notation = ''): number => { + if (!validRegex.test(notation)) { + throw new Error('Invalid string'); + } + + let value: number; + if (typeof notation === 'string' && notation.trim()) { + const match = matchRegex.exec(notation) ?? ['r']; + const symbol = match[0]; + const multiplier = getPowerFromSymbol(symbol); + value = Number(notation.split(symbol).join('.')) * multiplier; + } else { + value = Number(notation); + } + return parseInt(String(value), 10); +}; + +export const valueToNotation = (value: number | string): string => { + if (value === '' || isNaN(Number(value))) { + throw new Error('Invalid value'); + } + + const numValue = Number(value); + const exp = roundToStandard(getExponentialFor10(numValue)); + const multiplier = Math.pow(10, exp); + const res = (numValue / multiplier).toString(); + + if (res.indexOf('.') === -1) { + return res + getSymbolFromExp(exp); + } else { + return res.split('.').join(getSymbolFromExp(exp)); + } +}; diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..edac2f0 --- /dev/null +++ b/src/types.ts @@ -0,0 +1,10 @@ +export type ResistorColor = + | 'black' | 'brown' | 'red' | 'orange' | 'yellow' + | 'green' | 'blue' | 'violet' | 'grey' | 'white' + | 'gold' | 'silver' | 'none'; + +export type BandCount = 4 | 5; + +export type ResistorTolerance = 0.05 | 0.1 | 0.25 | 0.5 | 1 | 2 | 5 | 10 | 20; + +export type ResistorData = [notation: string, tolerance: ResistorTolerance]; diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 0000000..63c821a --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,22 @@ +export const getExponentialFor10 = (value: number): number => { + const strValue = Math.abs(value).toString(); + if (strValue.includes('.')) { + return -strValue.split('.')[1].length; + } else { + return strValue.length - 1; + } +}; + +export const roundToStandard = (value: number): number => { + return Math.floor(value / 3) * 3; +}; + +export const makeReverseMap = (forwardMap: Record): Record => { + const reverseMap: Record = {}; + for (const key in forwardMap) { + if (Object.prototype.hasOwnProperty.call(forwardMap, key)) { + reverseMap[forwardMap[key]] = key; + } + } + return reverseMap; +}; diff --git a/test/resistor-bands.ts b/test/resistor-bands.ts new file mode 100644 index 0000000..432b702 --- /dev/null +++ b/test/resistor-bands.ts @@ -0,0 +1,144 @@ +import { assert } from 'chai'; +import { bandsToNotation, notationToBands } from '../src'; + +describe('Error Resistor Bands to Resistor Notation', () => { + + it('asserts not an array throws an error', () => { + assert.throws(() => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + bandsToNotation('banjo' as any); + }, TypeError, 'Expected an array'); + }); + + it('asserts no bands throws an error', () => { + assert.throws(() => { + bandsToNotation([]); + }, Error, 'A resistor should have 4 or 5 bands'); + }); + + it('assert not enough bands throws an error', () => { + assert.throws(() => { + bandsToNotation(['red', 'yellow', 'black']); + }, Error, 'A resistor should have 4 or 5 bands'); + }); + + it('asserts too many bands throws an error', () => { + assert.throws(() => { + bandsToNotation(['red', 'yellow', 'black', 'brown', 'brown', 'brown']); + }, Error, 'A resistor should have 4 or 5 bands'); + }); + + it('asserts invalid values throws an error', () => { + assert.throws(() => { + bandsToNotation(['pink', 'banjo', 'ham sandwich', 'monkey', 'woo']); + }, Error); + }); + +}); + +describe('Resistor Bands to Resistor Notation', () => { + + it('2k4 - 5 bands', () => { + assert.deepEqual(bandsToNotation(['red', 'yellow', 'black', 'brown', 'brown']), ['2k4', 1]); + }); + + it('33k - 5 bands', () => { + assert.deepEqual(bandsToNotation(['orange', 'orange', 'black', 'red', 'brown']), ['33k', 1]); + }); + + it('2k4 - 4 bands', () => { + assert.deepEqual(bandsToNotation(['red', 'yellow', 'red', 'brown']), ['2k4', 1]); + }); + + it('33k - 4 bands', () => { + assert.deepEqual(bandsToNotation(['orange', 'orange', 'orange', 'brown']), ['33k', 1]); + }); + +}); + +describe('Error Resistor Notation to Resistor Bands', () => { + + it('asserts not an array throws an error', () => { + assert.throws(() => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + notationToBands('not an array' as any, 5); + }, TypeError, 'Expected an array'); + }); + +}); + +describe('Resistor Notation to Resistor Bands', () => { + + it('2k4 - 5 bands', () => { + assert.deepEqual(notationToBands(['2k4', 0.5], 5), ['red', 'yellow', 'black', 'brown', 'green']); + }); + + it('1 - 5 bands', () => { + assert.deepEqual(notationToBands(['1', 0.5], 5), ['brown', 'black', 'black', 'silver', 'green']); + }); + + it('3M - 5 bands', () => { + assert.deepEqual(notationToBands(['3M', 0.5], 5), ['orange', 'black', 'black', 'yellow', 'green']); + }); + + it('2k4 - 4 bands', () => { + assert.deepEqual(notationToBands(['2k4', 0.5], 4), ['red', 'yellow', 'red', 'green']); + }); + + it('1 - 4 bands', () => { + assert.deepEqual(notationToBands(['1', 0.5], 4), ['brown', 'black', 'gold', 'green']); + }); + + it('3M - 4 bands', () => { + assert.deepEqual(notationToBands(['3M', 0.5], 4), ['orange', 'black', 'green', 'green']); + }); + + it('assert defaults to 5 bands', () => { + assert.deepEqual(notationToBands(['3M', 0.5]), ['orange', 'black', 'black', 'yellow', 'green']); + }); + + it('assert defaults to 1% tolerance', () => { + assert.deepEqual(notationToBands(['3M']), ['orange', 'black', 'black', 'yellow', 'brown']); + }); + +}); + +describe('Resistor Bands to Resistor Notation - Tolerance', () => { + + it('1%', () => { + assert.deepEqual(bandsToNotation(['red', 'yellow', 'black', 'brown', 'brown']), ['2k4', 1]); + }); + + it('2%', () => { + assert.deepEqual(bandsToNotation(['red', 'yellow', 'black', 'brown', 'red']), ['2k4', 2]); + }); + + it('0.5%', () => { + assert.deepEqual(bandsToNotation(['red', 'yellow', 'black', 'brown', 'green']), ['2k4', 0.5]); + }); + + it('0.25%', () => { + assert.deepEqual(bandsToNotation(['red', 'yellow', 'black', 'brown', 'blue']), ['2k4', 0.25]); + }); + + it('0.1%', () => { + assert.deepEqual(bandsToNotation(['red', 'yellow', 'black', 'brown', 'violet']), ['2k4', 0.1]); + }); + + it('0.05%', () => { + assert.deepEqual(bandsToNotation(['red', 'yellow', 'black', 'brown', 'grey']), ['2k4', 0.05]); + }); + + it('5%', () => { + assert.deepEqual(bandsToNotation(['red', 'yellow', 'black', 'brown', 'gold']), ['2k4', 5]); + }); + + it('10%', () => { + assert.deepEqual(bandsToNotation(['red', 'yellow', 'black', 'brown', 'silver']), ['2k4', 10]); + }); + + it('20%', () => { + assert.deepEqual(bandsToNotation(['red', 'yellow', 'black', 'brown', 'none']), ['2k4', 20]); + }); + +}); diff --git a/test/resistor-notation.ts b/test/resistor-notation.ts new file mode 100644 index 0000000..be3bed5 --- /dev/null +++ b/test/resistor-notation.ts @@ -0,0 +1,110 @@ +import { assert } from 'chai'; +import { notationToValue, valueToNotation } from '../src'; + +describe('Error Notation to Number', () => { + + it('throws an error for an invalid symbol', () => { + assert.throws(() => { + notationToValue('5p'); + }, Error, 'Invalid symbol p'); + }); + + it('throws an error for invalid notation', () => { + assert.throws(() => { + notationToValue('I am not valid'); + }, Error, 'Invalid string'); + }); + +}); + +describe('Resistor notation to Number', () => { + + it('asserts 5 is a number', () => { + assert.isNumber(notationToValue('5'), 'Resistor notation 5 is a number'); + }); + + it('asserts 5k is a number', () => { + assert.isNumber(notationToValue('5k'), 'Resistor notation 5k is a number'); + }); + + it('asserts 5k5 is a number', () => { + assert.isNumber(notationToValue('5k5'), 'Resistor notation 5k5 is a number'); + }); + + it('asserts 5k', () => { + assert.equal(notationToValue('5k'), 5000, 'Resistor notation 5k = 5000'); + }); + + it('asserts 5k5', () => { + assert.equal(notationToValue('5k5'), 5500, 'Resistor notation 5k5 = 5500'); + }); + + it('asserts 1', () => { + assert.equal(notationToValue('1'), 1, 'Resistor notation 1 = 1'); + }); + + it('asserts 1M', () => { + assert.equal(notationToValue('1M'), 1000000, 'Resistor notation 1M = 1000000'); + }); + + it('asserts 1M2', () => { + assert.equal(notationToValue('1M2'), 1200000, 'Resistor notation 1M2 = 1200000'); + }); + +}); + +describe('Error Number to Resistor notation', () => { + + it('assert throws an error for invalid value', () => { + assert.throws(() => { + valueToNotation('woo'); + }, Error, 'Invalid value'); + }); + + it('assert throws an error for invalid value', () => { + assert.throws(() => { + valueToNotation(''); + }, Error, 'Invalid value'); + }); + +}); + +describe('Number to Resistor notation', () => { + + it('3 is a string', () => { + assert.isString(valueToNotation(3), 'Resistor notation 5 is a string'); + }); + + it('3k is a string', () => { + assert.isString(valueToNotation(3000), 'Resistor notation 5k is a string'); + }); + + it('3k3 is a string', () => { + assert.isString(valueToNotation(3300), 'Resistor notation 5k5 is a string'); + }); + + it('3k', () => { + assert.equal(valueToNotation('3000'), '3k', 'String 3000 = 3k'); + }); + + it('3k', () => { + assert.equal(valueToNotation(3000), '3k', 'Number 300 = 3k'); + }); + + it('3k3', () => { + assert.equal(valueToNotation(3300), '3k3', 'Number 3300 = 3k3'); + }); + + it('1', () => { + assert.equal(valueToNotation(1), '1', 'Number 1 = 1'); + }); + + it('1M', () => { + assert.equal(valueToNotation(1000000), '1m', 'Number 1000000 = 1m'); + }); + + it('2M2', () => { + assert.equal(valueToNotation(2200000), '2m2', 'Number 2200000 = 2m2'); + }); + +}); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..bccbba9 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "commonjs", + "lib": ["ES2020"], + "outDir": "./lib", + "rootDir": "./src", + "strict": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "esModuleInterop": true, + "skipLibCheck": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "lib", "test"], + "ts-node": { + "transpileOnly": true, + "compilerOptions": { + "module": "commonjs" + } + } +}