diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000..fca472f --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,6 @@ +module.exports = { + root: true, + parser: "@typescript-eslint/parser", + plugins: ["@typescript-eslint"], + extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"], +}; diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 3eee580..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "extends": "eslint:recommended", - "env": { - "node": true, - "es6": true, - "mocha": true - }, - "parserOptions": { - "ecmaVersion": 6, - "sourceType": "module" - }, - "plugins": [ - "mocha" - ], - "rules": { - "semi": "error", - "no-extra-boolean-cast": "off", - "no-useless-escape": "off" - } -} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..3ed19ae --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,34 @@ +name: Run tests + +on: + push: + branches: [ main, master ] + pull_request: + branches: [ main, master ] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Use Node.js 14.x + uses: actions/setup-node@v2 + with: + node-version: 14.x + - name: Install dependencies + run: npm ci + - run: npm run build --if-present + - run: npm test + + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Use Node.js 14.x + uses: actions/setup-node@v2 + with: + node-version: 14.x + - name: Install dependencies + run: npm ci + - run: npm run build --if-present + - run: npm run lint diff --git a/.gitignore b/.gitignore index 2b380c5..74acf84 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ npm-debug.log node_modules lib testDist +yarn-error.log \ No newline at end of file diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 0000000..2e7b6cb --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,7 @@ +module.exports = { + bracketSpacing: false, + jsxBracketSameLine: true, + singleQuote: true, + trailingComma: 'all', + arrowParens: 'avoid' +}; diff --git a/.vscode/settings.json b/.vscode/settings.json index c56f759..bffa885 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,5 +8,9 @@ "**/.DS_Store": true, "node_modules": true, "lib": true + }, + "[typescript]": { + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode" } } diff --git a/README.md b/README.md index 8b9c0c6..fae6554 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,11 @@ This project was built on top of code written by [nsafai](https://github.com/nsa What's different from the original? -- added support for the Italian language. -- added support for numbers written in words (for example `six cups milk`) -- added support for preposition before name of ingredient (for example `six cups of milk` or `sei tazze di latte`) +- No longer uses the "natural" library +- Works with Node.js, browser, React Native +- Added support for the Italian and German languages. +- Added support for numbers written in words (for example `six cups milk`) +- Added support for preposition before name of ingredient (for example `six cups of milk` or `sei tazze di latte`) ## To install @@ -74,6 +76,7 @@ Will return Languages currently supported: - English `eng` +- German `deu` - Italian `ita` ### Unicode Fractions @@ -84,10 +87,6 @@ Will also correctly parse unicode fractions into the proper amount Clone the repo and `yarn` to install packages. If `yarn test` comes back good after your code changes, give yourself a pat on the back. -## Natural Language Parsing - -This project uses Natural, for more information, see https://dzone.com/articles/using-natural-nlp-module - ### Publishing Checkout https://docs.npmjs.com/getting-started/publishing-npm-packages for more info diff --git a/next.config.js b/next.config.js deleted file mode 100644 index 8eaca55..0000000 --- a/next.config.js +++ /dev/null @@ -1,12 +0,0 @@ -module.exports = { - webpack: (config, { isServer }) => { - // Fixes npm packages that depend on `fs` module - if (!isServer) { - config.node = { - fs: "empty", - }; - } - - return config; - }, -}; diff --git a/package-lock.json b/package-lock.json index 4f265de..c25ebde 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,431 +1,4272 @@ { "name": "recipe-ingredient-parser-v3", "version": "1.2.16", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "recipe-ingredient-parser-v3", + "version": "1.2.16", + "license": "MIT", + "dependencies": { + "@types/node": "^10.5.1" + }, + "devDependencies": { + "@types/chai": "^4.1.4", + "@types/mocha": "^5.2.4", + "@typescript-eslint/eslint-plugin": "^5.27.1", + "@typescript-eslint/parser": "^5.27.1", + "chai": "^4.1.0", + "eslint": "^8.17.0", + "mocha": "^5.2.0", + "nodemon": "^2.0.14", + "prettier": "^2.6.2", + "tslint": "^5.10.0", + "typescript": "^4.2.3" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.16.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/highlight": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.16.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.17.12", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@eslint/eslintrc": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.3.2", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.9.5", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@sindresorhus/is": { + "version": "0.14.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "defer-to-connect": "^1.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@types/chai": { + "version": "4.3.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mocha": { + "version": "5.2.7", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "10.17.60", + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "5.27.1", + "@typescript-eslint/type-utils": "5.27.1", + "@typescript-eslint/utils": "5.27.1", + "debug": "^4.3.4", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.2.0", + "regexpp": "^3.2.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.3.7", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.27.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "5.27.1", + "@typescript-eslint/types": "5.27.1", + "@typescript-eslint/typescript-estree": "5.27.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "5.27.1", + "@typescript-eslint/visitor-keys": "5.27.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "5.27.1", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.27.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.27.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "5.27.1", + "@typescript-eslint/visitor-keys": "5.27.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.3.7", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.27.1", + "@typescript-eslint/types": "5.27.1", + "@typescript-eslint/typescript-estree": "5.27.1", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { + "version": "5.1.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/estraverse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "5.27.1", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/abbrev": { + "version": "1.1.1", + "dev": true, + "license": "ISC" + }, + "node_modules/acorn": { + "version": "8.7.1", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "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.2", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/array-union": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-align": "^3.0.0", + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.2", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "dev": true, + "license": "ISC" + }, + "node_modules/builtin-modules": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cacheable-request": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cacheable-request/node_modules/lowercase-keys": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chai": { + "version": "4.3.6", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "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/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/check-error": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "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" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/ci-info": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/cli-boxes": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clone-response": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^1.0.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "2.15.1", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/configstore": { + "version": "5.0.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-random-string": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decompress-response": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/deep-eql": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/defer-to-connect": { + "version": "1.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/diff": { + "version": "3.5.0", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/duplexer3": { + "version": "0.1.4", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/escape-goat": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint": { + "version": "8.17.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint/eslintrc": "^1.3.0", + "@humanwhocodes/config-array": "^0.9.2", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.2", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "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.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-scope": { + "version": "7.1.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/espree": { + "version": "9.3.2", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.7.1", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.2.11", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.13.0", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.5", + "dev": true, + "license": "ISC" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.2", + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/get-func-name": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/get-stream": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/global-dirs": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globals": { + "version": "13.15.0", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/got": { + "version": "9.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "dev": true, + "license": "ISC" + }, + "node_modules/growl": { + "version": "1.10.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.x" + } + }, + "node_modules/has": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-yarn": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/he": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.0", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/ignore": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-lazy": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "license": "ISC" + }, + "node_modules/ini": { + "version": "2.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-ci": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.9.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-installed-globally": { + "version": "0.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-npm": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/is-yarn-global": { + "version": "0.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/keyv": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.0" + } + }, + "node_modules/latest-version": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "package-json": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "dev": true, + "license": "MIT" + }, + "node_modules/loupe": { + "version": "2.3.4", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.0" + } + }, + "node_modules/lowercase-keys": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.6", + "dev": true, + "license": "MIT" + }, + "node_modules/mkdirp": { + "version": "0.5.1", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "0.0.8" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mkdirp/node_modules/minimist": { + "version": "0.0.8", + "dev": true, + "license": "MIT" + }, + "node_modules/mocha": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.5", + "he": "1.1.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "5.4.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/mocha/node_modules/debug": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/mocha/node_modules/glob": { + "version": "7.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mocha/node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "3.0.4", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mocha/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "5.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/nodemon": { + "version": "2.0.16", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.8", + "semver": "^5.7.1", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5", + "update-notifier": "^5.1.0" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/nodemon/node_modules/ms": { + "version": "2.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/nodemon/node_modules/semver": { + "version": "5.7.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/nopt": { + "version": "1.0.10", + "dev": true, + "license": "MIT", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "4.5.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-cancelable": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json": { + "version": "6.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pathval": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prepend-http": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/prettier": { + "version": "2.6.2", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "dev": true, + "license": "MIT" + }, + "node_modules/pump": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pupa": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-goat": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "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/rc": { + "version": "1.2.8", + "dev": true, + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/ini": { + "version": "1.3.8", + "dev": true, + "license": "ISC" + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/registry-auth-token": { + "version": "4.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "rc": "^1.2.8" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/registry-url": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "rc": "^1.2.8" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve": { + "version": "1.22.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/responselike": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "lowercase-keys": "^1.0.0" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "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", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/semver": { + "version": "6.3.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/semver-diff": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "dev": true, + "license": "ISC" + }, + "node_modules/slash": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/string-width": { + "version": "4.2.3", + "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", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/to-readable-stream": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/touch": { + "version": "3.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "nopt": "~1.0.10" + }, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "dev": true, + "license": "0BSD" + }, + "node_modules/tslint": { + "version": "5.20.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.8.0", + "tsutils": "^2.29.0" + }, + "bin": { + "tslint": "bin/tslint" + }, + "engines": { + "node": ">=4.8.0" + }, + "peerDependencies": { + "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev" + } + }, + "node_modules/tslint/node_modules/ansi-styles": { + "version": "3.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslint/node_modules/argparse": { + "version": "1.0.10", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/tslint/node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslint/node_modules/color-convert": { + "version": "1.9.3", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/tslint/node_modules/color-name": { + "version": "1.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/tslint/node_modules/commander": { + "version": "2.20.3", + "dev": true, + "license": "MIT" + }, + "node_modules/tslint/node_modules/diff": { + "version": "4.0.2", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tslint/node_modules/js-yaml": { + "version": "3.14.1", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/tslint/node_modules/mkdirp": { + "version": "0.5.6", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/tslint/node_modules/semver": { + "version": "5.7.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/tslint/node_modules/tsutils": { + "version": "2.29.0", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^1.8.1" + }, + "peerDependencies": { + "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" + } + }, + "node_modules/tsutils": { + "version": "3.21.0", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "4.7.3", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/unique-string": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/update-notifier": { + "version": "5.1.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boxen": "^5.0.0", + "chalk": "^4.1.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.4.0", + "is-npm": "^5.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.1.0", + "pupa": "^2.1.1", + "semver": "^7.3.4", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/yeoman/update-notifier?sponsor=1" + } + }, + "node_modules/update-notifier/node_modules/semver": { + "version": "7.3.7", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-parse-lax": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "prepend-http": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/widest-line": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "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", + "dev": true, + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/xdg-basedir": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "license": "ISC" + } + }, "dependencies": { "@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "version": "7.16.7", + "dev": true, + "requires": { + "@babel/highlight": "^7.16.7" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.16.7", + "dev": true + }, + "@babel/highlight": { + "version": "7.17.12", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "dev": true + } + } + }, + "@eslint/eslintrc": { + "version": "1.3.0", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.3.2", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + } + }, + "@humanwhocodes/config-array": { + "version": "0.9.5", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "dev": true + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@sindresorhus/is": { + "version": "0.14.0", + "dev": true + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "dev": true, + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "@types/chai": { + "version": "4.3.1", + "dev": true + }, + "@types/json-schema": { + "version": "7.0.11", + "dev": true + }, + "@types/mocha": { + "version": "5.2.7", + "dev": true + }, + "@types/node": { + "version": "10.17.60" + }, + "@typescript-eslint/eslint-plugin": { + "version": "5.27.1", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.27.1", + "@typescript-eslint/type-utils": "5.27.1", + "@typescript-eslint/utils": "5.27.1", + "debug": "^4.3.4", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.2.0", + "regexpp": "^3.2.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "dependencies": { + "semver": { + "version": "7.3.7", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/parser": { + "version": "5.27.1", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.27.1", + "@typescript-eslint/types": "5.27.1", + "@typescript-eslint/typescript-estree": "5.27.1", + "debug": "^4.3.4" + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.27.1", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.27.1", + "@typescript-eslint/visitor-keys": "5.27.1" + } + }, + "@typescript-eslint/type-utils": { + "version": "5.27.1", + "dev": true, + "requires": { + "@typescript-eslint/utils": "5.27.1", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/types": { + "version": "5.27.1", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.27.1", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.27.1", + "@typescript-eslint/visitor-keys": "5.27.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "dependencies": { + "semver": { + "version": "7.3.7", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/utils": { + "version": "5.27.1", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.27.1", + "@typescript-eslint/types": "5.27.1", + "@typescript-eslint/typescript-estree": "5.27.1", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "dependencies": { + "eslint-scope": { + "version": "5.1.1", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "estraverse": { + "version": "4.3.0", + "dev": true + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.27.1", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.27.1", + "eslint-visitor-keys": "^3.3.0" + } + }, + "abbrev": { + "version": "1.1.1", + "dev": true + }, + "acorn": { + "version": "8.7.1", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.2", + "dev": true, + "requires": {} + }, + "ajv": { + "version": "6.12.6", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-align": { + "version": "3.0.1", + "dev": true, + "requires": { + "string-width": "^4.1.0" + } + }, + "ansi-regex": { + "version": "5.0.1", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.2", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "2.0.1", + "dev": true + }, + "array-union": { + "version": "2.1.0", + "dev": true + }, + "assertion-error": { + "version": "1.1.0", + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "dev": true + }, + "binary-extensions": { + "version": "2.2.0", + "dev": true + }, + "boxen": { + "version": "5.1.2", + "dev": true, + "requires": { + "ansi-align": "^3.0.0", + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.2", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "dev": true + }, + "builtin-modules": { + "version": "1.1.1", + "dev": true + }, + "cacheable-request": { + "version": "6.1.0", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "dev": true + } + } + }, + "callsites": { + "version": "3.1.0", + "dev": true + }, + "camelcase": { + "version": "6.3.0", + "dev": true + }, + "chai": { + "version": "4.3.6", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "4.1.2", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "check-error": { + "version": "1.0.2", + "dev": true + }, + "chokidar": { + "version": "3.5.3", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.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" + } + }, + "ci-info": { + "version": "2.0.0", + "dev": true + }, + "cli-boxes": { + "version": "2.2.1", + "dev": true + }, + "clone-response": { + "version": "1.0.2", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "dev": true + }, + "commander": { + "version": "2.15.1", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "dev": true + }, + "configstore": { + "version": "5.0.1", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + } + }, + "cross-spawn": { + "version": "7.0.3", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "crypto-random-string": { + "version": "2.0.0", + "dev": true + }, + "debug": { + "version": "4.3.4", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "decompress-response": { + "version": "3.3.0", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "deep-eql": { + "version": "3.0.1", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "dev": true + }, + "deep-is": { + "version": "0.1.4", + "dev": true + }, + "defer-to-connect": { + "version": "1.1.3", + "dev": true + }, + "diff": { + "version": "3.5.0", + "dev": true + }, + "dir-glob": { + "version": "3.0.1", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dot-prop": { + "version": "5.3.0", + "dev": true, + "requires": { + "is-obj": "^2.0.0" + } + }, + "duplexer3": { + "version": "0.1.4", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "escape-goat": { + "version": "2.1.1", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "dev": true + }, + "eslint": { + "version": "8.17.0", + "dev": true, + "requires": { + "@eslint/eslintrc": "^1.3.0", + "@humanwhocodes/config-array": "^0.9.2", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.2", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "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.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "escape-string-regexp": { + "version": "4.0.0", + "dev": true + }, + "glob-parent": { + "version": "6.0.2", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + } + } + }, + "eslint-scope": { + "version": "7.1.1", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-utils": { + "version": "3.0.0", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "3.3.0", + "dev": true + }, + "espree": { + "version": "9.3.2", + "dev": true, + "requires": { + "acorn": "^8.7.1", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + } + }, + "esprima": { + "version": "4.0.1", + "dev": true + }, + "esquery": { + "version": "1.4.0", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + } + }, + "esrecurse": { + "version": "4.3.0", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "dev": true + }, + "fast-glob": { + "version": "3.2.11", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "dev": true + }, + "fastq": { + "version": "1.13.0", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "fill-range": { + "version": "7.0.1", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "flat-cache": { + "version": "3.0.4", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.5", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "glob": { + "version": "7.2.3", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "global-dirs": { + "version": "3.0.0", + "dev": true, + "requires": { + "ini": "2.0.0" + } + }, + "globals": { + "version": "13.15.0", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "globby": { + "version": "11.1.0", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "got": { + "version": "9.6.0", "dev": true, "requires": { - "@babel/highlight": "^7.12.13" + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" } }, - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "graceful-fs": { + "version": "4.2.10", "dev": true }, - "@babel/highlight": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", - "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", + "growl": { + "version": "1.10.5", + "dev": true + }, + "has": { + "version": "1.0.3", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" + "function-bind": "^1.1.1" } }, - "@types/chai": { - "version": "4.2.15", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.15.tgz", - "integrity": "sha512-rYff6FI+ZTKAPkJUoyz7Udq3GaoDZnxYDEvdEdFZASiA7PoErltHezDishqQiSDWrGxvxmplH304jyzQmjp0AQ==", + "has-flag": { + "version": "3.0.0", "dev": true }, - "@types/mocha": { - "version": "5.2.7", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", - "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==", + "has-yarn": { + "version": "2.1.0", "dev": true }, - "@types/node": { - "version": "10.17.56", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.56.tgz", - "integrity": "sha512-LuAa6t1t0Bfw4CuSR0UITsm1hP17YL+u82kfHGrHUWdhlBtH7sa7jGY5z7glGaIj/WDYDkRtgGd+KCjCzxBW1w==" + "he": { + "version": "1.1.1", + "dev": true }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "http-cache-semantics": { + "version": "4.1.0", + "dev": true + }, + "ignore": { + "version": "5.2.0", + "dev": true + }, + "ignore-by-default": { + "version": "1.0.1", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", "dev": true, "requires": { - "color-convert": "^1.9.0" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" } }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "import-lazy": { + "version": "2.1.0", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "dev": true + }, + "inflight": { + "version": "1.0.6", "dev": true, "requires": { - "sprintf-js": "~1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "inherits": { + "version": "2.0.4", "dev": true }, - "balanced-match": { + "ini": { + "version": "2.0.0", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-ci": { + "version": "2.0.0", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.9.0", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-extglob": { + "version": "2.1.1", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-installed-globally": { + "version": "0.4.0", + "dev": true, + "requires": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + } + }, + "is-npm": { + "version": "5.0.0", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "dev": true + }, + "is-obj": { + "version": "2.0.0", + "dev": true + }, + "is-path-inside": { + "version": "3.0.3", + "dev": true + }, + "is-typedarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "is-yarn-global": { + "version": "0.3.0", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", "dev": true, "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "argparse": "^2.0.1" } }, - "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==", + "json-buffer": { + "version": "3.0.0", "dev": true }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "json-schema-traverse": { + "version": "0.4.1", "dev": true }, - "chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "dev": true + }, + "keyv": { + "version": "3.1.0", "dev": true, "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" + "json-buffer": "3.0.0" } }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "latest-version": { + "version": "5.1.0", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "package-json": "^6.3.0" } }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "levn": { + "version": "0.4.1", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "lodash.merge": { + "version": "4.6.2", "dev": true }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "loupe": { + "version": "2.3.4", "dev": true, "requires": { - "color-name": "1.1.3" + "get-func-name": "^2.0.0" } }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "lowercase-keys": { + "version": "1.0.1", "dev": true }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "lru-cache": { + "version": "6.0.0", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "make-dir": { + "version": "3.1.0", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "merge2": { + "version": "1.4.1", "dev": true }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "micromatch": { + "version": "4.0.5", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "mimic-response": { + "version": "1.0.1", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.6", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "dev": true + } + } + }, + "mocha": { + "version": "5.2.0", + "dev": true, + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.5", + "he": "1.1.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "5.4.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "glob": { + "version": "7.1.2", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "minimatch": { + "version": "3.1.2", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "minimatch": { + "version": "3.0.4", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "ms": { + "version": "2.0.0", + "dev": true + }, + "supports-color": { + "version": "5.4.0", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "ms": { + "version": "2.1.2", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "dev": true + }, + "nodemon": { + "version": "2.0.16", + "dev": true, + "requires": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.8", + "semver": "^5.7.1", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5", + "update-notifier": "^5.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.3", + "dev": true + }, + "semver": { + "version": "5.7.1", + "dev": true + } + } + }, + "nopt": { + "version": "1.0.10", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-path": { + "version": "3.0.0", + "dev": true + }, + "normalize-url": { + "version": "4.5.1", + "dev": true + }, + "once": { + "version": "1.4.0", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optionator": { + "version": "0.9.1", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "p-cancelable": { + "version": "1.1.0", "dev": true }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "package-json": { + "version": "6.5.0", "dev": true, "requires": { - "ms": "2.0.0" + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" } }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "parent-module": { + "version": "1.0.1", "dev": true, "requires": { - "type-detect": "^4.0.0" + "callsites": "^3.0.0" } }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "path-is-absolute": { + "version": "1.0.1", "dev": true }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "path-key": { + "version": "3.1.1", "dev": true }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "path-parse": { + "version": "1.0.7", "dev": true }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "path-type": { + "version": "4.0.0", "dev": true }, - "function-bind": { + "pathval": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "get-func-name": { + "picomatch": { + "version": "2.3.1", + "dev": true + }, + "prelude-ls": { + "version": "1.2.1", + "dev": true + }, + "prepend-http": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "prettier": { + "version": "2.6.2", + "dev": true + }, + "pstree.remy": { + "version": "1.1.8", + "dev": true + }, + "pump": { + "version": "3.0.0", "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "end-of-stream": "^1.1.0", + "once": "^1.3.1" } }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "punycode": { + "version": "2.1.1", "dev": true }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "pupa": { + "version": "2.1.1", "dev": true, "requires": { - "function-bind": "^1.1.1" + "escape-goat": "^2.0.0" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "queue-microtask": { + "version": "1.2.3", "dev": true }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true + "rc": { + "version": "1.2.8", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "ini": { + "version": "1.3.8", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "dev": true + } + } }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "readdirp": { + "version": "3.6.0", "dev": true, "requires": { - "once": "^1.3.0", - "wrappy": "1" + "picomatch": "^2.2.1" } }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "regexpp": { + "version": "3.2.0", "dev": true }, - "is-core-module": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", - "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "registry-auth-token": { + "version": "4.2.1", "dev": true, "requires": { - "has": "^1.0.3" + "rc": "^1.2.8" } }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "registry-url": { + "version": "5.1.0", + "dev": true, + "requires": { + "rc": "^1.2.8" + } }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "resolve": { + "version": "1.22.0", "dev": true, "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" } }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "resolve-from": { + "version": "4.0.0", + "dev": true + }, + "responselike": { + "version": "1.0.2", "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "lowercase-keys": "^1.0.0" } }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "reusify": { + "version": "1.0.4", "dev": true }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "rimraf": { + "version": "3.0.2", "dev": true, "requires": { - "minimist": "0.0.8" + "glob": "^7.1.3" } }, - "mocha": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", - "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", + "run-parallel": { + "version": "1.2.0", "dev": true, "requires": { - "browser-stdout": "1.3.1", - "commander": "2.15.1", - "debug": "3.1.0", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.5", - "he": "1.1.1", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "supports-color": "5.4.0" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } + "queue-microtask": "^1.2.2" } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "semver": { + "version": "6.3.0", "dev": true }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "semver-diff": { + "version": "3.1.1", "dev": true, "requires": { - "wrappy": "1" + "semver": "^6.3.0" } }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "shebang-command": { + "version": "2.0.0", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", "dev": true }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "signal-exit": { + "version": "3.0.7", "dev": true }, - "pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "slash": { + "version": "3.0.0", "dev": true }, - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "sprintf-js": { + "version": "1.0.3", + "dev": true + }, + "string-width": { + "version": "4.2.3", "dev": true, "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" } }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true + "strip-ansi": { + "version": "6.0.1", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "strip-json-comments": { + "version": "3.1.1", "dev": true }, "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "version": "5.5.0", "dev": true, "requires": { "has-flag": "^3.0.0" } }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "dev": true + }, + "text-table": { + "version": "0.2.0", + "dev": true + }, + "to-readable-stream": { + "version": "1.0.0", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "touch": { + "version": "3.1.0", + "dev": true, + "requires": { + "nopt": "~1.0.10" + } + }, "tslib": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, "tslint": { "version": "5.20.1", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.1.tgz", - "integrity": "sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -443,40 +4284,215 @@ "tsutils": "^2.29.0" }, "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "chalk": { + "version": "2.4.2", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "dev": true + }, + "commander": { + "version": "2.20.3", + "dev": true + }, "diff": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "mkdirp": { + "version": "0.5.6", + "dev": true, + "requires": { + "minimist": "^1.2.6" + } + }, + "semver": { + "version": "5.7.1", + "dev": true + }, + "tsutils": { + "version": "2.29.0", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } } } }, "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "version": "3.21.0", "dev": true, "requires": { "tslib": "^1.8.1" } }, + "type-check": { + "version": "0.4.0", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, "type-detect": { "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, + "type-fest": { + "version": "0.20.2", + "dev": true + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, "typescript": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.3.tgz", - "integrity": "sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==", + "version": "4.7.3", + "dev": true + }, + "undefsafe": { + "version": "2.0.5", + "dev": true + }, + "unique-string": { + "version": "2.0.0", + "dev": true, + "requires": { + "crypto-random-string": "^2.0.0" + } + }, + "update-notifier": { + "version": "5.1.0", + "dev": true, + "requires": { + "boxen": "^5.0.0", + "chalk": "^4.1.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.4.0", + "is-npm": "^5.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.1.0", + "pupa": "^2.1.1", + "semver": "^7.3.4", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "semver": { + "version": "7.3.7", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "uri-js": { + "version": "4.4.1", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "url-parse-lax": { + "version": "3.0.0", + "dev": true, + "requires": { + "prepend-http": "^2.0.0" + } + }, + "v8-compile-cache": { + "version": "2.3.0", + "dev": true + }, + "which": { + "version": "2.0.2", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "widest-line": { + "version": "3.1.0", + "dev": true, + "requires": { + "string-width": "^4.0.0" + } + }, + "word-wrap": { + "version": "1.2.3", "dev": true }, + "wrap-ansi": { + "version": "7.0.0", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, "wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write-file-atomic": { + "version": "3.0.3", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "xdg-basedir": { + "version": "4.0.0", + "dev": true + }, + "yallist": { + "version": "4.0.0", "dev": true } } -} \ No newline at end of file +} diff --git a/package.json b/package.json index 551cff8..767fac1 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "scripts": { "build": "rm -rf lib && tsc", "build:test": "rm -rf testDist && tsc -p test/tsconfig.json", - "lint": "tslint \"{./**/*.ts,./**/*.tsx}\" --exclude \"{./node_modules/**,./**/*.d.ts}\"", + "lint": "eslint src/", + "fmt": "prettier --write src/ && yarn lint --fix", "prepublish": "npm run build", "test": "npm run build:test && NODE_ENV=test mocha testDist/test/**/*.js", "test:watch": "nodemon --ignore lib --ignore testDist -e ts,tsx -x 'npm run test --silent || true'", @@ -27,8 +28,13 @@ "devDependencies": { "@types/chai": "^4.1.4", "@types/mocha": "^5.2.4", + "@typescript-eslint/eslint-plugin": "^5.27.1", + "@typescript-eslint/parser": "^5.27.1", "chai": "^4.1.0", + "eslint": "^8.17.0", "mocha": "^5.2.0", + "nodemon": "^2.0.14", + "prettier": "^2.6.2", "tslint": "^5.10.0", "typescript": "^4.2.3" }, @@ -42,4 +48,4 @@ "combine", "units" ] -} \ No newline at end of file +} diff --git a/recipe-parser b/recipe-parser deleted file mode 160000 index c2214bf..0000000 --- a/recipe-parser +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c2214bfec9441e7a5584aa608b4603a15ced6243 diff --git a/src/convert.ts b/src/convert.ts index db057fa..b58ce63 100644 --- a/src/convert.ts +++ b/src/convert.ts @@ -1,18 +1,34 @@ -import { numbersMap} from './numbers'; +import {i18nMap, SupportedLanguages} from './i18n'; + +function keepThreeDecimals(val: number, delimiter: string) { + const strVal = val.toString(); + return ( + strVal.split('.')[0] + delimiter + strVal.split('.')[1].substring(0, 3) + ); +} + +export function convertFromFraction( + value: string, + language: SupportedLanguages, +): string { + const {isCommaDelimited} = i18nMap[language]; + + const delimiter = isCommaDelimited ? ',' : '.'; -export function convertFromFraction(value: string) { // number comes in, for example: 1 1/3 if (value && value.split(' ').length > 1) { const [whole, fraction] = value.split(' '); const [a, b] = fraction.split('/'); const remainder = parseFloat(a) / parseFloat(b); - const wholeAndFraction = parseInt(whole) ? parseInt(whole) + remainder : remainder; - return keepThreeDecimals(wholeAndFraction); + const wholeAndFraction = parseInt(whole) + ? parseInt(whole) + remainder + : remainder; + return keepThreeDecimals(wholeAndFraction, delimiter); } else if (!value || value.split('-').length > 1) { return value; } else { const [a, b] = value.split('/'); - return b ? keepThreeDecimals(parseFloat(a) / parseFloat(b)) : a; + return b ? keepThreeDecimals(parseFloat(a) / parseFloat(b), delimiter) : a; } } @@ -21,7 +37,7 @@ export function getFirstMatch(line: string, regex: RegExp) { return (match && match[0]) || ''; } -const unicodeObj: { [key: string]: string } = { +const unicodeObj: {[key: string]: string} = { '½': '1/2', '⅓': '1/3', '⅔': '2/3', @@ -39,97 +55,132 @@ const unicodeObj: { [key: string]: string } = { '⅝': '5/8', '⅞': '7/8', '⅑': '1/9', - '⅒': '1/10' + '⅒': '1/10', }; -export function text2num(s: string, language: string) { +export function text2num(s: string, language: SupportedLanguages) { const a = s.toString().split(/[\s-]+/); - let values: number[]=[0,0]; - a.forEach(x =>{ - values = feach(x, values[0], values[1], language) + let values: number[] = [0, 0]; + a.forEach(x => { + values = feach(x, values[0], values[1], language); }); - if(values[0] + values[1]<0) - return null - else + if (values[0] + values[1] < 0) { + return null; + } else { return values[0] + values[1]; + } } -export function feach(w: string, g: number, n: number, language: string) { - let number = numbersMap.get(language) - let small = number[0] - let magnitude = number[1] - var x = small[w]; +export function feach( + w: string, + g: number, + n: number, + language: SupportedLanguages, +): number[] { + const {numbersSmall, numbersMagnitude} = i18nMap[language]; + + let x = numbersSmall[w]; if (x != null) { - g = g + x; - } - else if (100 == magnitude[w]) { - if(g>0) + g = g + x; + } else if (100 == numbersMagnitude[w]) { + if (g > 0) { g = g * 100; - else - g = 100 - } - else { - x = magnitude[w]; - if (x != null) { - n = n + g * x - g = 0; - } - else - return [-1, -1] - + } else { + g = 100; + } + } else { + x = numbersMagnitude[w]; + if (x != null) { + n = n + g * x; + g = 0; + } else { + return [-1, -1]; + } } - return [g,n] + return [g, n]; } -export function findQuantityAndConvertIfUnicode(ingredientLine: string, language: string) { - const numericAndFractionRegex = /^(\d+\/\d+)|(\d+\s\d+\/\d+)|(\d+.\d+)|\d+/g; - //const numericRangeWithSpaceRegex = /^(\d+\-\d+)|^(\d+\s\-\s\d+)|^(\d+\sto\s\d+)/g; // for ex: "1 to 2" or "1 - 2" - const unicodeFractionRegex = /\d*[^\u0000-\u007F]+/g; - const onlyUnicodeFraction = /[^\u0000-\u007F]+/g; +export function findQuantityAndConvertIfUnicode( + ingredientLine: string, + language: SupportedLanguages, +) { + const {joiners, isCommaDelimited} = i18nMap[language]; + + // Supports any of "1/3" "1 1/3" "1,000" "1,000.01" "1000" + + const delimiter = isCommaDelimited ? ',' : '\\.'; + const magnitudeSeperator = isCommaDelimited ? '\\.' : ','; + + const numericAndFractionRegex = new RegExp( + `(\\d+\\/\\d+|\\d+\\s\\d+\\/\\d+|\\d+(?:${magnitudeSeperator}?\\d+)*${delimiter}\\d+|\\d+)`, + 'g', + ); + + const numericRangeWithSpaceRegex = new RegExp( + `^(\\d+\\-\\d+)|^(\\d+\\s\\-\\s\\d+)|^(\\d+\\s(?:${joiners.join( + '|', + )})\\s\\d+)`, + 'g', + ); // for ex: "1 to 2" or "1 - 2" + // const unicodeFractionRegex = /(\d*)\s*([^\u0000-\u007F]+)/g; + const unicodeFractionRegex = new RegExp( + `(\\d*)\\s*(${Object.keys(unicodeObj).join('|')})`, + '', + ); const wordUntilSpace = /[^\s]+/g; // found a unicode quantity inside our regex, for ex: '⅝' - if (ingredientLine.match(unicodeFractionRegex)) { - const numericPart = getFirstMatch(ingredientLine, numericAndFractionRegex); - const unicodePart = getFirstMatch(ingredientLine, numericPart ? onlyUnicodeFraction : unicodeFractionRegex); + const unicodeQuantityMatch = ingredientLine.match(unicodeFractionRegex); + if (unicodeQuantityMatch) { + const [str, numericPart, unicodePart] = unicodeQuantityMatch; // If there's a match for the unicodePart in our dictionary above if (unicodeObj[unicodePart]) { - return [`${numericPart} ${unicodeObj[unicodePart]}`, ingredientLine.replace(getFirstMatch(ingredientLine, unicodeFractionRegex), '').trim()]; + return [ + `${numericPart} ${unicodeObj[unicodePart]}`, + ingredientLine.replace(str, '').trim(), + ]; } } // found a quantity range, for ex: "2 to 3" - // if (ingredientLine.match(numericRangeWithSpaceRegex)) { - // const quantity = getFirstMatch(ingredientLine, numericRangeWithSpaceRegex).replace('to', '-').split(' ').join(''); - // const restOfIngredient = ingredientLine.replace(getFirstMatch(ingredientLine, numericRangeWithSpaceRegex), '').trim(); - // return [ingredientLine.match(numericRangeWithSpaceRegex) && quantity, restOfIngredient]; - // } + const quantityRangeMatch = ingredientLine.match(numericRangeWithSpaceRegex); + if (quantityRangeMatch) { + const quantity = getFirstMatch(ingredientLine, numericRangeWithSpaceRegex) + .replace(new RegExp(`${joiners.join('|')}`), '-') + .split(' ') + .join(''); + const restOfIngredient = ingredientLine + .replace(getFirstMatch(ingredientLine, numericRangeWithSpaceRegex), '') + .trim(); + return [quantity, restOfIngredient]; + } // found a numeric/fraction quantity, for example: "1 1/3" - if (ingredientLine.match(numericAndFractionRegex)) { + const numericFractionMatch = ingredientLine.match(numericAndFractionRegex); + if (numericFractionMatch) { const quantity = getFirstMatch(ingredientLine, numericAndFractionRegex); - const restOfIngredient = ingredientLine.replace(getFirstMatch(ingredientLine, numericAndFractionRegex), '').trim() - return [ingredientLine.match(numericAndFractionRegex) && quantity, restOfIngredient]; + const restOfIngredient = ingredientLine + .replace(getFirstMatch(ingredientLine, numericAndFractionRegex), '') + .trim(); + return [quantity, restOfIngredient]; } - else if(ingredientLine.match(wordUntilSpace)) { + + // found a word which we can test for numeric value + const wordUntilSpaceMatch = ingredientLine.match(wordUntilSpace); + if (wordUntilSpaceMatch) { const quantity = getFirstMatch(ingredientLine, wordUntilSpace); - const quantityNumber = text2num(quantity.toLowerCase(), language) - if(quantityNumber){ - const restOfIngredient = ingredientLine.replace(getFirstMatch(ingredientLine, wordUntilSpace), '').trim() - return [ingredientLine.match(wordUntilSpace) && quantityNumber + '', restOfIngredient]; + const quantityNumber = text2num(quantity.toLowerCase(), language); + if (quantityNumber) { + const restOfIngredient = ingredientLine + .replace(getFirstMatch(ingredientLine, wordUntilSpace), '') + .trim(); + const quantityString = isCommaDelimited + ? `${quantityNumber}`.replace('.', ',') + : `${quantityNumber}`; + return [quantityString, restOfIngredient]; } - else - return [null, ingredientLine]; - - } - - // no parse-able quantity found - else { return [null, ingredientLine]; } -} -function keepThreeDecimals(val: number) { - const strVal = val.toString(); - return strVal.split('.')[0] + '.' + strVal.split('.')[1].substring(0, 3); + return [null, ingredientLine]; } diff --git a/src/i18n/index.ts b/src/i18n/index.ts new file mode 100644 index 0000000..9327fea --- /dev/null +++ b/src/i18n/index.ts @@ -0,0 +1,11 @@ +import {LangDeu} from './lang.deu'; +import {LangEng} from './lang.eng'; +import {LangIta} from './lang.ita'; + +export type SupportedLanguages = 'eng' | 'ita' | 'deu'; + +export const i18nMap = { + deu: LangDeu, + eng: LangEng, + ita: LangIta, +}; diff --git a/src/i18n/interfaces.ts b/src/i18n/interfaces.ts new file mode 100644 index 0000000..20117d3 --- /dev/null +++ b/src/i18n/interfaces.ts @@ -0,0 +1,11 @@ +export type LanguageConfig = { + units: {[key: string]: string[]}; + pluralUnits: {[key: string]: string}; + symbolUnits: {[key: string]: string}; + prepositions: string[]; + joiners: string[]; + toTaste: string[]; + numbersSmall: {[key: string]: number}; + numbersMagnitude: {[key: string]: number}; + isCommaDelimited: boolean; +}; diff --git a/src/i18n/lang.deu.ts b/src/i18n/lang.deu.ts new file mode 100644 index 0000000..b0e2cdb --- /dev/null +++ b/src/i18n/lang.deu.ts @@ -0,0 +1,144 @@ +import {LanguageConfig} from './interfaces'; + +const units = { + Pack: ['pack', 'packung', 'pck', 'pck.', 'päckchen'], + Messerspitze: ['messerspitze', 'msp', 'msp.'], + Gramm: ['gramm', 'g', 'g.'], + Milligramm: ['milligramm', 'mg', 'mg.'], + Kilogramm: ['kilogramm', 'kg', 'kg.'], + Milliliter: ['milliliter', 'ml', 'ml.'], + Liter: ['liter', 'l', 'l.', 'lt'], + Teelöffel: ['Teelöffel', 'tl', 'tl.'], + Esslöffel: ['esslöffel', 'el', 'el.', 'essl', 'essl.'], + Kaffeelöffel: ['kaffeelöffel', 'kl', 'kl.'], + Unze: ['unze', 'oz', 'oz.'], + Pfund: ['pfund', 'lb', 'lb.', 'lbs', 'lbs.', 'Lb', 'Lbs'], + Dutzend: ['dutzend'], + Dose: ['dose', 'dosen', 'dose(n)', 'dose/n'], + Tasse: ['tasse', 'tassen', 'tasse(n)', 'tasse/n'], + Prise: ['prise', 'prisen', 'prise(n)', 'prise/n'], + Stück: ['stück', 'stücke', 'stück(e)', 'stück/e'], + Scheibe: ['Scheibe', 'Scheibe/n', 'Scheibe(n)'], + Tropfen: ['tropfen', 'tropf', 'tropf(en)', 'tropf/en'], + Zehe: ['Zehe', 'Zeh'], + Nelke: ['Nelke'], + Stange: ['stangen', 'stange', 'stange(n)', 'stange/n'], + Schuss: ['schuss', 'schusse', 'schüsse', 'schuss(e)', 'schuss/e', 'schuß'], + Flasche: ['flaschen', 'flasche', 'flasche(n)', 'flasche/n'], + Bund: ['bund', 'bunde', 'bund(e)', 'bund/e'], +} as {[key: string]: string[]}; + +const pluralUnits = { + Pack: 'Packung', + Messerspitze: 'Messerspitzen', + Gramm: 'Gramm', + Milligramm: 'Milligramm', + Kilogramm: 'Kilogramm', + Milliliter: 'Milliliter', + Liter: 'Liter', + Teelöffel: 'Teelöffel', + Esslöffel: 'Esslöffel', + Kaffeelöffel: 'Kaffeelöffel', + Unze: 'Unzen', + Pfund: 'Pfund', + Dutzend: 'Dutzend', + Dose: 'Dosen', + Tasse: 'Tassen', + Prise: 'Prisen', + Stück: 'Stücke', + Scheibe: 'Scheiben', + Tropfen: 'Tropfen', + Zehe: 'Zehen', + Nelke: 'Nelken', + Stange: 'Stangen', + Schuss: 'Schuss', + Flasche: 'Flaschen', + Bund: 'Bund', +} as {[key: string]: string}; + +const symbolUnits = { + Pack: 'Pck', + Messerspitze: 'Msp', + Gramm: 'g', + Milligramm: 'mg', + Kilogramm: 'kg', + Milliliter: 'ml', + Liter: 'L', + Teelöffel: 'TL', + Esslöffel: 'EL', + Kaffeelöffel: 'KL', + Unze: 'oz', + Pfund: 'lb', + Dutzend: '', + Dose: '', + Tasse: '', + Prise: '', + Stück: '', + Scheibe: '', + Tropf: '', + Zehe: '', + Nelke: '', + Stange: '', + Schuss: '', + Flasche: '', + Bund: '', +} as {[key: string]: string}; + +const prepositions = ['von']; +const joiners = ['bis']; + +const toTaste: string[] = []; + +const numbersSmall: {[key: string]: number} = { + null: 0, + ein: 1, + eins: 1, + eine: 1, + einen: 1, + zwei: 2, + drei: 3, + vier: 4, + fünf: 5, + sechs: 6, + sieben: 7, + acht: 8, + neun: 9, + zehn: 10, + elf: 11, + zwölf: 12, + dreizehn: 13, + vierzehn: 14, + fünfzehn: 15, + sechszehn: 16, + siebzehn: 17, + achtzehn: 18, + neunzehn: 19, + zwanzig: 20, + dreizig: 30, + vierzif: 40, + fünfzig: 50, + sechzig: 60, + siebzig: 70, + achtzig: 80, + neunzig: 90, +}; + +const numbersMagnitude: {[key: string]: number} = { + hundert: 100, + tausend: 1000, + million: 1000000, + milliarde: 1000000000, + billion: 1000000000000, +}; + +export const LangDeu: LanguageConfig = { + units, + pluralUnits, + symbolUnits, + prepositions, + joiners, + toTaste, + numbersSmall, + numbersMagnitude, + isCommaDelimited: true, +}; diff --git a/src/i18n/lang.eng.ts b/src/i18n/lang.eng.ts new file mode 100644 index 0000000..220ba3f --- /dev/null +++ b/src/i18n/lang.eng.ts @@ -0,0 +1,144 @@ +import {LanguageConfig} from './interfaces'; + +const units = { + clove: ['clove'], + gallon: ['gallon', 'gal'], + ounce: ['ounce', 'oz', 'oz.'], + pint: ['pint', 'pt', 'pts', 'pt.'], + pound: ['pound', 'lb', 'lb.', 'lbs', 'lbs.', 'Lb', 'Lbs'], + quart: ['quart', 'qt', 'qt.', 'qts', 'qts.'], + tablespoon: ['tablespoon', 'tbs', 'tbsp', 'tbspn'], + teaspoon: ['teaspoon', 'tsp', 'tspn', 't', 't.'], + gram: ['gram', 'g', 'g.'], + kilogram: ['kilogram', 'kg', 'kg.'], + liter: ['liter', 'l', 'l.', 'lt'], + milligram: ['milligram', 'mg', 'mg.'], + milliliter: ['milliliter', 'ml', 'ml.'], + package: ['package', 'pkg', 'pkgs'], + bag: ['bag', 'bags'], + box: ['box'], + can: ['can'], + cup: ['cup', 'c', 'c.'], + stick: ['stick', 'sticks'], + dozen: ['dozen'], + piece: ['piece', 'pcs', 'pcs.'], + pinch: ['pinch'], + slice: ['slice'], + small: ['small'], + medium: ['medium'], + large: ['large'], + handful: ['handful'], + inch: ['inch'], +} as {[key: string]: string[]}; + +const pluralUnits = { + cup: 'cups', + gallon: 'gallons', + ounce: 'ounces', + pint: 'pints', + pound: 'pounds', + quart: 'quarts', + tablespoon: 'tablespoons', + teaspoon: 'teaspoons', + gram: 'grams', + kilogram: 'kilograms', + liter: 'liters', + milligram: 'milligrams', + milliliter: 'milliliters', + clove: 'cloves', + bag: 'bags', + box: 'boxes', + pinch: 'pinches', + can: 'cans', + slice: 'slices', + piece: 'pieces', + stick: 'sticks', + small: 'small', + medium: 'medium', + large: 'large', + handful: 'handfuls', + inch: 'inches', +} as {[key: string]: string}; + +const symbolUnits = { + cup: 'c', + gallon: 'gal', + ounce: 'oz', + pint: 'pt', + pound: 'lb', + quart: 'qt', + tablespoon: 'tbs', + teaspoon: 'tsp', + gram: 'g', + kilogram: 'kg', + liter: 'lt', + milligram: 'mg', + milliliter: 'ml', + clove: '', + bag: '', + box: '', + pinch: '', + can: '', + slice: '', + piece: '', + stick: '', + handful: '', + inch: '', +} as {[key: string]: string}; + +const prepositions = ['of']; + +const joiners = ['to']; + +const toTaste = ['to taste']; + +const numbersSmall: {[key: string]: number} = { + zero: 0, + one: 1, + two: 2, + three: 3, + four: 4, + five: 5, + six: 6, + seven: 7, + eight: 8, + nine: 9, + ten: 10, + eleven: 11, + twelve: 12, + thirteen: 13, + fourteen: 14, + fifteen: 15, + sixteen: 16, + seventeen: 17, + eighteen: 18, + nineteen: 19, + twenty: 20, + thirty: 30, + forty: 40, + fifty: 50, + sixty: 60, + seventy: 70, + eighty: 80, + ninety: 90, +}; + +const numbersMagnitude: {[key: string]: number} = { + hundred: 100, + thousand: 1000, + million: 1000000, + billion: 1000000000, + trillion: 1000000000000, +}; + +export const LangEng: LanguageConfig = { + units, + pluralUnits, + symbolUnits, + prepositions, + joiners, + toTaste, + numbersSmall, + numbersMagnitude, + isCommaDelimited: false, +}; diff --git a/src/i18n/lang.ita.ts b/src/i18n/lang.ita.ts new file mode 100644 index 0000000..5f4c503 --- /dev/null +++ b/src/i18n/lang.ita.ts @@ -0,0 +1,195 @@ +import {LanguageConfig} from './interfaces'; + +const units = { + barattolo: ['barattolo', 'barattoli'], + bicchiere: ['bicchiere'], + bottiglia: ['bottiglie', 'bottiglia'], + bustina: ['bustina', 'bustine'], + cubetto: ['cubetto', 'cubetti'], + cucchiaio: ['cucchiai', 'cucchiaio'], + cucchiaino: ['cucchiaini', 'cucchiaino'], + confezione: ['confezioni', 'confezione'], + grammo: ['g', 'g.', 'gr', 'gr.', 'grammi', 'grammo'], + chilogrammo: [ + 'kg.', + 'kg', + 'kilogrammo', + 'chilogrammi', + 'kilogrammo', + 'chilogrammo', + ], + fetta: ['fetta', 'fette'], + fettina: ['fettina', 'fettine'], + fogliolina: ['fogliolina', 'foglioline'], + foglia: ['foglie', 'foglia'], + foglio: ['fogli', 'foglio'], + litro: ['l.', 'l', 'lt', 'litro'], + gambo: ['gambo', 'gambi'], + mazzo: ['mazzo', 'mazzi'], + mazzetto: ['Mazzetto', 'mazzetti', 'mazzetto'], + lattina: ['Lattina', 'lattina'], + milligrammo: ['mg.', 'mg', 'milligrammo'], + millilitro: ['ml', 'ml.', 'millilitro'], + panetto: ['Panetto', 'panetti', 'panetto'], + pacco: ['pkg', 'pkgs', 'pacchetto', 'pacco'], + pezzo: ['pezzo', 'pcs', 'pcs.', 'pezzi'], + pizzico: ['pizzico', 'pizzichi'], + tazza: ['tazza', 'tazzina', 'tazzine'], + sacco: ['sacco', 'sacchi'], + spicchio: ['spicchio', 'spicchi'], + scatola: ['scatola', 'scatole'], + vasetto: ['vasetto', 'vasetti'], + filo: ['filo'], + ciuffo: ['ciuffo'], + scatoletta: ['scatoletta'], + manciata: ['manciata'], + rametto: ['rametto', 'rametti'], + rotolo: ['rotolo'], + pugno: ['pugno', 'pugni'], + bicchierino: ['bicchierino'], + // noce: ['noce'], +} as {[key: string]: string[]}; + +const pluralUnits = { + barattolo: 'barattoli', + bicchiere: 'bicchieri', + bustina: 'bustine', + bottiglia: 'bottiglie', + cubetto: 'cubetti', + gambo: 'gambi', + tazza: 'tazze', + quarto: 'quarti', + cucchiaio: 'cucchiai', + cucchiaino: 'cucchiaini', + confezione: 'confezioni', + grammo: 'grammi', + chilogrammo: 'chilogrammi', + litro: 'litri', + milligrammo: 'milligrammi', + millilitro: 'millilitri', + spicchio: 'spicchi', + scatola: 'scatole', + pizzico: 'pizzichi', + lattina: 'lattine', + fetta: 'fette', + fettina: 'fettine', + pezzo: 'pezzi', + panetto: 'panetti', + foglio: 'fogli', + fogliolina: 'foglioline', + foglia: 'foglie', + mazzo: 'mazzi', + mazzetto: 'mazzetti', + vasetto: 'vasetti', + filo: 'fili', + ciuffo: 'ciuffi', + sacco: 'sacchi', + scatoletta: 'scatolette', + manciata: 'manciate', + rametto: 'rametti', + rotolo: 'rotoli', + bicchierino: 'bicchierini', + pugno: 'pugni', + //noce: 'noci' +} as {[key: string]: string}; + +const symbolUnits = { + bicchiere: '', + bustina: '', + cubetto: '', + gambo: '', + tazza: '', + quarto: '', + cucchiaio: '', + spicchio: '', + scatola: '', + pizzico: '', + lattina: '', + fetta: '', + pezzo: '', + panetto: '', + foglia: '', + mazzetto: '', + manciata: '', + vasetto: '', + grammo: 'g', + cucchiaino: 'cc', + chilogrammo: 'kg', + litro: 'lt', + milligrammo: 'mg', + millilitro: 'ml', +} as {[key: string]: string}; + +const prepositions = ['di', "d'"]; + +const joiners = ['o']; + +const toTaste = ['quanto basta']; + +export const numbersSmall: {[key: string]: number} = { + zero: 0, + mezzo: 0.5, + mezza: 0.5, + metà: 0.5, + meta: 0.5, + uno: 1, + una: 1, + un: 1, + due: 2, + tre: 3, + quattro: 4, + cinque: 5, + sei: 6, + sette: 7, + otto: 8, + nove: 9, + dieci: 10, + undici: 11, + dodici: 12, + dozzina: 12, + tredici: 13, + quattordici: 14, + quindici: 15, + sedici: 16, + diciassette: 17, + diciotto: 18, + diciannove: 19, + venti: 20, + ventuno: 21, + trenta: 30, + trentuno: 31, + quaranta: 40, + quarantuno: 41, + cinquanta: 50, + cinquantuno: 51, + sessasanta: 60, + sessasantuno: 61, + settanta: 70, + settantuno: 71, + ottanta: 80, + ottantuno: 81, + novanta: 90, + novantuno: 91, +}; + +export const numbersMagnitude: {[key: string]: number} = { + cento: 100, + etto: 100, + mille: 1000, + mila: 1000, + millione: 1000000, + milliardo: 1000000000, + trilliardo: 1000000000000, +}; + +export const LangIta: LanguageConfig = { + units, + pluralUnits, + symbolUnits, + prepositions, + joiners, + toTaste, + numbersSmall, + numbersMagnitude, + isCommaDelimited: true, +}; diff --git a/src/index.ts b/src/index.ts index 81d189d..c3f9a05 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,190 +1,220 @@ import * as convert from './convert'; -import { unitsMap} from './units'; -import { repeatingFractions } from './repeatingFractions'; -import {toTasteMap} from './numbers'; - -//import * as Natural from 'natural'; - -//const nounInflector = new Natural.NounInflector(); +import {SupportedLanguages, i18nMap} from './i18n'; +import {repeatingFractions} from './repeatingFractions'; export interface Ingredient { ingredient: string; - quantity: string | null; + quantity: number | null; unit: string | null; - minQty: string | null; - maxQty: string | null; + symbol: string | null; + minQty: number | null; + maxQty: number | null; } -export function toTasteRecognize(input: string, language: string){ - const toTaste = toTasteMap[language] - const firstLetter = toTaste.match(/\b(\w)/g); - //componing first two word - //const word = firstWord.concat(' ').concat(secondWord) - - if(firstLetter){ - //checking the extended version - let regEx = new RegExp(toTaste, 'gi') - if(input.match(regEx)){ - return [(firstLetter.join('.') +'.').toLocaleLowerCase(), convert.getFirstMatch(input, regEx), true] as [string, string, boolean] - } - const regExString = firstLetter.join('[.]?') +'[.]?' - regEx = new RegExp(regExString, 'gi') - //const a = input.toString().split(/[\s-]+/); - if(input.match(regEx)){ - return [(firstLetter.join('.') +'.').toLocaleLowerCase(), convert.getFirstMatch(input, regEx), false] as [string, string, boolean] +export function toTasteRecognize( + input: string, + language: SupportedLanguages, +): [string, string, boolean] { + const {toTaste} = i18nMap[language]; + + for (const toTasteItem of toTaste) { + const firstLetter = toTasteItem.match(/\b(\w)/g); + + if (firstLetter) { + // checking the extended version + let regEx = new RegExp(toTasteItem, 'gi'); + if (input.match(regEx)) { + return [ + (firstLetter.join('.') + '.').toLocaleLowerCase(), + convert.getFirstMatch(input, regEx), + true, + ]; + } + const regExString = firstLetter.join('[.]?') + '[.]?'; + regEx = new RegExp('(\\b' + regExString + '\\b)', 'gi'); + // const a = input.toString().split(/[\s-]+/); + if (input.match(regEx)) { + return [ + (firstLetter.join('.') + '.').toLocaleLowerCase(), + convert.getFirstMatch(input, regEx), + false, + ]; + } } } - return ['', '', false] as [string, string, boolean] + + return ['', '', false]; } -function getUnit(input: string, language: string) { - // const word = input.concat(' ').concat(secondWord) - let unit = unitsMap.get(language) - let units = unit[0]; - let pluralUnits = unit[1]; - let symbolUnits = unit[3] - let response = [] as string[]; - const [toTaste, match, extFlag] = toTasteRecognize(input, language) - if(toTaste) { - if (extFlag){ - response = [toTaste, toTaste, match]; - } - else - { - response = [toTaste, toTaste, match]; - } +function getUnit(input: string, language: SupportedLanguages): string[] { + const {units, pluralUnits, symbolUnits} = i18nMap[language]; + const [toTaste, toTasteMatch] = toTasteRecognize(input, language); + + const res = (response: string[]) => { + const symbol = symbolUnits[response[0]]; + response.splice(2, 0, symbol); + return response; + }; + + if (toTaste) { + return res([toTaste, toTaste, toTasteMatch]); } - else - { - if (units[input] || pluralUnits[input]) { - response = [input, pluralUnits[input], input ]; - } - for (const unit of Object.keys(units)) { - for (const shorthand of units[unit]) { - const regex = new RegExp('(?=\\b'+shorthand+'\\b)', 'gi') - if (input.match(regex)) { - response = [unit, pluralUnits[unit], shorthand]; - } + if (units[input] || pluralUnits[input]) { + return res([input, pluralUnits[input], input]); + } + + for (const unit of Object.keys(units)) { + for (const shorthand of units[unit]) { + const regex = new RegExp( + '((?:^|\\s)' + shorthand.replace(/\./g, '\\.') + '(?:$|\\s))', + 'gi', + ); + + const match = input.match(regex); + if (match) { + return res([unit, pluralUnits[unit], match[0]]); } } - for (const pluralUnit of Object.keys(pluralUnits)) { - const regex = new RegExp('(?=\\b'+pluralUnits[pluralUnit]+'\\b)', 'gi') - if (input.match(regex)) { - response = [pluralUnit, pluralUnits[pluralUnit], pluralUnits[pluralUnit]]; - } - } } - let symbol = symbolUnits[response[0]] - response.splice(2, 0, symbol) - - return response + + for (const pluralUnit of Object.keys(pluralUnits)) { + const regex = new RegExp('(\\b' + pluralUnits[pluralUnit] + '\\b)', 'gi'); + const match = input.match(regex); + if (match) { + return res([pluralUnit, pluralUnits[pluralUnit], match[0]]); + } + } + + return []; } /* return the proposition if it's used before of the name of the ingredient */ -function getPreposition(input: string, language: string) { - let prepositionMap = unitsMap.get(language) - let prepositions = prepositionMap[2]; +function getPreposition(input: string, language: SupportedLanguages) { + const {prepositions} = i18nMap[language]; + for (const preposition of prepositions) { - let regex = new RegExp('^' + preposition ) - if (convert.getFirstMatch(input, regex)) - return preposition; - + const regex = new RegExp('^' + preposition); + if (convert.getFirstMatch(input, regex)) { + return preposition; + } } - + return null; } -export function parse(recipeString: string, language: string) { - let ingredientLine = recipeString.trim().replace(/^(-)/,""); // removes leading and trailing whitespace +function convertToNumber(input: string, language: SupportedLanguages): number { + const {isCommaDelimited} = i18nMap[language]; + if (!input) return 0; + + return +input.replace(isCommaDelimited ? /\./ : /,/, '').replace(/,/, '.'); +} + +export function parse(recipeString: string, language: SupportedLanguages) { + const ingredientLine = recipeString.trim(); // removes leading and trailing whitespace + /* restOfIngredient represents rest of ingredient line. For example: "1 pinch salt" --> quantity: 1, restOfIngredient: pinch salt */ - let [quantity, restOfIngredient] = convert.findQuantityAndConvertIfUnicode(ingredientLine, language) as string[]; - quantity = convert.convertFromFraction(quantity); + let [quantity, restOfIngredient] = convert.findQuantityAndConvertIfUnicode( + ingredientLine, + language, + ) as string[]; + quantity = convert.convertFromFraction(quantity, language); /* extraInfo will be any info in parantheses. We'll place it at the end of the ingredient. For example: "sugar (or other sweetener)" --> extraInfo: "(or other sweetener)" */ let extraInfo; - if (convert.getFirstMatch(restOfIngredient, /\(([^\)]+)\)/)) { - extraInfo = convert.getFirstMatch(restOfIngredient, /\(([^\)]+)\)/); + if (convert.getFirstMatch(restOfIngredient, /\(([^\\)]+)\)/)) { + extraInfo = convert.getFirstMatch(restOfIngredient, /\(([^\\)]+)\)/); restOfIngredient = restOfIngredient.replace(extraInfo, '').trim(); } // grab unit and turn it into non-plural version, for ex: "Tablespoons" OR "Tsbp." --> "tablespoon" - let [unit, unitPlural, symbol, originalUnit] = getUnit(restOfIngredient, language) as string[] + const [unit, unitPlural, symbol, originalUnit] = getUnit( + restOfIngredient, + language, + ) as string[]; + // remove unit from the ingredient if one was found and trim leading and trailing whitespace - - let ingredient = !!originalUnit ? restOfIngredient.replace(originalUnit, '').trim() : restOfIngredient.replace(unit, '').trim(); - ingredient=ingredient.split('.').join("").trim() - let preposition = getPreposition(ingredient.split(' ')[0], language) - - if(preposition) { - let regex = new RegExp('^' + preposition) - ingredient = ingredient.replace(regex,'').trim() + let ingredient = originalUnit + ? restOfIngredient.replace(originalUnit, '').trim() + : restOfIngredient.replace(unit, '').trim(); + ingredient = ingredient.split('.').join('').trim(); + const preposition = getPreposition(ingredient.split(' ')[0], language); + + if (preposition) { + const regex = new RegExp('^' + preposition); + ingredient = ingredient.replace(regex, '').trim(); } - + let minQty = quantity; // default to quantity let maxQty = quantity; // default to quantity // if quantity is non-nil and is a range, for ex: "1-2", we want to get minQty and maxQty if (quantity && quantity.includes('-')) { [minQty, maxQty] = quantity.split('-'); - } - if ((!quantity || quantity == '0') && !unit){ - unit ='q.b.' - unitPlural='q.b.' + quantity = minQty; } return { - quantity: +quantity, - unit: !!unit ? unit : null, - unitPlural: !!unitPlural ? unitPlural : null, - symbol: !!symbol ? symbol : null, - ingredient: extraInfo ? `${ingredient} ${extraInfo}` : ingredient.replace(/( )*\.( )*/g,''), - minQty: +minQty, - maxQty: +maxQty, + quantity: convertToNumber(quantity, language), + unit: unit ? unit : null, + unitPlural: unitPlural ? unitPlural : null, + symbol: symbol ? symbol : null, + ingredient: extraInfo + ? `${ingredient} ${extraInfo}` + : ingredient.replace(/( )*\.( )*/g, ''), + minQty: convertToNumber(minQty, language), + maxQty: convertToNumber(maxQty, language), }; } -export function multiLineParse(recipeString: string, language: string) { - const ingredients = recipeString.split(/[,👉🏻👉\r\n-]/); - let result = [] - let i; - for (var ingredient of ingredients) { - i = parse(ingredient, language) - if (i['ingredient']){ - result.push(i) - } - } - return result; +export function multiLineParse( + recipeString: string, + language: SupportedLanguages, +) { + const ingredients = recipeString.split(/[,👉🏻👉\r\n-]/); // eslint-disable-line no-misleading-character-class + + return ingredients.map(x => parse(x, language)).filter(x => x['ingredient']); } -export function combine(ingredientArray: Ingredient[]) { +export function combine(ingredientArray: Ingredient[]): Ingredient[] { const combinedIngredients = ingredientArray.reduce((acc, ingredient) => { const key = ingredient.ingredient + ingredient.unit; // when combining different units, remove this from the key and just use the name const existingIngredient = acc[key]; if (existingIngredient) { - return Object.assign(acc, { [key]: combineTwoIngredients(existingIngredient, ingredient) }); + return Object.assign(acc, { + [key]: combineTwoIngredients(existingIngredient, ingredient), + }); } else { - return Object.assign(acc, { [key]: ingredient }); + return Object.assign(acc, {[key]: ingredient}); } - }, {} as { [key: string]: Ingredient }); + }, {} as {[key: string]: Ingredient}); - return Object.keys(combinedIngredients).reduce((acc, key) => { - const ingredient = combinedIngredients[key]; - return acc.concat(ingredient); - }, [] as Ingredient[]).sort(compareIngredients); + return Object.keys(combinedIngredients) + .reduce((acc, key) => { + const ingredient = combinedIngredients[key]; + return acc.concat(ingredient); + }, [] as Ingredient[]) + .sort(compareIngredients); } -export function prettyPrintingPress(ingredient: Ingredient) { - let quantity = ''; +export function prettyPrintingPress( + ingredient: Ingredient, + language: SupportedLanguages, +): string { + let quantityString = ''; let unit = ingredient.unit; if (ingredient.quantity) { - const [whole, remainder] = ingredient.quantity.split('.'); + const whole = Math.floor(ingredient.quantity); + const remainder = + ingredient.quantity % 1 + ? `${(ingredient.quantity % 1).toPrecision(3)}`.split('.')[1] + : undefined; if (+whole !== 0 && typeof whole !== 'undefined') { - quantity = whole; + quantityString = `${whole}`; } - if (+remainder !== 0 && typeof remainder !== 'undefined') { + if (remainder && typeof remainder !== 'undefined') { let fractional; if (repeatingFractions[remainder]) { fractional = repeatingFractions[remainder]; @@ -201,16 +231,20 @@ export function prettyPrintingPress(ingredient: Ingredient) { fractional = Math.floor(numerator) + '/' + Math.floor(denominator); } - quantity += quantity ? ' ' + fractional : fractional; + quantityString += quantityString ? ' ' + fractional : fractional; + } + if ( + ((+whole !== 0 && typeof remainder !== 'undefined') || +whole > 1) && + unit + ) { + const lang = i18nMap[language]; + unit = lang.pluralUnits[unit] || unit; } - /* if (((+whole !== 0 && typeof remainder !== 'undefined') || +whole > 1) && unit) { - unit = nounInflector.pluralize(unit); - }*/ } else { return ingredient.ingredient; } - return `${quantity}${unit ? ' ' + unit : ''} ${ingredient.ingredient}`; + return `${quantityString}${unit ? ' ' + unit : ''} ${ingredient.ingredient}`; } function gcd(a: number, b: number): number { @@ -222,11 +256,23 @@ function gcd(a: number, b: number): number { } // TODO: Maybe change this to existingIngredients: Ingredient | Ingredient[] -function combineTwoIngredients(existingIngredients: Ingredient, ingredient: Ingredient): Ingredient { - const quantity = existingIngredients.quantity && ingredient.quantity ? (Number(existingIngredients.quantity) + Number(ingredient.quantity)).toString() : null; - const minQty = existingIngredients.minQty && ingredient.minQty ? (Number(existingIngredients.minQty) + Number(ingredient.minQty)).toString() : null; - const maxQty = existingIngredients.maxQty && ingredient.maxQty ? (Number(existingIngredients.maxQty) + Number(ingredient.maxQty)).toString() : null; - return Object.assign({}, existingIngredients, { quantity, minQty, maxQty }); +function combineTwoIngredients( + existingIngredients: Ingredient, + ingredient: Ingredient, +): Ingredient { + const quantity = + existingIngredients.quantity !== null && ingredient.quantity !== null + ? Number(existingIngredients.quantity) + Number(ingredient.quantity) + : null; + const minQty = + existingIngredients.minQty !== null && ingredient.minQty !== null + ? Number(existingIngredients.minQty) + Number(ingredient.minQty) + : null; + const maxQty = + existingIngredients.maxQty !== null && ingredient.maxQty !== null + ? Number(existingIngredients.maxQty) + Number(ingredient.maxQty) + : null; + return Object.assign({}, existingIngredients, {quantity, minQty, maxQty}); } function compareIngredients(a: Ingredient, b: Ingredient) { diff --git a/src/numbers.ts b/src/numbers.ts deleted file mode 100644 index dc05085..0000000 --- a/src/numbers.ts +++ /dev/null @@ -1,103 +0,0 @@ -export const engSmall: { [key: string]: number } = { - 'zero': 0, - 'one': 1, - 'two': 2, - 'three': 3, - 'four': 4, - 'five': 5, - 'six': 6, - 'seven': 7, - 'eight': 8, - 'nine': 9, - 'ten': 10, - 'eleven': 11, - 'twelve': 12, - 'thirteen': 13, - 'fourteen': 14, - 'fifteen': 15, - 'sixteen': 16, - 'seventeen': 17, - 'eighteen': 18, - 'nineteen': 19, - 'twenty': 20, - 'thirty': 30, - 'forty': 40, - 'fifty': 50, - 'sixty': 60, - 'seventy': 70, - 'eighty': 80, - 'ninety': 90 - }; - - export const engMagnitude: { [key: string]: number } = { - 'hundred': 100, - 'thousand': 1000, - 'million': 1000000, - 'billion': 1000000000, - 'trillion': 1000000000000, - }; - - export const itaSmall: { [key: string]: number } = { - 'zero': 0, - 'mezzo': 0.5, - 'mezza': 0.5, - 'metà': 0.5, - 'meta': 0.5, - 'uno': 1, - 'una': 1, - 'un': 1, - 'due': 2, - 'tre': 3, - 'quattro': 4, - 'cinque': 5, - 'sei': 6, - 'sette': 7, - 'otto': 8, - 'nove': 9, - 'dieci': 10, - 'undici': 11, - 'dodici': 12, - 'dozzina': 12, - 'tredici': 13, - 'quattordici': 14, - 'quindici': 15, - 'sedici': 16, - 'diciassette': 17, - 'diciotto': 18, - 'diciannove': 19, - 'venti': 20, - 'ventuno': 21, - 'trenta': 30, - 'trentuno': 31, - 'quaranta': 40, - 'quarantuno': 41, - 'cinquanta': 50, - 'cinquantuno': 51, - 'sessasanta': 60, - 'sessasantuno': 61, - 'settanta': 70, - 'settantuno': 71, - 'ottanta': 80, - 'ottantuno': 81, - 'novanta': 90, - 'novantuno': 91 - - }; - - export const itaMagnitude: { [key: string]: number } = { - 'cento': 100, - 'etto': 100, - 'mille': 1000, - 'mila': 1000, - 'millione': 1000000, - 'milliardo': 1000000000, - 'trilliardo': 1000000000000, - }; - export const toTasteMap: {[key:string]: string } = { - 'eng': 'to taste', - 'ita': 'quanto basta', - }; -export const numbersMap = new Map(); -numbersMap.set("eng",[engSmall, engMagnitude]); -numbersMap.set("ita",[itaSmall, itaMagnitude]); - diff --git a/src/repeatingFractions.ts b/src/repeatingFractions.ts index c1f208a..42d766c 100644 --- a/src/repeatingFractions.ts +++ b/src/repeatingFractions.ts @@ -3,5 +3,5 @@ export const repeatingFractions = { [666]: '2/3', [111]: '1/9', [166]: '1/6', - [833]: '5/6' -} as { [key: string]: string }; + [833]: '5/6', +} as {[key: string]: string}; diff --git a/src/units.ts b/src/units.ts deleted file mode 100644 index 99705fe..0000000 --- a/src/units.ts +++ /dev/null @@ -1,197 +0,0 @@ -export const engUnits = { - bag: ['bag', 'bags'], - box: ['box'], - can: ['can'], - cup: ['cup','c', 'c.', 'C', 'Cups'], - clove: ['clove'], - gallon: ['gallon','gal'], - ounce: ['ounce','oz', 'oz.'], - pint: ['pint','pt', 'pts', 'pt.'], - pound: ['pound','lb', 'lb.', 'lbs', 'lbs.', 'Lb', 'Lbs'], - quart: ['quart','qt', 'qt.', 'qts', 'qts.'], - tablespoon: ['tbs', 'tbsp', 'tbspn', 'T', 'T.', 'Tablespoons', 'Tablespoon'], - teaspoon: ['teaspoon','tsp', 'tspn', 't', 't.'], - gram: ['gram','g', 'g.'], - kilogram: ['kilogram','kg', 'kg.', 'Kg', 'Kg.'], - liter: ['liter','l', 'l.', 'lt', 'Lt', 'LT', 'L', 'L.'], - milligram: ['milligram','mg', 'mg.'], - milliliter: ['milliliter','ml', 'ml.', 'mL', 'mL.'], - package: ['package','pkg', 'pkgs'], - stick: ['stick','sticks'], - piece: ['piece','pcs', 'pcs.'], - pinch: ['pinch'], - small: ['Small'], - slice: ['slice'], - medium: ['Medium'], - large: ['large', 'Large'], -} as { [key: string]: string[] }; - -export const engPluralUnits = { - cup: 'cups', - gallon: 'gallons', - ounce: 'ounces', - pint: 'pints', - pound: 'pounds', - quart: 'quarts', - tablespoon: 'tablespoons', - teaspoon: 'teaspoons', - gram: 'grams', - kilogram: 'kilograms', - liter: 'liters', - milligram: 'milligrams', - milliliter: 'milliliters', - clove: 'cloves', - bag: 'bags', - box: 'boxes', - pinch: 'pinches', - can: 'cans', - slice: 'slices', - piece: 'pieces' -} as { [key: string]: string }; - -export const engNameToSymbol= { - cup: 'c', - gallon: 'gal', - ounce: 'oz', - pint: 'pt', - pound: 'lb', - quart: 'qt', - tablespoon: 'tbs', - teaspoon: 'tsp', - gram: 'g', - kilogram: 'kg', - liter: 'lt', - milligram: 'mg', - milliliter: 'ml', - clove: '', - bag: '', - box: '', - pinch: '', - can: '', - slice: '', - piece: '' -} as { [key: string]: string }; - -export const engPreposition = ['of']; - - -export const itaUnits = { - barattolo: ['barattolo', 'barattoli'], - bicchiere: ['bicchiere'], - bottiglia: ['bottiglie','bottiglia'], - bustina: ['bustina', 'bustine'], - cubetto: ['cubetto', 'cubetti'], - cucchiaio: ['cucchiai','cucchiaio'], - cucchiaino: ['cucchiaini','cucchiaino'], - confezione: ['confezioni','confezione'], - grammo: ['g', 'g\\.', 'gr', 'gr\\.','grammi','grammo'], - chilogrammo: ['kg.', 'kg', 'kilogrammo', 'chilogrammi','kilogrammo','chilogrammo'], - fetta: ['fetta', 'fette'], - fettina: ['fettina', 'fettine'], - fogliolina: ['fogliolina','foglioline'], - foglia: ['foglie','foglia'], - foglio: ['fogli','foglio'], - gambo: ['gambo', 'gambi'], - litro: [ 'l\\.','l', 'lt','litro'], - mazzo: ['mazzo','mazzi'], - mazzetto: ['Mazzetto','mazzetti','mazzetto'], - lattina: ['Lattina','lattina'], - milligrammo: ['mg.','mg', 'milligrammo'], - millilitro: [ 'ml','ml\\.', 'millilitro'], - panetto: ['Panetto', 'panetti', 'panetto'], - pacco: ['pkg', 'pkgs', 'pacchetto','pacco'], - pezzo: ['pezzo','pcs', 'pcs.','pezzi'], - pizzico: ['pizzico','pizzichi'], - tazza: ['tazza', 'tazzina','tazzine'], - sacco: ['sacco', 'sacchi'], - spicchio: ['spicchio', 'spicchi'], - scatola: ['scatola', 'scatole'], - vasetto: ['vasetto', 'vasetti'], - filo: ['filo'], - ciuffo: ['ciuffo'], - scatoletta: ['scatoletta'], - manciata: ['manciata'], - rametto: ['rametto', 'rametti'], - rotolo: ['rotolo'], - pugno: ['pugno', 'pugni'], - bicchierino: ['bicchierino'], - - //noce: ['noce'], -} as { [key: string]: string[] }; - -export const itaPluralUnits = { - barattolo: 'barattoli', - bicchiere: 'bicchieri', - bustina: 'bustine', - bottiglia: 'bottiglie', - cubetto: 'cubetti', - gambo: 'gambi', - tazza: 'tazze', - quarto: 'quarti', - cucchiaio: 'cucchiai', - cucchiaino: 'cucchiaini', - confezione: 'confezioni', - grammo: 'grammi', - chilogrammo: 'chilogrammi', - litro: 'litri', - milligrammo: 'milligrammi', - millilitro: 'millilitri', - spicchio: 'spicchi', - scatola: 'scatole', - pizzico: 'pizzichi', - lattina: 'lattine', - fetta: 'fette', - fettina: 'fettine', - pezzo: 'pezzi', - panetto: 'panetti', - foglio: 'fogli', - fogliolina: 'foglioline', - foglia: 'foglie', - mazzo: 'mazzi', - mazzetto: 'mazzetti', - vasetto: 'vasetti', - filo: 'fili', - ciuffo: 'ciuffi', - sacco: 'sacchi', - scatoletta: 'scatolette', - manciata: 'manciate', - rametto: 'rametti', - rotolo: 'rotoli', - bicchierino: 'bicchierini', - pugno: 'pugni' - //noce: 'noci' -} as { [key: string]: string }; - -export const itaNameToSymbol = { - bicchiere: '', - bustina: '', - cubetto: '', - gambo: '', - tazza: '', - quarto: '', - cucchiaio: '', - spicchio: '', - scatola: '', - pizzico: '', - lattina: '', - fetta: '', - pezzo: '', - panetto: '', - foglia: '', - mazzetto: '', - manciata: '', - vasetto: '', - grammo: 'g', - cucchiaino: 'cc', - chilogrammo: 'kg', - litro: 'lt', - milligrammo: 'mg', - millilitro: 'ml', -} as { [key: string]: string }; - -export const itaPreposition = ['di','d\'']; - -export const unitsMap = new Map(); -unitsMap.set("eng",[engUnits, engPluralUnits, engPreposition, engNameToSymbol]); -unitsMap.set("ita",[itaUnits, itaPluralUnits, itaPreposition, itaNameToSymbol]); - diff --git a/test/index-deu.test.ts b/test/index-deu.test.ts new file mode 100644 index 0000000..ca34706 --- /dev/null +++ b/test/index-deu.test.ts @@ -0,0 +1,393 @@ +import {expect} from 'chai'; +import {parse} from '../src/index'; + +describe('recipe parser deu', () => { + it('returns an object', () => { + expect(typeof parse('1 tasse Wasser', 'deu')).to.equal('object'); + }); + + describe('translates the quantity', () => { + it('of "1 tealöffel wasser"', () => { + expect(parse('1 teelöffel Wasser', 'deu').quantity).to.equal(1); + }); + it('of "1,5 teelöffel Wasser"', () => { + expect(parse('1,5 teelöffel Wasser', 'deu').quantity).to.equal(1.5); + }); + it('of "1 1/2 teelöffel Wasser"', () => { + expect(parse('1 1/2 teelöffel Wasser', 'deu').quantity).to.equal(1.5); + }); + it('of "1/3 teelöffel Wasser"', () => { + expect(parse('1/3 cup Wasser', 'deu').quantity).to.equal(0.333); + }); + it('of "1/2 teelöffel Wasser"', () => { + expect(parse('1/2 teelöffel Wasser', 'deu').quantity).to.equal(0.5); + }); + it('of "10 1/2 teelöffel Wasser"', () => { + expect(parse('10 1/2 teelöffel Wasser', 'deu').quantity).to.equal(10.5); + }); + it('of "about 1/2 teelöffel Wasser"', () => { + expect(parse('about 1/2 teelöffel Wasser', 'deu').quantity).to.equal(0.5); + }); + + describe('translates the quantity from string to number', () => { + it('ein teelöffel Wasser"', () => { + expect(parse('ein teelöffel Wasser', 'deu').quantity).to.equal(1); + }); + + it('ein teelöffel Wasser"', () => { + expect(parse('eine teelöffel Wasser', 'deu').quantity).to.equal(1); + }); + + it('ein teelöffel Wasser"', () => { + expect(parse('einen teelöffel Wasser', 'deu').quantity).to.equal(1); + }); + it('zwanzig teelöffel Wasser"', () => { + expect(parse('zwanzig teelöffel Wasser', 'deu').quantity).to.equal(20); + }); + it('fünf teelöffel Wasser"', () => { + expect(parse('fünf teelöffel Wasser', 'deu').quantity).to.equal(5); + }); + }); + + describe('translates the quantity range', () => { + const expectation = { + ingredient: 'Wasser', + maxQty: 20, + minQty: 10, + quantity: 10, + symbol: 'TL', + unit: 'Teelöffel', + unitPlural: 'Teelöffel', + }; + it('of "10-20 teelöffel Wasser"', () => { + expect(parse('10-20 teelöffel Wasser', 'deu')).to.deep.equal( + expectation, + ); + }); + it('of "10 - 20 teelöffel Wasser"', () => { + expect(parse('10 - 20 teelöffel Wasser', 'deu')).to.deep.equal( + expectation, + ); + }); + it('of "10 to 20 teelöffel Wasser"', () => { + expect(parse('10 bis 20 teelöffel Wasser', 'deu')).to.deep.equal( + expectation, + ); + }); + }); + + describe('of unicode fractions', () => { + const unicodeAmounts = [ + '¼', + '½', + '¾', + '⅐', + '⅑', + '⅒', + '⅓', + '⅔', + '⅕', + '⅖', + '⅗', + '⅘', + '⅙', + '⅚', + '⅛', + '⅜', + '⅝', + '⅞', + ]; + const unicodeExpectedAmounts = [ + 0.25, 0.5, 0.75, 0.142, 0.111, 0.1, 0.333, 0.666, 0.2, 0.4, 0.6, 0.8, + 0.166, 0.833, 0.125, 0.375, 0.625, 0.875, + ]; + + for (let u = 0; u < unicodeAmounts.length; u++) { + const element = unicodeAmounts[u]; + const expectedAmount = unicodeExpectedAmounts[u]; + it(`${element} to ${expectedAmount}`, () => { + expect(parse(`${element} teelöffel Wasser`, 'deu').quantity).to.equal( + expectedAmount, + ); + }); + } + + const mixedValues = [ + '1¼', + '2½', + '3¾', + '4⅐', + '5⅑', + '6⅒', + '7⅓', + '8⅔', + '9⅕', + '10⅖', + '11⅗', + '12⅘', + '13⅙', + '14⅚', + '15⅛', + '16⅜', + '17⅝', + '18⅞', + ]; + const mixedExpectedValues = [ + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + '10', + '11', + '12', + '13', + '14', + '15', + '16', + '17', + '18', + ]; + + for (let u = 0; u < mixedValues.length; u++) { + const element = mixedValues[u]; + const expectedAmount = + Number(mixedExpectedValues[u]) + Number(unicodeExpectedAmounts[u]); + it(`${element} to ${expectedAmount}`, () => { + expect(parse(`${element} teelöffel Wasser`, 'deu').quantity).to.equal( + expectedAmount, + ); + }); + } + }); + + it("doesn't freak out if a strange unicode character is present", () => { + expect(parse('1/3 tasse confectioners’ zucker', 'deu')).to.deep.equal({ + quantity: 0.333, + unit: 'Tasse', + unitPlural: 'Tassen', + symbol: null, + ingredient: 'confectioners’ zucker', + minQty: 0.333, + maxQty: 0.333, + }); + }); + }); + + describe('translates the literal units', () => { + it('of "1 tasse Wasser"', () => { + expect(parse('1 tasse Wasser', 'deu').unit).to.equal('Tasse'); + }); + it('of "1 unze Wasser"', () => { + expect(parse('1 unze Wasser', 'deu').unit).to.equal('Unze'); + }); + it('of "1 pfund Wasser"', () => { + expect(parse('1 pfund Wasser', 'deu').unit).to.equal('Pfund'); + }); + it('of "1 esslöffel Wasser"', () => { + expect(parse('1 esslöffel Wasser', 'deu').unit).to.equal('Esslöffel'); + }); + it('of "1 teelöffel Wasser"', () => { + expect(parse('1 teelöffel Wasser', 'deu').unit).to.equal('Teelöffel'); + }); + it('of "1 gramm Wasser"', () => { + expect(parse('1 gramm Wasser', 'deu').unit).to.equal('Gramm'); + }); + it('of "1 kilogramm Wasser"', () => { + expect(parse('1 kilogramm Wasser', 'deu').unit).to.equal('Kilogramm'); + }); + it('of "1 liter Wasser"', () => { + expect(parse('1 liter Wasser', 'deu').unit).to.equal('Liter'); + }); + it('of "1 milligramm Wasser"', () => { + expect(parse('1 milligramm Wasser', 'deu').unit).to.equal('Milligramm'); + }); + it('of "1 milliliter Wasser"', () => { + expect(parse('1 milliliter Wasser', 'deu').unit).to.equal('Milliliter'); + }); + it('of "1 packung Würst"', () => { + expect(parse('1 packung Würst', 'deu').unit).to.equal('Pack'); + }); + it('"1 Prise Wasser"', () => { + expect(parse('1 Prise salt', 'deu').unit).to.equal('Prise'); + }); + it('"1 (14.5 oz) dose tomatoes"', () => { + expect(parse('1 (14.5 oz) dose tomatoes', 'deu')).to.deep.equal({ + unit: 'Dose', + unitPlural: 'Dosen', + symbol: null, + quantity: 1, + ingredient: 'tomatoes (14.5 oz)', + minQty: 1, + maxQty: 1, + }); + }); + it('"25 lb beef stew chunks (or buy a roast and chop into small cubes)"', () => { + expect( + parse( + '25 lb beef stew chunks (or buy a roast and chop into small cubes)', + 'deu', + ), + ).to.deep.equal({ + unit: 'Pfund', + unitPlural: 'Pfund', + symbol: 'lb', + quantity: 25, + ingredient: + 'beef stew chunks (or buy a roast and chop into small cubes)', + minQty: 25, + maxQty: 25, + }); + }); + it('"parses ingredient with range: 1 bis 2 Apfel"', () => { + expect(parse('1 bis 2 Apfel', 'deu')).to.deep.equal({ + unit: null, + unitPlural: null, + symbol: null, + quantity: 1, + ingredient: 'Apfel', + minQty: 1, + maxQty: 2, + }); + }); + it('"parses ingredient with range: 1 - 2 Apfel"', () => { + expect(parse('1 - 2 Apfel', 'deu')).to.deep.equal({ + unit: null, + unitPlural: null, + symbol: null, + quantity: 1, + ingredient: 'Apfel', + minQty: 1, + maxQty: 2, + }); + }); + it('"parses ingredient with range: 1-2 Apfel"', () => { + expect(parse('1-2 Apfel', 'deu')).to.deep.equal({ + unit: null, + unitPlural: null, + symbol: null, + quantity: 1, + ingredient: 'Apfel', + minQty: 1, + maxQty: 2, + }); + }); + it('"1 Stück Käse"', () => { + expect(parse('1 Stück Käse', 'deu')).to.deep.equal({ + unit: 'Stück', + unitPlural: 'Stücke', + symbol: null, + quantity: 1, + ingredient: 'Käse', + minQty: 1, + maxQty: 1, + }); + }); + }); + + it('translates unit when no unit provided', () => { + expect(parse('1 tortilla', 'deu')).to.deep.equal({ + unit: null, + unitPlural: null, + symbol: null, + ingredient: 'tortilla', + quantity: 1, + minQty: 1, + maxQty: 1, + }); + }); + + it("doesn't explode when no unit and no quantity provided", () => { + expect(parse('Powdered Sugar', 'deu')).to.deep.equal({ + ingredient: 'Powdered Sugar', + quantity: 0, + unit: null, + unitPlural: null, + symbol: null, + minQty: 0, + maxQty: 0, + }); + }); + + describe('translates the abbreviated units of', () => { + it('"1 unze Wasser"', () => { + expect(parse('1 oz Wasser', 'deu').unit).to.equal('Unze'); + expect(parse('1 oz. Wasser', 'deu').unit).to.equal('Unze'); + expect(parse('2 unzen Wasser', 'deu').unit).to.equal('Unze'); + }); + it('"1 pfund Wasser"', () => { + expect(parse('1 lb Wasser', 'deu').unit).to.equal('Pfund'); + expect(parse('1 lb. Wasser', 'deu').unit).to.equal('Pfund'); + expect(parse('2 lbs Wasser', 'deu').unit).to.equal('Pfund'); + expect(parse('2 pfund Wasser', 'deu').unit).to.equal('Pfund'); + }); + it('"1 esslöffel Öl"', () => { + expect(parse('1 el Öl', 'deu').unit).to.equal('Esslöffel'); + expect(parse('1 EL Öl', 'deu').unit).to.equal('Esslöffel'); + expect(parse('1 El Öl', 'deu').unit).to.equal('Esslöffel'); + expect(parse('1 el. Öl', 'deu').unit).to.equal('Esslöffel'); + expect(parse('2 esslöffel Öl', 'deu').unit).to.equal('Esslöffel'); + expect(parse('1 esslöffel Öl', 'deu').unit).to.equal('Esslöffel'); + }); + it('"1 teelöffel Wasser"', () => { + expect(parse('1 tl Wasser', 'deu').unit).to.equal('Teelöffel'); + expect(parse('1 tl. Wasser', 'deu').unit).to.equal('Teelöffel'); + expect(parse('1 TL Wasser', 'deu').unit).to.equal('Teelöffel'); + expect(parse('2 teelöffel Wasser', 'deu').unit).to.equal('Teelöffel'); + }); + it('"1 Gramm Wasser"', () => { + expect(parse('1 g Wasser', 'deu').unit).to.equal('Gramm'); + expect(parse('1 g. Wasser', 'deu').unit).to.equal('Gramm'); + expect(parse('2 Gramm Wasser', 'deu').unit).to.equal('Gramm'); + }); + it('"1 Kilogramm Wasser"', () => { + expect(parse('1 kg Wasser', 'deu').unit).to.equal('Kilogramm'); + expect(parse('1 kg. Wasser', 'deu').unit).to.equal('Kilogramm'); + expect(parse('2 Kilogramm Wasser', 'deu').unit).to.equal('Kilogramm'); + }); + it('"1 liter Wasser"', () => { + expect(parse('1 l Wasser', 'deu').unit).to.equal('Liter'); + expect(parse('1 L. Wasser', 'deu').unit).to.equal('Liter'); + expect(parse('2 liter Wasser', 'deu').unit).to.equal('Liter'); + }); + it('"1 Milligramm Wasser"', () => { + expect(parse('1 mg Wasser', 'deu').unit).to.equal('Milligramm'); + expect(parse('1 mg. Wasser', 'deu').unit).to.equal('Milligramm'); + expect(parse('1 Milligramm Wasser', 'deu').unit).to.equal('Milligramm'); + }); + it('"1 Milliliter Wasser"', () => { + expect(parse('1 ml Wasser', 'deu').unit).to.equal('Milliliter'); + expect(parse('1 ml. Wasser', 'deu').unit).to.equal('Milliliter'); + expect(parse('1 Milliliter Wasser', 'deu').unit).to.equal('Milliliter'); + }); + it('"1 prise Salz"', () => { + expect(parse('1 prise Salz', 'deu').unit).to.equal('Prise'); + expect(parse('2 prisen Salz', 'deu').unit).to.equal('Prise'); + expect(parse('2 prise/n Salz', 'deu').unit).to.equal('Prise'); + expect(parse('2 prise(n) Salz', 'deu').unit).to.equal('Prise'); + }); + }); + + describe('translates the ingredient von', () => { + it('"1 teelöffel Wasser"', () => { + expect(parse('1 teelöffel von Wasser', 'deu').ingredient).to.equal( + 'Wasser', + ); + }); + it('"1 teelöffel milk"', () => { + expect(parse('1 teelöffel von milk', 'deu').ingredient).to.equal('milk'); + }); + it('"1 teelöffel von milk"', () => { + expect(parse('1 teelöffel von milk', 'deu').ingredient).to.equal('milk'); + }); + it('"1 teelöffel von milk"', () => { + expect( + parse('1 teelöffel von powdered sugar', 'deu').ingredient, + ).to.equal('powdered sugar'); + }); + }); +}); diff --git a/test/index-eng.test.ts b/test/index-eng.test.ts new file mode 100644 index 0000000..5b1f782 --- /dev/null +++ b/test/index-eng.test.ts @@ -0,0 +1,489 @@ +import {expect} from 'chai'; +import {parse} from '../src/index'; + +describe('recipe parser eng', () => { + it('returns an object', () => { + expect(typeof parse('1 cup water', 'eng')).to.equal('object'); + }); + + describe('translates the quantity', () => { + it('of "to taste of water"', () => { + expect(parse('to taste of water', 'eng').unit).to.equal('t.t.'); + }); + it('of "To taste of water"', () => { + expect(parse('To taste of water', 'eng').unit).to.equal('t.t.'); + }); + it('of "t.t. of water"', () => { + expect(parse('t.t. of water', 'eng').unit).to.equal('t.t.'); + }); + it('of "t.t. of water"', () => { + expect(parse('t.t. of water', 'eng').unit).to.equal('t.t.'); + }); + it('of "TT of water"', () => { + expect(parse('TT of water', 'eng').unit).to.equal('t.t.'); + }); + it('of "TT. of water"', () => { + expect(parse('TT. of water', 'eng').unit).to.equal('t.t.'); + }); + it('of "T.t of water"', () => { + expect(parse('T.t of water', 'eng').unit).to.equal('t.t.'); + }); + it('of "1 teaspoon water"', () => { + expect(parse('1 teaspoon water', 'eng').quantity).to.equal(1); + }); + it('of "1.5 teaspoon water"', () => { + expect(parse('1.5 teaspoon water', 'eng').quantity).to.equal(1.5); + }); + it('of "1 1/2 teaspoon water"', () => { + expect(parse('1 1/2 teaspoon water', 'eng').quantity).to.equal(1.5); + }); + it('of "1/3 teaspoon water"', () => { + expect(parse('1/3 cup water', 'eng').quantity).to.equal(0.333); + }); + it('of "1/2 teaspoon water"', () => { + expect(parse('1/2 teaspoon water', 'eng').quantity).to.equal(0.5); + }); + it('of "10 1/2 teaspoon water"', () => { + expect(parse('10 1/2 teaspoon water', 'eng').quantity).to.equal(10.5); + }); + it('of "about 1/2 teaspoon water"', () => { + expect(parse('about 1/2 teaspoon water', 'eng').quantity).to.equal(0.5); + }); + + it('of "1,500.50 teaspoon water"', () => { + expect(parse('1,500.50 teaspoon water', 'eng').quantity).to.equal(1500.5); + }); + + describe('translates the quantity from string to number', () => { + it('zero teaspoon water"', () => { + expect(parse('zero teaspoon water', 'eng').quantity).to.equal(0); + }); + it('one teaspoon water"', () => { + expect(parse('one teaspoon water', 'eng').quantity).to.equal(1); + }); + it('twenty-one teaspoon water"', () => { + expect(parse('twenty-one teaspoon water', 'eng').quantity).to.equal(21); + }); + it('five teaspoon water"', () => { + expect(parse('five teaspoon water', 'eng').quantity).to.equal(5); + }); + }); + + describe('to taste detector', () => { + it('does not detect words containing the same characters', () => { + expect(parse('100g of butter', 'eng').unit).to.equal('gram'); + expect(parse('100g of butter', 'eng').ingredient).to.equal('butter'); + }); + }); + + describe('translates the quantity range', () => { + const expectation = { + ingredient: 'water', + maxQty: 20, + minQty: 10, + quantity: 10, + symbol: 'tsp', + unit: 'teaspoon', + unitPlural: 'teaspoons', + }; + it('of "10-20 teaspoon water"', () => { + expect(parse('10-20 teaspoon water', 'eng')).to.deep.equal(expectation); + }); + it('of "10 - 20 teaspoon water"', () => { + expect(parse('10 - 20 teaspoon water', 'eng')).to.deep.equal( + expectation, + ); + }); + it('of "10 to 20 teaspoon water"', () => { + expect(parse('10 to 20 teaspoon water', 'eng')).to.deep.equal( + expectation, + ); + }); + }); + + describe('of unicode fractions', () => { + const unicodeAmounts = [ + '¼', + '½', + '¾', + '⅐', + '⅑', + '⅒', + '⅓', + '⅔', + '⅕', + '⅖', + '⅗', + '⅘', + '⅙', + '⅚', + '⅛', + '⅜', + '⅝', + '⅞', + ]; + const unicodeExpectedAmounts = [ + 0.25, 0.5, 0.75, 0.142, 0.111, 0.1, 0.333, 0.666, 0.2, 0.4, 0.6, 0.8, + 0.166, 0.833, 0.125, 0.375, 0.625, 0.875, + ]; + + for (let u = 0; u < unicodeAmounts.length; u++) { + const element = unicodeAmounts[u]; + const expectedAmount = unicodeExpectedAmounts[u]; + it(`${element} to ${expectedAmount}`, () => { + expect(parse(`${element} teaspoon water`, 'eng').quantity).to.equal( + expectedAmount, + ); + }); + } + + const mixedValues = [ + '1¼', + '2½', + '3¾', + '4⅐', + '5⅑', + '6⅒', + '7⅓', + '8⅔', + '9⅕', + '10 ⅖', + '11 ⅗', + '12 ⅘', + '13 ⅙', + '14 ⅚', + '15 ⅛', + '16 ⅜', + '17 ⅝', + '18 ⅞', + ]; + const mixedExpectedValues = [ + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + '10', + '11', + '12', + '13', + '14', + '15', + '16', + '17', + '18', + ]; + + for (let u = 0; u < mixedValues.length; u++) { + const element = mixedValues[u]; + const expectedAmount = + Number(mixedExpectedValues[u]) + Number(unicodeExpectedAmounts[u]); + it(`${element} to ${expectedAmount}`, () => { + expect(parse(`${element} teaspoon water`, 'eng').quantity).to.equal( + expectedAmount, + ); + }); + } + }); + + it("doesn't freak out if a strange unicode character is present", () => { + expect(parse('1/3 cup confectioners’ sugar', 'eng')).to.deep.equal({ + quantity: 0.333, + unit: 'cup', + unitPlural: 'cups', + symbol: 'c', + ingredient: 'confectioners’ sugar', + minQty: 0.333, + maxQty: 0.333, + }); + }); + + it('correctly removes unicode value from ingredient', () => { + expect(parse('2 ½ cup confectioners’ sugar', 'eng')).to.deep.equal({ + quantity: 2.5, + unit: 'cup', + unitPlural: 'cups', + symbol: 'c', + ingredient: 'confectioners’ sugar', + minQty: 2.5, + maxQty: 2.5, + }); + + expect(parse('2½ cup confectioners’ sugar', 'eng')).to.deep.equal({ + quantity: 2.5, + unit: 'cup', + unitPlural: 'cups', + symbol: 'c', + ingredient: 'confectioners’ sugar', + minQty: 2.5, + maxQty: 2.5, + }); + }); + }); + + describe('translates the literal units', () => { + it('of "1 cup water"', () => { + expect(parse('1 cup water', 'eng').unit).to.equal('cup'); + }); + it('of "1 gallon water"', () => { + expect(parse('1 gallon water', 'eng').unit).to.equal('gallon'); + }); + it('of "1 ounce water"', () => { + expect(parse('1 ounce water', 'eng').unit).to.equal('ounce'); + }); + it('of "1 pint water"', () => { + expect(parse('1 pint water', 'eng').unit).to.equal('pint'); + }); + it('of "1 pound water"', () => { + expect(parse('1 pound water', 'eng').unit).to.equal('pound'); + }); + it('of "1 quart water"', () => { + expect(parse('1 quart water', 'eng').unit).to.equal('quart'); + }); + it('of "1 tablespoon water"', () => { + expect(parse('1 tablespoon water', 'eng').unit).to.equal('tablespoon'); + }); + it('of "1 teaspoon water"', () => { + expect(parse('1 teaspoon water', 'eng').unit).to.equal('teaspoon'); + }); + it('of "1 gram water"', () => { + expect(parse('1 gram water', 'eng').unit).to.equal('gram'); + }); + it('of "1 kilogram water"', () => { + expect(parse('1 kilogram water', 'eng').unit).to.equal('kilogram'); + }); + it('of "1 liter water"', () => { + expect(parse('1 liter water', 'eng').unit).to.equal('liter'); + }); + it('of "1 milligram water"', () => { + expect(parse('1 milligram water', 'eng').unit).to.equal('milligram'); + }); + it('of "1 milliliter water"', () => { + expect(parse('1 milliliter water', 'eng').unit).to.equal('milliliter'); + }); + it('of "1 large onion"', () => { + expect(parse('1 large onion', 'eng').unit).to.equal('large'); + }); + it('of "1 whole onion"', () => { + expect(parse('1 whole onion', 'eng').unit).to.equal(null); + }); + it('of "1 clove garlic"', () => { + expect(parse('1 clove garlic', 'eng').unit).to.equal('clove'); + }); + it('of "1 bag garlic"', () => { + expect(parse('1 bag garlic', 'eng').unit).to.equal('bag'); + }); + it('of "1 package sausage"', () => { + expect(parse('1 package sausage', 'eng').unit).to.equal('package'); + }); + it('"1 pinch water"', () => { + expect(parse('1 pinch salt', 'eng').unit).to.equal('pinch'); + }); + it('"1 (14.5 oz) can tomatoes"', () => { + expect(parse('1 (14.5 oz) can tomatoes', 'eng')).to.deep.equal({ + unit: 'can', + unitPlural: 'cans', + symbol: null, + quantity: 1, + ingredient: 'tomatoes (14.5 oz)', + minQty: 1, + maxQty: 1, + }); + }); + it('"25 lb beef stew chunks (or buy a roast and chop into small cubes)"', () => { + expect( + parse( + '25 lb beef stew chunks (or buy a roast and chop into small cubes)', + 'eng', + ), + ).to.deep.equal({ + unit: 'pound', + unitPlural: 'pounds', + symbol: 'lb', + quantity: 25, + ingredient: + 'beef stew chunks (or buy a roast and chop into small cubes)', + minQty: 25, + maxQty: 25, + }); + }); + it('"parses ingredient with range: 1 to 2 chicken breasts"', () => { + expect(parse('1 to 2 chicken breasts', 'eng')).to.deep.equal({ + unit: null, + unitPlural: null, + symbol: null, + quantity: 1, + ingredient: 'chicken breasts', + minQty: 1, + maxQty: 2, + }); + }); + it('"parses ingredient with range: 1 - 2 chicken breasts"', () => { + expect(parse('1 - 2 chicken breasts', 'eng')).to.deep.equal({ + unit: null, + unitPlural: null, + symbol: null, + quantity: 1, + ingredient: 'chicken breasts', + minQty: 1, + maxQty: 2, + }); + }); + it('"parses ingredient with range: 1-2 chicken breasts"', () => { + expect(parse('1-2 chicken breasts', 'eng')).to.deep.equal({ + unit: null, + unitPlural: null, + symbol: null, + quantity: 1, + ingredient: 'chicken breasts', + minQty: 1, + maxQty: 2, + }); + }); + it('"1 (16 oz) box pasta"', () => { + expect(parse('1 (16 oz) box pasta', 'eng')).to.deep.equal({ + unit: 'box', + unitPlural: 'boxes', + symbol: null, + quantity: 1, + ingredient: 'pasta (16 oz)', + minQty: 1, + maxQty: 1, + }); + }); + it('"1 slice cheese"', () => { + expect(parse('1 slice cheese', 'eng')).to.deep.equal({ + unit: 'slice', + unitPlural: 'slices', + symbol: null, + quantity: 1, + ingredient: 'cheese', + minQty: 1, + maxQty: 1, + }); + }); + }); + + it('translates unit when no unit provided', () => { + expect(parse('1 tortilla', 'eng')).to.deep.equal({ + unit: null, + unitPlural: null, + symbol: null, + ingredient: 'tortilla', + quantity: 1, + minQty: 1, + maxQty: 1, + }); + }); + + it("doesn't explode when no unit and no quantity provided", () => { + expect(parse('Powdered Sugar', 'eng')).to.deep.equal({ + ingredient: 'Powdered Sugar', + quantity: 0, + unit: null, + unitPlural: null, + symbol: null, + minQty: 0, + maxQty: 0, + }); + }); + + describe('translates the abbreviated units of', () => { + it('"1 cup water"', () => { + expect(parse('1 c water', 'eng').unit).to.equal('cup'); + expect(parse('2 c. water', 'eng').unit).to.equal('cup'); + expect(parse('2 cups water', 'eng').unit).to.equal('cup'); + }); + it('"1 gallon water"', () => { + expect(parse('1 gal water', 'eng').unit).to.equal('gallon'); + expect(parse('1 gallons water', 'eng').unit).to.equal('gallon'); + }); + it('"1 ounce water"', () => { + expect(parse('1 oz water', 'eng').unit).to.equal('ounce'); + expect(parse('1 oz. water', 'eng').unit).to.equal('ounce'); + expect(parse('2 ounces water', 'eng').unit).to.equal('ounce'); + }); + it('"1 pint water"', () => { + expect(parse('1 pt water', 'eng').unit).to.equal('pint'); + expect(parse('2 pts water', 'eng').unit).to.equal('pint'); + expect(parse('1 pt. water', 'eng').unit).to.equal('pint'); + expect(parse('2 pints water', 'eng').unit).to.equal('pint'); + }); + it('"1 pound water"', () => { + expect(parse('1 lb water', 'eng').unit).to.equal('pound'); + expect(parse('1 lb. water', 'eng').unit).to.equal('pound'); + expect(parse('2 lbs water', 'eng').unit).to.equal('pound'); + expect(parse('2 pounds water', 'eng').unit).to.equal('pound'); + }); + it('"1 quart water"', () => { + expect(parse('1 qt water', 'eng').unit).to.equal('quart'); + expect(parse('1 qt. water', 'eng').unit).to.equal('quart'); + expect(parse('1 qts water', 'eng').unit).to.equal('quart'); + expect(parse('1 quarts water', 'eng').unit).to.equal('quart'); + }); + it('"1 tablespoon water"', () => { + expect(parse('1 tbs water', 'eng').unit).to.equal('tablespoon'); + expect(parse('1 tbsp water', 'eng').unit).to.equal('tablespoon'); + expect(parse('1 tbspn water', 'eng').unit).to.equal('tablespoon'); + expect(parse('2 tablespoons water', 'eng').unit).to.equal('tablespoon'); + expect(parse('1 Tablespoon water', 'eng').unit).to.equal('tablespoon'); + expect(parse('2 Tablespoons water', 'eng').unit).to.equal('tablespoon'); + }); + it('"1 teaspoon water"', () => { + expect(parse('1 tsp water', 'eng').unit).to.equal('teaspoon'); + expect(parse('1 tspn water', 'eng').unit).to.equal('teaspoon'); + expect(parse('1 t water', 'eng').unit).to.equal('teaspoon'); + expect(parse('1 t. water', 'eng').unit).to.equal('teaspoon'); + expect(parse('2 teaspoons water', 'eng').unit).to.equal('teaspoon'); + }); + it('"1 gram water"', () => { + expect(parse('1 g water', 'eng').unit).to.equal('gram'); + expect(parse('1 g. water', 'eng').unit).to.equal('gram'); + expect(parse('2 grams water', 'eng').unit).to.equal('gram'); + }); + it('"1 kilogram water"', () => { + expect(parse('1 kg water', 'eng').unit).to.equal('kilogram'); + expect(parse('1 kg. water', 'eng').unit).to.equal('kilogram'); + expect(parse('2 kilograms water', 'eng').unit).to.equal('kilogram'); + }); + it('"1 liter water"', () => { + expect(parse('1 l water', 'eng').unit).to.equal('liter'); + expect(parse('1 l. water', 'eng').unit).to.equal('liter'); + expect(parse('2 liters water', 'eng').unit).to.equal('liter'); + }); + it('"1 milligram water"', () => { + expect(parse('1 mg water', 'eng').unit).to.equal('milligram'); + expect(parse('1 mg. water', 'eng').unit).to.equal('milligram'); + expect(parse('1 milligrams water', 'eng').unit).to.equal('milligram'); + }); + it('"1 milliliter water"', () => { + expect(parse('1 ml water', 'eng').unit).to.equal('milliliter'); + expect(parse('1 ml. water', 'eng').unit).to.equal('milliliter'); + expect(parse('1 milliliters water', 'eng').unit).to.equal('milliliter'); + }); + it('"1 pinch water"', () => { + expect(parse('2 pinches salt', 'eng').unit).to.equal('pinch'); + }); + }); + + describe('translates the ingredient of', () => { + it('"1 teaspoon water"', () => { + expect(parse('1 teaspoon of water', 'eng').ingredient).to.equal('water'); + }); + it('"1 teaspoon milk"', () => { + expect(parse('1 teaspoon of milk', 'eng').ingredient).to.equal('milk'); + }); + it('"1 teaspoon of milk"', () => { + expect(parse('1 teaspoon of milk', 'eng').ingredient).to.equal('milk'); + }); + it('"1 teaspoon of milk"', () => { + expect(parse('1 teaspoon of powdered sugar', 'eng').ingredient).to.equal( + 'powdered sugar', + ); + }); + }); +}); diff --git a/test/index-ita.test.ts b/test/index-ita.test.ts new file mode 100644 index 0000000..8ddcd2f --- /dev/null +++ b/test/index-ita.test.ts @@ -0,0 +1,880 @@ +import {expect} from 'chai'; +import {multiLineParse, parse} from '../src/index'; + +describe('recipe parser ita', () => { + it('returns an object', () => { + expect(typeof parse('1 tazza acqua', 'ita')).to.equal('object'); + }); + + describe('translates the unit', () => { + it('of "qb di acqua"', () => { + expect(parse('qb di acqua', 'ita').unit).to.equal('q.b.'); + expect(parse('qb di acqua', 'ita').quantity).to.equal(0); + }); + it('of "quanto basta acqua"', () => { + expect(parse('quanto basta di acqua', 'ita').unit).to.equal('q.b.'); + }); + it('of "Quanto basta acqua"', () => { + expect(parse('Quanto basta di acqua', 'ita').unit).to.equal('q.b.'); + }); + it('of "Quanto Basta acqua"', () => { + expect(parse('Quanto Basta di acqua', 'ita').unit).to.equal('q.b.'); + }); + it('of "q.b. di farina"', () => { + expect(parse('q.b. di farina', 'ita').ingredient).to.equal('farina'); + }); + it('of "q.b. di farina"', () => { + expect(parse('q.b. di farina', 'ita').unit).to.equal('q.b.'); + }); + it('of "q.b. farina"', () => { + expect(parse('q.b. farina', 'ita').ingredient).to.equal('farina'); + }); + it('of "grammi farina"', () => { + expect(parse('grammi farina', 'ita').unit).to.equal('grammo'); + }); + it('of "grammi farina"', () => { + expect(parse('grammi farina', 'ita').ingredient).to.equal('farina'); + }); + it('of "Q.B. di acqua"', () => { + expect(parse('Q.B. di acqua', 'ita').unit).to.equal('q.b.'); + }); + it('of "acqua quanto basta"', () => { + expect(parse('acqua quanto basta', 'ita').unit).to.equal('q.b.'); + }); + + it('of "QB di acqua"', () => { + expect(parse('QB di acqua', 'ita').unit).to.equal('q.b.'); + }); + it('of "QB. di acqua"', () => { + expect(parse('QB. di acqua', 'ita').unit).to.equal('q.b.'); + }); + it('of "Q.B di acqua"', () => { + expect(parse('Q.b di acqua', 'ita').unit).to.equal('q.b.'); + }); + it('of "1 cucchiao acqua"', () => { + expect(parse('1 cucchiao acqua', 'ita').quantity).to.equal(1); + }); + it('of "1,5 cucchiao acqua"', () => { + expect(parse('1,5 cucchiao acqua', 'ita').quantity).to.equal(1.5); + }); + it('of "1 1/2 cucchiao acqua"', () => { + expect(parse('1 1/2 cucchiao acqua', 'ita').quantity).to.equal(1.5); + }); + it('of "1/3 cucchiao acqua"', () => { + expect(parse('1/3 cucchiao acqua', 'ita').quantity).to.equal(0.333); + }); + it('of "1/2 cucchiao acqua"', () => { + expect(parse('1/2 cucchiao acqua', 'ita').quantity).to.equal(0.5); + }); + it('of "10 1/2 cucchiao acqua"', () => { + expect(parse('10 1/2 cucchiao acqua', 'ita').quantity).to.equal(10.5); + }); + it('of "about 1/2 cucchiao acqua"', () => { + expect(parse('about 1/2 cucchiao acqua', 'ita').quantity).to.equal(0.5); + }); + + describe('translates the quantity from string to number', () => { + it("Un cucchiaio d'acqua", () => { + expect(parse("Un cucchiaio d'acqua", 'ita').quantity).to.equal(1); + }); + it("Un cucchiaio d'acqua", () => { + expect(parse("Un cucchiaio d'acqua", 'ita').quantity).to.equal(1); + }); + it("mezzo cucchiaio d'acqua", () => { + expect(parse("mezzo cucchiaio d'acqua", 'ita').quantity).to.equal(0.5); + }); + it("meta cucchiaio d'acqua", () => { + expect(parse("meta cucchiaio d'acqua", 'ita').quantity).to.equal(0.5); + }); + it('Venti cucchiai d\'acqua"', () => { + expect(parse("Venti cucchiai d'acqua", 'ita').quantity).to.equal(20); + }); + it('cinque cucchiai d\'acqua"', () => { + expect(parse("cinque cucchiai d'acqua", 'ita').quantity).to.equal(5); + }); + it('ventuno cucchiai d\'acqua"', () => { + expect(parse("ventuno cucchiai d'acqua", 'ita').quantity).to.equal(21); + }); + it('mezzo spicchio d\'aglio"', () => { + expect(parse("mezzo spicchio d'aglio", 'ita').quantity).to.equal(0.5); + }); + it('cento grammi d\'aglio"', () => { + expect(parse("cento grammi d'aglio", 'ita').quantity).to.equal(100); + }); + it('cento-due grammi d\'aglio"', () => { + expect(parse("cento-due grammi d'aglio", 'ita').quantity).to.equal(102); + }); + it('due-cento grammi d\'aglio"', () => { + expect(parse("due-cento grammi d'aglio", 'ita').quantity).to.equal(200); + }); + it('due-mila grammi d\'aglio"', () => { + expect(parse("due-mila grammi d'aglio", 'ita').quantity).to.equal(2000); + }); + it('due grammi farina"', () => { + expect(parse('due grammi farina', 'ita').quantity).to.equal(2); + }); + }); + + // describe('translates the quantity range', () => { + // it('of "10-20 cucchiao acqua"', () => { + // expect(parse('10-20 cucchiao acqua', 'ita').quantity).to.equal('10-20'); + // }); + // it('of "10 - 20 cucchiao acqua"', () => { + // expect(parse('10 - 20 cucchiao acqua', 'ita').quantity).to.equal('10-20'); + // }); + // it('of "10 to 20 cucchiao acqua"', () => { + // expect(parse('10 to 20 cucchiao acqua', 'ita').quantity).to.equal('10-20'); + // }); + // }); + + describe('of unicode fractions', () => { + const unicodeAmounts = [ + '¼', + '½', + '¾', + '⅐', + '⅑', + '⅒', + '⅓', + '⅔', + '⅕', + '⅖', + '⅗', + '⅘', + '⅙', + '⅚', + '⅛', + '⅜', + '⅝', + '⅞', + ]; + const unicodeExpectedAmounts = [ + 0.25, 0.5, 0.75, 0.142, 0.111, 0.1, 0.333, 0.666, 0.2, 0.4, 0.6, 0.8, + 0.166, 0.833, 0.125, 0.375, 0.625, 0.875, + ]; + + for (let u = 0; u < unicodeAmounts.length; u++) { + const element = unicodeAmounts[u]; + const expectedAmount = unicodeExpectedAmounts[u]; + it(`${element} to ${expectedAmount}`, () => { + expect(parse(`${element} cucchiao acqua`, 'ita').quantity).to.equal( + expectedAmount, + ); + }); + } + + const mixedValues = [ + '1¼', + '2½', + '3¾', + '4⅐', + '5⅑', + '6⅒', + '7⅓', + '8⅔', + '9⅕', + '10⅖', + '11⅗', + '12⅘', + '13⅙', + '14⅚', + '15⅛', + '16⅜', + '17⅝', + '18⅞', + ]; + const mixedExpectedValues = [ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + ]; + + for (let u = 0; u < mixedValues.length; u++) { + const element = mixedValues[u]; + const expectedAmount = + Number(mixedExpectedValues[u]) + Number(unicodeExpectedAmounts[u]); + it(`${element} to ${expectedAmount}`, () => { + expect(parse(`${element} cucchiao acqua`, 'ita').quantity).to.equal( + expectedAmount, + ); + }); + } + }); + + it("doesn't freak out if a strange unicode character is present", () => { + expect(parse('1/3 tazza zucchero a velo', 'ita')).to.deep.equal({ + quantity: 0.333, + unit: 'tazza', + unitPlural: 'tazze', + symbol: null, + ingredient: 'zucchero a velo', + minQty: 0.333, + maxQty: 0.333, + }); + }); + }); + + describe('translates the literal units', () => { + it('of "1 tazza acqua"', () => { + expect(parse('1 tazza acqua', 'ita').unit).to.equal('tazza'); + }); + it('of "1 litro acqua"', () => { + expect(parse('1 litro acqua', 'ita').unit).to.equal('litro'); + }); + it('of "1 lt acqua"', () => { + expect(parse('1 lt acqua', 'ita').unit).to.equal('litro'); + }); + it('of "1 kg acqua"', () => { + expect(parse('1 kg acqua', 'ita').unit).to.equal('chilogrammo'); + }); + it('of "1 L acqua"', () => { + expect(parse('1 L acqua', 'ita').unit).to.equal('litro'); + }); + it('of "1 L. acqua"', () => { + expect(parse('1 L. acqua', 'ita').unit).to.equal('litro'); + }); + it('of "1 cucchiaio acqua"', () => { + expect(parse('1 cucchiaio acqua', 'ita').unit).to.equal('cucchiaio'); + }); + it('of "1 cucchiaio acqua"', () => { + expect(parse('1 cucchiaio acqua', 'ita').unit).to.equal('cucchiaio'); + }); + it('of "1 grammo acqua"', () => { + expect(parse('1 grammo acqua', 'ita').unit).to.equal('grammo'); + }); + it('of "1 chilogrammo acqua"', () => { + expect(parse('1 chilogrammo acqua', 'ita').unit).to.equal('chilogrammo'); + }); + it('of "1 litro acqua"', () => { + expect(parse('1 litro acqua', 'ita').unit).to.equal('litro'); + }); + it('of "1 milligrammo acqua"', () => { + expect(parse('1 milligrammo acqua', 'ita').unit).to.equal('milligrammo'); + }); + it('of "1 millilitro acqua"', () => { + expect(parse('1 millilitro acqua', 'ita').unit).to.equal('millilitro'); + }); + it('of "1 l cipolla"', () => { + expect(parse('1 l cipolla', 'ita').unit).to.equal('litro'); + }); + it('of "1 cipolla intera"', () => { + expect(parse('1 cipolla intera', 'ita').unit).to.equal(null); + }); + it('of "1 spicchio agilio"', () => { + expect(parse('1 spicchio agilio', 'ita').unit).to.equal('spicchio'); + }); + it('of "1 bustina aglio"', () => { + expect(parse('1 bustina aglio', 'ita').unit).to.equal('bustina'); + }); + it('of "1 pacco salsicce"', () => { + expect(parse('1 pacco salsicce', 'ita').unit).to.equal('pacco'); + }); + it('"1 pizzico sale"', () => { + expect(parse('1 pizzico sale', 'ita').unit).to.equal('pizzico'); + }); + it('"1 foglia prezzemolo"', () => { + expect(parse('1 foglia prezzemolo', 'ita').unit).to.equal('foglia'); + }); + it('"1 mazzetto prezzemolo"', () => { + expect(parse('1 mazzetto prezzemolo', 'ita').unit).to.equal('mazzetto'); + }); + it('"1 vasetto yogurt"', () => { + expect(parse('1 vasetto yogurt', 'ita').unit).to.equal('vasetto'); + }); + it('"1 (14.5 oz) lattina pommodori"', () => { + expect(parse('1 (14.5 oz) lattina pommodori', 'ita')).to.deep.equal({ + unit: 'lattina', + unitPlural: 'lattine', + symbol: null, + quantity: 1, + ingredient: 'pommodori (14.5 oz)', + minQty: 1, + maxQty: 1, + }); + }); + it('"parses ingredient with range: 1 to 2 petto di pollo"', () => { + expect(parse('1 o 2 petto di pollo', 'ita')).to.deep.equal({ + unit: null, + unitPlural: null, + symbol: null, + quantity: 1, + ingredient: 'petto di pollo', + minQty: 1, + maxQty: 2, + }); + }); + it('"parses ingredient with range: 1 - 2 petto di pollo"', () => { + expect(parse('1 - 2 petto di pollo', 'ita')).to.deep.equal({ + unit: null, + unitPlural: null, + symbol: null, + quantity: 1, + ingredient: 'petto di pollo', + minQty: 1, + maxQty: 2, + }); + }); + it('"parses ingredient with range: 1-2 petto di pollo"', () => { + expect(parse('1-2 petto di pollo', 'ita')).to.deep.equal({ + unit: null, + unitPlural: null, + symbol: null, + quantity: 1, + ingredient: 'petto di pollo', + minQty: 1, + maxQty: 2, + }); + }); + it('"1 (16 oz) scatola pasta"', () => { + expect(parse('1 (16 oz) scatola pasta', 'ita')).to.deep.equal({ + unit: 'scatola', + unitPlural: 'scatole', + symbol: null, + quantity: 1, + ingredient: 'pasta (16 oz)', + minQty: 1, + maxQty: 1, + }); + }); + it('"1 fetta di formaggio"', () => { + expect(parse('1 fetta di formaggio', 'ita')).to.deep.equal({ + unit: 'fetta', + unitPlural: 'fette', + quantity: 1, + symbol: null, + ingredient: 'formaggio', + minQty: 1, + maxQty: 1, + }); + }); + it('"1 spicchio d\'aglio"', () => { + expect(parse("1 spicchio d'aglio", 'ita')).to.deep.equal({ + unit: 'spicchio', + unitPlural: 'spicchi', + quantity: 1, + symbol: null, + ingredient: 'aglio', + minQty: 1, + maxQty: 1, + }); + }); + describe('" check the correct symbol"', () => { + it('"grammi di farina"', () => { + expect(parse('grammi di farina', 'ita')).to.deep.equal({ + unit: 'grammo', + unitPlural: 'grammi', + quantity: 0, + symbol: 'g', + ingredient: 'farina', + minQty: 0, + maxQty: 0, + }); + }); + it('"100 grammi di farina"', () => { + expect(parse('100 grammi di farina', 'ita')).to.deep.equal({ + unit: 'grammo', + unitPlural: 'grammi', + quantity: 100, + symbol: 'g', + ingredient: 'farina', + minQty: 100, + maxQty: 100, + }); + }); + it('"1 spicchio d\'aglio"', () => { + expect(parse("1 spicchio d'aglio", 'ita')).to.deep.equal({ + unit: 'spicchio', + unitPlural: 'spicchi', + quantity: 1, + symbol: null, + ingredient: 'aglio', + minQty: 1, + maxQty: 1, + }); + }); + it('"1 kilogrammo d\'aglio"', () => { + expect(parse("1 kilogrammo d'aglio", 'ita')).to.deep.equal({ + unit: 'chilogrammo', + unitPlural: 'chilogrammi', + quantity: 1, + symbol: 'kg', + ingredient: 'aglio', + minQty: 1, + maxQty: 1, + }); + }); + it('"1 cucchiaino riso"', () => { + expect(parse('1 cucchiaino riso', 'ita')).to.deep.equal({ + unit: 'cucchiaino', + unitPlural: 'cucchiaini', + quantity: 1, + symbol: 'cc', + ingredient: 'riso', + minQty: 1, + maxQty: 1, + }); + }); + it('"100 litri di latte"', () => { + expect(parse('100 litri di latte', 'ita')).to.deep.equal({ + unit: 'litro', + unitPlural: 'litri', + quantity: 100, + symbol: 'lt', + ingredient: 'latte', + minQty: 100, + maxQty: 100, + }); + }); + it('"100 milligrammi di olio"', () => { + expect(parse('100 milligrammi di olio', 'ita')).to.deep.equal({ + unit: 'milligrammo', + unitPlural: 'milligrammi', + quantity: 100, + symbol: 'mg', + ingredient: 'olio', + minQty: 100, + maxQty: 100, + }); + }); + it('"100 rotoli di olio"', () => { + expect(parse('100 rotoli di olio', 'ita')).to.deep.equal({ + unit: 'rotolo', + unitPlural: 'rotoli', + quantity: 100, + symbol: null, + ingredient: 'olio', + minQty: 100, + maxQty: 100, + }); + }); + it('"100 bicchierini di olio"', () => { + expect(parse('100 bicchierino di olio', 'ita')).to.deep.equal({ + unit: 'bicchierino', + unitPlural: 'bicchierini', + quantity: 100, + symbol: null, + ingredient: 'olio', + minQty: 100, + maxQty: 100, + }); + }); + it('"Un filo d\'olio"', () => { + expect(parse("Un filo d'olio", 'ita')).to.deep.equal({ + unit: 'filo', + unitPlural: 'fili', + quantity: 1, + symbol: null, + ingredient: 'olio', + minQty: 1, + maxQty: 1, + }); + }); + it('"Un ciuffo di prezzemolo"', () => { + expect(parse('Un ciuffo di prezzemolo', 'ita')).to.deep.equal({ + unit: 'ciuffo', + unitPlural: 'ciuffi', + quantity: 1, + symbol: null, + ingredient: 'prezzemolo', + minQty: 1, + maxQty: 1, + }); + }); + it('"100 millilitri di latte"', () => { + expect(parse('100 millilitri di latte', 'ita')).to.deep.equal({ + unit: 'millilitro', + unitPlural: 'millilitri', + quantity: 100, + symbol: 'ml', + ingredient: 'latte', + minQty: 100, + maxQty: 100, + }); + }); + it('"quanto basta di latte"', () => { + expect(parse('quanto basta di latte', 'ita')).to.deep.equal({ + unit: 'q.b.', + unitPlural: 'q.b.', + quantity: 0, + symbol: null, + ingredient: 'latte', + minQty: 0, + maxQty: 0, + }); + }); + it('"Quanto Basta di latte"', () => { + expect(parse('quanto basta di latte', 'ita')).to.deep.equal({ + unit: 'q.b.', + unitPlural: 'q.b.', + quantity: 0, + symbol: null, + ingredient: 'latte', + minQty: 0, + maxQty: 0, + }); + }); + it('"qb di latte"', () => { + expect(parse('quanto basta di latte', 'ita')).to.deep.equal({ + unit: 'q.b.', + unitPlural: 'q.b.', + quantity: 0, + symbol: null, + ingredient: 'latte', + minQty: 0, + maxQty: 0, + }); + }); + it('"q.b. di latte"', () => { + expect(parse('q.b. di latte', 'ita')).to.deep.equal({ + unit: 'q.b.', + unitPlural: 'q.b.', + quantity: 0, + symbol: null, + ingredient: 'latte', + minQty: 0, + maxQty: 0, + }); + }); + it('"q.b. latte"', () => { + expect(parse('q.b. latte', 'ita')).to.deep.equal({ + unit: 'q.b.', + unitPlural: 'q.b.', + quantity: 0, + symbol: null, + ingredient: 'latte', + minQty: 0, + maxQty: 0, + }); + }); + }); + }); + + it('translates unit when no unit provided', () => { + expect(parse('1 tortilla', 'ita')).to.deep.equal({ + unit: null, + unitPlural: null, + symbol: null, + ingredient: 'tortilla', + quantity: 1, + minQty: 1, + maxQty: 1, + }); + }); + it('test order and case sensitive', () => { + expect(parse('100 ml. tortilla ', 'ita')).to.deep.equal({ + unit: 'millilitro', + unitPlural: 'millilitri', + symbol: 'ml', + ingredient: 'tortilla', + quantity: 100, + minQty: 100, + maxQty: 100, + }); + expect(parse('100 mg. tortilla ', 'ita')).to.deep.equal({ + unit: 'milligrammo', + unitPlural: 'milligrammi', + symbol: 'mg', + ingredient: 'tortilla', + quantity: 100, + minQty: 100, + maxQty: 100, + }); + expect(parse('100 g. tortilla ', 'ita')).to.deep.equal({ + unit: 'grammo', + unitPlural: 'grammi', + symbol: 'g', + ingredient: 'tortilla', + quantity: 100, + minQty: 100, + maxQty: 100, + }); + expect(parse("1 g. d' acqua", 'ita')).to.deep.equal({ + unit: 'grammo', + unitPlural: 'grammi', + symbol: 'g', + ingredient: 'acqua', + quantity: 1, + minQty: 1, + maxQty: 1, + }); + expect(parse('100 g. di tortilla ', 'ita')).to.deep.equal({ + unit: 'grammo', + unitPlural: 'grammi', + symbol: 'g', + ingredient: 'tortilla', + quantity: 100, + minQty: 100, + maxQty: 100, + }); + expect(parse('q.b. di sale', 'ita')).to.deep.equal({ + unit: 'q.b.', + unitPlural: 'q.b.', + symbol: null, + ingredient: 'sale', + quantity: 0, + minQty: 0, + maxQty: 0, + }); + expect(parse('100 gr. tortilla ', 'ita')).to.deep.equal({ + unit: 'grammo', + unitPlural: 'grammi', + symbol: 'g', + ingredient: 'tortilla', + quantity: 100, + minQty: 100, + maxQty: 100, + }); + expect(parse('tortilla 100 gr.', 'ita')).to.deep.equal({ + unit: 'grammo', + unitPlural: 'grammi', + symbol: 'g', + ingredient: 'tortilla', + quantity: 100, + minQty: 100, + maxQty: 100, + }); + expect(parse('basilico quanto basta', 'ita')).to.deep.equal({ + unit: 'q.b.', + unitPlural: 'q.b.', + symbol: null, + ingredient: 'basilico', + quantity: 0, + minQty: 0, + maxQty: 0, + }); + expect(parse('basilico q.b.', 'ita')).to.deep.equal({ + unit: 'q.b.', + unitPlural: 'q.b.', + symbol: null, + ingredient: 'basilico', + quantity: 0, + minQty: 0, + maxQty: 0, + }); + expect(parse('basilico QB', 'ita')).to.deep.equal({ + unit: 'q.b.', + unitPlural: 'q.b.', + symbol: null, + ingredient: 'basilico', + quantity: 0, + minQty: 0, + maxQty: 0, + }); + expect(parse('basilico millilitri 100', 'ita')).to.deep.equal({ + unit: 'millilitro', + unitPlural: 'millilitri', + symbol: 'ml', + ingredient: 'basilico', + quantity: 100, + minQty: 100, + maxQty: 100, + }); + }); + it("doesn't explode when no unit and no quantity provided", () => { + expect(parse('zucchero a velo', 'ita')).to.deep.equal({ + unit: null, + unitPlural: null, + symbol: null, + ingredient: 'zucchero a velo', + quantity: 0, + minQty: 0, + maxQty: 0, + }); + }); + it('test noci', () => { + expect(parse('quattro noci', 'ita')).to.deep.equal({ + unit: null, + unitPlural: null, + symbol: null, + ingredient: 'noci', + quantity: 4, + minQty: 4, + maxQty: 4, + }); + expect(parse('una noce', 'ita')).to.deep.equal({ + unit: null, + unitPlural: null, + symbol: null, + ingredient: 'noce', + quantity: 1, + minQty: 1, + maxQty: 1, + }); + expect(parse('100 gr di noci', 'ita')).to.deep.equal({ + unit: 'grammo', + unitPlural: 'grammi', + symbol: 'g', + ingredient: 'noci', + quantity: 100, + minQty: 100, + maxQty: 100, + }); + }); + describe('translates the abbreviated units of', () => { + it('"1 tazza acqua"', () => { + expect(parse('1 tazza acqua', 'ita').unit).to.equal('tazza'); + expect(parse('2 tazzine acqua', 'ita').unit).to.equal('tazza'); + expect(parse('2 tazze acqua', 'ita').unit).to.equal('tazza'); + }); + it('"1 litro acqua"', () => { + expect(parse('1 l acqua', 'ita').unit).to.equal('litro'); + expect(parse('1 litri acqua', 'ita').unit).to.equal('litro'); + }); + it('"1 grammo acqua"', () => { + expect(parse('1 gr acqua', 'ita').unit).to.equal('grammo'); + expect(parse('2 g acqua', 'ita').unit).to.equal('grammo'); + expect(parse('2 g. acqua', 'ita').ingredient).to.equal('acqua'); + }); + it('"1 chilogrammo acqua"', () => { + expect(parse('1 kg acqua', 'ita').unit).to.equal('chilogrammo'); + expect(parse('2 KG acqua', 'ita').unit).to.equal('chilogrammo'); + expect(parse('1 kilogrammo acqua', 'ita').unit).to.equal('chilogrammo'); + expect(parse('2 Kilogrammo acqua', 'ita').unit).to.equal('chilogrammo'); + expect(parse('acqua KILOGRAMMO 2', 'ita').unit).to.equal('chilogrammo'); + expect(parse('acqua KILOGRAMMO due', 'ita').unit).to.equal('chilogrammo'); + }); + it('"1 tazza acqua"', () => { + expect(parse('1 tazza acqua', 'ita').unit).to.equal('tazza'); + expect(parse('1 tazzina acqua', 'ita').unit).to.equal('tazza'); + expect(parse('2 tazzine acqua', 'ita').unit).to.equal('tazza'); + expect(parse('2 Tazza acqua', 'ita').unit).to.equal('tazza'); + }); + it('"1 millilitro acqua"', () => { + expect(parse('1 ml acqua', 'ita').unit).to.equal('millilitro'); + expect(parse('1 ml. acqua', 'ita').unit).to.equal('millilitro'); + expect(parse('1 millilitro acqua', 'ita').unit).to.equal('millilitro'); + expect(parse('1 Millilitro acqua', 'ita').unit).to.equal('millilitro'); + }); + it('"1 cucchiaio acqua"', () => { + expect(parse('2 cucchiai acqua', 'ita').unit).to.equal('cucchiaio'); + expect(parse('1 Cucchiaio acqua', 'ita').unit).to.equal('cucchiaio'); + expect(parse('2 cucchiai acqua', 'ita').unit).to.equal('cucchiaio'); + }); + it('"1 cucchiaino acqua"', () => { + expect(parse('1 Cucchiaino acqua', 'ita').unit).to.equal('cucchiaino'); + expect(parse('1 cucchiaino acqua', 'ita').unit).to.equal('cucchiaino'); + expect(parse('2 Cucchiaini acqua', 'ita').unit).to.equal('cucchiaino'); + expect(parse('2 cucchiaini acqua', 'ita').unit).to.equal('cucchiaino'); + }); + it('"1 grammo acqua"', () => { + expect(parse('1 g acqua', 'ita').unit).to.equal('grammo'); + expect(parse('1 g. acqua', 'ita').unit).to.equal('grammo'); + expect(parse('2 grammi acqua', 'ita').unit).to.equal('grammo'); + }); + it('"1 chilogrammo acqua"', () => { + expect(parse('1 kg acqua', 'ita').unit).to.equal('chilogrammo'); + expect(parse('1 kg. acqua', 'ita').unit).to.equal('chilogrammo'); + expect(parse('2 chilogrammi acqua', 'ita').unit).to.equal('chilogrammo'); + }); + it('"1 litro acqua"', () => { + expect(parse('1 l acqua', 'ita').unit).to.equal('litro'); + expect(parse('1 l. acqua', 'ita').unit).to.equal('litro'); + expect(parse('2 litri acqua', 'ita').unit).to.equal('litro'); + }); + it('"1 milligrammo acqua"', () => { + expect(parse('1 mg acqua', 'ita').unit).to.equal('milligrammo'); + expect(parse('1 mg. acqua', 'ita').unit).to.equal('milligrammo'); + expect(parse('1 milligrammo acqua', 'ita').unit).to.equal('milligrammo'); + }); + it('"1 millilitro acqua"', () => { + expect(parse('1 ml acqua', 'ita').unit).to.equal('millilitro'); + expect(parse('1 ml. acqua', 'ita').unit).to.equal('millilitro'); + expect(parse('1 millilitro acqua', 'ita').unit).to.equal('millilitro'); + }); + it('"1 pizzico acqua"', () => { + expect(parse('2 pizzichi sale', 'ita').unit).to.equal('pizzico'); + }); + it('"1 cubetto di ghiaccio"', () => { + expect(parse('2 cubetto di ghiaccio', 'ita').unit).to.equal('cubetto'); + }); + }); + + describe('translates the ingredient of', () => { + it('"1 cucchiaio d\'acqua"', () => { + expect(parse("1 cucchiaio d'acqua", 'ita').ingredient).to.equal('acqua'); + }); + it('"1 spicchio d\'aglio"', () => { + expect(parse("1 cucchiaio d'acqua", 'ita').ingredient).to.equal('acqua'); + }); + it('"1 cucchiaio di latte"', () => { + expect(parse('1 cucchiaio di latte', 'ita').ingredient).to.equal('latte'); + }); + it('"1 cucchiaio acqua"', () => { + expect(parse('1 cucchiaio acqua', 'ita').ingredient).to.equal('acqua'); + }); + it('"1 cucchiaio latte"', () => { + expect(parse('1 cucchiaio latte', 'ita').ingredient).to.equal('latte'); + }); + }); + + describe('translates the ingredient of', () => { + it('"1 g di latte"', () => { + expect(parse('1 g di latte', 'ita').ingredient).to.equal('latte'); + }); + it('"1 kg di latte"', () => { + expect(parse('1 kg di latte', 'ita').ingredient).to.equal('latte'); + }); + it('"250 kg di farina"', () => { + expect(parse('250 kg di farina', 'ita').ingredient).to.equal('farina'); + }); + it('"dieci kg farina"', () => { + expect(parse('dieci kg farina', 'ita').ingredient).to.equal('farina'); + }); + it('"dieci kg farina"', () => { + expect(parse('dieci kg farina', 'ita').ingredient).to.equal('farina'); + }); + }); + + describe('split on separator', () => { + it('"quattro noci - quattro noci"', () => { + expect( + multiLineParse('quattro noci - quattro noci', 'ita')[0], + ).to.deep.equal({ + unit: null, + unitPlural: null, + symbol: null, + ingredient: 'noci', + quantity: 4, + minQty: 4, + maxQty: 4, + }); + }), + it('"tre noci - 8 noci"', () => { + expect( + multiLineParse('tre noci - quattro noci', 'ita')[0], + ).to.deep.equal({ + unit: null, + unitPlural: null, + symbol: null, + ingredient: 'noci', + quantity: 3, + minQty: 3, + maxQty: 3, + }); + }); + it('"👉 tre noci 👉 8 noci"', () => { + expect( + multiLineParse('👉 tre noci 👉 quattro noci', 'ita')[0], + ).to.deep.equal({ + unit: null, + unitPlural: null, + symbol: null, + ingredient: 'noci', + quantity: 3, + minQty: 3, + maxQty: 3, + }); + }); + it('"👉🏻 tre noci 👉 8 noci"', () => { + expect( + multiLineParse('👉🏻 tre noci 👉 quattro noci', 'ita')[0], + ).to.deep.equal({ + unit: null, + unitPlural: null, + symbol: null, + ingredient: 'noci', + quantity: 3, + minQty: 3, + maxQty: 3, + }); + }); + }); +}); diff --git a/test/index.test.ts b/test/index.test.ts index 09c2564..6d79e63 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -1,1666 +1,509 @@ -import { expect } from 'chai'; -import { parse, multiLineParse } from '../src/index'; -/* -describe('recipe parser eng', () => { - it('returns an object', () => { - expect(typeof parse('1 cup water', 'eng')).to.equal('object'); - }); - - describe('translates the quantity', () => { - it('of "to taste of water"', () => { - expect(parse('to taste of water', 'eng').unit).to.equal('t.t.'); - }); - it('of "To taste of water"', () => { - expect(parse('To taste of water', 'eng').unit).to.equal('t.t.'); - }); - it('of "t.t. of water"', () => { - expect(parse('t.t. of water', 'eng').unit).to.equal('t.t.'); - }); - it('of "t.t. of water"', () => { - expect(parse('t.t. of water', 'eng').unit).to.equal('t.t.'); - }); - it('of "TT of water"', () => { - expect(parse('TT of water', 'eng').unit).to.equal('t.t.'); - }); - it('of "TT. of water"', () => { - expect(parse('TT. of water', 'eng').unit).to.equal('t.t.'); - }); - it('of "T.t of water"', () => { - expect(parse('T.t of water', 'eng').unit).to.equal('t.t.'); - }); - it('of "1 teaspoon water"', () => { - expect(parse('1 teaspoon water', 'eng').quantity).to.equal(1); - }); - it('of "1.5 teaspoon water"', () => { - expect(parse('1.5 teaspoon water', 'eng').quantity).to.equal(1.5); - }); - it('of "1 1/2 teaspoon water"', () => { - expect(parse('1 1/2 teaspoon water', 'eng').quantity).to.equal(1.5); - }); - it('of "1/3 teaspoon water"', () => { - expect(parse('1/3 cup water', 'eng').quantity).to.equal(0.333); - }); - it('of "1/2 teaspoon water"', () => { - expect(parse('1/2 teaspoon water', 'eng').quantity).to.equal(0.5); - }); - it('of "10 1/2 teaspoon water"', () => { - expect(parse('10 1/2 teaspoon water', 'eng').quantity).to.equal(10.5); - }); - it('of "about 1/2 teaspoon water"', () => { - expect(parse('about 1/2 teaspoon water', 'eng').quantity).to.equal(0.5); - }); +import {expect} from 'chai'; +import {combine, Ingredient, prettyPrintingPress} from '../src/index'; - describe('translates the quantity from string to number', () => { - it('one teaspoon water"', () => { - expect(parse('one teaspoon water', 'eng').quantity).to.equal(1); - }); - it('twenty-one teaspoon water"', () => { - expect(parse('twenty-one teaspoon water', 'eng').quantity).to.equal(21); - }); - it('five teaspoon water"', () => { - expect(parse('five teaspoon water', 'eng').quantity).to.equal(5); - }); - }); +describe('combine ingredients', () => { + it('accepts an empty array', () => { + expect(combine([])).to.deep.equal([]); + }); -// describe('translates the quantity range', () => { -// it('of "10-20 teaspoon water"', () => { -// expect(parse('10-20 teaspoon water', 'eng').quantity).to.equal('10-20'); -// }); -// it('of "10 - 20 teaspoon water"', () => { -// expect(parse('10 - 20 teaspoon water', 'eng').quantity).to.equal('10-20'); -// }); -// it('of "10 to 20 teaspoon water"', () => { -// expect(parse('10 to 20 teaspoon water', 'eng').quantity).to.equal('10-20'); -// }); -// }); + it('returns sorted ingredients', () => { + const ingredientArray: Ingredient[] = [ + { + ingredient: 'butter', + quantity: 2, + unit: 'tablespoon', + symbol: 'tbs', + minQty: 2, + maxQty: 2, + }, + { + ingredient: 'apples', + quantity: 2, + unit: 'pound', + symbol: 'lb', + minQty: 2, + maxQty: 2, + }, + ]; + expect(combine(ingredientArray)).to.deep.equal([ + { + ingredient: 'apples', + quantity: 2, + unit: 'pound', + symbol: 'lb', + minQty: 2, + maxQty: 2, + }, + { + ingredient: 'butter', + quantity: 2, + unit: 'tablespoon', + symbol: 'tbs', + minQty: 2, + maxQty: 2, + }, + ]); + }); - describe('of unicode fractions', () => { - const unicodeAmounts = ['¼', '½', '¾', '⅐', '⅑', '⅒', '⅓', '⅔', '⅕', '⅖', '⅗', '⅘', '⅙', '⅚', '⅛', '⅜', '⅝', '⅞']; - const unicodeExpectedAmounts = [0.25, 0.5, 0.75, 0.142, 0.111, 0.1, 0.333, 0.666, 0.2, 0.4, 0.6, 0.8, 0.166, 0.833, 0.125, 0.375, 0.625, 0.875]; + it('combines two ingredient objects into one', () => { + const ingredientArray: Ingredient[] = [ + { + ingredient: 'butter', + quantity: 2, + unit: 'tablespoon', + symbol: 'tbs', + minQty: 2, + maxQty: 2, + }, + { + ingredient: 'butter', + quantity: 2, + unit: 'tablespoon', + symbol: 'tbs', + minQty: 2, + maxQty: 2, + }, + ]; + expect(combine(ingredientArray)).to.deep.equal([ + { + ingredient: 'butter', + quantity: 4, + unit: 'tablespoon', + symbol: 'tbs', + minQty: 4, + maxQty: 4, + }, + ]); + }); - for (let u = 0; u < unicodeAmounts.length; u++) { - const element = unicodeAmounts[u]; - const expectedAmount = unicodeExpectedAmounts[u]; - it(`${element} to ${expectedAmount}`, () => { - expect(parse(`${element} teaspoon water`, 'eng').quantity).to.equal(expectedAmount); - }); - } + it('combines three ingredient objects into one', () => { + const ingredientArray: Ingredient[] = [ + { + ingredient: 'butter', + quantity: 2, + unit: 'tablespoon', + symbol: 'tbs', + minQty: 2, + maxQty: 2, + }, + { + ingredient: 'butter', + quantity: 2, + unit: 'tablespoon', + symbol: 'tbs', + minQty: 2, + maxQty: 2, + }, + { + ingredient: 'butter', + quantity: 2, + unit: 'tablespoon', + symbol: 'tbs', + minQty: 2, + maxQty: 2, + }, + ]; + expect(combine(ingredientArray)).to.deep.equal([ + { + ingredient: 'butter', + quantity: 6, + unit: 'tablespoon', + symbol: 'tbs', + minQty: 6, + maxQty: 6, + }, + ]); + }); - const mixedValues = ['1¼', '2½', '3¾', '4⅐', '5⅑', '6⅒', '7⅓', '8⅔', '9⅕', '10⅖', '11⅗', '12⅘', '13⅙', '14⅚', '15⅛', '16⅜', '17⅝', '18⅞']; - const mixedExpectedValues = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18']; + it('combines four ingredient objects into two', () => { + const ingredientArray: Ingredient[] = [ + { + ingredient: 'butter', + quantity: 2, + unit: 'tablespoon', + symbol: 'tbs', + minQty: 2, + maxQty: 2, + }, + { + ingredient: 'butter', + quantity: 2, + unit: 'tablespoon', + symbol: 'tbs', + minQty: 2, + maxQty: 2, + }, + { + ingredient: 'butter', + quantity: 2, + unit: 'tablespoon', + symbol: 'tbs', + minQty: 2, + maxQty: 2, + }, + { + ingredient: 'apple', + quantity: 2, + unit: 'pound', + symbol: 'lb', + minQty: 2, + maxQty: 2, + }, + ]; + expect(combine(ingredientArray)).to.deep.equal([ + { + ingredient: 'apple', + quantity: 2, + unit: 'pound', + symbol: 'lb', + minQty: 2, + maxQty: 2, + }, + { + ingredient: 'butter', + quantity: 6, + unit: 'tablespoon', + symbol: 'tbs', + minQty: 6, + maxQty: 6, + }, + ]); + }); - for (let u = 0; u < mixedValues.length; u++) { - const element = mixedValues[u]; - const expectedAmount = (Number(mixedExpectedValues[u]) + Number(unicodeExpectedAmounts[u])); - it(`${element} to ${expectedAmount}`, () => { - expect(parse(`${element} teaspoon water`, 'eng').quantity).to.equal(expectedAmount); - }); - } - }); + it('combines 2 ingredients that have a quantity range', () => { + const ingredientArray: Ingredient[] = [ + { + ingredient: 'butter', + quantity: 2, + unit: 'tablespoon', + symbol: 'tbs', + minQty: 2, + maxQty: 3, + }, + { + ingredient: 'butter', + quantity: 2, + unit: 'tablespoon', + symbol: 'tbs', + minQty: 1, + maxQty: 2, + }, + ]; + expect(combine(ingredientArray)).to.deep.equal([ + { + ingredient: 'butter', + quantity: 4, + unit: 'tablespoon', + symbol: 'tbs', + minQty: 3, + maxQty: 5, + }, + ]); + }); - it('doesn\'t freak out if a strange unicode character is present', () => { - expect(parse('1/3 cup confectioners’ sugar', 'eng')).to.deep.equal({ - quantity: 0.333, - unit: 'cup', - unitPlural: 'cups', - symbol: 'c', - ingredient: 'confectioners’ sugar', - minQty: 0.333, - maxQty: 0.333, - }); - }); + it('combines 1 ingredient with no range, and 1 with a range', () => { + const ingredientArray: Ingredient[] = [ + { + ingredient: 'butter', + quantity: 10, + unit: 'tablespoon', + symbol: 'tbs', + minQty: 1, + maxQty: 10, + }, + { + ingredient: 'butter', + quantity: 2, + unit: 'tablespoon', + symbol: 'tbs', + minQty: 2, + maxQty: 2, + }, + ]; + expect(combine(ingredientArray)).to.deep.equal([ + { + ingredient: 'butter', + quantity: 12, + unit: 'tablespoon', + symbol: 'tbs', + minQty: 3, + maxQty: 12, + }, + ]); }); - describe('translates the literal units', () => { - it('of "1 cup water"', () => { - expect(parse('1 cup water', 'eng').unit).to.equal('cup'); - }); - it('of "1 gallon water"', () => { - expect(parse('1 gallon water', 'eng').unit).to.equal('gallon'); - }); - it('of "1 ounce water"', () => { - expect(parse('1 ounce water', 'eng').unit).to.equal('ounce'); - }); - it('of "1 pint water"', () => { - expect(parse('1 pint water', 'eng').unit).to.equal('pint'); - }); - it('of "1 pound water"', () => { - expect(parse('1 pound water', 'eng').unit).to.equal('pound'); - }); - it('of "1 quart water"', () => { - expect(parse('1 quart water', 'eng').unit).to.equal('quart'); - }); - it('of "1 tablespoon water"', () => { - expect(parse('1 tablespoon water', 'eng').unit).to.equal('tablespoon'); - }); - it('of "1 teaspoon water"', () => { - expect(parse('1 teaspoon water', 'eng').unit).to.equal('teaspoon'); - }); - it('of "1 gram water"', () => { - expect(parse('1 gram water', 'eng').unit).to.equal('gram'); - }); - it('of "1 kilogram water"', () => { - expect(parse('1 kilogram water', 'eng').unit).to.equal('kilogram'); - }); - it('of "1 liter water"', () => { - expect(parse('1 liter water', 'eng').unit).to.equal('liter'); - }); - it('of "1 milligram water"', () => { - expect(parse('1 milligram water', 'eng').unit).to.equal('milligram'); - }); - it('of "1 milliliter water"', () => { - expect(parse('1 milliliter water', 'eng').unit).to.equal('milliliter'); - }); - it('of "1 large onion"', () => { - expect(parse('1 large onion', 'eng').unit).to.equal("large"); - }); - it('of "1 whole onion"', () => { - expect(parse('1 whole onion', 'eng').unit).to.equal(null); - }); - it('of "1 clove garlic"', () => { - expect(parse('1 clove garlic', 'eng').unit).to.equal('clove'); - }); - it('of "1 bag garlic"', () => { - expect(parse('1 bag garlic', 'eng').unit).to.equal('bag'); - }); - it('of "1 package sausage"', () => { - expect(parse('1 package sausage', 'eng').unit).to.equal('package'); - }); - it('"1 pinch water"', () => { - expect(parse('1 pinch salt', 'eng').unit).to.equal('pinch'); - }); - it('"1 (14.5 oz) can tomatoes"', () => { - expect(parse('1 (14.5 oz) can tomatoes', 'eng')).to.deep.equal({ - unit: 'can', - unitPlural: 'cans', + it('combines 2 ingredient with a range, and 1 different ingredient without a range', () => { + const ingredientArray: Ingredient[] = [ + { + ingredient: 'butter', + quantity: 10, + unit: 'tablespoon', + symbol: 'tbs', + minQty: 1, + maxQty: 10, + }, + { + ingredient: 'butter', + quantity: 2, + unit: 'tablespoon', + symbol: 'tbs', + minQty: 2, + maxQty: 2, + }, + { + ingredient: 'apple', + quantity: 2, + unit: null, + symbol: null, + minQty: 2, + maxQty: 2, + }, + ]; + expect(combine(ingredientArray)).to.deep.equal([ + { + ingredient: 'apple', + quantity: 2, + unit: null, symbol: null, + minQty: 2, + maxQty: 2, + }, + { + ingredient: 'butter', + quantity: 12, + unit: 'tablespoon', + symbol: 'tbs', + minQty: 3, + maxQty: 12, + }, + ]); + }); + + it('does not combine if ingredients have different units (for now)', () => { + const ingredientArray: Ingredient[] = [ + { + ingredient: 'butter', + quantity: 2, + unit: 'tablespoon', + symbol: 'tbs', + minQty: 2, + maxQty: 2, + }, + { + ingredient: 'butter', + quantity: 2, + unit: 'tablespoon', + symbol: 'tbs', + minQty: 2, + maxQty: 2, + }, + { + ingredient: 'butter', quantity: 1, - ingredient: 'tomatoes (14.5 oz)', + unit: 'stick', + symbol: null, minQty: 1, maxQty: 1, - }); - }); - it('"25 lb beef stew chunks (or buy a roast and chop into small cubes)"', () => { - expect(parse('25 lb beef stew chunks (or buy a roast and chop into small cubes)', 'eng')).to.deep.equal({ + }, + { + ingredient: 'apple', + quantity: 2, unit: 'pound', - unitPlural: 'pounds', symbol: 'lb', - quantity: 25, - ingredient: 'beef stew chunks (or buy a roast and chop into small cubes)', - minQty: 25, - maxQty: 25, - }); - }); - // it('"parses ingredient with range: 1 to 2 chicken breasts"', () => { - // expect(parse('1 to 2 chicken breasts', 'eng')).to.deep.equal({ - // unit: null, - // unitPlural: null, - // symbol: null, - // quantity: '1-2', - // ingredient: 'chicken breasts', - // minQty: '1', - // maxQty: '2', - // }); - // }); - // it('"parses ingredient with range: 1 - 2 chicken breasts"', () => { - // expect(parse('1 - 2 chicken breasts', 'eng')).to.deep.equal({ - // unit: null, - // unitPlural: null, - // symbol: null, - // quantity: '1-2', - // ingredient: 'chicken breasts', - // minQty: '1', - // maxQty: '2', - // }); - // }); - // it('"parses ingredient with range: 1-2 chicken breasts"', () => { - // expect(parse('1-2 chicken breasts', 'eng')).to.deep.equal({ - // unit: null, - // unitPlural: null, - // symbol: null, - // quantity: '1-2', - // ingredient: 'chicken breasts', - // minQty: '1', - // maxQty: '2', - // }); - // }); - it('"1 (16 oz) box pasta"', () => { - expect(parse('1 (16 oz) box pasta', 'eng')).to.deep.equal({ - unit: 'box', - unitPlural: 'boxes', - symbol: null, + minQty: 2, + maxQty: 2, + }, + ]; + expect(combine(ingredientArray)).to.deep.equal([ + { + ingredient: 'apple', + quantity: 2, + unit: 'pound', + symbol: 'lb', + minQty: 2, + maxQty: 2, + }, + { + ingredient: 'butter', + quantity: 4, + unit: 'tablespoon', + symbol: 'tbs', + minQty: 4, + maxQty: 4, + }, + { + ingredient: 'butter', quantity: 1, - ingredient: 'pasta (16 oz)', - minQty: 1, - maxQty: 1, - }); - }); - it('"1 slice cheese"', () => { - expect(parse('1 slice cheese', 'eng')).to.deep.equal({ - unit: 'slice', - unitPlural: 'slices', + unit: 'stick', symbol: null, - quantity: 1, - ingredient: 'cheese', minQty: 1, maxQty: 1, - }); - }); + }, + ]); }); - it('translates unit when no unit provided', () => { - expect(parse('1 tortilla', 'eng')).to.deep.equal({ - unit: null, - unitPlural: null, - symbol: null, - ingredient: 'tortilla', - quantity: 1, - minQty: 1, - maxQty: 1, - }); + it('handles the no-unit case', () => { + const ingredientArray: Ingredient[] = [ + { + ingredient: 'tortilla', + quantity: 10, + unit: null, + symbol: null, + minQty: 10, + maxQty: 10, + }, + { + ingredient: 'tortilla', + quantity: 5, + unit: null, + symbol: null, + minQty: 5, + maxQty: 5, + }, + ]; + expect(combine(ingredientArray)).to.deep.equal([ + { + ingredient: 'tortilla', + quantity: 15, + unit: null, + symbol: null, + minQty: 15, + maxQty: 15, + }, + ]); }); - it('doesn\'t explode when no unit and no quantity provided', () => { - expect(parse('Powdered Sugar', 'eng')).to.deep.equal({ + it('handles the no-unit and no-quantity case', () => { + const ingredientArray: Ingredient[] = [ + { ingredient: 'Powdered Sugar', quantity: 0, unit: null, - unitPlural: null, symbol: null, minQty: 0, maxQty: 0, - }); - }); - - describe('translates the abbreviated units of', () => { - it('"1 cup water"', () => { - expect(parse('1 c water', 'eng').unit).to.equal('cup'); - expect(parse('2 c. water', 'eng').unit).to.equal('cup'); - expect(parse('2 cups water', 'eng').unit).to.equal('cup'); - }); - it('"1 gallon water"', () => { - expect(parse('1 gal water', 'eng').unit).to.equal('gallon'); - expect(parse('1 gallons water', 'eng').unit).to.equal('gallon'); - }); - it('"1 ounce water"', () => { - expect(parse('1 oz water', 'eng').unit).to.equal('ounce'); - expect(parse('1 oz. water', 'eng').unit).to.equal('ounce'); - expect(parse('2 ounces water', 'eng').unit).to.equal('ounce'); - }); - it('"1 pint water"', () => { - expect(parse('1 pt water', 'eng').unit).to.equal('pint'); - expect(parse('2 pts water', 'eng').unit).to.equal('pint'); - expect(parse('1 pt. water', 'eng').unit).to.equal('pint'); - expect(parse('2 pints water', 'eng').unit).to.equal('pint'); - }); - it('"1 pound water"', () => { - expect(parse('1 lb water', 'eng').unit).to.equal('pound'); - expect(parse('1 lb. water', 'eng').unit).to.equal('pound'); - expect(parse('2 lbs water', 'eng').unit).to.equal('pound'); - expect(parse('2 pounds water', 'eng').unit).to.equal('pound'); - }); - it('"1 quart water"', () => { - expect(parse('1 qt water', 'eng').unit).to.equal('quart'); - expect(parse('1 qt. water', 'eng').unit).to.equal('quart'); - expect(parse('1 qts water', 'eng').unit).to.equal('quart'); - expect(parse('1 quarts water', 'eng').unit).to.equal('quart'); - }); - it('"1 tablespoon water"', () => { - expect(parse('1 T water', 'eng').unit).to.equal('tablespoon'); - expect(parse('1 T. water', 'eng').unit).to.equal('tablespoon'); - expect(parse('1 tbs water', 'eng').unit).to.equal('tablespoon'); - expect(parse('1 tbsp water', 'eng').unit).to.equal('tablespoon'); - expect(parse('1 tbspn water', 'eng').unit).to.equal('tablespoon'); - expect(parse('2 tablespoons water', 'eng').unit).to.equal('tablespoon'); - expect(parse('1 Tablespoon water', 'eng').unit).to.equal('tablespoon'); - expect(parse('2 Tablespoons water', 'eng').unit).to.equal('tablespoon'); - }); - it('"1 teaspoon water"', () => { - expect(parse('1 tsp water', 'eng').unit).to.equal('teaspoon'); - expect(parse('1 tspn water', 'eng').unit).to.equal('teaspoon'); - expect(parse('1 t water', 'eng').unit).to.equal('teaspoon'); - expect(parse('1 t. water', 'eng').unit).to.equal('teaspoon'); - expect(parse('2 teaspoons water', 'eng').unit).to.equal('teaspoon'); - }); - it('"1 gram water"', () => { - expect(parse('1 g water', 'eng').unit).to.equal('gram'); - expect(parse('1 g. water', 'eng').unit).to.equal('gram'); - expect(parse('2 grams water', 'eng').unit).to.equal('gram'); - }); - it('"1 kilogram water"', () => { - expect(parse('1 kg water', 'eng').unit).to.equal('kilogram'); - expect(parse('1 kg. water', 'eng').unit).to.equal('kilogram'); - expect(parse('2 kilograms water', 'eng').unit).to.equal('kilogram'); - }); - it('"1 liter water"', () => { - expect(parse('1 l water', 'eng').unit).to.equal('liter'); - expect(parse('1 l. water', 'eng').unit).to.equal('liter'); - expect(parse('2 liters water', 'eng').unit).to.equal('liter'); - }); - it('"1 milligram water"', () => { - expect(parse('1 mg water', 'eng').unit).to.equal('milligram'); - expect(parse('1 mg. water', 'eng').unit).to.equal('milligram'); - expect(parse('1 milligrams water', 'eng').unit).to.equal('milligram'); - }); - it('"1 milliliter water"', () => { - expect(parse('1 ml water', 'eng').unit).to.equal('milliliter'); - expect(parse('1 ml. water', 'eng').unit).to.equal('milliliter'); - expect(parse('1 milliliters water', 'eng').unit).to.equal('milliliter'); - }); - it('"1 pinch water"', () => { - expect(parse('2 pinches salt', 'eng').unit).to.equal('pinch'); - }); - }); - - describe('translates the ingredient of', () => { - it('"1 teaspoon water"', () => { - expect(parse('1 teaspoon of water', 'eng').ingredient).to.equal('water'); - }); - it('"1 teaspoon milk"', () => { - expect(parse('1 teaspoon of milk', 'eng').ingredient).to.equal('milk'); - }); - it('"1 teaspoon of milk"', () => { - expect(parse('1 teaspoon of milk', 'eng').ingredient).to.equal('milk'); - }); - it('"1 teaspoon of milk"', () => { - expect(parse('1 teaspoon of powdered sugar', 'eng').ingredient).to.equal('powdered sugar'); - }); - }); -}); -*/ -/////ITALIAN TEST -describe('split on separator', () => { - it('"quattro noci - quattro noci"', () => { - expect(multiLineParse('quattro noci - quattro noci', 'ita')[0]).to.deep.equal({ - unit: null, - unitPlural: null, - symbol: null, - ingredient: 'noci', - quantity: 4, - minQty: 4, - maxQty: 4, - }); -}), -it('"tre noci - 8 noci"', () => { - expect(multiLineParse('tre noci - quattro noci', 'ita')[0]).to.deep.equal({ - unit: null, - unitPlural: null, - symbol: null, - ingredient: 'noci', - quantity: 3, - minQty: 3, - maxQty: 3, -}); -}); -it('"👉 tre noci 👉 8 noci"', () => { - expect(multiLineParse('👉 tre noci 👉 quattro noci', 'ita')[0]).to.deep.equal({ - unit: null, - unitPlural: null, - symbol: null, - ingredient: 'noci', - quantity: 3, - minQty: 3, - maxQty: 3, -}); -}); -it('"👉🏻 tre noci 👉 8 noci"', () => { - expect(multiLineParse('👉🏻 tre noci 👉 quattro noci', 'ita')[0]).to.deep.equal({ - unit: null, - unitPlural: null, - symbol: null, - ingredient: 'noci', - quantity: 3, - minQty: 3, - maxQty: 3, -}); -}); -}); -describe('recipe parser ita', () => { - it('returns an object', () => { - expect(typeof parse('1 tazza acqua', 'ita')).to.equal('object'); - }); - describe('translates the unit', () => { - it('of "qb di acqua"', () => { - expect(parse('qb di acqua', 'ita').unit).to.equal('q.b.'); - expect(parse('qb di acqua', 'ita').quantity).to.equal(0); - - }); - it('of "quanto basta acqua"', () => { - expect(parse('quanto basta di acqua', 'ita').unit).to.equal('q.b.'); - }); - it('of "Quanto basta acqua"', () => { - expect(parse('Quanto basta di acqua', 'ita').unit).to.equal('q.b.'); - }); - it('of "Quanto Basta acqua"', () => { - expect(parse('Quanto Basta di acqua', 'ita').unit).to.equal('q.b.'); - }); - it('of "q.b. di farina"', () => { - expect(parse('q.b. di farina', 'ita').ingredient).to.equal('farina'); - }); - it('of "q.b. di farina"', () => { - expect(parse('q.b. di farina', 'ita').unit).to.equal('q.b.'); - }); - it('of "q.b. farina"', () => { - expect(parse('q.b. farina', 'ita').ingredient).to.equal('farina'); - }); - it('of "grammi farina"', () => { - expect(parse('grammi farina', 'ita').unit).to.equal('grammo'); - }); - it('of "grammi farina"', () => { - expect(parse('grammi farina', 'ita').ingredient).to.equal('farina'); - }); - it('of "Q.B. di acqua"', () => { - expect(parse('Q.B. di acqua', 'ita').unit).to.equal('q.b.'); - }); - it('of "acqua quanto basta"', () => { - expect(parse('acqua quanto basta', 'ita').unit).to.equal('q.b.'); - }); - - it('of "QB di acqua"', () => { - expect(parse('QB di acqua', 'ita').unit).to.equal('q.b.'); - }); - it('of "QB. di acqua"', () => { - expect(parse('QB. di acqua', 'ita').unit).to.equal('q.b.'); - }); - it('of "Q.B di acqua"', () => { - expect(parse('Q.b di acqua', 'ita').unit).to.equal('q.b.'); - }); - it('of "1 cucchiao acqua"', () => { - expect(parse('1 cucchiao acqua', 'ita').quantity).to.equal(1); - }); - it('of "1.5 cucchiao acqua"', () => { - expect(parse('1.5 cucchiao acqua', 'ita').quantity).to.equal(1.5); - }); - it('of "1 1/2 cucchiao acqua"', () => { - expect(parse('1 1/2 cucchiao acqua', 'ita').quantity).to.equal(1.5); - }); - it('of "1/3 cucchiao acqua"', () => { - expect(parse('1/3 cucchiao acqua', 'ita').quantity).to.equal(0.333); - }); - it('of "1/2 cucchiao acqua"', () => { - expect(parse('1/2 cucchiao acqua', 'ita').quantity).to.equal(0.5); - }); - it('of "10 1/2 cucchiao acqua"', () => { - expect(parse('10 1/2 cucchiao acqua', 'ita').quantity).to.equal(10.5); - }); - it('of "about 1/2 cucchiao acqua"', () => { - expect(parse('about 1/2 cucchiao acqua', 'ita').quantity).to.equal(0.5); - }); - - describe('translates the quantity from string to number', () => { - it('Un cucchiaio d\'acqua', () => { - expect(parse('Un cucchiaio d\'acqua', 'ita').quantity).to.equal(1); - }); - it('Un cucchiaio d\'acqua', () => { - expect(parse('Un cucchiaio d\'acqua', 'ita').quantity).to.equal(1); - }); - it('mezzo cucchiaio d\'acqua', () => { - expect(parse('mezzo cucchiaio d\'acqua', 'ita').quantity).to.equal(0.5); - }); - it('meta cucchiaio d\'acqua', () => { - expect(parse('meta cucchiaio d\'acqua', 'ita').quantity).to.equal(0.5); - }); - it('Venti cucchiai d\'acqua"', () => { - expect(parse('Venti cucchiai d\'acqua', 'ita').quantity).to.equal(20); - }); - it('cinque cucchiai d\'acqua"', () => { - expect(parse('cinque cucchiai d\'acqua', 'ita').quantity).to.equal(5); - }); - it('ventuno cucchiai d\'acqua"', () => { - expect(parse('ventuno cucchiai d\'acqua', 'ita').quantity).to.equal(21); - }); - it('mezzo spicchio d\'aglio"', () => { - expect(parse('mezzo spicchio d\'aglio', 'ita').quantity).to.equal(0.5); - }); - it('cento grammi d\'aglio"', () => { - expect(parse('cento grammi d\'aglio', 'ita').quantity).to.equal(100); - }); - it('cento-due grammi d\'aglio"', () => { - expect(parse('cento-due grammi d\'aglio', 'ita').quantity).to.equal(102); - }); - it('due-cento grammi d\'aglio"', () => { - expect(parse('due-cento grammi d\'aglio', 'ita').quantity).to.equal(200); - }); - it('due-mila grammi d\'aglio"', () => { - expect(parse('due-mila grammi d\'aglio', 'ita').quantity).to.equal(2000); - }); - it('due grammi farina"', () => { - expect(parse('due grammi farina', 'ita').quantity).to.equal(2); - }); - }); - - // describe('translates the quantity range', () => { - // it('of "10-20 cucchiao acqua"', () => { - // expect(parse('10-20 cucchiao acqua', 'ita').quantity).to.equal('10-20'); - // }); - // it('of "10 - 20 cucchiao acqua"', () => { - // expect(parse('10 - 20 cucchiao acqua', 'ita').quantity).to.equal('10-20'); - // }); - // it('of "10 to 20 cucchiao acqua"', () => { - // expect(parse('10 to 20 cucchiao acqua', 'ita').quantity).to.equal('10-20'); - // }); - // }); - - - describe('of unicode fractions', () => { - const unicodeAmounts = ['¼', '½', '¾', '⅐', '⅑', '⅒', '⅓', '⅔', '⅕', '⅖', '⅗', '⅘', '⅙', '⅚', '⅛', '⅜', '⅝', '⅞']; - const unicodeExpectedAmounts = [0.25, 0.5, 0.75, 0.142, 0.111, 0.1, 0.333, 0.666, 0.2, 0.4, 0.6, 0.8, 0.166, 0.833, 0.125, 0.375, 0.625, 0.875]; - - for (let u = 0; u < unicodeAmounts.length; u++) { - const element = unicodeAmounts[u]; - const expectedAmount = unicodeExpectedAmounts[u]; - it(`${element} to ${expectedAmount}`, () => { - expect(parse(`${element} cucchiao acqua`, 'ita').quantity).to.equal(expectedAmount); - }); - } - - const mixedValues = ['1¼', '2½', '3¾', '4⅐', '5⅑', '6⅒', '7⅓', '8⅔', '9⅕', '10⅖', '11⅗', '12⅘', '13⅙', '14⅚', '15⅛', '16⅜', '17⅝', '18⅞']; - const mixedExpectedValues = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]; - - for (let u = 0; u < mixedValues.length; u++) { - const element = mixedValues[u]; - const expectedAmount = (Number(mixedExpectedValues[u]) + Number(unicodeExpectedAmounts[u])); - it(`${element} to ${expectedAmount}`, () => { - expect(parse(`${element} cucchiao acqua`, 'ita').quantity).to.equal(expectedAmount); - }); - } - }); - - it('doesn\'t freak out if a strange unicode character is present', () => { - expect(parse('1/3 tazza zucchero a velo', 'ita')).to.deep.equal({ - quantity: 0.333, - unit: 'tazza', - unitPlural: 'tazze', - symbol: null, - ingredient: 'zucchero a velo', - minQty: 0.333, - maxQty: 0.333, - }); - }); - }); - - describe('translates the literal units', () => { - it('of "1 tazza acqua"', () => { - expect(parse('1 tazza acqua', 'ita').unit).to.equal('tazza'); - }); - it('of "1 litro acqua"', () => { - expect(parse('1 litro acqua', 'ita').unit).to.equal('litro'); - }); - it('of "1 lt acqua"', () => { - expect(parse('1 lt acqua', 'ita').unit).to.equal('litro'); - }); - it('of "1 kg acqua"', () => { - expect(parse('1 kg acqua', 'ita').unit).to.equal('chilogrammo'); - }); - it('of "1 L acqua"', () => { - expect(parse('1 L acqua', 'ita').unit).to.equal('litro'); - }); - it('of "1 L. acqua"', () => { - expect(parse('1 L. acqua', 'ita').unit).to.equal('litro'); - }); - it('of "1 cucchiaio acqua"', () => { - expect(parse('1 cucchiaio acqua', 'ita').unit).to.equal('cucchiaio'); - }); - it('of "1 cucchiaio acqua"', () => { - expect(parse('1 cucchiaio acqua', 'ita').unit).to.equal('cucchiaio'); - }); - it('of "1 grammo acqua"', () => { - expect(parse('1 grammo acqua', 'ita').unit).to.equal('grammo'); - }); - it('of "1 chilogrammo acqua"', () => { - expect(parse('1 chilogrammo acqua', 'ita').unit).to.equal('chilogrammo'); - }); - it('of "1 litro acqua"', () => { - expect(parse('1 litro acqua', 'ita').unit).to.equal('litro'); - }); - it('of "1 milligrammo acqua"', () => { - expect(parse('1 milligrammo acqua', 'ita').unit).to.equal('milligrammo'); - }); - it('of "1 millilitro acqua"', () => { - expect(parse('1 millilitro acqua', 'ita').unit).to.equal('millilitro'); - }); - it('of "1 l cipolla"', () => { - expect(parse('1 l cipolla', 'ita').unit).to.equal("litro"); - }); - it('of "1 cipolla intera"', () => { - expect(parse('1 cipolla intera', 'ita').unit).to.equal(null); - }); - it('of "1 spicchio agilio"', () => { - expect(parse('1 spicchio agilio', 'ita').unit).to.equal('spicchio'); - }); - it('of "1 bustina aglio"', () => { - expect(parse('1 bustina aglio', 'ita').unit).to.equal('bustina'); - }); - it('of "1 pacco salsicce"', () => { - expect(parse('1 pacco salsicce', 'ita').unit).to.equal('pacco'); - }); - it('"1 pizzico sale"', () => { - expect(parse('1 pizzico sale', 'ita').unit).to.equal('pizzico'); - }); - it('"1 foglia prezzemolo"', () => { - expect(parse('1 foglia prezzemolo', 'ita').unit).to.equal('foglia'); - }); - it('"1 mazzetto prezzemolo"', () => { - expect(parse('1 mazzetto prezzemolo', 'ita').unit).to.equal('mazzetto'); - }); - it('"1 vasetto yogurt"', () => { - expect(parse('1 vasetto yogurt', 'ita').unit).to.equal('vasetto'); - }); - it('"1 (14.5 oz) lattina pommodori"', () => { - expect(parse('1 (14.5 oz) lattina pommodori', 'ita')).to.deep.equal({ - unit: 'lattina', - unitPlural: 'lattine', - symbol: null, - quantity: 1, - ingredient: 'pommodori (14.5 oz)', - minQty: 1, - maxQty: 1, - }); - }); - // it('"parses ingredient with range: 1 to 2 petto di pollo"', () => { - // expect(parse('1 to 2 petto di pollo', 'ita')).to.deep.equal({ - // unit: null, - // unitPlural: null, - // symbol: null, - // quantity: '1-2', - // ingredient: 'petto di pollo', - // minQty: '1', - // maxQty: '2', - // }); - // }); - // it('"parses ingredient with range: 1 - 2 petto di pollo"', () => { - // expect(parse('1 - 2 petto di pollo', 'ita')).to.deep.equal({ - // unit: null, - // unitPlural: null, - // symbol: null, - // quantity: '1-2', - // ingredient: 'petto di pollo', - // minQty: '1', - // maxQty: '2', - // }); - // }); - // it('"parses ingredient with range: 1-2 petto di pollo"', () => { - // expect(parse('1-2 petto di pollo', 'ita')).to.deep.equal({ - // unit: null, - // unitPlural: null, - // symbol: null, - // quantity: '1-2', - // ingredient: 'petto di pollo', - // minQty: 1, - // maxQty: 2, - // }); - // }); - it('"1 (16 oz) scatola pasta"', () => { - expect(parse('1 (16 oz) scatola pasta', 'ita')).to.deep.equal({ - unit: 'scatola', - unitPlural: 'scatole', - symbol: null, - quantity: 1, - ingredient: 'pasta (16 oz)', - minQty: 1, - maxQty: 1, - }); - }); - it('"1 fetta di formaggio"', () => { - expect(parse('1 fetta di formaggio', 'ita')).to.deep.equal({ - unit: 'fetta', - unitPlural: 'fette', - quantity: 1, + }, + { + ingredient: 'Powdered Sugar', + quantity: 0, + unit: null, symbol: null, - ingredient: 'formaggio', - minQty: 1, - maxQty: 1, - }); - }); - it('"1 spicchio d\'aglio"', () => { - expect(parse('1 spicchio d\'aglio', 'ita')).to.deep.equal({ - unit: 'spicchio', - unitPlural: 'spicchi', - quantity: 1, + minQty: 0, + maxQty: 0, + }, + ]; + expect(combine(ingredientArray)).to.deep.equal([ + { + ingredient: 'Powdered Sugar', + quantity: 0, + unit: null, symbol: null, - ingredient: 'aglio', - minQty: 1, - maxQty: 1, - }); - }); - describe('" check the correct symbol"', () => { - it('"grammi di farina"', () => { - expect(parse('grammi di farina', 'ita')).to.deep.equal({ - unit: 'grammo', - unitPlural: 'grammi', - quantity: 0, - symbol: 'g', - ingredient: 'farina', - minQty: 0, - maxQty: 0, - }); - }); - it('"100 grammi di farina"', () => { - expect(parse('100 grammi di farina', 'ita')).to.deep.equal({ - unit: 'grammo', - unitPlural: 'grammi', - quantity: 100, - symbol: 'g', - ingredient: 'farina', - minQty: 100, - maxQty: 100, - }); - }); - it('"1 spicchio d\'aglio"', () => { - expect(parse('1 spicchio d\'aglio', 'ita')).to.deep.equal({ - unit: 'spicchio', - unitPlural: 'spicchi', - quantity: 1, - symbol: null, - ingredient: 'aglio', - minQty: 1, - maxQty: 1, - }); - }); - it('"1 kilogrammo d\'aglio"', () => { - expect(parse('1 kilogrammo d\'aglio', 'ita')).to.deep.equal({ - unit: 'chilogrammo', - unitPlural: 'chilogrammi', - quantity: 1, - symbol: 'kg', - ingredient: 'aglio', - minQty: 1, - maxQty: 1, - }); - }); - it('"1 cucchiaino riso"', () => { - expect(parse('1 cucchiaino riso', 'ita')).to.deep.equal({ - unit: 'cucchiaino', - unitPlural: 'cucchiaini', - quantity: 1, - symbol: 'cc', - ingredient: 'riso', - minQty: 1, - maxQty: 1, - }); - }); - it('"100 litri di latte"', () => { - expect(parse('100 litri di latte', 'ita')).to.deep.equal({ - unit: 'litro', - unitPlural: 'litri', - quantity: 100, - symbol: 'lt', - ingredient: 'latte', - minQty: 100, - maxQty: 100, - }); - }); - it('"100 milligrammi di olio"', () => { - expect(parse('100 milligrammi di olio', 'ita')).to.deep.equal({ - unit: 'milligrammo', - unitPlural: 'milligrammi', - quantity: 100, - symbol: 'mg', - ingredient: 'olio', - minQty: 100, - maxQty: 100, - }); - }); - it('"100 rotoli di olio"', () => { - expect(parse('100 rotoli di olio', 'ita')).to.deep.equal({ - unit: 'rotolo', - unitPlural: 'rotoli', - quantity: 100, - symbol: null, - ingredient: 'olio', - minQty: 100, - maxQty: 100, - }); - }); - it('"100 bicchierini di olio"', () => { - expect(parse('100 bicchierino di olio', 'ita')).to.deep.equal({ - unit: 'bicchierino', - unitPlural: 'bicchierini', - quantity: 100, - symbol: null, - ingredient: 'olio', - minQty: 100, - maxQty: 100, - }); - }); - it('"Un filo d\'olio"', () => { - expect(parse('Un filo d\'olio', 'ita')).to.deep.equal({ - unit: 'filo', - unitPlural: 'fili', - quantity: 1, - symbol: null, - ingredient: 'olio', - minQty: 1, - maxQty: 1, - }); - }); - it('"Un ciuffo di prezzemolo"', () => { - expect(parse('Un ciuffo di prezzemolo', 'ita')).to.deep.equal({ - unit: 'ciuffo', - unitPlural: 'ciuffi', - quantity: 1, - symbol: null, - ingredient: 'prezzemolo', - minQty: 1, - maxQty: 1, - }); - }); - it('"100 millilitri di latte"', () => { - expect(parse('100 millilitri di latte', 'ita')).to.deep.equal({ - unit: 'millilitro', - unitPlural: 'millilitri', - quantity: 100, - symbol: 'ml', - ingredient: 'latte', - minQty: 100, - maxQty: 100, - }); - }); - it('"quanto basta di latte"', () => { - expect(parse('quanto basta di latte', 'ita')).to.deep.equal({ - unit: "q.b.", - unitPlural: "q.b.", - quantity: 0, - symbol: null, - ingredient: 'latte', - minQty: 0, - maxQty: 0, - }); - }); - it('"Quanto Basta di latte"', () => { - expect(parse('quanto basta di latte', 'ita')).to.deep.equal({ - unit: "q.b.", - unitPlural: "q.b.", - quantity: 0, - symbol: null, - ingredient: 'latte', - minQty: 0, - maxQty: 0, - }); - }); - it('"qb di latte"', () => { - expect(parse('quanto basta di latte', 'ita')).to.deep.equal({ - unit: "q.b.", - unitPlural: "q.b.", - quantity: 0, - symbol: null, - ingredient: 'latte', - minQty: 0, - maxQty: 0, - }); - }); - it('"q.b. di latte"', () => { - expect(parse('q.b. di latte', 'ita')).to.deep.equal({ - unit: "q.b.", - unitPlural: "q.b.", - quantity: 0, - symbol: null, - ingredient: 'latte', - minQty: 0, - maxQty: 0, - }); - }); - it('"q.b. latte"', () => { - expect(parse('q.b. latte', 'ita')).to.deep.equal({ - unit: "q.b.", - unitPlural: "q.b.", - quantity: 0, - symbol: null, - ingredient: 'latte', - minQty: 0, - maxQty: 0, - }); - }); - }); + minQty: 0, + maxQty: 0, + }, + ]); }); +}); - it('translates unit when no unit provided', () => { - expect(parse('1 tortilla', 'ita')).to.deep.equal({ - unit: null, - unitPlural: null, +describe('pretty printing press', () => { + const ingredients: Ingredient[] = [ + { + ingredient: 'milk', + unit: 'cup', + symbol: null, + quantity: 1.5, + minQty: 1.5, + maxQty: 1.5, + }, + { + ingredient: 'milk', + unit: 'cup', + symbol: null, + quantity: 0.25, + minQty: 0.25, + maxQty: 0.25, + }, + { + ingredient: 'milk', + unit: 'cup', symbol: null, - ingredient: 'tortilla', - quantity: 1, - minQty: 1, - maxQty: 1, - }); - }); - it('test order and case sensitive', () => { - expect(parse('100 ml. tortilla ', 'ita')).to.deep.equal({ - unit: 'millilitro', - unitPlural: 'millilitri', - symbol: 'ml', - ingredient: 'tortilla', - quantity: 100, - minQty: 100, - maxQty: 100, - }); - expect(parse('100 mg. tortilla ', 'ita')).to.deep.equal({ - unit: 'milligrammo', - unitPlural: 'milligrammi', - symbol: 'mg', - ingredient: 'tortilla', - quantity: 100, - minQty: 100, - maxQty: 100, - }); - expect(parse('100 g. tortilla ', 'ita')).to.deep.equal({ - unit: 'grammo', - unitPlural: 'grammi', - symbol: 'g', - ingredient: 'tortilla', - quantity: 100, - minQty: 100, - maxQty: 100, - }); - expect(parse('1 g. d\' acqua', 'ita')).to.deep.equal({ - unit: 'grammo', - unitPlural: 'grammi', - symbol: 'g', - ingredient: 'acqua', quantity: 1, minQty: 1, maxQty: 1, - }); - expect(parse('100 g. di tortilla ', 'ita')).to.deep.equal({ - unit: 'grammo', - unitPlural: 'grammi', - symbol: 'g', - ingredient: 'tortilla', - quantity: 100, - minQty: 100, - maxQty: 100, - }); - expect(parse('q.b. di sale', 'ita')).to.deep.equal({ - unit: 'q.b.', - unitPlural: "q.b.", + }, + { + ingredient: 'something', + unit: 'box', symbol: null, - ingredient: 'sale', - quantity: 0, - minQty: 0, - maxQty: 0, - }); - expect(parse('100 gr. tortilla ', 'ita')).to.deep.equal({ - unit: 'grammo', - unitPlural: 'grammi', - symbol: 'g', - ingredient: 'tortilla', - quantity: 100, - minQty: 100, - maxQty: 100, - }); - expect(parse('tortilla 100 gr.', 'ita')).to.deep.equal({ - unit: 'grammo', - unitPlural: 'grammi', - symbol: 'g', - ingredient: 'tortilla', - quantity: 100, - minQty: 100, - maxQty: 100, - }); - expect(parse('basilico quanto basta', 'ita')).to.deep.equal({ - unit: 'q.b.', - unitPlural: "q.b.", + quantity: 2, + minQty: 2, + maxQty: 2, + }, + { + ingredient: 'milk', + unit: 'teaspoon', symbol: null, - ingredient: 'basilico', - quantity: 0, - minQty: 0, - maxQty: 0, - }); - expect(parse('basilico q.b.', 'ita')).to.deep.equal({ - unit: 'q.b.', - unitPlural: "q.b.", + quantity: 1.333, + minQty: 1.333, + maxQty: 1.333, + }, + { + ingredient: 'milk', + unit: 'teaspoon', symbol: null, - ingredient: 'basilico', - quantity: 0, - minQty: 0, - maxQty: 0, - }); - expect(parse('basilico QB', 'ita')).to.deep.equal({ - unit: 'q.b.', - unitPlural: "q.b.", + quantity: 1.666, + minQty: 1.666, + maxQty: 1.666, + }, + { + ingredient: 'milk', + unit: 'teaspoon', symbol: null, - ingredient: 'basilico', - quantity: 0, - minQty: 0, - maxQty: 0, - }); - expect(parse('basilico millilitri 100', 'ita')).to.deep.equal({ - unit: 'millilitro', - unitPlural: 'millilitri', - symbol: 'ml', - ingredient: 'basilico', - quantity: 100, - minQty: 100, - maxQty: 100, - }); - }); - it('doesn\'t explode when no unit and no quantity provided', () => { - expect(parse('zucchero a velo', 'ita')).to.deep.equal({ - unit: 'q.b.', - unitPlural: 'q.b.', + quantity: 1.111, + minQty: 1.111, + maxQty: 1.111, + }, + { + ingredient: 'milk', + unit: 'teaspoon', symbol: null, - ingredient: 'zucchero a velo', - quantity: 0, - minQty: 0, - maxQty: 0, - }); - }); - it('test noci', () => { - expect(parse('quattro noci', 'ita')).to.deep.equal({ + quantity: 1.166, + minQty: 1.166, + maxQty: 1.166, + }, + { + ingredient: 'milk', + unit: 'teaspoon', + symbol: null, + quantity: 1.833, + minQty: 1.1833, + maxQty: 1.1833, + }, + { + ingredient: 'powdered sugar', unit: null, - unitPlural: null, symbol: null, - ingredient: 'noci', - quantity: 4, - minQty: 4, - maxQty: 4, - }); - expect(parse('una noce', 'ita')).to.deep.equal({ + quantity: null, + minQty: null, + maxQty: null, + }, + { + ingredient: 'eggs', unit: null, - unitPlural: null, symbol: null, - ingredient: 'noce', - quantity: 1, - minQty: 1, - maxQty: 1, - }); - expect(parse('100 gr di noci', 'ita')).to.deep.equal({ - unit: 'grammo', - unitPlural: 'grammi', - symbol: 'g', - ingredient: 'noci', - quantity: 100, - minQty: 100, - maxQty: 100, - }); - }); - describe('translates the abbreviated units of', () => { - it('"1 tazza acqua"', () => { - expect(parse('1 tazza acqua', 'ita').unit).to.equal('tazza'); - expect(parse('2 tazzine acqua', 'ita').unit).to.equal('tazza'); - expect(parse('2 tazze acqua', 'ita').unit).to.equal('tazza'); - }); - it('"1 litro acqua"', () => { - expect(parse('1 l acqua', 'ita').unit).to.equal('litro'); - expect(parse('1 litri acqua', 'ita').unit).to.equal('litro'); - }); - it('"1 grammo acqua"', () => { - expect(parse('1 gr acqua', 'ita').unit).to.equal('grammo'); - expect(parse('2 g acqua', 'ita').unit).to.equal('grammo'); - expect(parse('2 g. acqua', 'ita').ingredient).to.equal('acqua'); - - }); - it('"1 chilogrammo acqua"', () => { - expect(parse('1 kg acqua', 'ita').unit).to.equal('chilogrammo'); - expect(parse('2 KG acqua', 'ita').unit).to.equal('chilogrammo'); - expect(parse('1 kilogrammo acqua', 'ita').unit).to.equal('chilogrammo'); - expect(parse('2 Kilogrammo acqua', 'ita').unit).to.equal('chilogrammo'); - expect(parse('acqua KILOGRAMMO 2', 'ita').unit).to.equal('chilogrammo'); - expect(parse('acqua KILOGRAMMO due', 'ita').unit).to.equal('chilogrammo'); - - }); - it('"1 tazza acqua"', () => { - expect(parse('1 tazza acqua', 'ita').unit).to.equal('tazza'); - expect(parse('1 tazzina acqua', 'ita').unit).to.equal('tazza'); - expect(parse('2 tazzine acqua', 'ita').unit).to.equal('tazza'); - expect(parse('2 Tazza acqua', 'ita').unit).to.equal('tazza'); - }); - it('"1 millilitro acqua"', () => { - expect(parse('1 ml acqua', 'ita').unit).to.equal('millilitro'); - expect(parse('1 ml. acqua', 'ita').unit).to.equal('millilitro'); - expect(parse('1 millilitro acqua', 'ita').unit).to.equal('millilitro'); - expect(parse('1 Millilitro acqua', 'ita').unit).to.equal('millilitro'); - }); - it('"1 cucchiaio acqua"', () => { - expect(parse('2 cucchiai acqua', 'ita').unit).to.equal('cucchiaio'); - expect(parse('1 Cucchiaio acqua', 'ita').unit).to.equal('cucchiaio'); - expect(parse('2 cucchiai acqua', 'ita').unit).to.equal('cucchiaio'); - }); - it('"1 cucchiaino acqua"', () => { - expect(parse('1 Cucchiaino acqua', 'ita').unit).to.equal('cucchiaino'); - expect(parse('1 cucchiaino acqua', 'ita').unit).to.equal('cucchiaino'); - expect(parse('2 Cucchiaini acqua', 'ita').unit).to.equal('cucchiaino'); - expect(parse('2 cucchiaini acqua', 'ita').unit).to.equal('cucchiaino'); - }); - it('"1 grammo acqua"', () => { - expect(parse('1 g acqua', 'ita').unit).to.equal('grammo'); - expect(parse('1 g. acqua', 'ita').unit).to.equal('grammo'); - expect(parse('2 grammi acqua', 'ita').unit).to.equal('grammo'); - }); - it('"1 chilogrammo acqua"', () => { - expect(parse('1 kg acqua', 'ita').unit).to.equal('chilogrammo'); - expect(parse('1 kg. acqua', 'ita').unit).to.equal('chilogrammo'); - expect(parse('2 chilogrammi acqua', 'ita').unit).to.equal('chilogrammo'); - }); - it('"1 litro acqua"', () => { - expect(parse('1 l acqua', 'ita').unit).to.equal('litro'); - expect(parse('1 l. acqua', 'ita').unit).to.equal('litro'); - expect(parse('2 litri acqua', 'ita').unit).to.equal('litro'); - }); - it('"1 milligrammo acqua"', () => { - expect(parse('1 mg acqua', 'ita').unit).to.equal('milligrammo'); - expect(parse('1 mg. acqua', 'ita').unit).to.equal('milligrammo'); - expect(parse('1 milligrammo acqua', 'ita').unit).to.equal('milligrammo'); - }); - it('"1 millilitro acqua"', () => { - expect(parse('1 ml acqua', 'ita').unit).to.equal('millilitro'); - expect(parse('1 ml. acqua', 'ita').unit).to.equal('millilitro'); - expect(parse('1 millilitro acqua', 'ita').unit).to.equal('millilitro'); - }); - it('"1 pizzico acqua"', () => { - expect(parse('2 pizzichi sale', 'ita').unit).to.equal('pizzico'); - }); - it('"1 cubetto di ghiaccio"', () => { - expect(parse('2 cubetto di ghiaccio', 'ita').unit).to.equal('cubetto'); - }); - }); - - describe('translates the ingredient of', () => { - it('"1 cucchiaio d\'acqua"', () => { - expect(parse('1 cucchiaio d\'acqua', 'ita').ingredient).to.equal('acqua'); - }); - it('"1 spicchio d\'aglio"', () => { - expect(parse('1 cucchiaio d\'acqua', 'ita').ingredient).to.equal('acqua'); - }); - it('"1 cucchiaio di latte"', () => { - expect(parse('1 cucchiaio di latte', 'ita').ingredient).to.equal('latte'); - }); - it('"1 cucchiaio acqua"', () => { - expect(parse('1 cucchiaio acqua', 'ita').ingredient).to.equal('acqua'); - }); - it('"1 cucchiaio latte"', () => { - expect(parse('1 cucchiaio latte', 'ita').ingredient).to.equal('latte'); - }); - }); - - describe('translates the ingredient of', () => { - it('"1 g di latte"', () => { - expect(parse('1 g di latte', 'ita').ingredient).to.equal('latte'); - }); - it('"1 kg di latte"', () => { - expect(parse('1 kg di latte', 'ita').ingredient).to.equal('latte'); - }); - it('"250 kg di farina"', () => { - expect(parse('250 kg di farina', 'ita').ingredient).to.equal('farina'); - }); - it('"dieci kg farina"', () => { - expect(parse('dieci kg farina', 'ita').ingredient).to.equal('farina'); - }); - it('"dieci kg farina"', () => { - expect(parse('dieci kg farina', 'ita').ingredient).to.equal('farina'); - }); - }); - describe('translates q.b. without quantity of', () => { - it('"latte"', () => { - expect(parse('latte', 'ita').unit).to.equal('q.b.'); - }); - it('"farina"', () => { - expect(parse('farina', 'ita').unit).to.equal('q.b.'); - }); - it('"250 kg di farina"', () => { - expect(parse('250 kg di farina', 'ita').quantity).to.equal(250); - }); - - }); -}); - -///// - -//describe('combine ingredients', () => { -// it('accepts an empty array', () => { -// expect(combine([])).to.deep.equal([]); -// }); -// -// it('returns sorted ingredients', () => { -// const ingredientArray = [ -// { -// ingredient: 'butter', -// quantity: 2, -// unit: 'tablespoon', -// symbol: 'tbs', -// minQty: 2, -//// maxQty: 2, -//// }, -//// { -//// ingredient: 'apples', -//// quantity: 2, -//// unit: 'pound', -//// symbol: 'lb', -//// minQty: 2, -//// maxQty: 2, -//// } -//// ]; -//// expect(combine(ingredientArray)).to.deep.equal([ -//// { -//// ingredient: 'apples', -//// quantity: 2, -//// unit: 'pound', -//// symbol: 'lb', -// minQty: 2, -// maxQty: 2, -// }, -// { -// ingredient: 'butter', -// quantity: 2, -// unit: 'tablespoon', -// symbol: 'tbs', -// minQty: 2, -// maxQty: 2, -// } -// ]); -// }); - -// it('combines two ingredient objects into one', () => { -// const ingredientArray = [ -// { -// ingredient: 'butter', -// quantity: '2', -// unit: 'tablespoon', -// symbol: 'tbs', -// minQty: '2', -// maxQty: '2', -// }, -// { -// ingredient: 'butter', -// quantity: '2', -// unit: 'tablespoon', -// symbol: 'tbs', -// minQty: '2', -// maxQty: '2', -// } -// ]; -// expect(combine(ingredientArray)).to.deep.equal([ -// { -// ingredient: 'butter', -// quantity: '4', -// unit: 'tablespoon', -// symbol: 'tbs', -// minQty: '4', -// maxQty: '4', -// } -// ]); -// }); - -// it('combines three ingredient objects into one', () => { -// const ingredientArray = [ -// { -// ingredient: 'butter', -// quantity: '2', -// unit: 'tablespoon', -// symbol: 'tbs', -// minQty: '2', -// maxQty: '2', -// }, -// { -// ingredient: 'butter', -// quantity: '2', -// unit: 'tablespoon', -// symbol: 'tbs', -// minQty: '2', -// maxQty: '2', -// }, -// { -// ingredient: 'butter', -// quantity: '2', -// unit: 'tablespoon', -// symbol: 'tbs', -// minQty: '2', -// maxQty: '2', -// } -// ]; -// expect(combine(ingredientArray)).to.deep.equal([ -// { -// ingredient: 'butter', -// quantity: '6', -// unit: 'tablespoon', -// symbol: 'tbs', -// minQty: '6', -// maxQty: '6', -// } -// ]); -// }); - -// it('combines four ingredient objects into two', () => { -// const ingredientArray = [ -// { -// ingredient: 'butter', -// quantity: '2', -// unit: 'tablespoon', -// minQty: '2', -// maxQty: '2', -// }, -// { -// ingredient: 'butter', -// quantity: '2', -// unit: 'tablespoon', -// minQty: '2', -// maxQty: '2', -// }, -// { -// ingredient: 'butter', -// quantity: '2', -// unit: 'tablespoon', -// minQty: '2', -// maxQty: '2', -// }, -// { -// ingredient: 'apple', -// quantity: '2', -// unit: 'pound', -// minQty: '2', -// maxQty: '2', -// } -// ]; -// expect(combine(ingredientArray)).to.deep.equal([ -// { -// ingredient: 'apple', -// quantity: '2', -// unit: 'pound', -// minQty: '2', -// maxQty: '2', -// }, -// { -// ingredient: 'butter', -// quantity: '6', -// unit: 'tablespoon', -// minQty: '6', -// maxQty: '6', -// } -// ]); -// }); - -// it('combines 2 ingredients that have a quantity range', () => { -// const ingredientArray = [ -// { -// ingredient: 'butter', -// quantity: '2', -// unit: 'tablespoon', -// minQty: '2', -// maxQty: '3', -// }, -// { -// ingredient: 'butter', -// quantity: '2', -// unit: 'tablespoon', -// minQty: '1', -// maxQty: '2', -// } -// ]; -// expect(combine(ingredientArray)).to.deep.equal([ -// { -// ingredient: 'butter', -// quantity: '4', -// unit: 'tablespoon', -// minQty: '3', -// maxQty: '5', -// } -// ]); -// }); - -// it('combines 1 ingredient with no range, and 1 with a range', () => { -// const ingredientArray = [ -// { -// ingredient: 'butter', -// quantity: '10', -// unit: 'tablespoon', -//// minQty: '1', -// maxQty: '10', -// }, -// { -// ingredient: 'butter', -// quantity: '2', -// unit: 'tablespoon', -// minQty: '2', -// maxQty: '2', -// } -// ]; -// expect(combine(ingredientArray)).to.deep.equal([ -// { -// ingredient: 'butter', -// quantity: '12', -// unit: 'tablespoon', -// minQty: '3', -// maxQty: '12', -// } -// ]); -// }); - -// it('combines 2 ingredient with a range, and 1 different ingredient without a range', () => { -// const ingredientArray = [ -// { -// ingredient: 'butter', -// quantity: '10', -// unit: 'tablespoon', -// minQty: '1', -// maxQty: '10', -// }, -// { -// ingredient: 'butter', -// quantity: '2', -// unit: 'tablespoon', -// minQty: '2', -// maxQty: '2', -// }, -// { -// ingredient: 'apple', -// quantity: '2', -// unit: null, -// minQty: '2', -// maxQty: '2', -// } -// ]; -// expect(combine(ingredientArray)).to.deep.equal([ -// { -// ingredient: 'apple', -// quantity: '2', -// unit: null, -// minQty: '2', -// maxQty: '2', -// }, -// { -// ingredient: 'butter', -// quantity: '12', -// unit: 'tablespoon', -// minQty: '3', -// maxQty: '12', -// } -// ]); -// }); - -// it('does not combine if ingredients have different units (for now)', () => { -//// const ingredientArray = [ -//// { -//// ingredient: 'butter', -//// quantity: '2', -//// unit: 'tablespoon', -//// minQty: '2', -//// maxQty: '2', -//// }, -//// { -//// ingredient: 'butter', -//// quantity: '2', -//// unit: 'tablespoon', -//// minQty: '2', -//// maxQty: '2', -// }, -// { -// ingredient: 'butter', -// quantity: '1', -// unit: 'stick', -// minQty: '1', -// maxQty: '1', -// }, -// { -// ingredient: 'apple', -// quantity: '2', -// unit: 'pound', -// minQty: '2', -// maxQty: '2', -// } -// ]; -// expect(combine(ingredientArray)).to.deep.equal([ -// { -// ingredient: 'apple', -// quantity: '2', -// unit: 'pound', -// minQty: '2', -// maxQty: '2', -// }, -// { -// ingredient: 'butter', -// quantity: '4', -// unit: 'tablespoon', -// minQty: '4', -// maxQty: '4', -// }, -// { -// ingredient: 'butter', -// quantity: '1', -// unit: 'stick', -// minQty: '1', -// maxQty: '1', -// } -// ]); -// }); -// -// it('handles the no-unit case', () => { -// const ingredientArray = [ -// { -// ingredient: 'tortilla', -// quantity: '10', -// unit: null, -// symbol: null, -// minQty: '10', -// maxQty: '10', -// }, -// { -// ingredient: 'tortilla', -// quantity: 5, -// unit: null, -// symbol: null, -// minQty: 5, -// maxQty: 5, -// } -// ]; -// expect(combine(ingredientArray)).to.deep.equal([ -// { -// ingredient: 'tortilla', -// quantity: 15, -// unit: null, -// symbol: null, -// minQty: 15, -// maxQty: 15, -// } -// ]); -// }); -// -// it('handles the no-unit and no-quantity case', () => { -// const ingredientArray = [ -// { -// ingredient: 'Powdered Sugar', -// quantity: 0, -// unit: null, -// symbol: null, -// minQty: 0, -// maxQty: 0, -// }, -// { -// ingredient: 'Powdered Sugar', -// quantity: 0, -// unit: null, -// symbol: null, -// minQty: 0, -// maxQty: 0, -// } -// ]; -// expect(combine(ingredientArray)).to.deep.equal([ -// { -// ingredient: 'Powdered Sugar', -// quantity: 0, -// unit: null, -// symbol: null, -// minQty: 0, -// maxQty: 0, -// } -// ]); -// }); -//}); -/* -describe('pretty printing press', () => { - const ingredients = [{ - ingredient: 'milk', - unit: 'cup', - quantity: '1.5', - minQty: '1.5', - maxQty: '1.5', - }, { - ingredient: 'milk', - unit: 'cup', - quantity: '0.25', - minQty: '0.25', - maxQty: '0.25', - }, { - ingredient: 'milk', - unit: 'cup', - quantity: '1', - minQty: '1', - maxQty: '1', - }, { - ingredient: 'something', - unit: 'box', - quantity: '2', - minQty: '2', - maxQty: '2', - }, { - ingredient: 'milk', - unit: 'teaspoon', - quantity: '1.333', - minQty: '1.333', - maxQty: '1.333', - }, { - ingredient: 'milk', - unit: 'teaspoon', - quantity: '1.666', - minQty: '1.666', - maxQty: '1.666', - }, { - ingredient: 'milk', - unit: 'teaspoon', - quantity: '1.111', - minQty: '1.111', - maxQty: '1.111', - }, { - ingredient: 'milk', - unit: 'teaspoon', - quantity: '1.166', - minQty: '1.166', - maxQty: '1.166', - }, { - ingredient: 'milk', - unit: 'teaspoon', - quantity: '1.833', - minQty: '1.1833', - maxQty: '1.1833', - }, { - ingredient: 'powdered sugar', - unit: null, - quantity: null, - minQty: null, - maxQty: null, - }, { - ingredient: 'eggs', - unit: null, - quantity: '18', - minQty: '18', - maxQty: '18', - }, { - ingredient: 'large eggs', - unit: null, - quantity: '18', - minQty: '18', - maxQty: '18', - }]; + quantity: 18, + minQty: 18, + maxQty: 18, + }, + { + ingredient: 'large eggs', + unit: null, + symbol: null, + quantity: 18, + minQty: 18, + maxQty: 18, + }, + ]; const expectedOutcome = [ '1 1/2 cups milk', '1/4 cup milk', @@ -1673,11 +516,13 @@ describe('pretty printing press', () => { '1 5/6 teaspoons milk', 'powdered sugar', '18 eggs', - '18 large eggs' + '18 large eggs', ]; for (let i = 0; i < ingredients.length; i++) { it(`returns expected outcome ${expectedOutcome[i]}`, () => { - expect(prettyPrintingPress(ingredients[i])).to.equal(expectedOutcome[i]); + expect(prettyPrintingPress(ingredients[i], 'eng')).to.equal( + expectedOutcome[i], + ); }); } -});*/ +}); diff --git a/tslint.json b/tslint.json deleted file mode 100644 index b088c10..0000000 --- a/tslint.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "extends": "tslint:recommended", - "rules": { - "arrow-parens": false, - "ban": [true, ["describe", "only"], ["it", "only"]], - "interface-name": [false], - "max-classes-per-file": [false], - "max-line-length": [false], - "member-access": [false], - "member-ordering": [false], - "no-console": [true, "log", "error"], - "no-empty": false, - "no-trailing-whitespace": false, - "no-unused-expression": false, - "no-var-requires": false, - "only-arrow-functions": [false], - "quotemark": [true, "single"], - "trailing-comma": [false], - "variable-name": [false], - "radix": false, - "object-literal-sort-keys": [false], - "ordered-imports": [false] - } -} diff --git a/yarn-error.log b/yarn-error.log deleted file mode 100644 index 881cddc..0000000 --- a/yarn-error.log +++ /dev/null @@ -1,688 +0,0 @@ -Arguments: - /Users/matteodospina/.nvm/versions/node/v11.10.1/bin/node /usr/local/Cellar/yarn/1.22.10/libexec/bin/yarn.js - -PATH: - /Users/matteodospina/.nvm/versions/node/v11.10.1/bin:/Users/matteodospina/.composer/vendor/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:Users/matteodospina/.composer/vendor/bin:/usr/local/go/bin:/Library/Apple/usr/bin:/Applications/Postgres.app/Contents/Versions/latest/bin:/Users/matteodospina/.nvm/versions/node/v11.10.1/bin:/Users/matteodospina/.composer/vendor/bin - -Yarn version: - 1.22.10 - -Node version: - 11.10.1 - -Platform: - darwin x64 - -Trace: - SyntaxError: /Users/matteodospina/Documents/parser/recipe-parser-matteo/recipe-parser/package.json: Unexpected token } in JSON at position 1390 - at JSON.parse () - at /usr/local/Cellar/yarn/1.22.10/libexec/lib/cli.js:1625:59 - at Generator.next () - at step (/usr/local/Cellar/yarn/1.22.10/libexec/lib/cli.js:310:30) - at /usr/local/Cellar/yarn/1.22.10/libexec/lib/cli.js:321:13 - -npm manifest: - { - "name": "recipe-ingredient-parser-v3", - "version": "1.1.14", - "description": "Natural language parser for recipes and ingredient lists, incl. combining ingredients", - "main": "lib/index.js", - "types": "lib/index.d.ts", - "scripts": { - "build": "rm -rf lib && tsc", - "build:test": "rm -rf testDist && tsc -p test/tsconfig.json", - "lint": "tslint \"{./**/*.ts,./**/*.tsx}\" --exclude \"{./node_modules/**,./**/*.d.ts}\"", - "prepublish": "npm run build", - "test": "npm run build:test && NODE_ENV=test mocha testDist/test/**/*.js", - "test:watch": "nodemon --ignore lib --ignore testDist -e ts,tsx -x 'npm run test --silent || true'", - "test:ci": "npm run lint && npm test", - "watch": "nodemon --watch src -e ts,tsx -x 'npm run build'" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/suprmat95/recipe-parser/" - }, - "author": "Matteo D'Ospina ", - "license": "MIT", - "bugs": { - "url": "https://github.com/suprmat95/recipe-parser/issues" - }, - "homepage": "https://github.com/suprmat95/recipe-parser#readme", - "devDependencies": { - "@types/chai": "^4.1.4", - "@types/mocha": "^5.2.4", - "chai": "^4.1.0", - "mocha": "^5.2.0", - "tslint": "^5.10.0", - "typescript": "^4.2.3" - }, - "dependencies": { - "@types/natural": "^2.1.1", - "@types/node": "^14.14.37", - "natural": "^5.0.1", - }, - "keywords": [ - "recipe", - "parser", - "ingredient", - "combine", - "units" - ] - } - -yarn manifest: - No manifest - -Lockfile: - # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. - # yarn lockfile v1 - - - "@babel/code-frame@^7.0.0": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658" - integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g== - dependencies: - "@babel/highlight" "^7.12.13" - - "@babel/helper-validator-identifier@^7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" - integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== - - "@babel/highlight@^7.12.13": - version "7.13.10" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.13.10.tgz#a8b2a66148f5b27d666b15d81774347a731d52d1" - integrity sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg== - dependencies: - "@babel/helper-validator-identifier" "^7.12.11" - chalk "^2.0.0" - js-tokens "^4.0.0" - - "@types/chai@^4.1.4": - version "4.2.15" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.15.tgz#b7a6d263c2cecf44b6de9a051cf496249b154553" - integrity sha512-rYff6FI+ZTKAPkJUoyz7Udq3GaoDZnxYDEvdEdFZASiA7PoErltHezDishqQiSDWrGxvxmplH304jyzQmjp0AQ== - - "@types/mocha@^5.2.4": - version "5.2.7" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.7.tgz#315d570ccb56c53452ff8638738df60726d5b6ea" - integrity sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ== - - "@types/natural@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@types/natural/-/natural-2.1.1.tgz#761232e1518d7ecb551af63c53e65709de09d8d3" - integrity sha512-FsDESOG70ni89e6DFZHMVvqRWrQWB8H2ad8+10qUAIGA5JX1td0NfSM/qyO4KQVkqOne/8+tNeLTDiDZsH9Dkg== - dependencies: - "@types/node" "*" - - "@types/node@*", "@types/node@^14.14.37": - version "14.14.37" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.37.tgz#a3dd8da4eb84a996c36e331df98d82abd76b516e" - integrity sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw== - - afinn-165@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/afinn-165/-/afinn-165-1.0.4.tgz#3abf6b8922dd5db84d84e0abd155924381dd73a4" - integrity sha512-7+Wlx3BImrK0HiG6y3lU4xX7SpBPSSu8T9iguPMlaueRFxjbYwAQrp9lqZUuFikqKbd/en8lVREILvP2J80uJA== - - ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - - apparatus@^0.0.10: - version "0.0.10" - resolved "https://registry.yarnpkg.com/apparatus/-/apparatus-0.0.10.tgz#81ea756772ada77863db54ceee8202c109bdca3e" - integrity sha512-KLy/ugo33KZA7nugtQ7O0E1c8kQ52N3IvD/XgIh4w/Nr28ypfkwDfA67F1ev4N1m5D+BOk1+b2dEJDfpj/VvZg== - dependencies: - sylvester ">= 0.0.8" - - argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - - assertion-error@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" - integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== - - balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - - brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - - browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== - - builtin-modules@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" - integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= - - chai@^4.1.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.4.tgz#b55e655b31e1eac7099be4c08c21964fce2e6c49" - integrity sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA== - dependencies: - assertion-error "^1.1.0" - check-error "^1.0.2" - deep-eql "^3.0.1" - get-func-name "^2.0.0" - pathval "^1.1.1" - type-detect "^4.0.5" - - chalk@^2.0.0, chalk@^2.3.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - - check-error@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" - integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= - - cli@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cli/-/cli-1.0.1.tgz#22817534f24bfa4950c34d532d48ecbc621b8c14" - integrity sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ= - dependencies: - exit "0.1.2" - glob "^7.1.1" - - color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - - color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - - commander@2.15.1: - version "2.15.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" - integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== - - commander@^2.12.1: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - - concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - - console-browserify@1.1.x: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" - integrity sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA= - dependencies: - date-now "^0.1.4" - - core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - - date-now@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" - integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= - - debug@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== - dependencies: - ms "2.0.0" - - deep-eql@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" - integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== - dependencies: - type-detect "^4.0.0" - - diff@3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" - integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== - - diff@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - - dom-serializer@0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" - integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== - dependencies: - domelementtype "^2.0.1" - entities "^2.0.0" - - domelementtype@1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" - integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== - - domelementtype@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.1.0.tgz#a851c080a6d1c3d94344aed151d99f669edf585e" - integrity sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w== - - domhandler@2.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.3.0.tgz#2de59a0822d5027fabff6f032c2b25a2a8abe738" - integrity sha1-LeWaCCLVAn+r/28DLCsloqir5zg= - dependencies: - domelementtype "1" - - domutils@1.5: - version "1.5.1" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" - integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= - dependencies: - dom-serializer "0" - domelementtype "1" - - entities@1.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-1.0.0.tgz#b2987aa3821347fcde642b24fdfc9e4fb712bf26" - integrity sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY= - - entities@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" - integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== - - escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - - esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - - exit@0.1.2, exit@0.1.x: - version "0.1.2" - resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" - integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= - - fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - - function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - - get-func-name@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" - integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= - - glob@7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" - integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - - glob@^7.1.1: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - - growl@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== - - has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - - has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - - he@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" - integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= - - htmlparser2@3.8.x: - version "3.8.3" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.8.3.tgz#996c28b191516a8be86501a7d79757e5c70c1068" - integrity sha1-mWwosZFRaovoZQGn15dX5ccMEGg= - dependencies: - domelementtype "1" - domhandler "2.3" - domutils "1.5" - entities "1.0" - readable-stream "1.1" - - inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - - inherits@2, inherits@~2.0.1: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - - is-core-module@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" - integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ== - dependencies: - has "^1.0.3" - - isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= - - js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - - js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - - jshint@^2.12.0: - version "2.12.0" - resolved "https://registry.yarnpkg.com/jshint/-/jshint-2.12.0.tgz#52e75bd058d587ef81a0e2f95e5cf18eb5dc5c37" - integrity sha512-TwuuaUDmra0JMkuqvqy+WGo2xGHSNjv1BA1nTIgtH2K5z1jHuAEeAgp7laaR+hLRmajRjcrM71+vByBDanCyYA== - dependencies: - cli "~1.0.0" - console-browserify "1.1.x" - exit "0.1.x" - htmlparser2 "3.8.x" - lodash "~4.17.19" - minimatch "~3.0.2" - shelljs "0.3.x" - strip-json-comments "1.0.x" - - json-stable-stringify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" - integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= - dependencies: - jsonify "~0.0.0" - - jsonify@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" - integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= - - lodash@~4.17.19: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - - minimatch@3.0.4, minimatch@^3.0.4, minimatch@~3.0.2: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - - minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= - - minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - - mkdirp@0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= - dependencies: - minimist "0.0.8" - - mkdirp@^0.5.1: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== - dependencies: - minimist "^1.2.5" - - mocha@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6" - integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ== - dependencies: - browser-stdout "1.3.1" - commander "2.15.1" - debug "3.1.0" - diff "3.5.0" - escape-string-regexp "1.0.5" - glob "7.1.2" - growl "1.10.5" - he "1.1.1" - minimatch "3.0.4" - mkdirp "0.5.1" - supports-color "5.4.0" - - ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - - natural@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/natural/-/natural-5.0.1.tgz#6f21524eeb67cb09f604537cacc44b35c81a784d" - integrity sha512-f/KYLldfYuBlxnSs0r2ROBlxltfgduO7iXKn2/xGL/U+XuKZm75+ph3LENuW0yHw5Rdnl4Wl+0EScc/jvnnlRA== - dependencies: - afinn-165 "^1.0.2" - apparatus "^0.0.10" - jshint "^2.12.0" - json-stable-stringify "^1.0.1" - sylvester "^0.0.12" - underscore "^1.9.1" - wordnet-db "^3.1.11" - - once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - - path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - - path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== - - pathval@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" - integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== - - readable-stream@1.1: - version "1.1.13" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.13.tgz#f6eef764f514c89e2b9e23146a75ba106756d23e" - integrity sha1-9u73ZPUUyJ4rniMUanW6EGdW0j4= - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - - resolve@^1.3.2: - version "1.20.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" - integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== - dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" - - semver@^5.3.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - - shelljs@0.3.x: - version "0.3.0" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.3.0.tgz#3596e6307a781544f591f37da618360f31db57b1" - integrity sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E= - - sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - - string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= - - strip-json-comments@1.0.x: - version "1.0.4" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91" - integrity sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E= - - supports-color@5.4.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" - integrity sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w== - dependencies: - has-flag "^3.0.0" - - supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - - "sylvester@>= 0.0.8": - version "0.0.21" - resolved "https://registry.yarnpkg.com/sylvester/-/sylvester-0.0.21.tgz#2987b1ce2bd2f38b0dce2a34388884bfa4400ea7" - integrity sha1-KYexzivS84sNzio0OIiEv6RADqc= - - sylvester@^0.0.12: - version "0.0.12" - resolved "https://registry.yarnpkg.com/sylvester/-/sylvester-0.0.12.tgz#5a884415cd2d002c57e7a3aac99462a75ce9fdb4" - integrity sha1-WohEFc0tACxX56OqyZRip1zp/bQ= - - tslib@^1.8.0, tslib@^1.8.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - - tslint@^5.10.0: - version "5.20.1" - resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.20.1.tgz#e401e8aeda0152bc44dd07e614034f3f80c67b7d" - integrity sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg== - dependencies: - "@babel/code-frame" "^7.0.0" - builtin-modules "^1.1.1" - chalk "^2.3.0" - commander "^2.12.1" - diff "^4.0.1" - glob "^7.1.1" - js-yaml "^3.13.1" - minimatch "^3.0.4" - mkdirp "^0.5.1" - resolve "^1.3.2" - semver "^5.3.0" - tslib "^1.8.0" - tsutils "^2.29.0" - - tsutils@^2.29.0: - version "2.29.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" - integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== - dependencies: - tslib "^1.8.1" - - type-detect@^4.0.0, type-detect@^4.0.5: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - - typescript@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.3.tgz#39062d8019912d43726298f09493d598048c1ce3" - integrity sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw== - - underscore@^1.9.1: - version "1.12.1" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.12.1.tgz#7bb8cc9b3d397e201cf8553336d262544ead829e" - integrity sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw== - - wordnet-db@^3.1.11: - version "3.1.14" - resolved "https://registry.yarnpkg.com/wordnet-db/-/wordnet-db-3.1.14.tgz#7ba1ec2cb5730393f0856efcc738a60085426199" - integrity sha512-zVyFsvE+mq9MCmwXUWHIcpfbrHHClZWZiVOzKSxNJruIcFn2RbY55zkhiAMMxM8zCVSmtNiViq8FsAZSFpMYag== - - wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index a452669..0000000 --- a/yarn.lock +++ /dev/null @@ -1,415 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@babel/code-frame@^7.0.0": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658" - integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g== - dependencies: - "@babel/highlight" "^7.12.13" - -"@babel/helper-validator-identifier@^7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" - integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== - -"@babel/highlight@^7.12.13": - version "7.13.10" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.13.10.tgz#a8b2a66148f5b27d666b15d81774347a731d52d1" - integrity sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg== - dependencies: - "@babel/helper-validator-identifier" "^7.12.11" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@types/chai@^4.1.4": - version "4.2.15" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.15.tgz#b7a6d263c2cecf44b6de9a051cf496249b154553" - integrity sha512-rYff6FI+ZTKAPkJUoyz7Udq3GaoDZnxYDEvdEdFZASiA7PoErltHezDishqQiSDWrGxvxmplH304jyzQmjp0AQ== - -"@types/mocha@^5.2.4": - version "5.2.7" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.7.tgz#315d570ccb56c53452ff8638738df60726d5b6ea" - integrity sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ== - -"@types/node@^10.5.1": - version "10.17.56" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.56.tgz#010c9e047c3ff09ddcd11cbb6cf5912725cdc2b3" - integrity sha512-LuAa6t1t0Bfw4CuSR0UITsm1hP17YL+u82kfHGrHUWdhlBtH7sa7jGY5z7glGaIj/WDYDkRtgGd+KCjCzxBW1w== - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -assertion-error@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" - integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== - -builtin-modules@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" - integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= - -chai@^4.1.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.4.tgz#b55e655b31e1eac7099be4c08c21964fce2e6c49" - integrity sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA== - dependencies: - assertion-error "^1.1.0" - check-error "^1.0.2" - deep-eql "^3.0.1" - get-func-name "^2.0.0" - pathval "^1.1.1" - type-detect "^4.0.5" - -chalk@^2.0.0, chalk@^2.3.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -check-error@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" - integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -commander@2.15.1: - version "2.15.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" - integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== - -commander@^2.12.1: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -debug@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== - dependencies: - ms "2.0.0" - -deep-eql@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" - integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== - dependencies: - type-detect "^4.0.0" - -diff@3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" - integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== - -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -get-func-name@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" - integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= - -glob@7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" - integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.1.1: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -growl@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -he@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" - integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -is-core-module@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" - integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ== - dependencies: - has "^1.0.3" - -js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -minimatch@3.0.4, minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= - -minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - -mkdirp@0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= - dependencies: - minimist "0.0.8" - -mkdirp@^0.5.1: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== - dependencies: - minimist "^1.2.5" - -mocha@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6" - integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ== - dependencies: - browser-stdout "1.3.1" - commander "2.15.1" - debug "3.1.0" - diff "3.5.0" - escape-string-regexp "1.0.5" - glob "7.1.2" - growl "1.10.5" - he "1.1.1" - minimatch "3.0.4" - mkdirp "0.5.1" - supports-color "5.4.0" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== - -pathval@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" - integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== - -resolve@^1.3.2: - version "1.20.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" - integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== - dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" - -semver@^5.3.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -supports-color@5.4.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" - integrity sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w== - dependencies: - has-flag "^3.0.0" - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -tslib@^1.8.0, tslib@^1.8.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tslint@^5.10.0: - version "5.20.1" - resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.20.1.tgz#e401e8aeda0152bc44dd07e614034f3f80c67b7d" - integrity sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg== - dependencies: - "@babel/code-frame" "^7.0.0" - builtin-modules "^1.1.1" - chalk "^2.3.0" - commander "^2.12.1" - diff "^4.0.1" - glob "^7.1.1" - js-yaml "^3.13.1" - minimatch "^3.0.4" - mkdirp "^0.5.1" - resolve "^1.3.2" - semver "^5.3.0" - tslib "^1.8.0" - tsutils "^2.29.0" - -tsutils@^2.29.0: - version "2.29.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" - integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== - dependencies: - tslib "^1.8.1" - -type-detect@^4.0.0, type-detect@^4.0.5: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - -typescript@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.3.tgz#39062d8019912d43726298f09493d598048c1ce3" - integrity sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw== - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=