From e8b8a89c3808553391e0a5e3c8a1b33aa2331327 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sun, 10 Jan 2021 15:42:13 +0900 Subject: [PATCH 01/63] add package.json --- .gitignore | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 5 +++ yarn.lock | 8 ++++ 3 files changed, 129 insertions(+) create mode 100644 .gitignore create mode 100644 package.json create mode 100644 yarn.lock diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..30a39ca --- /dev/null +++ b/.gitignore @@ -0,0 +1,116 @@ + +# Created by https://www.toptal.com/developers/gitignore/api/node +# Edit at https://www.toptal.com/developers/gitignore?templates=node + +### Node ### +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.test +.env*.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# End of https://www.toptal.com/developers/gitignore/api/node diff --git a/package.json b/package.json new file mode 100644 index 0000000..fd91724 --- /dev/null +++ b/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "typescript": "^4.1.3" + } +} diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..3986214 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,8 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +typescript@^4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.3.tgz#519d582bd94cba0cf8934c7d8e8467e473f53bb7" + integrity sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg== From 067c630f4583ad4f7712255de1f12f3748996b75 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sun, 10 Jan 2021 15:49:25 +0900 Subject: [PATCH 02/63] Add eslint and prettier --- .eslintignore | 1 + .eslintrc.js | 78 ++++ package.json | 14 +- tsconfig.json | 20 ++ yarn.lock | 973 ++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 1085 insertions(+), 1 deletion(-) create mode 100644 .eslintignore create mode 100644 .eslintrc.js create mode 100644 tsconfig.json diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..a9ba028 --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +.eslintrc.js diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..fb08275 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,78 @@ +"use strict"; + +module.exports = { + root: true, + env: { + browser: true, + node: true, + es6: true, + }, + + parser: "@typescript-eslint/parser", + parserOptions: { + sourceType: "module", + project: "./tsconfig.json", + tsconfigRootDir: __dirname, // TODO: https://github.com/typescript-eslint/typescript-eslint/issues/251 + useJSXTextNode: true, + }, + + plugins: ["@typescript-eslint", "prettier" ], + + extends: [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:prettier/recommended", + "prettier", + ], + + rules: { + "prettier/prettier": [ + "warn", + { + bracketSpacing: true, + printWidth: 120, + singleQuote: true, + tabWidth: 4, + trailingComma: "es5", // EcmaScript5 において、validな場合には末尾カンマを許可する + arrowParens: "always", // アロー関数の引数に対する括弧を必須にする + useTabs: false, + jsxBracketSameLine: false, + parser: "typescript", + }, + ], + "@typescript-eslint/no-namespace": "off", + // '@typescript-eslint/indent': 'off', + // '@typescript-eslint/interface-name-prefix': ['warn', 'always'], + // '@typescript-eslint/no-empty-interface': 'off', + // '@typescript-eslint/no-object-literal-type-assertion': 'off', + // '@typescript-eslint/no-unused-vars': 'warn', + // '@typescript-eslint/no-explicit-any': 'off', + // "@typescript-eslint/no-empty-function": [2, {"allow": ["arrowFunctions", "constructors"]}], + // // 'no-console': ['warn', { allow: ['error', 'warn'] }], + // // TSLintの例外対応 + // '@typescript-eslint/array-type': 'warn', // 配列を[]で定義(Array<>は許可しない) + // '@typescript-eslint/camelcase': 'off', // キャメルケースを許可しない + // '@typescript-eslint/explicit-function-return-type': ['off'], // 関数の戻り値の型の指定 + // '@typescript-eslint/explicit-member-accessibility': 'warn', // TODO: https://github.com/typescript-eslint/typescript-eslint/issues/214 + // 'import/no-extraneous-dependencies': 'off', // package.jsonのdevDependencies import問題 + // 'import/no-unresolved': 'off', // TODO: aliasの時だけ拡張子が解決出来ずエラーになるので対策 + // 'import/order': 'off', // importの順序 + // 'import/prefer-default-export': 'off', // exportが1つしかない場合はdefaultにする + // 'no-irregular-whitespace': ['error', { skipRegExps: true }], // 正規表現のみスペースの使用を許可する + // 'no-nested-ternary': 'off', // 三項演算子のネストを許可しない + }, + + settings: { + propWrapperFunctions: [ + // The names of any function used to wrap propTypes, e.g. `forbidExtraProps`. If this isn't set, any propTypes wrapped in a function will be skipped. + "forbidExtraProps", + { property: "freeze", object: "Object" }, + { property: "myFavoriteWrapper" }, + ], + linkComponents: [ + // Components used as alternatives to for linking, eg. + "Hyperlink", + { name: "Link", linkAttribute: "to" }, + ], + }, +}; diff --git a/package.json b/package.json index fd91724..33dd9f2 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,17 @@ { - "dependencies": { + "name": "object-oriented-modeling-samples", + "version": "0.0.1", + "devDependencies": { + "@typescript-eslint/eslint-plugin": "^4.12.0", + "@typescript-eslint/parser": "^4.12.0", + "eslint": "^7.17.0", + "eslint-config-prettier": "^7.1.0", + "eslint-plugin-prettier": "^3.3.1", + "prettier": "^2.2.1", "typescript": "^4.1.3" + }, + "scripts": { + "eslint": "eslint src --ext .js,.jsx,.ts,.tsx", + "eslint:fix": "eslint src --ext .js,.jsx,.ts,.tsx --fix" } } diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..a1419e5 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "experimentalDecorators": true, + "sourceMap": true, + "target": "es5", + "module": "es2015", + "jsx": "react", + "moduleResolution": "node", + "lib": [ + "es2020", + "dom" + ], + "allowSyntheticDefaultImports": true, + "typeRoots": [ + "./node_modules/@types", + "./@types" + ], + "baseUrl": "./src" + } +} diff --git a/yarn.lock b/yarn.lock index 3986214..3e012a3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,7 +2,980 @@ # yarn lockfile v1 +"@babel/code-frame@^7.0.0": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" + integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== + dependencies: + "@babel/highlight" "^7.10.4" + +"@babel/helper-validator-identifier@^7.10.4": + 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.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143" + integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA== + dependencies: + "@babel/helper-validator-identifier" "^7.10.4" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@eslint/eslintrc@^0.2.2": + version "0.2.2" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.2.2.tgz#d01fc791e2fc33e88a29d6f3dc7e93d0cd784b76" + integrity sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ== + dependencies: + ajv "^6.12.4" + debug "^4.1.1" + espree "^7.3.0" + globals "^12.1.0" + ignore "^4.0.6" + import-fresh "^3.2.1" + js-yaml "^3.13.1" + lodash "^4.17.19" + minimatch "^3.0.4" + strip-json-comments "^3.1.1" + +"@nodelib/fs.scandir@2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69" + integrity sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA== + dependencies: + "@nodelib/fs.stat" "2.0.4" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.4", "@nodelib/fs.stat@^2.0.2": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz#a3f2dd61bab43b8db8fa108a121cfffe4c676655" + integrity sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz#cce9396b30aa5afe9e3756608f5831adcb53d063" + integrity sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow== + dependencies: + "@nodelib/fs.scandir" "2.1.4" + fastq "^1.6.0" + +"@types/json-schema@^7.0.3": + version "7.0.6" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0" + integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== + +"@typescript-eslint/eslint-plugin@^4.12.0": + version "4.12.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.12.0.tgz#00d1b23b40b58031e6d7c04a5bc6c1a30a2e834a" + integrity sha512-wHKj6q8s70sO5i39H2g1gtpCXCvjVszzj6FFygneNFyIAxRvNSVz9GML7XpqrB9t7hNutXw+MHnLN/Ih6uyB8Q== + dependencies: + "@typescript-eslint/experimental-utils" "4.12.0" + "@typescript-eslint/scope-manager" "4.12.0" + debug "^4.1.1" + functional-red-black-tree "^1.0.1" + regexpp "^3.0.0" + semver "^7.3.2" + tsutils "^3.17.1" + +"@typescript-eslint/experimental-utils@4.12.0": + version "4.12.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.12.0.tgz#372838e76db76c9a56959217b768a19f7129546b" + integrity sha512-MpXZXUAvHt99c9ScXijx7i061o5HEjXltO+sbYfZAAHxv3XankQkPaNi5myy0Yh0Tyea3Hdq1pi7Vsh0GJb0fA== + dependencies: + "@types/json-schema" "^7.0.3" + "@typescript-eslint/scope-manager" "4.12.0" + "@typescript-eslint/types" "4.12.0" + "@typescript-eslint/typescript-estree" "4.12.0" + eslint-scope "^5.0.0" + eslint-utils "^2.0.0" + +"@typescript-eslint/parser@^4.12.0": + version "4.12.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.12.0.tgz#e1cf30436e4f916c31fcc962158917bd9e9d460a" + integrity sha512-9XxVADAo9vlfjfoxnjboBTxYOiNY93/QuvcPgsiKvHxW6tOZx1W4TvkIQ2jB3k5M0pbFP5FlXihLK49TjZXhuQ== + dependencies: + "@typescript-eslint/scope-manager" "4.12.0" + "@typescript-eslint/types" "4.12.0" + "@typescript-eslint/typescript-estree" "4.12.0" + debug "^4.1.1" + +"@typescript-eslint/scope-manager@4.12.0": + version "4.12.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.12.0.tgz#beeb8beca895a07b10c593185a5612f1085ef279" + integrity sha512-QVf9oCSVLte/8jvOsxmgBdOaoe2J0wtEmBr13Yz0rkBNkl5D8bfnf6G4Vhox9qqMIoG7QQoVwd2eG9DM/ge4Qg== + dependencies: + "@typescript-eslint/types" "4.12.0" + "@typescript-eslint/visitor-keys" "4.12.0" + +"@typescript-eslint/types@4.12.0": + version "4.12.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.12.0.tgz#fb891fe7ccc9ea8b2bbd2780e36da45d0dc055e5" + integrity sha512-N2RhGeheVLGtyy+CxRmxdsniB7sMSCfsnbh8K/+RUIXYYq3Ub5+sukRCjVE80QerrUBvuEvs4fDhz5AW/pcL6g== + +"@typescript-eslint/typescript-estree@4.12.0": + version "4.12.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.12.0.tgz#3963418c850f564bdab3882ae23795d115d6d32e" + integrity sha512-gZkFcmmp/CnzqD2RKMich2/FjBTsYopjiwJCroxqHZIY11IIoN0l5lKqcgoAPKHt33H2mAkSfvzj8i44Jm7F4w== + dependencies: + "@typescript-eslint/types" "4.12.0" + "@typescript-eslint/visitor-keys" "4.12.0" + debug "^4.1.1" + globby "^11.0.1" + is-glob "^4.0.1" + lodash "^4.17.15" + semver "^7.3.2" + tsutils "^3.17.1" + +"@typescript-eslint/visitor-keys@4.12.0": + version "4.12.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.12.0.tgz#a470a79be6958075fa91c725371a83baf428a67a" + integrity sha512-hVpsLARbDh4B9TKYz5cLbcdMIOAoBYgFPCSP9FFS/liSF+b33gVNq8JHY3QGhHNVz85hObvL7BEYLlgx553WCw== + dependencies: + "@typescript-eslint/types" "4.12.0" + eslint-visitor-keys "^2.0.0" + +acorn-jsx@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" + integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== + +acorn@^7.4.0: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + +ajv@^6.10.0, ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + 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" + +ajv@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-7.0.3.tgz#13ae747eff125cafb230ac504b2406cf371eece2" + integrity sha512-R50QRlXSxqXcQP5SvKUrw8VZeypvo12i2IX0EeR5PiZ7bEKeHWgzgo264LDadUsCU42lTJVhFikTqJwNeH34gQ== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +ansi-colors@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + +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" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +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" + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + +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" + +braces@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +chalk@^2.0.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" + +chalk@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" + integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +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-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +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= + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +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= + +cross-spawn@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +debug@^4.0.1, debug@^4.1.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" + integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== + dependencies: + ms "2.1.2" + +deep-is@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +enquirer@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + dependencies: + ansi-colors "^4.1.1" + +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= + +eslint-config-prettier@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-7.1.0.tgz#5402eb559aa94b894effd6bddfa0b1ca051c858f" + integrity sha512-9sm5/PxaFG7qNJvJzTROMM1Bk1ozXVTKI0buKOyb0Bsr1hrwi0H/TzxF/COtf1uxikIK8SwhX7K6zg78jAzbeA== + +eslint-plugin-prettier@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.3.1.tgz#7079cfa2497078905011e6f82e8dd8453d1371b7" + integrity sha512-Rq3jkcFY8RYeQLgk2cCwuc0P7SEFwDravPhsJZOQ5N4YI4DSg50NyqJ/9gdZHzQlHf8MvafSesbNJCcP/FF6pQ== + dependencies: + prettier-linter-helpers "^1.0.0" + +eslint-scope@^5.0.0, eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +eslint-utils@^2.0.0, eslint-utils@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" + integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== + dependencies: + eslint-visitor-keys "^1.1.0" + +eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" + integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== + +eslint-visitor-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" + integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== + +eslint@^7.17.0: + version "7.17.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.17.0.tgz#4ccda5bf12572ad3bf760e6f195886f50569adb0" + integrity sha512-zJk08MiBgwuGoxes5sSQhOtibZ75pz0J35XTRlZOk9xMffhpA9BTbQZxoXZzOl5zMbleShbGwtw+1kGferfFwQ== + dependencies: + "@babel/code-frame" "^7.0.0" + "@eslint/eslintrc" "^0.2.2" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.0.1" + doctrine "^3.0.0" + enquirer "^2.3.5" + eslint-scope "^5.1.1" + eslint-utils "^2.1.0" + eslint-visitor-keys "^2.0.0" + espree "^7.3.1" + esquery "^1.2.0" + esutils "^2.0.2" + file-entry-cache "^6.0.0" + functional-red-black-tree "^1.0.1" + glob-parent "^5.0.0" + globals "^12.1.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + js-yaml "^3.13.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash "^4.17.19" + minimatch "^3.0.4" + natural-compare "^1.4.0" + optionator "^0.9.1" + progress "^2.0.0" + regexpp "^3.1.0" + semver "^7.2.1" + strip-ansi "^6.0.0" + strip-json-comments "^3.1.0" + table "^6.0.4" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + +espree@^7.3.0, espree@^7.3.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" + integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== + dependencies: + acorn "^7.4.0" + acorn-jsx "^5.3.1" + eslint-visitor-keys "^1.3.0" + +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== + +esquery@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.3.1.tgz#b78b5828aa8e214e29fb74c4d5b752e1c033da57" + integrity sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" + integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +fast-deep-equal@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-diff@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + +fast-glob@^3.1.1: + version "3.2.4" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.4.tgz#d20aefbf99579383e7f3cc66529158c9b98554d3" + integrity sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.0" + merge2 "^1.3.0" + micromatch "^4.0.2" + picomatch "^2.2.1" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fastq@^1.6.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.10.0.tgz#74dbefccade964932cdf500473ef302719c652bb" + integrity sha512-NL2Qc5L3iQEsyYzweq7qfgy5OtXCmGzGvhElGEd/SoFWEMOEczNh5s5ocaF01HDetxz+p8ecjNPA6cZxxIHmzA== + dependencies: + reusify "^1.0.4" + +file-entry-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.0.tgz#7921a89c391c6d93efec2169ac6bf300c527ea0a" + integrity sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA== + dependencies: + flat-cache "^3.0.4" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + +flatted@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.0.tgz#a5d06b4a8b01e3a63771daa5cb7a1903e2e57067" + integrity sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA== + +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= + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +glob-parent@^5.0.0, glob-parent@^5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" + integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== + dependencies: + is-glob "^4.0.1" + +glob@^7.1.3: + 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" + +globals@^12.1.0: + version "12.4.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" + integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== + dependencies: + type-fest "^0.8.1" + +globby@^11.0.1: + version "11.0.2" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.2.tgz#1af538b766a3b540ebfb58a32b2e2d5897321d83" + integrity sha512-2ZThXDvvV8fYFRVIxnrMQBipZQDr7MxKAmQK1vujaj9/7eF0efG7BPUKJ7jP7G5SLF37xKDXvO4S/KKLj/Z0og== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.1.1" + ignore "^5.1.4" + merge2 "^1.3.0" + slash "^3.0.0" + +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-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +ignore@^5.1.4: + version "5.1.8" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" + integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== + +import-fresh@^3.0.0, import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +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-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.0, is-glob@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +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" + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20: + version "4.17.20" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" + integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +merge2@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" + integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== + dependencies: + braces "^3.0.1" + picomatch "^2.0.5" + +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" + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +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" + +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + 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" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +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-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +picomatch@^2.0.5, picomatch@^2.2.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" + integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" + integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q== + +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +regexpp@^3.0.0, regexpp@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" + integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +run-parallel@^1.1.9: + version "1.1.10" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.10.tgz#60a51b2ae836636c81377df16cb107351bcd13ef" + integrity sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw== + +semver@^7.2.1, semver@^7.3.2: + version "7.3.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97" + integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw== + dependencies: + lru-cache "^6.0.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +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-width@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" + integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" + +strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== + dependencies: + ansi-regex "^5.0.0" + +strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +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" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +table@^6.0.4: + version "6.0.7" + resolved "https://registry.yarnpkg.com/table/-/table-6.0.7.tgz#e45897ffbcc1bcf9e8a87bf420f2c9e5a7a52a34" + integrity sha512-rxZevLGTUzWna/qBLObOe16kB2RTnnbhciwgPbMMlazz1yZGVEgnZK762xyVdVznhqxrfCeBMmMkgOOaPwjH7g== + dependencies: + ajv "^7.0.2" + lodash "^4.17.20" + slice-ansi "^4.0.0" + string-width "^4.2.0" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.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== + +tsutils@^3.17.1: + version "3.19.1" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.19.1.tgz#d8566e0c51c82f32f9c25a4d367cd62409a547a9" + integrity sha512-GEdoBf5XI324lu7ycad7s6laADfnAqCw6wLGI+knxvw9vsIYBaJfYdmeCEG3FMMUiSm3OGgNb+m6utsWf5h9Vw== + dependencies: + tslib "^1.8.1" + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-fest@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" + integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== + typescript@^4.1.3: version "4.1.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.3.tgz#519d582bd94cba0cf8934c7d8e8467e473f53bb7" integrity sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg== + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +v8-compile-cache@^2.0.3: + version "2.2.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz#9471efa3ef9128d2f7c6a7ca39c4dd6b5055b132" + integrity sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q== + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +word-wrap@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== From caf0b4090c4ae89a17d1f4261dcd4833e762f4ef Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sun, 10 Jan 2021 15:57:45 +0900 Subject: [PATCH 03/63] =?UTF-8?q?jest=20=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 23 +- tsconfig.json | 3 + yarn.lock | 3394 +++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 3314 insertions(+), 106 deletions(-) diff --git a/package.json b/package.json index 33dd9f2..6e89aa4 100644 --- a/package.json +++ b/package.json @@ -2,16 +2,37 @@ "name": "object-oriented-modeling-samples", "version": "0.0.1", "devDependencies": { + "@types/jest": "^26.0.20", "@typescript-eslint/eslint-plugin": "^4.12.0", "@typescript-eslint/parser": "^4.12.0", "eslint": "^7.17.0", "eslint-config-prettier": "^7.1.0", "eslint-plugin-prettier": "^3.3.1", + "jest": "^26.6.3", "prettier": "^2.2.1", + "ts-jest": "^26.4.4", "typescript": "^4.1.3" }, "scripts": { "eslint": "eslint src --ext .js,.jsx,.ts,.tsx", - "eslint:fix": "eslint src --ext .js,.jsx,.ts,.tsx --fix" + "eslint:fix": "eslint src --ext .js,.jsx,.ts,.tsx --fix", + "test": "jest --env=jsdom --silent=false" + }, + "jest": { + "moduleFileExtensions": [ + "js", + "ts" + ], + "verbose": true, + "silent": false, + "testRegex": "[^/.]+\\.(test|spec)\\.(tsx?|jsx?)$", + "transform": { + "^.+\\.(ts)$": "ts-jest" + }, + "globals": { + "ts-jest": { + "tsconfig": "tsconfig.json" + } + } } } diff --git a/tsconfig.json b/tsconfig.json index a1419e5..db10b15 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,6 +15,9 @@ "./node_modules/@types", "./@types" ], + "types": [ + "jest" + ], "baseUrl": "./src" } } diff --git a/yarn.lock b/yarn.lock index 3e012a3..5ee73cb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,18 +2,138 @@ # yarn lockfile v1 -"@babel/code-frame@^7.0.0": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.11": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== dependencies: "@babel/highlight" "^7.10.4" -"@babel/helper-validator-identifier@^7.10.4": +"@babel/core@^7.1.0", "@babel/core@^7.7.5": + version "7.12.10" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.10.tgz#b79a2e1b9f70ed3d84bbfb6d8c4ef825f606bccd" + integrity sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/generator" "^7.12.10" + "@babel/helper-module-transforms" "^7.12.1" + "@babel/helpers" "^7.12.5" + "@babel/parser" "^7.12.10" + "@babel/template" "^7.12.7" + "@babel/traverse" "^7.12.10" + "@babel/types" "^7.12.10" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.1" + json5 "^2.1.2" + lodash "^4.17.19" + semver "^5.4.1" + source-map "^0.5.0" + +"@babel/generator@^7.12.10", "@babel/generator@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.11.tgz#98a7df7b8c358c9a37ab07a24056853016aba3af" + integrity sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA== + dependencies: + "@babel/types" "^7.12.11" + jsesc "^2.5.1" + source-map "^0.5.0" + +"@babel/helper-function-name@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz#1fd7738aee5dcf53c3ecff24f1da9c511ec47b42" + integrity sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA== + dependencies: + "@babel/helper-get-function-arity" "^7.12.10" + "@babel/template" "^7.12.7" + "@babel/types" "^7.12.11" + +"@babel/helper-get-function-arity@^7.12.10": + version "7.12.10" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz#b158817a3165b5faa2047825dfa61970ddcc16cf" + integrity sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag== + dependencies: + "@babel/types" "^7.12.10" + +"@babel/helper-member-expression-to-functions@^7.12.7": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz#aa77bd0396ec8114e5e30787efa78599d874a855" + integrity sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw== + dependencies: + "@babel/types" "^7.12.7" + +"@babel/helper-module-imports@^7.12.1": + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz#1bfc0229f794988f76ed0a4d4e90860850b54dfb" + integrity sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA== + dependencies: + "@babel/types" "^7.12.5" + +"@babel/helper-module-transforms@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz#7954fec71f5b32c48e4b303b437c34453fd7247c" + integrity sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w== + dependencies: + "@babel/helper-module-imports" "^7.12.1" + "@babel/helper-replace-supers" "^7.12.1" + "@babel/helper-simple-access" "^7.12.1" + "@babel/helper-split-export-declaration" "^7.11.0" + "@babel/helper-validator-identifier" "^7.10.4" + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.12.1" + "@babel/types" "^7.12.1" + lodash "^4.17.19" + +"@babel/helper-optimise-call-expression@^7.12.10": + version "7.12.10" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz#94ca4e306ee11a7dd6e9f42823e2ac6b49881e2d" + integrity sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ== + dependencies: + "@babel/types" "^7.12.10" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.8.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" + integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== + +"@babel/helper-replace-supers@^7.12.1": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz#ea511658fc66c7908f923106dd88e08d1997d60d" + integrity sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.12.7" + "@babel/helper-optimise-call-expression" "^7.12.10" + "@babel/traverse" "^7.12.10" + "@babel/types" "^7.12.11" + +"@babel/helper-simple-access@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz#32427e5aa61547d38eb1e6eaf5fd1426fdad9136" + integrity sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA== + dependencies: + "@babel/types" "^7.12.1" + +"@babel/helper-split-export-declaration@^7.11.0", "@babel/helper-split-export-declaration@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz#1b4cc424458643c47d37022223da33d76ea4603a" + integrity sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g== + dependencies: + "@babel/types" "^7.12.11" + +"@babel/helper-validator-identifier@^7.10.4", "@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/helpers@^7.12.5": + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.5.tgz#1a1ba4a768d9b58310eda516c449913fe647116e" + integrity sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA== + dependencies: + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.12.5" + "@babel/types" "^7.12.5" + "@babel/highlight@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143" @@ -23,6 +143,141 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@babel/parser@^7.1.0", "@babel/parser@^7.12.10", "@babel/parser@^7.12.11", "@babel/parser@^7.12.7": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.11.tgz#9ce3595bcd74bc5c466905e86c535b8b25011e79" + integrity sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg== + +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-bigint@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" + integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.8.3": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz#bcb297c5366e79bebadef509549cd93b04f19978" + integrity sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-import-meta@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz#dd6c0b357ac1bb142d98537450a319625d13d2a0" + integrity sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/template@^7.10.4", "@babel/template@^7.12.7", "@babel/template@^7.3.3": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.7.tgz#c817233696018e39fbb6c491d2fb684e05ed43bc" + integrity sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/parser" "^7.12.7" + "@babel/types" "^7.12.7" + +"@babel/traverse@^7.1.0", "@babel/traverse@^7.12.1", "@babel/traverse@^7.12.10", "@babel/traverse@^7.12.5": + version "7.12.12" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.12.tgz#d0cd87892704edd8da002d674bc811ce64743376" + integrity sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w== + dependencies: + "@babel/code-frame" "^7.12.11" + "@babel/generator" "^7.12.11" + "@babel/helper-function-name" "^7.12.11" + "@babel/helper-split-export-declaration" "^7.12.11" + "@babel/parser" "^7.12.11" + "@babel/types" "^7.12.12" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.19" + +"@babel/types@^7.0.0", "@babel/types@^7.12.1", "@babel/types@^7.12.10", "@babel/types@^7.12.11", "@babel/types@^7.12.12", "@babel/types@^7.12.5", "@babel/types@^7.12.7", "@babel/types@^7.3.0", "@babel/types@^7.3.3": + version "7.12.12" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.12.tgz#4608a6ec313abbd87afa55004d373ad04a96c299" + integrity sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ== + dependencies: + "@babel/helper-validator-identifier" "^7.12.11" + lodash "^4.17.19" + to-fast-properties "^2.0.0" + +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + +"@cnakazawa/watch@^1.0.3": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" + integrity sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ== + dependencies: + exec-sh "^0.3.2" + minimist "^1.2.0" + "@eslint/eslintrc@^0.2.2": version "0.2.2" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.2.2.tgz#d01fc791e2fc33e88a29d6f3dc7e93d0cd784b76" @@ -39,6 +294,193 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + +"@istanbuljs/schema@^0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd" + integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw== + +"@jest/console@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-26.6.2.tgz#4e04bc464014358b03ab4937805ee36a0aeb98f2" + integrity sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g== + dependencies: + "@jest/types" "^26.6.2" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^26.6.2" + jest-util "^26.6.2" + slash "^3.0.0" + +"@jest/core@^26.6.3": + version "26.6.3" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-26.6.3.tgz#7639fcb3833d748a4656ada54bde193051e45fad" + integrity sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw== + dependencies: + "@jest/console" "^26.6.2" + "@jest/reporters" "^26.6.2" + "@jest/test-result" "^26.6.2" + "@jest/transform" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.4" + jest-changed-files "^26.6.2" + jest-config "^26.6.3" + jest-haste-map "^26.6.2" + jest-message-util "^26.6.2" + jest-regex-util "^26.0.0" + jest-resolve "^26.6.2" + jest-resolve-dependencies "^26.6.3" + jest-runner "^26.6.3" + jest-runtime "^26.6.3" + jest-snapshot "^26.6.2" + jest-util "^26.6.2" + jest-validate "^26.6.2" + jest-watcher "^26.6.2" + micromatch "^4.0.2" + p-each-series "^2.1.0" + rimraf "^3.0.0" + slash "^3.0.0" + strip-ansi "^6.0.0" + +"@jest/environment@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-26.6.2.tgz#ba364cc72e221e79cc8f0a99555bf5d7577cf92c" + integrity sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA== + dependencies: + "@jest/fake-timers" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/node" "*" + jest-mock "^26.6.2" + +"@jest/fake-timers@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-26.6.2.tgz#459c329bcf70cee4af4d7e3f3e67848123535aad" + integrity sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA== + dependencies: + "@jest/types" "^26.6.2" + "@sinonjs/fake-timers" "^6.0.1" + "@types/node" "*" + jest-message-util "^26.6.2" + jest-mock "^26.6.2" + jest-util "^26.6.2" + +"@jest/globals@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-26.6.2.tgz#5b613b78a1aa2655ae908eba638cc96a20df720a" + integrity sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA== + dependencies: + "@jest/environment" "^26.6.2" + "@jest/types" "^26.6.2" + expect "^26.6.2" + +"@jest/reporters@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-26.6.2.tgz#1f518b99637a5f18307bd3ecf9275f6882a667f6" + integrity sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^26.6.2" + "@jest/test-result" "^26.6.2" + "@jest/transform" "^26.6.2" + "@jest/types" "^26.6.2" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.2" + graceful-fs "^4.2.4" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^4.0.3" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.0.2" + jest-haste-map "^26.6.2" + jest-resolve "^26.6.2" + jest-util "^26.6.2" + jest-worker "^26.6.2" + slash "^3.0.0" + source-map "^0.6.0" + string-length "^4.0.1" + terminal-link "^2.0.0" + v8-to-istanbul "^7.0.0" + optionalDependencies: + node-notifier "^8.0.0" + +"@jest/source-map@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-26.6.2.tgz#29af5e1e2e324cafccc936f218309f54ab69d535" + integrity sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA== + dependencies: + callsites "^3.0.0" + graceful-fs "^4.2.4" + source-map "^0.6.0" + +"@jest/test-result@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-26.6.2.tgz#55da58b62df134576cc95476efa5f7949e3f5f18" + integrity sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ== + dependencies: + "@jest/console" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + +"@jest/test-sequencer@^26.6.3": + version "26.6.3" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz#98e8a45100863886d074205e8ffdc5a7eb582b17" + integrity sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw== + dependencies: + "@jest/test-result" "^26.6.2" + graceful-fs "^4.2.4" + jest-haste-map "^26.6.2" + jest-runner "^26.6.3" + jest-runtime "^26.6.3" + +"@jest/transform@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-26.6.2.tgz#5ac57c5fa1ad17b2aae83e73e45813894dcf2e4b" + integrity sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA== + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^26.6.2" + babel-plugin-istanbul "^6.0.0" + chalk "^4.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.2.4" + jest-haste-map "^26.6.2" + jest-regex-util "^26.0.0" + jest-util "^26.6.2" + micromatch "^4.0.2" + pirates "^4.0.1" + slash "^3.0.0" + source-map "^0.6.1" + write-file-atomic "^3.0.0" + +"@jest/types@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" + integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^15.0.0" + chalk "^4.0.0" + "@nodelib/fs.scandir@2.1.4": version "2.1.4" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69" @@ -60,11 +502,124 @@ "@nodelib/fs.scandir" "2.1.4" fastq "^1.6.0" +"@sinonjs/commons@^1.7.0": + version "1.8.1" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.1.tgz#e7df00f98a203324f6dc7cc606cad9d4a8ab2217" + integrity sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz#293674fccb3262ac782c7aadfdeca86b10c75c40" + integrity sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA== + dependencies: + "@sinonjs/commons" "^1.7.0" + +"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.7": + version "7.1.12" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.12.tgz#4d8e9e51eb265552a7e4f1ff2219ab6133bdfb2d" + integrity sha512-wMTHiiTiBAAPebqaPiPDLFA4LYPKr6Ph0Xq/6rq1Ur3v66HXyG+clfR9CNETkD7MQS8ZHvpQOtA53DLws5WAEQ== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.2.tgz#f3d71178e187858f7c45e30380f8f1b7415a12d8" + integrity sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.0.tgz#0c888dd70b3ee9eebb6e4f200e809da0076262be" + integrity sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.11.0.tgz#b9a1efa635201ba9bc850323a8793ee2d36c04a0" + integrity sha512-kSjgDMZONiIfSH1Nxcr5JIRMwUetDki63FSQfpTCz8ogF3Ulqm8+mr5f78dUYs6vMiB6gBusQqfQmBvHZj/lwg== + dependencies: + "@babel/types" "^7.3.0" + +"@types/graceful-fs@^4.1.2": + version "4.1.4" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.4.tgz#4ff9f641a7c6d1a3508ff88bc3141b152772e753" + integrity sha512-mWA/4zFQhfvOA8zWkXobwJvBD7vzcxgrOQ0J5CH1votGqdq9m7+FwtGaqyCZqC3NyyBkc9z4m+iry4LlqcMWJg== + dependencies: + "@types/node" "*" + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762" + integrity sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw== + +"@types/istanbul-lib-report@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" + integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz#508b13aa344fa4976234e75dddcc34925737d821" + integrity sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA== + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/jest@26.x", "@types/jest@^26.0.20": + version "26.0.20" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.20.tgz#cd2f2702ecf69e86b586e1f5223a60e454056307" + integrity sha512-9zi2Y+5USJRxd0FsahERhBwlcvFh6D2GLQnY2FH2BzK8J9s9omvNHIbvABwIluXa0fD8XVKMLTO0aOEuUfACAA== + dependencies: + jest-diff "^26.0.0" + pretty-format "^26.0.0" + "@types/json-schema@^7.0.3": version "7.0.6" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0" integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== +"@types/node@*": + version "14.14.20" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.20.tgz#f7974863edd21d1f8a494a73e8e2b3658615c340" + integrity sha512-Y93R97Ouif9JEOWPIUyU+eyIdyRqQR0I8Ez1dzku4hDx34NWh4HbtIc3WNzwB1Y9ULvNGeu5B8h8bVL5cAk4/A== + +"@types/normalize-package-data@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" + integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== + +"@types/prettier@^2.0.0": + version "2.1.6" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.1.6.tgz#f4b1efa784e8db479cdb8b14403e2144b1e9ff03" + integrity sha512-6gOkRe7OIioWAXfnO/2lFiv+SJichKVSys1mSsgyrYHSEjk8Ctv4tSR/Odvnu+HWlH2C8j53dahU03XmQdd5fA== + +"@types/stack-utils@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff" + integrity sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw== + +"@types/yargs-parser@*": + version "20.2.0" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.0.tgz#dd3e6699ba3237f0348cd085e4698780204842f9" + integrity sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA== + +"@types/yargs@^15.0.0": + version "15.0.12" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.12.tgz#6234ce3e3e3fa32c5db301a170f96a599c960d74" + integrity sha512-f+fD/fQAo3BCbCDlrUpznF1A5Zp9rB0noS5vnoormHSIPFKL0Z2DcUJ3Gxp5ytH4uLRNxy7AwYUC9exZzqGMAw== + dependencies: + "@types/yargs-parser" "*" + "@typescript-eslint/eslint-plugin@^4.12.0": version "4.12.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.12.0.tgz#00d1b23b40b58031e6d7c04a5bc6c1a30a2e834a" @@ -135,17 +690,35 @@ "@typescript-eslint/types" "4.12.0" eslint-visitor-keys "^2.0.0" +abab@^2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" + integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== + +acorn-globals@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" + integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== + dependencies: + acorn "^7.1.1" + acorn-walk "^7.1.1" + acorn-jsx@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== -acorn@^7.4.0: +acorn-walk@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" + integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== + +acorn@^7.1.1, acorn@^7.4.0: version "7.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -ajv@^6.10.0, ajv@^6.12.4: +ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -170,6 +743,13 @@ ansi-colors@^4.1.1: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== +ansi-escapes@^4.2.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.1.tgz#a5c47cc43181f1f38ffd7076837700d395522a61" + integrity sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA== + dependencies: + type-fest "^0.11.0" + ansi-regex@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" @@ -189,6 +769,22 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +anymatch@^3.0.3: + version "3.1.1" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" + integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -196,21 +792,159 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + astral-regex@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" + integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== + +babel-jest@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-26.6.3.tgz#d87d25cb0037577a0c89f82e5755c5d293c01056" + integrity sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA== + dependencies: + "@jest/transform" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/babel__core" "^7.1.7" + babel-plugin-istanbul "^6.0.0" + babel-preset-jest "^26.6.2" + chalk "^4.0.0" + graceful-fs "^4.2.4" + slash "^3.0.0" + +babel-plugin-istanbul@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz#e159ccdc9af95e0b570c75b4573b7c34d671d765" + integrity sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^4.0.0" + test-exclude "^6.0.0" + +babel-plugin-jest-hoist@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz#8185bd030348d254c6d7dd974355e6a28b21e62d" + integrity sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.0.0" + "@types/babel__traverse" "^7.0.6" + +babel-preset-current-node-syntax@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" + integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== + dependencies: + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.8.3" + "@babel/plugin-syntax-import-meta" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-top-level-await" "^7.8.3" + +babel-preset-jest@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz#747872b1171df032252426586881d62d31798fee" + integrity sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ== + dependencies: + babel-plugin-jest-hoist "^26.6.2" + babel-preset-current-node-syntax "^1.0.0" + 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= +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -219,6 +953,22 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +braces@^2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + braces@^3.0.1: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" @@ -226,11 +976,72 @@ braces@^3.0.1: dependencies: fill-range "^7.0.1" +browser-process-hrtime@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" + integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== + +bs-logger@0.x: + version "0.2.6" + resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" + integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== + dependencies: + fast-json-stable-stringify "2.x" + +bser@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" + +buffer-from@1.x, buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== +camelcase@^5.0.0, camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^6.0.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" + integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== + +capture-exit@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" + integrity sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g== + dependencies: + rsvp "^4.8.4" + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + chalk@^2.0.0: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -248,6 +1059,58 @@ chalk@^4.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== + +cjs-module-lexer@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz#4186fcca0eae175970aee870b9fe2d6cf8d5655f" + integrity sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw== + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +cliui@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" + integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^6.2.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + +collect-v8-coverage@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" + integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -272,12 +1135,52 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + 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= -cross-spawn@^7.0.2: +convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" + integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== + dependencies: + safe-buffer "~5.1.1" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +cross-spawn@^6.0.0: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^7.0.0, cross-spawn@^7.0.2: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -286,37 +1189,161 @@ cross-spawn@^7.0.2: shebang-command "^2.0.0" which "^2.0.1" -debug@^4.0.1, debug@^4.1.1: +cssom@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" + integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== + +cssom@~0.3.6: + version "0.3.8" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" + integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== + +cssstyle@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" + integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== + dependencies: + cssom "~0.3.6" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +data-urls@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" + integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ== + dependencies: + abab "^2.0.3" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.0.0" + +debug@^2.2.0, debug@^2.3.3: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: version "4.3.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== dependencies: ms "2.1.2" -deep-is@^0.1.3: +decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decimal.js@^10.2.0: + version "10.2.1" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.1.tgz#238ae7b0f0c793d3e3cea410108b35a2c01426a3" + integrity sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw== + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +deep-is@^0.1.3, deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= dependencies: - path-type "^4.0.0" + is-descriptor "^0.1.0" -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= dependencies: - esutils "^2.0.2" + is-descriptor "^1.0.0" -emoji-regex@^8.0.0: +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +detect-newline@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== + +diff-sequences@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1" + integrity sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q== + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +domexception@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" + integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg== + dependencies: + webidl-conversions "^5.0.0" + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +emittery@^0.7.1: + version "0.7.2" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.7.2.tgz#25595908e13af0f5674ab419396e2fb394cdfa82" + integrity sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ== + +emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + enquirer@^2.3.5: version "2.3.6" resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" @@ -324,11 +1351,35 @@ enquirer@^2.3.5: dependencies: ansi-colors "^4.1.1" +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + 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= +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +escodegen@^1.14.1: + version "1.14.3" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" + integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== + dependencies: + esprima "^4.0.1" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + eslint-config-prettier@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-7.1.0.tgz#5402eb559aa94b894effd6bddfa0b1ca051c858f" @@ -418,7 +1469,7 @@ espree@^7.3.0, espree@^7.3.1: acorn-jsx "^5.3.1" eslint-visitor-keys "^1.3.0" -esprima@^4.0.0: +esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== @@ -437,7 +1488,7 @@ esrecurse@^4.3.0: dependencies: estraverse "^5.2.0" -estraverse@^4.1.1: +estraverse@^4.1.1, estraverse@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== @@ -452,6 +1503,113 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +exec-sh@^0.3.2: + version "0.3.4" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.4.tgz#3a018ceb526cc6f6df2bb504b2bfe8e3a4934ec5" + integrity sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A== + +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" + integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== + dependencies: + cross-spawn "^7.0.0" + get-stream "^5.0.0" + human-signals "^1.1.1" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.0" + onetime "^5.1.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expect@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/expect/-/expect-26.6.2.tgz#c6b996bf26bf3fe18b67b2d0f51fc981ba934417" + integrity sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA== + dependencies: + "@jest/types" "^26.6.2" + ansi-styles "^4.0.0" + jest-get-type "^26.3.0" + jest-matcher-utils "^26.6.2" + jest-message-util "^26.6.2" + jest-regex-util "^26.0.0" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + fast-deep-equal@^3.1.1: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -474,12 +1632,12 @@ fast-glob@^3.1.1: micromatch "^4.0.2" picomatch "^2.2.1" -fast-json-stable-stringify@^2.0.0: +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== -fast-levenshtein@^2.0.6: +fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= @@ -491,6 +1649,13 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" +fb-watchman@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" + integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== + dependencies: + bser "2.1.1" + file-entry-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.0.tgz#7921a89c391c6d93efec2169ac6bf300c527ea0a" @@ -498,6 +1663,16 @@ file-entry-cache@^6.0.0: dependencies: flat-cache "^3.0.4" +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + fill-range@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" @@ -505,6 +1680,14 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + flat-cache@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" @@ -518,16 +1701,93 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.0.tgz#a5d06b4a8b01e3a63771daa5cb7a1903e2e57067" integrity sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA== +for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + 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= +fsevents@^2.1.2: + version "2.3.1" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.1.tgz#b209ab14c61012636c8863507edf7fb68cc54e9f" + integrity sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw== + +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== + functional-red-black-tree@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= +gensync@^1.0.0-beta.1: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-stream@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + glob-parent@^5.0.0, glob-parent@^5.1.0: version "5.1.1" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" @@ -535,7 +1795,7 @@ glob-parent@^5.0.0, glob-parent@^5.1.0: dependencies: is-glob "^4.0.1" -glob@^7.1.3: +glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== @@ -547,6 +1807,11 @@ glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + globals@^12.1.0: version "12.4.0" resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" @@ -566,6 +1831,29 @@ globby@^11.0.1: merge2 "^1.3.0" slash "^3.0.0" +graceful-fs@^4.2.4: + version "4.2.4" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" + integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== + +growly@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" + integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.3: + version "5.1.5" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== + dependencies: + ajv "^6.12.3" + har-schema "^2.0.0" + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -576,6 +1864,82 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +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" + +hosted-git-info@^2.1.4: + version "2.8.8" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" + integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== + +html-encoding-sniffer@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" + integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ== + dependencies: + whatwg-encoding "^1.0.5" + +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +human-signals@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" + integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" @@ -594,6 +1958,14 @@ import-fresh@^3.0.0, import-fresh@^3.2.1: parent-module "^1.0.0" resolve-from "^4.0.0" +import-local@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.2.tgz#a8cfd0431d1de4a2199703d003e3e62364fa6db6" + integrity sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" @@ -612,6 +1984,98 @@ inherits@2: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +ip-regex@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" + integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-ci@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" + integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== + dependencies: + ci-info "^2.0.0" + +is-core-module@^2.1.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" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-docker@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.1.1.tgz#4125a88e44e450d384e09047ede71adc2d144156" + integrity sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw== + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -622,6 +2086,11 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== +is-generator-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" + integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== + is-glob@^4.0.0, is-glob@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" @@ -629,104 +2098,951 @@ is-glob@^4.0.0, is-glob@^4.0.1: dependencies: is-extglob "^2.1.1" +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= +is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" -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== +is-potential-custom-element-name@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz#0c52e54bcca391bb2c494b21e8626d7336c6e397" + integrity sha1-DFLlS8yjkbssSUsh6GJtczbG45c= -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" +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== +is-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" + integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== -json-schema-traverse@^1.0.0: +is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" + is-docker "^2.0.0" -lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20: - version "4.17.20" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" - integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== +isarray@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= dependencies: - yallist "^4.0.0" + isarray "1.0.0" -merge2@^1.3.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= -micromatch@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" - integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== - dependencies: - braces "^3.0.1" - picomatch "^2.0.5" +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= -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== +istanbul-lib-coverage@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec" + integrity sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg== + +istanbul-lib-instrument@^4.0.0, istanbul-lib-instrument@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d" + integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ== dependencies: - brace-expansion "^1.1.7" + "@babel/core" "^7.7.5" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.0.0" + semver "^6.3.0" -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +istanbul-lib-report@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" + integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^3.0.0" + supports-color "^7.1.0" -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= +istanbul-lib-source-maps@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz#75743ce6d96bb86dc7ee4352cf6366a23f0b1ad9" + integrity sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" -once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= +istanbul-reports@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.0.2.tgz#d593210e5000683750cb09fc0644e4b6e27fd53b" + integrity sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw== dependencies: - wrappy "1" + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" +jest-changed-files@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-26.6.2.tgz#f6198479e1cc66f22f9ae1e22acaa0b429c042d0" + integrity sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ== + dependencies: + "@jest/types" "^26.6.2" + execa "^4.0.0" + throat "^5.0.0" + +jest-cli@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-26.6.3.tgz#43117cfef24bc4cd691a174a8796a532e135e92a" + integrity sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg== + dependencies: + "@jest/core" "^26.6.3" + "@jest/test-result" "^26.6.2" + "@jest/types" "^26.6.2" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.4" + import-local "^3.0.2" + is-ci "^2.0.0" + jest-config "^26.6.3" + jest-util "^26.6.2" + jest-validate "^26.6.2" + prompts "^2.0.1" + yargs "^15.4.1" + +jest-config@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-26.6.3.tgz#64f41444eef9eb03dc51d5c53b75c8c71f645349" + integrity sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg== + dependencies: + "@babel/core" "^7.1.0" + "@jest/test-sequencer" "^26.6.3" + "@jest/types" "^26.6.2" + babel-jest "^26.6.3" + chalk "^4.0.0" + deepmerge "^4.2.2" + glob "^7.1.1" + graceful-fs "^4.2.4" + jest-environment-jsdom "^26.6.2" + jest-environment-node "^26.6.2" + jest-get-type "^26.3.0" + jest-jasmine2 "^26.6.3" + jest-regex-util "^26.0.0" + jest-resolve "^26.6.2" + jest-util "^26.6.2" + jest-validate "^26.6.2" + micromatch "^4.0.2" + pretty-format "^26.6.2" + +jest-diff@^26.0.0, jest-diff@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-26.6.2.tgz#1aa7468b52c3a68d7d5c5fdcdfcd5e49bd164394" + integrity sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA== + dependencies: + chalk "^4.0.0" + diff-sequences "^26.6.2" + jest-get-type "^26.3.0" + pretty-format "^26.6.2" + +jest-docblock@^26.0.0: + version "26.0.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-26.0.0.tgz#3e2fa20899fc928cb13bd0ff68bd3711a36889b5" + integrity sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w== + dependencies: + detect-newline "^3.0.0" + +jest-each@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-26.6.2.tgz#02526438a77a67401c8a6382dfe5999952c167cb" + integrity sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A== + dependencies: + "@jest/types" "^26.6.2" + chalk "^4.0.0" + jest-get-type "^26.3.0" + jest-util "^26.6.2" + pretty-format "^26.6.2" + +jest-environment-jsdom@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz#78d09fe9cf019a357009b9b7e1f101d23bd1da3e" + integrity sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q== + dependencies: + "@jest/environment" "^26.6.2" + "@jest/fake-timers" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/node" "*" + jest-mock "^26.6.2" + jest-util "^26.6.2" + jsdom "^16.4.0" + +jest-environment-node@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-26.6.2.tgz#824e4c7fb4944646356f11ac75b229b0035f2b0c" + integrity sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag== + dependencies: + "@jest/environment" "^26.6.2" + "@jest/fake-timers" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/node" "*" + jest-mock "^26.6.2" + jest-util "^26.6.2" + +jest-get-type@^26.3.0: + version "26.3.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0" + integrity sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig== + +jest-haste-map@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.6.2.tgz#dd7e60fe7dc0e9f911a23d79c5ff7fb5c2cafeaa" + integrity sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w== + dependencies: + "@jest/types" "^26.6.2" + "@types/graceful-fs" "^4.1.2" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.4" + jest-regex-util "^26.0.0" + jest-serializer "^26.6.2" + jest-util "^26.6.2" + jest-worker "^26.6.2" + micromatch "^4.0.2" + sane "^4.0.3" + walker "^1.0.7" + optionalDependencies: + fsevents "^2.1.2" + +jest-jasmine2@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz#adc3cf915deacb5212c93b9f3547cd12958f2edd" + integrity sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg== + dependencies: + "@babel/traverse" "^7.1.0" + "@jest/environment" "^26.6.2" + "@jest/source-map" "^26.6.2" + "@jest/test-result" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + expect "^26.6.2" + is-generator-fn "^2.0.0" + jest-each "^26.6.2" + jest-matcher-utils "^26.6.2" + jest-message-util "^26.6.2" + jest-runtime "^26.6.3" + jest-snapshot "^26.6.2" + jest-util "^26.6.2" + pretty-format "^26.6.2" + throat "^5.0.0" + +jest-leak-detector@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz#7717cf118b92238f2eba65054c8a0c9c653a91af" + integrity sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg== + dependencies: + jest-get-type "^26.3.0" + pretty-format "^26.6.2" + +jest-matcher-utils@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz#8e6fd6e863c8b2d31ac6472eeb237bc595e53e7a" + integrity sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw== + dependencies: + chalk "^4.0.0" + jest-diff "^26.6.2" + jest-get-type "^26.3.0" + pretty-format "^26.6.2" + +jest-message-util@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-26.6.2.tgz#58173744ad6fc0506b5d21150b9be56ef001ca07" + integrity sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA== + dependencies: + "@babel/code-frame" "^7.0.0" + "@jest/types" "^26.6.2" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.4" + micromatch "^4.0.2" + pretty-format "^26.6.2" + slash "^3.0.0" + stack-utils "^2.0.2" + +jest-mock@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-26.6.2.tgz#d6cb712b041ed47fe0d9b6fc3474bc6543feb302" + integrity sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew== + dependencies: + "@jest/types" "^26.6.2" + "@types/node" "*" + +jest-pnp-resolver@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" + integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== + +jest-regex-util@^26.0.0: + version "26.0.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" + integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A== + +jest-resolve-dependencies@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz#6680859ee5d22ee5dcd961fe4871f59f4c784fb6" + integrity sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg== + dependencies: + "@jest/types" "^26.6.2" + jest-regex-util "^26.0.0" + jest-snapshot "^26.6.2" + +jest-resolve@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-26.6.2.tgz#a3ab1517217f469b504f1b56603c5bb541fbb507" + integrity sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ== + dependencies: + "@jest/types" "^26.6.2" + chalk "^4.0.0" + graceful-fs "^4.2.4" + jest-pnp-resolver "^1.2.2" + jest-util "^26.6.2" + read-pkg-up "^7.0.1" + resolve "^1.18.1" + slash "^3.0.0" + +jest-runner@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-26.6.3.tgz#2d1fed3d46e10f233fd1dbd3bfaa3fe8924be159" + integrity sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ== + dependencies: + "@jest/console" "^26.6.2" + "@jest/environment" "^26.6.2" + "@jest/test-result" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.7.1" + exit "^0.1.2" + graceful-fs "^4.2.4" + jest-config "^26.6.3" + jest-docblock "^26.0.0" + jest-haste-map "^26.6.2" + jest-leak-detector "^26.6.2" + jest-message-util "^26.6.2" + jest-resolve "^26.6.2" + jest-runtime "^26.6.3" + jest-util "^26.6.2" + jest-worker "^26.6.2" + source-map-support "^0.5.6" + throat "^5.0.0" + +jest-runtime@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-26.6.3.tgz#4f64efbcfac398331b74b4b3c82d27d401b8fa2b" + integrity sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw== + dependencies: + "@jest/console" "^26.6.2" + "@jest/environment" "^26.6.2" + "@jest/fake-timers" "^26.6.2" + "@jest/globals" "^26.6.2" + "@jest/source-map" "^26.6.2" + "@jest/test-result" "^26.6.2" + "@jest/transform" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/yargs" "^15.0.0" + chalk "^4.0.0" + cjs-module-lexer "^0.6.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.3" + graceful-fs "^4.2.4" + jest-config "^26.6.3" + jest-haste-map "^26.6.2" + jest-message-util "^26.6.2" + jest-mock "^26.6.2" + jest-regex-util "^26.0.0" + jest-resolve "^26.6.2" + jest-snapshot "^26.6.2" + jest-util "^26.6.2" + jest-validate "^26.6.2" + slash "^3.0.0" + strip-bom "^4.0.0" + yargs "^15.4.1" + +jest-serializer@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-26.6.2.tgz#d139aafd46957d3a448f3a6cdabe2919ba0742d1" + integrity sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g== + dependencies: + "@types/node" "*" + graceful-fs "^4.2.4" + +jest-snapshot@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-26.6.2.tgz#f3b0af1acb223316850bd14e1beea9837fb39c84" + integrity sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og== + dependencies: + "@babel/types" "^7.0.0" + "@jest/types" "^26.6.2" + "@types/babel__traverse" "^7.0.4" + "@types/prettier" "^2.0.0" + chalk "^4.0.0" + expect "^26.6.2" + graceful-fs "^4.2.4" + jest-diff "^26.6.2" + jest-get-type "^26.3.0" + jest-haste-map "^26.6.2" + jest-matcher-utils "^26.6.2" + jest-message-util "^26.6.2" + jest-resolve "^26.6.2" + natural-compare "^1.4.0" + pretty-format "^26.6.2" + semver "^7.3.2" + +jest-util@^26.1.0, jest-util@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.6.2.tgz#907535dbe4d5a6cb4c47ac9b926f6af29576cbc1" + integrity sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q== + dependencies: + "@jest/types" "^26.6.2" + "@types/node" "*" + chalk "^4.0.0" + graceful-fs "^4.2.4" + is-ci "^2.0.0" + micromatch "^4.0.2" + +jest-validate@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-26.6.2.tgz#23d380971587150467342911c3d7b4ac57ab20ec" + integrity sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ== + dependencies: + "@jest/types" "^26.6.2" + camelcase "^6.0.0" + chalk "^4.0.0" + jest-get-type "^26.3.0" + leven "^3.1.0" + pretty-format "^26.6.2" + +jest-watcher@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-26.6.2.tgz#a5b683b8f9d68dbcb1d7dae32172d2cca0592975" + integrity sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ== + dependencies: + "@jest/test-result" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + jest-util "^26.6.2" + string-length "^4.0.1" + +jest-worker@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" + integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^7.0.0" + +jest@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest/-/jest-26.6.3.tgz#40e8fdbe48f00dfa1f0ce8121ca74b88ac9148ef" + integrity sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q== + dependencies: + "@jest/core" "^26.6.3" + import-local "^3.0.2" + jest-cli "^26.6.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" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +jsdom@^16.4.0: + version "16.4.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.4.0.tgz#36005bde2d136f73eee1a830c6d45e55408edddb" + integrity sha512-lYMm3wYdgPhrl7pDcRmvzPhhrGVBeVhPIqeHjzeiHN3DFmD1RBpbExbi8vU7BJdH8VAZYovR8DMt0PNNDM7k8w== + dependencies: + abab "^2.0.3" + acorn "^7.1.1" + acorn-globals "^6.0.0" + cssom "^0.4.4" + cssstyle "^2.2.0" + data-urls "^2.0.0" + decimal.js "^10.2.0" + domexception "^2.0.1" + escodegen "^1.14.1" + html-encoding-sniffer "^2.0.1" + is-potential-custom-element-name "^1.0.0" + nwsapi "^2.2.0" + parse5 "5.1.1" + request "^2.88.2" + request-promise-native "^1.0.8" + saxes "^5.0.0" + symbol-tree "^3.2.4" + tough-cookie "^3.0.1" + w3c-hr-time "^1.0.2" + w3c-xmlserializer "^2.0.0" + webidl-conversions "^6.1.0" + whatwg-encoding "^1.0.5" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.0.0" + ws "^7.2.3" + xml-name-validator "^3.0.0" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +json5@2.x, json5@^2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" + integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== + dependencies: + minimist "^1.2.5" + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +lines-and-columns@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" + integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash.memoize@4.x: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= + +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= + +lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20: + version "4.17.20" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" + integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +make-dir@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +make-error@1.x: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +makeerror@1.0.x: + version "1.0.11" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" + integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw= + dependencies: + tmpl "1.0.x" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +micromatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" + integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== + dependencies: + braces "^3.0.1" + picomatch "^2.0.5" + +mime-db@1.45.0: + version "1.45.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.45.0.tgz#cceeda21ccd7c3a745eba2decd55d4b73e7879ea" + integrity sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w== + +mime-types@^2.1.12, mime-types@~2.1.19: + version "2.1.28" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.28.tgz#1160c4757eab2c5363888e005273ecf79d2a0ecd" + integrity sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ== + dependencies: + mime-db "1.45.0" + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +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@^1.1.1, minimist@^1.2.0, 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== + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@1.x: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= + +node-modules-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" + integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= + +node-notifier@^8.0.0: + version "8.0.1" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-8.0.1.tgz#f86e89bbc925f2b068784b31f382afdc6ca56be1" + integrity sha512-BvEXF+UmsnAfYfoapKM9nGxnP+Wn7P91YfXmrKnfcYCx6VBeoN5Ez5Ogck6I8Bi5k4RlpqRYaw75pAwzX9OphA== + dependencies: + growly "^1.3.0" + is-wsl "^2.2.0" + semver "^7.3.2" + shellwords "^0.1.1" + uuid "^8.3.0" + which "^2.0.2" + +normalize-package-data@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +npm-run-path@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +nwsapi@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" + integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +optionator@^0.8.1: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" + +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== dependencies: deep-is "^0.1.3" @@ -736,6 +3052,35 @@ optionator@^0.9.1: type-check "^0.4.0" word-wrap "^1.2.3" +p-each-series@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.2.0.tgz#105ab0357ce72b202a8a8b94933672657b5e2a9a" + integrity sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA== + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" @@ -743,31 +3088,95 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" +parse-json@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.1.0.tgz#f96088cdf24a8faa9aea9a009f2d9d942c999646" + integrity sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +parse5@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" + integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + 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-key@^3.1.0: +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== +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== + path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -picomatch@^2.0.5, picomatch@^2.2.1: +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== +pirates@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" + integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA== + dependencies: + node-modules-regexp "^1.0.0" + +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + prettier-linter-helpers@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" @@ -780,55 +3189,301 @@ prettier@^2.2.1: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q== +pretty-format@^26.0.0, pretty-format@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93" + integrity sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg== + dependencies: + "@jest/types" "^26.6.2" + ansi-regex "^5.0.0" + ansi-styles "^4.0.0" + react-is "^17.0.1" + progress@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== -punycode@^2.1.0: +prompts@^2.0.1: + version "2.4.0" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.0.tgz#4aa5de0723a231d1ee9121c40fdf663df73f61d7" + integrity sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + +psl@^1.1.28: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +react-is@^17.0.1: + version "17.0.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.1.tgz#5b3531bd76a645a4c9fb6e693ed36419e3301339" + integrity sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA== + +read-pkg-up@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" + integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== + dependencies: + find-up "^4.1.0" + read-pkg "^5.2.0" + type-fest "^0.8.1" + +read-pkg@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" + integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== + dependencies: + "@types/normalize-package-data" "^2.4.0" + normalize-package-data "^2.5.0" + parse-json "^5.0.0" + type-fest "^0.6.0" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + regexpp@^3.0.0, regexpp@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +request-promise-core@1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" + integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw== + dependencies: + lodash "^4.17.19" + +request-promise-native@^1.0.8: + version "1.0.9" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28" + integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== + dependencies: + request-promise-core "1.1.4" + stealthy-require "^1.1.1" + tough-cookie "^2.3.3" + +request@^2.88.2: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + require-from-string@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@^1.10.0, resolve@^1.18.1: + version "1.19.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c" + integrity sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg== + dependencies: + is-core-module "^2.1.0" + path-parse "^1.0.6" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rimraf@^3.0.2: +rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== dependencies: glob "^7.1.3" +rsvp@^4.8.4: + version "4.8.5" + resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" + integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== + run-parallel@^1.1.9: version "1.1.10" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.10.tgz#60a51b2ae836636c81377df16cb107351bcd13ef" integrity sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw== -semver@^7.2.1, semver@^7.3.2: +safe-buffer@^5.0.1, safe-buffer@^5.1.2: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sane@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/sane/-/sane-4.1.0.tgz#ed881fd922733a6c461bc189dc2b6c006f3ffded" + integrity sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA== + dependencies: + "@cnakazawa/watch" "^1.0.3" + anymatch "^2.0.0" + capture-exit "^2.0.0" + exec-sh "^0.3.2" + execa "^1.0.0" + fb-watchman "^2.0.0" + micromatch "^3.1.4" + minimist "^1.1.1" + walker "~1.0.5" + +saxes@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" + integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== + dependencies: + xmlchars "^2.2.0" + +"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@7.x, semver@^7.2.1, semver@^7.3.2: version "7.3.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97" integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw== dependencies: lru-cache "^6.0.0" +semver@^6.0.0, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -836,11 +3491,31 @@ shebang-command@^2.0.0: dependencies: shebang-regex "^3.0.0" +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + shebang-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== +shellwords@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" + integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" + integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== + +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -855,12 +3530,157 @@ slice-ansi@^4.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +source-map-resolve@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@^0.5.6: + version "0.5.19" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" + integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + +source-map@^0.5.0, source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@^0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +spdx-correct@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.7" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz#e9c18a410e5ed7e12442a549fbd8afa767038d65" + integrity sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ== + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + 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-width@^4.2.0: +sshpk@^1.7.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +stack-utils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.3.tgz#cd5f030126ff116b78ccb3c027fe302713b61277" + integrity sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw== + dependencies: + escape-string-regexp "^2.0.0" + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +stealthy-require@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= + +string-length@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.1.tgz#4a973bf31ef77c4edbceadd6af2611996985f8a1" + integrity sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw== + dependencies: + char-regex "^1.0.2" + strip-ansi "^6.0.0" + +string-width@^4.1.0, string-width@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== @@ -876,6 +3696,21 @@ strip-ansi@^6.0.0: dependencies: ansi-regex "^5.0.0" +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" @@ -888,13 +3723,26 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" -supports-color@^7.1.0: +supports-color@^7.0.0, supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== dependencies: has-flag "^4.0.0" +supports-hyperlinks@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz#f663df252af5f37c5d49bbd7eeefa9e0b9e59e47" + integrity sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA== + dependencies: + has-flag "^4.0.0" + supports-color "^7.0.0" + +symbol-tree@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" + integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== + table@^6.0.4: version "6.0.7" resolved "https://registry.yarnpkg.com/table/-/table-6.0.7.tgz#e45897ffbcc1bcf9e8a87bf420f2c9e5a7a52a34" @@ -905,11 +3753,58 @@ table@^6.0.4: slice-ansi "^4.0.0" string-width "^4.2.0" +terminal-link@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" + integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== + dependencies: + ansi-escapes "^4.2.1" + supports-hyperlinks "^2.0.0" + +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= +throat@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b" + integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA== + +tmpl@1.0.x: + version "1.0.4" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" + integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -917,6 +3812,57 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +tough-cookie@^2.3.3, tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +tough-cookie@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-3.0.1.tgz#9df4f57e739c26930a018184887f4adb7dca73b2" + integrity sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg== + dependencies: + ip-regex "^2.1.0" + psl "^1.1.28" + punycode "^2.1.1" + +tr46@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.0.2.tgz#03273586def1595ae08fedb38d7733cee91d2479" + integrity sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg== + dependencies: + punycode "^2.1.1" + +ts-jest@^26.4.4: + version "26.4.4" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-26.4.4.tgz#61f13fb21ab400853c532270e52cc0ed7e502c49" + integrity sha512-3lFWKbLxJm34QxyVNNCgXX1u4o/RV0myvA2y2Bxm46iGIjKlaY0own9gIckbjZJPn+WaJEnfPPJ20HHGpoq4yg== + dependencies: + "@types/jest" "26.x" + bs-logger "0.x" + buffer-from "1.x" + fast-json-stable-stringify "2.x" + jest-util "^26.1.0" + json5 "2.x" + lodash.memoize "4.x" + make-error "1.x" + mkdirp "1.x" + semver "7.x" + yargs-parser "20.x" + tslib@^1.8.1: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" @@ -929,6 +3875,18 @@ tsutils@^3.17.1: dependencies: tslib "^1.8.1" +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" @@ -936,16 +3894,63 @@ type-check@^0.4.0, type-check@~0.4.0: dependencies: prelude-ls "^1.2.1" +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +type-detect@4.0.8: + 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== + +type-fest@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1" + integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ== + +type-fest@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" + integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== + type-fest@^0.8.1: version "0.8.1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + typescript@^4.1.3: version "4.1.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.3.tgz#519d582bd94cba0cf8934c7d8e8467e473f53bb7" integrity sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg== +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -953,29 +3958,208 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +uuid@^8.3.0: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + v8-compile-cache@^2.0.3: version "2.2.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz#9471efa3ef9128d2f7c6a7ca39c4dd6b5055b132" integrity sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q== -which@^2.0.1: +v8-to-istanbul@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-7.1.0.tgz#5b95cef45c0f83217ec79f8fc7ee1c8b486aee07" + integrity sha512-uXUVqNUCLa0AH1vuVxzi+MI4RfxEOKt9pBgKwHbgH7st8Kv2P1m+jvWNnektzBh5QShF3ODgKmUFCf38LnVz1g== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + source-map "^0.7.3" + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +w3c-hr-time@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" + integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== + dependencies: + browser-process-hrtime "^1.0.0" + +w3c-xmlserializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" + integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA== + dependencies: + xml-name-validator "^3.0.0" + +walker@^1.0.7, walker@~1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" + integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs= + dependencies: + makeerror "1.0.x" + +webidl-conversions@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" + integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA== + +webidl-conversions@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" + integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== + +whatwg-encoding@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" + integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== + dependencies: + iconv-lite "0.4.24" + +whatwg-mimetype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" + integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== + +whatwg-url@^8.0.0: + version "8.4.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.4.0.tgz#50fb9615b05469591d2b2bd6dfaed2942ed72837" + integrity sha512-vwTUFf6V4zhcPkWp/4CQPr1TW9Ml6SF4lVyaIMBdJw5i6qUUJ1QWM4Z6YYVkfka0OUIzVo/0aNtGVGk256IKWw== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^2.0.2" + webidl-conversions "^6.1.0" + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which@^1.2.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^2.0.1, which@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" -word-wrap@^1.2.3: +word-wrap@^1.2.3, word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= +write-file-atomic@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== + dependencies: + imurmurhash "^0.1.4" + is-typedarray "^1.0.0" + signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" + +ws@^7.2.3: + version "7.4.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.2.tgz#782100048e54eb36fe9843363ab1c68672b261dd" + integrity sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA== + +xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== + +xmlchars@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" + integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== + +y18n@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4" + integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ== + yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yargs-parser@20.x: + version "20.2.4" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + +yargs-parser@^18.1.2: + version "18.1.3" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" + integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs@^15.4.1: + version "15.4.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" + integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== + dependencies: + cliui "^6.0.0" + decamelize "^1.2.0" + find-up "^4.1.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^4.2.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^18.1.2" From 66e8ded5172c239ae2a475db3e8a3cf8e216a3fe Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sun, 10 Jan 2021 15:57:58 +0900 Subject: [PATCH 04/63] =?UTF-8?q?=E3=82=AB=E3=83=95=E3=82=A7=E3=83=A9?= =?UTF-8?q?=E3=83=B3=E3=83=81=20chapter1=20=E3=81=AE=E6=9C=80=E5=88=9D?= =?UTF-8?q?=E3=81=AE=E3=82=B9=E3=83=86=E3=83=83=E3=83=97=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cafe/chapter1.test.ts | 29 ++++++++++++++++++++++++ cafe/index.ts | 51 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 cafe/chapter1.test.ts create mode 100644 cafe/index.ts diff --git a/cafe/chapter1.test.ts b/cafe/chapter1.test.ts new file mode 100644 index 0000000..4e5dc45 --- /dev/null +++ b/cafe/chapter1.test.ts @@ -0,0 +1,29 @@ +import { Dish, Nutrition, Plate, Price } from './index'; + +describe('チャプター1', () => { + it('Price', () => { + const price = new Price(150); + expect(price.toString()).toEqual('Price(150円)'); + }); + + it('Nutrition', () => { + const nutrition = new Nutrition(1, 2, 3); + expect(nutrition.toString()).toEqual('Nutrition(赤:1, 緑:2, 黄:3)'); + }); + + it('Dish', () => { + const pasta = new Dish(new Price(250), new Nutrition(1, 1, 3)); + expect(pasta.toString()).toEqual('Dish(Nutrition(赤:1, 緑:1, 黄:3), Price(250円))'); + }); + + it('太郎のプレート', () => { + const pasta = new Dish(new Price(250), new Nutrition(1, 1, 3)); + const bread = new Dish(new Price(150), new Nutrition(0, 0, 3)); + const dessert = new Dish(new Price(150), new Nutrition(0, 1, 0)); + const taroPlate = new Plate([pasta, bread, dessert]); + + expect(taroPlate).toBeInstanceOf(Plate); + expect(taroPlate.dishes).toHaveLength(3); + // expect(taroPlate.dishes[0]).toEqual('パスタ&サラダ'); + }); +}); diff --git a/cafe/index.ts b/cafe/index.ts new file mode 100644 index 0000000..98a38ce --- /dev/null +++ b/cafe/index.ts @@ -0,0 +1,51 @@ +class Plate { + // 1つの Plate は、複数個の Dish を持つ + public readonly dishes: Dish[]; + + constructor(dishes: Dish[]) { + this.dishes = dishes; + } +} + +class Dish { + public readonly price: Price; + public readonly nutrition: Nutrition; + + constructor(price: Price, nutrition: Nutrition) { + this.price = price; + this.nutrition = nutrition; + } + + toString(): string { + return `Dish(${this.nutrition}, ${this.price})`; + } +} + +class Nutrition { + public readonly red: number; + public readonly green: number; + public readonly yellow: number; + + constructor(red: number, green: number, yellow: number) { + this.red = red; + this.green = green; + this.yellow = yellow; + } + + toString(): string { + return `Nutrition(赤:${this.red}, 緑:${this.green}, 黄:${this.yellow})`; + } +} + +class Price { + public readonly value: number; + constructor(value: number) { + this.value = value; + } + + toString(): string { + return `Price(${this.value}円)`; + } +} + +export { Plate, Dish, Nutrition, Price }; From 4734921447a139ba40bc643ffd76ac54a96bd421 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sun, 10 Jan 2021 16:08:28 +0900 Subject: [PATCH 05/63] =?UTF-8?q?chapter1=20=E3=82=AB=E3=83=95=E3=82=A7?= =?UTF-8?q?=E3=81=AE=E4=BE=8B=E3=81=AB=20name=20=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cafe/chapter1.test.ts | 18 ++++++++++++------ cafe/index.ts | 15 ++++++++++++--- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/cafe/chapter1.test.ts b/cafe/chapter1.test.ts index 4e5dc45..b824a36 100644 --- a/cafe/chapter1.test.ts +++ b/cafe/chapter1.test.ts @@ -12,18 +12,24 @@ describe('チャプター1', () => { }); it('Dish', () => { - const pasta = new Dish(new Price(250), new Nutrition(1, 1, 3)); - expect(pasta.toString()).toEqual('Dish(Nutrition(赤:1, 緑:1, 黄:3), Price(250円))'); + const pasta = new Dish('パスタ&サラダ', new Price(250), new Nutrition(1, 1, 3)); + expect(pasta.toString()).toEqual('Dish(パスタ&サラダ, Nutrition(赤:1, 緑:1, 黄:3), Price(250円))'); }); it('太郎のプレート', () => { - const pasta = new Dish(new Price(250), new Nutrition(1, 1, 3)); - const bread = new Dish(new Price(150), new Nutrition(0, 0, 3)); - const dessert = new Dish(new Price(150), new Nutrition(0, 1, 0)); - const taroPlate = new Plate([pasta, bread, dessert]); + const pasta = new Dish('パスタ&ランチ', new Price(250), new Nutrition(1, 1, 3)); + const bread = new Dish('くるみパン', new Price(150), new Nutrition(0, 0, 3)); + const dessert = new Dish('フルーツ', new Price(150), new Nutrition(0, 1, 0)); + const taroPlate = new Plate('太郎のプレート', [pasta, bread, dessert]); expect(taroPlate).toBeInstanceOf(Plate); expect(taroPlate.dishes).toHaveLength(3); + expect(taroPlate.toString()).toEqual( + `Plate 太郎のプレート + - Dish(パスタ&ランチ, Nutrition(赤:1, 緑:1, 黄:3), Price(250円)) + - Dish(くるみパン, Nutrition(赤:0, 緑:0, 黄:3), Price(150円)) + - Dish(フルーツ, Nutrition(赤:0, 緑:1, 黄:0), Price(150円))` + ); // expect(taroPlate.dishes[0]).toEqual('パスタ&サラダ'); }); }); diff --git a/cafe/index.ts b/cafe/index.ts index 98a38ce..b2ded92 100644 --- a/cafe/index.ts +++ b/cafe/index.ts @@ -1,23 +1,32 @@ class Plate { + public readonly name: string; // 1つの Plate は、複数個の Dish を持つ public readonly dishes: Dish[]; - constructor(dishes: Dish[]) { + constructor(name: string, dishes: Dish[]) { + this.name = name; this.dishes = dishes; } + + toString(): string { + const dishes = this.dishes.map((dish) => ` - ${dish.toString()}`); + return `Plate ${this.name}\n${dishes.join('\n')}`; + } } class Dish { + public readonly name: string; public readonly price: Price; public readonly nutrition: Nutrition; - constructor(price: Price, nutrition: Nutrition) { + constructor(name: string, price: Price, nutrition: Nutrition) { + this.name = name; this.price = price; this.nutrition = nutrition; } toString(): string { - return `Dish(${this.nutrition}, ${this.price})`; + return `Dish(${this.name}, ${this.nutrition}, ${this.price})`; } } From 2432592bc684a8f838259f40253e05582dfa1e12 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sun, 10 Jan 2021 16:46:51 +0900 Subject: [PATCH 06/63] =?UTF-8?q?chapter1=20=E3=83=9D=E3=83=BC=E3=82=AB?= =?UTF-8?q?=E3=83=BC=E3=81=AE=E4=BE=8B=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/chapter1.test.ts | 36 ++++++++++++++++++++ poker/index.ts | 75 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 poker/chapter1.test.ts create mode 100644 poker/index.ts diff --git a/poker/chapter1.test.ts b/poker/chapter1.test.ts new file mode 100644 index 0000000..9781b66 --- /dev/null +++ b/poker/chapter1.test.ts @@ -0,0 +1,36 @@ +import { Card, Hand, Rank, Suit } from './index'; + +describe('Chapter1: ポーカー', () => { + it('Suit', () => { + const spade = Suit.Spade; + expect(`${spade}`).toEqual('♠'); + }); + + it('Rank', () => { + const one = new Rank(1); + expect(`${one}`).toEqual('A'); + + const two = new Rank(2); + expect(`${two}`).toEqual('2'); + }); + + it('Card', () => { + const spade = Suit.Spade; + const one = new Rank(1); + const card = new Card(spade, one); + + expect(`${card}`).toEqual('[♠A]'); + }); + + it('Hand', () => { + const hand = new Hand([ + new Card(Suit.Diamond, new Rank(3)), + new Card(Suit.Club, new Rank(3)), + new Card(Suit.Spade, new Rank(11)), + new Card(Suit.Heart, new Rank(4)), + new Card(Suit.Diamond, new Rank(1)), + ]); + + expect(`${hand}`).toEqual('Hand([♦3], [♣3], [♠J], [♥4], [♦A])'); + }); +}); diff --git a/poker/index.ts b/poker/index.ts new file mode 100644 index 0000000..7cedaea --- /dev/null +++ b/poker/index.ts @@ -0,0 +1,75 @@ +class Hand { + public readonly cards: Card[]; + + constructor(cards: Card[]) { + this.cards = cards; + } + + toString(): string { + const cards = this.cards.map((card) => `${card}`); + return `Hand(${cards.join(', ')})`; + } +} + +class Card { + public readonly suit: Suit; + public readonly rank: Rank; + + constructor(suit: Suit, rank: Rank) { + this.suit = suit; + this.rank = rank; + } + + toString(): string { + return `[${this.suit}${this.rank}]`; + } +} + +class Rank { + public readonly value: number; + + constructor(value: number) { + this.value = value; + } + + toString(): string { + switch (this.value) { + case 1: + return 'A'; + case 11: + return 'J'; + case 12: + return 'Q'; + case 13: + return 'K'; + default: + return `${this.value}`; + } + } +} + +class Suit { + public readonly value: string; + + private mapping = { + Spade: '♠', + Heart: '♥', + Diamond: '♦', + Club: '♣', + }; + + private constructor(value: string) { + this.value = value; + } + + toString(): string { + return this.mapping[this.value]; + } + + public static Spade = new Suit('Spade'); + public static Heart = new Suit('Heart'); + public static Diamond = new Suit('Diamond'); + public static Club = new Suit('Club'); +} + +export { Hand, Card, Rank, Suit }; From e03dbd97f38c7b61334a76ad08a8562ddfeb9894 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Fri, 12 Feb 2021 12:07:52 +0900 Subject: [PATCH 07/63] =?UTF-8?q?1=E8=A1=8C80=E6=96=87=E5=AD=97=E3=81=A7?= =?UTF-8?q?=E6=94=B9=E8=A1=8C=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.eslintrc.js b/.eslintrc.js index fb08275..b4c83fd 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -30,7 +30,7 @@ module.exports = { "warn", { bracketSpacing: true, - printWidth: 120, + printWidth: 80, singleQuote: true, tabWidth: 4, trailingComma: "es5", // EcmaScript5 において、validな場合には末尾カンマを許可する From 472754fa145c473a8dd7cb4fd16115049ff1bcfd Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Fri, 12 Feb 2021 12:24:14 +0900 Subject: [PATCH 08/63] =?UTF-8?q?chapter2=20=E3=83=A9=E3=83=B3=E3=83=81?= =?UTF-8?q?=E3=83=97=E3=83=AC=E3=83=BC=E3=83=88=E3=81=AE=E4=BE=8B=20(?= =?UTF-8?q?=E5=89=B2=E5=BC=95=E3=82=AF=E3=83=A9=E3=82=B9=E7=AD=89)=20?= =?UTF-8?q?=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cafe/chapter2.test.ts | 65 +++++++++++++++++++ cafe/index.ts | 142 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 207 insertions(+) create mode 100644 cafe/chapter2.test.ts diff --git a/cafe/chapter2.test.ts b/cafe/chapter2.test.ts new file mode 100644 index 0000000..6b27284 --- /dev/null +++ b/cafe/chapter2.test.ts @@ -0,0 +1,65 @@ +import { + Discount, + DiscountName, + Dish, + LowCarbonDiscount, + NiceCalorieDiscount, + Nutrition, + NutritionBalanceDiscount, + Plate, + Price, +} from './index'; + +it('Chapter2: カフェ (太郎のプレート)', () => { + const pasta = new Dish( + 'パスタ&ランチ', + new Price(250), + new Nutrition(1, 1, 3) + ); + const bread = new Dish( + 'くるみパン', + new Price(150), + new Nutrition(0, 0, 3) + ); + const dessert = new Dish( + 'フルーツ', + new Price(150), + new Nutrition(0, 1, 0) + ); + const taroPlate = new Plate('太郎のプレート', [pasta, bread, dessert]); + + const taroDiscounts_1 = [ + new Discount(DiscountName.LowCarbon, taroPlate), + new Discount(DiscountName.NiceCalorie, taroPlate), + new Discount(DiscountName.NutritionGoodBalance, taroPlate), + ]; + + const taroDiscounts_2 = [ + new LowCarbonDiscount(taroPlate), + new NiceCalorieDiscount(taroPlate), + new NutritionBalanceDiscount(taroPlate), + ]; + + // 太郎のプレートに対する割引の候補の中から、有効なものだけを取り出す + taroDiscounts_2.filter((discount) => discount.available()); +}); + +it('Chapter2: カフェ (次郎のプレート)', () => { + const pasta = new Dish( + 'パスタ&ランチ', + new Price(250), + new Nutrition(1, 1, 3) + ); + // FIXME: パンの種類を変える + const bread = new Dish( + 'くるみパン', + new Price(150), + new Nutrition(0, 0, 3) + ); + const dessert = new Dish( + 'フルーツ', + new Price(150), + new Nutrition(0, 1, 0) + ); + const taroPlate = new Plate('太郎のプレート', [pasta, bread, dessert]); +}); diff --git a/cafe/index.ts b/cafe/index.ts index b2ded92..719c5c8 100644 --- a/cafe/index.ts +++ b/cafe/index.ts @@ -12,6 +12,11 @@ class Plate { const dishes = this.dishes.map((dish) => ` - ${dish.toString()}`); return `Plate ${this.name}\n${dishes.join('\n')}`; } + + totalAmount(): Price { + // TODO: Dish の値段を合計したものを返す + return new Price(0); + } } class Dish { @@ -58,3 +63,140 @@ class Price { } export { Plate, Dish, Nutrition, Price }; + +class DiscountAmount { + readonly value: number; + constructor(value: number) { + this.value = value; + } + + add(other: DiscountAmount): DiscountAmount { + return new DiscountAmount(this.value + other.value); + } +} + +/** + * 割引を実装する + * + * - 1つの割引クラスで実装する + * - 割引の種類に応じて実装する + */ + +enum DiscountName { + NutritionGoodBalance = 'NutritionGoodBalance', + NiceCalorie = 'NiceCalorie', + LowCarbon = 'LowCarbon', +} + +// 1つの割引クラスで実装する + +class Discount { + private readonly name: DiscountName; + private readonly plate: Plate; + constructor(name: DiscountName, plate: Plate) { + this.name = name; + this.plate = plate; + } + + calcDiscount(): DiscountAmount { + switch (this.name) { + case DiscountName.NutritionGoodBalance: + return this.calcNutritionGoodBalanceDiscount(); + case DiscountName.LowCarbon: + return this.calcLowCarbonDiscount(); + case DiscountName.NiceCalorie: + return this.calcNiceCalorieDiscount(); + } + } + + private calcNutritionGoodBalanceDiscount(): DiscountAmount { + // バランス配慮セット割引の条件に適合したときに、その割引金額を返す + // 適合しないときには、 0円割引として値を返す + return new DiscountAmount(0); + } + + private calcLowCarbonDiscount(): DiscountAmount { + // 糖質配慮セット割引の条件に適合したときに、その割引金額を返す + // 適合しないときには、 0円割引として値を返す + return new DiscountAmount(0); + } + + private calcNiceCalorieDiscount(): DiscountAmount { + // ナイスカロリーセット割引の条件に適合したときに、その割引金額を返す + // 適合しないときには、 0円割引として値を返す + return new DiscountAmount(0); + } +} + +// 割引の種類に応じてクラスを分ける + +interface IDiscount { + available(): boolean; + calcDiscount(): DiscountAmount; +} + +class NutritionBalanceDiscount implements IDiscount { + private readonly plate: Plate; + public constructor(plate: Plate) { + this.plate = plate; + } + // 条件: 赤の合計が 3点以上のとき + public available(): boolean { + return false; // ここは一旦モックで実装 + } + // 割引: 緑を含む料理が 20% 割引(一番安いもの1点) + public calcDiscount(): DiscountAmount { + if (this.available()) { + // 緑を含む料理の一番安いものを this.plate から探して計算する + return new DiscountAmount(0); + } + // 適用条件を満たさないときは 0円割引として返す + return new DiscountAmount(0); + } +} + +class NiceCalorieDiscount implements IDiscount { + private readonly plate: Plate; + public constructor(plate: Plate) { + this.plate = plate; + } + // 条件: 三色の合計点数が 6点〜8点 の間 + public available(): boolean { + return false; // ここは一旦モックで実装 + } + // 割引: 50円引 + public calcDiscount(): DiscountAmount { + if (this.available()) { + return new DiscountAmount(50); + } + return new DiscountAmount(0); + } +} + +class LowCarbonDiscount implements IDiscount { + private readonly plate: Plate; + public constructor(plate: Plate) { + this.plate = plate; + } + // 条件: 黄の合計が 5点以下 + public available(): boolean { + return false; // ここは一旦モックで実装 + } + // 割引: 30円引 + public calcDiscount(): DiscountAmount { + if (this.available()) { + return new DiscountAmount(30); + } + return new DiscountAmount(0); + } +} + +export { + DiscountName, + DiscountAmount, + Discount, + IDiscount, + LowCarbonDiscount, + NiceCalorieDiscount, + NutritionBalanceDiscount, +}; From eee5e31f180fa8f22dff6a112979c7fe1c770d6e Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sun, 14 Feb 2021 18:14:41 +0900 Subject: [PATCH 09/63] =?UTF-8?q?chapter2=20=E3=83=9D=E3=83=BC=E3=82=AB?= =?UTF-8?q?=E3=83=BC=E3=81=AE=E4=BE=8B=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/index.ts | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/poker/index.ts b/poker/index.ts index 7cedaea..e925e47 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -73,3 +73,56 @@ class Suit { } export { Hand, Card, Rank, Suit }; + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +interface IPokerHand {} + +class OnePairPokerHand implements IPokerHand { + readonly pair: [Card, Card]; + + constructor(cardA: Card, cardB: Card) { + if (cardA.rank === cardB.rank) { + this.pair = [cardA, cardB]; + } else { + throw new Error(`Invalid cards: ${cardA}, ${cardB}`); + } + } +} + +class ThreeCardPokerHand implements IPokerHand { + readonly cards: [Card, Card, Card]; + + constructor(cardA: Card, cardB: Card, cardC: Card) { + if (cardA.rank === cardB.rank && cardB.rank === cardC.rank) { + this.cards = [cardA, cardB, cardC]; + } else { + throw new Error(`Invalid cards: ${cardA}, ${cardB}, ${cardC}`); + } + } +} + +class FullHousePokerHand implements IPokerHand { + readonly pair: [Card, Card]; + readonly threeCards: [Card, Card, Card]; + + constructor(pair: [Card, Card], threeCards: [Card, Card, Card]) { + this.pair = pair; + this.threeCards = threeCards; + + if (this.pair[0].rank !== this.pair[1].rank) { + throw new Error(`Invalid pair: ${this.pair}`); + } + if ( + this.threeCards[0].rank !== this.threeCards[1].rank || + this.threeCards[0].rank !== this.threeCards[2].rank + ) { + throw new Error(`Invalid cards: ${this.threeCards}`); + } + + if (this.pair[0].rank === this.threeCards[0].rank) { + throw new Error(`Invalid cards`); + } + } +} + +export { IPokerHand, OnePairPokerHand, ThreeCardPokerHand, FullHousePokerHand }; From d4784eb9adead9ca1f8b420a904e8d9c252b2354 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sun, 14 Feb 2021 18:19:01 +0900 Subject: [PATCH 10/63] =?UTF-8?q?chapter2=20=E3=83=9D=E3=83=BC=E3=82=AB?= =?UTF-8?q?=E3=83=BC=E3=81=AE=E3=82=AA=E3=83=96=E3=82=B8=E3=82=A7=E3=82=AF?= =?UTF-8?q?=E3=83=88=E4=BD=9C=E6=88=90=E4=BE=8B=E3=81=AE=E3=82=B3=E3=83=BC?= =?UTF-8?q?=E3=83=89=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/chapter2.test.ts | 69 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 poker/chapter2.test.ts diff --git a/poker/chapter2.test.ts b/poker/chapter2.test.ts new file mode 100644 index 0000000..f477e75 --- /dev/null +++ b/poker/chapter2.test.ts @@ -0,0 +1,69 @@ +import { + Card, + FullHousePokerHand, + Hand, + OnePairPokerHand, + Rank, + Suit, + ThreeCardPokerHand, +} from './index'; + +it('Chapter2: Poker', () => { + const taroHand = new Hand([ + new Card(Suit.Diamond, new Rank(3)), + new Card(Suit.Club, new Rank(3)), + new Card(Suit.Spade, new Rank(11)), + new Card(Suit.Heart, new Rank(4)), + new Card(Suit.Diamond, new Rank(1)), + ]); + + const taroPokerHands = [ + new OnePairPokerHand( + new Card(Suit.Diamond, new Rank(3)), + new Card(Suit.Club, new Rank(3)) + ), + ]; + + const jiroHand = new Hand([ + new Card(Suit.Diamond, new Rank(3)), + new Card(Suit.Club, new Rank(3)), + new Card(Suit.Spade, new Rank(11)), + new Card(Suit.Heart, new Rank(11)), + new Card(Suit.Diamond, new Rank(11)), + ]); + + const jiroCandidatePokerHands = [ + new OnePairPokerHand( + new Card(Suit.Diamond, new Rank(3)), + new Card(Suit.Club, new Rank(3)) + ), + new OnePairPokerHand( + new Card(Suit.Spade, new Rank(11)), + new Card(Suit.Heart, new Rank(11)) + ), + new OnePairPokerHand( + new Card(Suit.Spade, new Rank(11)), + new Card(Suit.Diamond, new Rank(11)) + ), + new OnePairPokerHand( + new Card(Suit.Spade, new Rank(11)), + new Card(Suit.Diamond, new Rank(11)) + ), + new ThreeCardPokerHand( + new Card(Suit.Spade, new Rank(11)), + new Card(Suit.Heart, new Rank(11)), + new Card(Suit.Diamond, new Rank(11)) + ), + new FullHousePokerHand( + [ + new Card(Suit.Diamond, new Rank(3)), + new Card(Suit.Club, new Rank(3)), + ], + [ + new Card(Suit.Spade, new Rank(11)), + new Card(Suit.Heart, new Rank(11)), + new Card(Suit.Diamond, new Rank(11)), + ] + ), + ]; +}); From ee8ea7fa8977141ef91baea637b741d001b7e32b Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sun, 7 Mar 2021 15:09:19 +0900 Subject: [PATCH 11/63] =?UTF-8?q?DishCollection=20=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cafe/index.ts | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/cafe/index.ts b/cafe/index.ts index 719c5c8..b26fed3 100644 --- a/cafe/index.ts +++ b/cafe/index.ts @@ -64,6 +64,27 @@ class Price { export { Plate, Dish, Nutrition, Price }; +class DishCollection { + private readonly dishes: Dish[]; + constructor(dishes: Dish[]) { + this.dishes = dishes; + } + + greenDishes(): DishCollection { + return new DishCollection( + this.dishes.filter((dish) => dish.nutrition.green > 0) + ); + } + + orderByPrice(): DishCollection { + return new DishCollection( + Array.from(this.dishes).sort( + (a, b) => a.price.value - b.price.value + ) + ); + } +} + class DiscountAmount { readonly value: number; constructor(value: number) { @@ -147,8 +168,26 @@ class NutritionBalanceDiscount implements IDiscount { // 割引: 緑を含む料理が 20% 割引(一番安いもの1点) public calcDiscount(): DiscountAmount { if (this.available()) { - // 緑を含む料理の一番安いものを this.plate から探して計算する - return new DiscountAmount(0); + // 緑を含む料理を探す + const greenDishes = [] as Dish[]; + this.plate.dishes.forEach((dish) => { + if (dish.nutrition.green > 0) { + greenDishes.push(dish); + } + }); + // その中で一番安い料理を探す + let lowestPriceDish: Dish | null = null; + greenDishes.forEach((dish) => { + if (!lowestPriceDish) { + lowestPriceDish = dish; + } + + if (lowestPriceDish.price.value > dish.price.value) { + lowestPriceDish = dish; + } + }); + // その料理の 20% が割引金額 + return new DiscountAmount(lowestPriceDish.price.value * 0.2); } // 適用条件を満たさないときは 0円割引として返す return new DiscountAmount(0); From 2612e9984025f4261dc739fe285de2c159ed5ac1 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sat, 20 Mar 2021 18:19:23 +0900 Subject: [PATCH 12/63] =?UTF-8?q?=E3=83=90=E3=83=A9=E3=83=B3=E3=82=B9?= =?UTF-8?q?=E9=85=8D=E6=85=AE=E3=82=BB=E3=83=83=E3=83=88=E5=89=B2=E5=BC=95?= =?UTF-8?q?=E3=81=AE=E6=96=99=E7=90=86=E3=82=92=E7=89=B9=E5=AE=9A=E3=81=99?= =?UTF-8?q?=E3=82=8B=E5=87=A6=E7=90=86=E3=82=922=E3=81=A4=E3=81=AE?= =?UTF-8?q?=E3=83=90=E3=83=AA=E3=82=A8=E3=83=BC=E3=82=B7=E3=83=A7=E3=83=B3?= =?UTF-8?q?=E3=81=A7=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cafe/index.ts | 91 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 69 insertions(+), 22 deletions(-) diff --git a/cafe/index.ts b/cafe/index.ts index b26fed3..47d4dd3 100644 --- a/cafe/index.ts +++ b/cafe/index.ts @@ -17,6 +17,23 @@ class Plate { // TODO: Dish の値段を合計したものを返す return new Price(0); } + + findLowestPriceGreenDish(): Dish | undefined { + // 緑を含む料理を探す + const greenDishes = []; + this.dishes.forEach((dish) => { + if (dish.nutrition.green > 0) { + greenDishes.push(dish); + } + }); + + // 値段の安い順に並び替えて + const sortedGreenDishes = greenDishes.sort( + (a, b) => a.price.value - b.price.value + ); + // 最初の要素を返す + return sortedGreenDishes[0]; + } } class Dish { @@ -158,39 +175,69 @@ interface IDiscount { class NutritionBalanceDiscount implements IDiscount { private readonly plate: Plate; + public constructor(plate: Plate) { this.plate = plate; } - // 条件: 赤の合計が 3点以上のとき + + // 条件: 赤と緑の合計が 3点以上のとき public available(): boolean { return false; // ここは一旦モックで実装 } + // 割引: 緑を含む料理が 20% 割引(一番安いもの1点) public calcDiscount(): DiscountAmount { - if (this.available()) { - // 緑を含む料理を探す - const greenDishes = [] as Dish[]; - this.plate.dishes.forEach((dish) => { - if (dish.nutrition.green > 0) { - greenDishes.push(dish); - } - }); - // その中で一番安い料理を探す - let lowestPriceDish: Dish | null = null; - greenDishes.forEach((dish) => { - if (!lowestPriceDish) { - lowestPriceDish = dish; - } - - if (lowestPriceDish.price.value > dish.price.value) { - lowestPriceDish = dish; - } - }); + if (!this.available()) { + // 適用条件を満たさないときは 0円割引として返す + return new DiscountAmount(0); + } + + // 緑を含む料理を探す + const greenDishes = [] as Dish[]; + this.plate.dishes.forEach((dish) => { + if (dish.nutrition.green > 0) { + greenDishes.push(dish); + } + }); + + // 値段の安い順に並び替えて + const sortedGreenDishes = greenDishes.sort( + (a, b) => a.price.value - b.price.value + ); + // 先頭の要素(=一番安い料理)を取り出す + const lowestPriceDish = sortedGreenDishes[0]; + if (lowestPriceDish) { // その料理の 20% が割引金額 return new DiscountAmount(lowestPriceDish.price.value * 0.2); + } else { + return new DiscountAmount(0); + } + } +} + +class NutritionBalanceDiscount2 implements IDiscount { + private readonly plate: Plate; + public constructor(plate: Plate) { + this.plate = plate; + } + + // 条件: 赤と緑の合計が 3点以上のとき + public available(): boolean { + return false; // TODO: 実装する + } + + // 割引: 緑を含む料理が 20% 割引(一番安いもの1点) + public calcDiscount(): DiscountAmount { + if (!this.available()) { + return new DiscountAmount(0); + } + + const targetDish = this.plate.findLowestPriceGreenDish(); + if (targetDish) { + return new DiscountAmount(targetDish.price.value * 0.2); + } else { + return new DiscountAmount(0); } - // 適用条件を満たさないときは 0円割引として返す - return new DiscountAmount(0); } } From f76a96b48db7457a811788fd61ae42f41832114b Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sun, 21 Mar 2021 14:11:28 +0900 Subject: [PATCH 13/63] =?UTF-8?q?DishCollection=20=E5=88=A9=E7=94=A8?= =?UTF-8?q?=E4=BE=8B=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cafe/index.ts | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/cafe/index.ts b/cafe/index.ts index 47d4dd3..a9fd1e6 100644 --- a/cafe/index.ts +++ b/cafe/index.ts @@ -36,6 +36,32 @@ class Plate { } } +class Plate2 { + public readonly name: string; + public readonly dishes: DishCollection; + + constructor(name: string, dishes: Dish[]) { + this.name = name; + this.dishes = new DishCollection(dishes); + } + + toString(): string { + const dishes = this.dishes.map((dish) => ` - ${dish.toString()}`); + return `Plate ${this.name}\n${dishes.join('\n')}`; + } + + totalAmount(): Price { + // TODO: Dish の値段を合計したものを返す + return new Price(0); + } + + findLowestPriceGreenDish(): Dish | undefined { + // 緑を含む料理を探す + const greenDishes = this.dishes.greenDishes().orderByPrice(); + return greenDishes.first(); + } +} + class Dish { public readonly name: string; public readonly price: Price; @@ -87,6 +113,14 @@ class DishCollection { this.dishes = dishes; } + map(fn: (value: Dish, index: number) => T): T[] { + return this.dishes.map(fn); + } + + first(): Dish | undefined { + return this.dishes[0]; + } + greenDishes(): DishCollection { return new DishCollection( this.dishes.filter((dish) => dish.nutrition.green > 0) From 6fdcb4dc1922e6ee2ac7ca49068d3b44cf77fc9b Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sat, 10 Apr 2021 14:16:48 +0900 Subject: [PATCH 14/63] =?UTF-8?q?Hand,=20Card,=20Rank,=20Suit=20=E3=82=92?= =?UTF-8?q?=E3=83=AA=E3=83=95=E3=82=A1=E3=82=AF=E3=82=BF=E3=83=AA=E3=83=B3?= =?UTF-8?q?=E3=82=B0=20&=20=E3=83=86=E3=82=B9=E3=83=88=E3=82=B1=E3=83=BC?= =?UTF-8?q?=E3=82=B9=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/index.ts | 21 +++++++++++-- poker/latest.test.ts | 74 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 poker/latest.test.ts diff --git a/poker/index.ts b/poker/index.ts index e925e47..e19bc05 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -2,6 +2,11 @@ class Hand { public readonly cards: Card[]; constructor(cards: Card[]) { + if (cards.length != 5) { + throw new Error( + `Invalid the number of cards: expected 5 cards, but got ${cards.length} cards` + ); + } this.cards = cards; } @@ -23,10 +28,14 @@ class Card { toString(): string { return `[${this.suit}${this.rank}]`; } + + isEqual(other: Card): boolean { + return this.suit.isEqual(other.suit) && this.rank.isEqual(other.rank); + } } class Rank { - public readonly value: number; + private readonly value: number; constructor(value: number) { this.value = value; @@ -46,10 +55,14 @@ class Rank { return `${this.value}`; } } + + isEqual(other: Rank): boolean { + return this.toString() === other.toString(); + } } class Suit { - public readonly value: string; + private readonly value: string; private mapping = { Spade: '♠', @@ -66,6 +79,10 @@ class Suit { return this.mapping[this.value]; } + isEqual(other: Suit): boolean { + return this.toString() === other.toString(); + } + public static Spade = new Suit('Spade'); public static Heart = new Suit('Heart'); public static Diamond = new Suit('Diamond'); diff --git a/poker/latest.test.ts b/poker/latest.test.ts new file mode 100644 index 0000000..b9554b6 --- /dev/null +++ b/poker/latest.test.ts @@ -0,0 +1,74 @@ +import { Card, Hand, Rank, Suit } from './index'; + +describe('Rank', () => { + describe('isEqual()', () => { + it('同じランクのときに true が返る', () => { + const one = new Rank(1); + const otherOne = new Rank(1); + expect(one.isEqual(otherOne)).toBeTruthy(); + }); + + it('ランクが異なるときに false が返る', () => { + const one = new Rank(1); + const two = new Rank(2); + expect(one.isEqual(two)).toBeFalsy(); + }); + }); +}); + +describe('Card', () => { + describe('isEqual()', () => { + it('同じランク、スートのときに true が返る', () => { + const two = new Rank(2); + const cardA = new Card(Suit.Diamond, two); + expect(cardA.isEqual(new Card(Suit.Diamond, two))).toBeTruthy(); + }); + + it('ランクが異なるときに false が返る', () => { + const two = new Rank(2); + const three = new Rank(3); + const cardA = new Card(Suit.Diamond, two); + expect(cardA.isEqual(new Card(Suit.Diamond, three))).toBeFalsy(); + }); + + it('スートが異なるときに false が返る', () => { + const two = new Rank(2); + const cardA = new Card(Suit.Diamond, two); + expect(cardA.isEqual(new Card(Suit.Club, two))).toBeFalsy(); + }); + }); +}); + +describe('Hand', () => { + describe('constructor', () => { + it('success', () => { + const hand = new Hand([ + new Card(Suit.Diamond, new Rank(3)), + new Card(Suit.Club, new Rank(3)), + new Card(Suit.Spade, new Rank(11)), + new Card(Suit.Heart, new Rank(4)), + new Card(Suit.Diamond, new Rank(1)), + ]); + expect(hand).toBeInstanceOf(Hand); + }); + + it('too many cards', () => { + expect(() => { + new Hand([ + new Card(Suit.Diamond, new Rank(3)), + new Card(Suit.Club, new Rank(3)), + new Card(Suit.Spade, new Rank(11)), + new Card(Suit.Heart, new Rank(4)), + new Card(Suit.Diamond, new Rank(1)), + new Card(Suit.Diamond, new Rank(2)), + ]); + }).toThrow('Invalid the number of cards'); + }); + + it('too few cards', () => { + expect(() => { + new Hand([new Card(Suit.Diamond, new Rank(3))]); + }).toThrow('Invalid the number of cards'); + }); + }); +}); From 63d9ccd37c097d67058d432560fc13448d5feb6b Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sat, 10 Apr 2021 14:25:04 +0900 Subject: [PATCH 15/63] =?UTF-8?q?Rank=E3=82=B3=E3=83=B3=E3=82=B9=E3=83=88?= =?UTF-8?q?=E3=83=A9=E3=82=AF=E3=82=BF=E3=81=A7=E5=80=A4=E3=81=AE=E7=AF=84?= =?UTF-8?q?=E5=9B=B2=E3=82=92=E3=83=81=E3=82=A7=E3=83=83=E3=82=AF=E3=81=99?= =?UTF-8?q?=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/index.ts | 4 ++++ poker/latest.test.ts | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/poker/index.ts b/poker/index.ts index e19bc05..943d6ad 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -38,6 +38,10 @@ class Rank { private readonly value: number; constructor(value: number) { + if (value < 1 || 13 < value || !Number.isInteger(value)) { + throw new Error(`Invalid value of Rank: got ${value}`); + } + this.value = value; } diff --git a/poker/latest.test.ts b/poker/latest.test.ts index b9554b6..99bf24f 100644 --- a/poker/latest.test.ts +++ b/poker/latest.test.ts @@ -1,6 +1,19 @@ import { Card, Hand, Rank, Suit } from './index'; describe('Rank', () => { + describe('constructor', () => { + it('success', () => { + expect(new Rank(1)).toBeInstanceOf(Rank); + expect(new Rank(2.0)).toBeInstanceOf(Rank); + }); + + it('invalid', () => { + expect(() => new Rank(0)).toThrow(); + expect(() => new Rank(1.1)).toThrow(); + expect(() => new Rank(14)).toThrow(); + }); + }); + describe('isEqual()', () => { it('同じランクのときに true が返る', () => { const one = new Rank(1); From 7f4bf89c56b8e5414d6be04940a7383da2545699 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sat, 10 Apr 2021 14:44:12 +0900 Subject: [PATCH 16/63] =?UTF-8?q?Rank=E3=82=92=E5=BC=B7=E3=81=84=E9=A0=86?= =?UTF-8?q?=E3=81=AB=E4=B8=A6=E3=81=B3=E6=9B=BF=E3=81=88=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/index.ts | 24 ++++++++++++++++++++++++ poker/latest.test.ts | 18 ++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/poker/index.ts b/poker/index.ts index 943d6ad..0a7b82d 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -63,6 +63,30 @@ class Rank { isEqual(other: Rank): boolean { return this.toString() === other.toString(); } + + private strength(): number { + if (this.value == 1) { + return 14; + } + return this.value; + } + + /** + * Rankの強い順に並び替える + * + * - other のほうが強い時には、正の値を + * - other のほうが弱い時には、負の値を + * - other と this が同じランクのときには、 0 を返します。 + * + * @param other {Rank} + */ + compareByStrength(other: Rank): number { + return other.strength() - this.strength(); + } + + static compareByStrength(a: Rank, b: Rank): number { + return a.compareByStrength(b); + } } class Suit { diff --git a/poker/latest.test.ts b/poker/latest.test.ts index 99bf24f..c6a29fc 100644 --- a/poker/latest.test.ts +++ b/poker/latest.test.ts @@ -27,6 +27,24 @@ describe('Rank', () => { expect(one.isEqual(two)).toBeFalsy(); }); }); + + describe('compareByStrength()', () => { + it('同じランクのとき', () => { + const two = new Rank(2); + expect(two.compareByStrength(two)).toEqual(0); + }); + + it('Rankの強い順に並び替えられること', () => { + const ace = new Rank(1); + const two = new Rank(2); + const five = new Rank(5); + const king = new Rank(13); + + expect( + [ace, two, five, king].sort(Rank.compareByStrength) + ).toEqual([ace, king, five, two]); + }); + }); }); describe('Card', () => { From 857a8f8ed70a546187c1acfd6c11017be35809ed Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sat, 10 Apr 2021 14:52:02 +0900 Subject: [PATCH 17/63] =?UTF-8?q?Suit=E3=82=92=E5=BC=B7=E3=81=84=E9=A0=86?= =?UTF-8?q?=E3=81=AB=E4=B8=A6=E3=81=B3=E6=9B=BF=E3=81=88=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/index.ts | 11 +++++++++++ poker/latest.test.ts | 16 ++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/poker/index.ts b/poker/index.ts index 0a7b82d..1557ce0 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -92,6 +92,7 @@ class Rank { class Suit { private readonly value: string; + private readonly strengthOrder = ['Spade', 'Heart', 'Diamond', 'Club']; private mapping = { Spade: '♠', Heart: '♥', @@ -115,6 +116,16 @@ class Suit { public static Heart = new Suit('Heart'); public static Diamond = new Suit('Diamond'); public static Club = new Suit('Club'); + + compareByStrength(other: Suit): number { + const myOrder = this.strengthOrder.indexOf(this.value); + const otherOder = this.strengthOrder.indexOf(other.value); + return myOrder - otherOder; + } + + static compareByStrength(a: Suit, b: Suit): number { + return a.compareByStrength(b); + } } export { Hand, Card, Rank, Suit }; diff --git a/poker/latest.test.ts b/poker/latest.test.ts index c6a29fc..b069f75 100644 --- a/poker/latest.test.ts +++ b/poker/latest.test.ts @@ -47,6 +47,22 @@ describe('Rank', () => { }); }); +describe('Suit', () => { + describe('compareByStrength()', () => { + it('同じスートのとき', () => { + expect(Suit.Diamond.compareByStrength(Suit.Diamond)).toEqual(0); + }); + + it('スートの強い順に並び替えられること', () => { + expect( + [Suit.Diamond, Suit.Heart, Suit.Club, Suit.Spade].sort( + Suit.compareByStrength + ) + ).toEqual([Suit.Spade, Suit.Heart, Suit.Diamond, Suit.Club]); + }); + }); +}); + describe('Card', () => { describe('isEqual()', () => { it('同じランク、スートのときに true が返る', () => { From 6cd22b075cbcbc715ffb248ee03e83fa2026cec9 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sat, 10 Apr 2021 14:58:53 +0900 Subject: [PATCH 18/63] =?UTF-8?q?Card=E3=82=92=E5=BC=B7=E3=81=95=E9=A0=86?= =?UTF-8?q?=E3=81=AB=E3=82=BD=E3=83=BC=E3=83=88=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/index.ts | 14 ++++++++++++++ poker/latest.test.ts | 26 ++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/poker/index.ts b/poker/index.ts index 1557ce0..f126854 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -32,6 +32,20 @@ class Card { isEqual(other: Card): boolean { return this.suit.isEqual(other.suit) && this.rank.isEqual(other.rank); } + + compareByStrength(other: Card): number { + const compareRank = this.rank.compareByStrength(other.rank); + + if (compareRank == 0) { + return this.suit.compareByStrength(other.suit); + } else { + return compareRank; + } + } + + static compareByStrength(a: Card, b: Card): number { + return a.compareByStrength(b); + } } class Rank { diff --git a/poker/latest.test.ts b/poker/latest.test.ts index b069f75..8a11b97 100644 --- a/poker/latest.test.ts +++ b/poker/latest.test.ts @@ -84,6 +84,32 @@ describe('Card', () => { expect(cardA.isEqual(new Card(Suit.Club, two))).toBeFalsy(); }); }); + + describe('compareByStrength()', () => { + it('ランクの強い順にカードが並ぶ', () => { + const card3 = new Card(Suit.Diamond, new Rank(3)); + const card4 = new Card(Suit.Club, new Rank(4)); + const card11 = new Card(Suit.Spade, new Rank(11)); + const card1 = new Card(Suit.Heart, new Rank(1)); + + expect( + [card1, card3, card4, card11].sort(Card.compareByStrength) + ).toEqual([card1, card11, card4, card3]); + }); + + it('同じランクのカードはスートの強い順に並ぶ', () => { + const card3 = new Card(Suit.Diamond, new Rank(3)); + const card4club = new Card(Suit.Club, new Rank(4)); + const card4spade = new Card(Suit.Spade, new Rank(4)); + const card5 = new Card(Suit.Heart, new Rank(5)); + + expect( + [card3, card4club, card4spade, card5].sort( + Card.compareByStrength + ) + ).toEqual([card5, card4spade, card4club, card3]); + }); + }); }); describe('Hand', () => { From b78a8f3c013ffe9da087319665549db2d74d4f92 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sat, 10 Apr 2021 15:34:20 +0900 Subject: [PATCH 19/63] =?UTF-8?q?Hand=20=E3=81=AE=E4=B8=80=E8=87=B4?= =?UTF-8?q?=E6=AF=94=E8=BC=83=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/index.ts | 10 +++++++++ poker/latest.test.ts | 49 ++++++++++++++++++++++++++++++++------------ 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/poker/index.ts b/poker/index.ts index f126854..b6d1a85 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -14,6 +14,16 @@ class Hand { const cards = this.cards.map((card) => `${card}`); return `Hand(${cards.join(', ')})`; } + + contain(other: Card): boolean { + return !!this.cards.find((card) => card.isEqual(other)); + } + + isEqual(other: Hand): boolean { + return this.cards.every((card) => { + return other.contain(card); + }); + } } class Card { diff --git a/poker/latest.test.ts b/poker/latest.test.ts index 8a11b97..5914257 100644 --- a/poker/latest.test.ts +++ b/poker/latest.test.ts @@ -113,26 +113,27 @@ describe('Card', () => { }); describe('Hand', () => { + const diamond3 = new Card(Suit.Diamond, new Rank(3)); + const club3 = new Card(Suit.Club, new Rank(3)); + const spade11 = new Card(Suit.Spade, new Rank(11)); + const heart4 = new Card(Suit.Heart, new Rank(4)); + const diamond1 = new Card(Suit.Diamond, new Rank(1)); + + const hand = new Hand([diamond3, club3, spade11, heart4, diamond1]); + describe('constructor', () => { it('success', () => { - const hand = new Hand([ - new Card(Suit.Diamond, new Rank(3)), - new Card(Suit.Club, new Rank(3)), - new Card(Suit.Spade, new Rank(11)), - new Card(Suit.Heart, new Rank(4)), - new Card(Suit.Diamond, new Rank(1)), - ]); expect(hand).toBeInstanceOf(Hand); }); it('too many cards', () => { expect(() => { new Hand([ - new Card(Suit.Diamond, new Rank(3)), - new Card(Suit.Club, new Rank(3)), - new Card(Suit.Spade, new Rank(11)), - new Card(Suit.Heart, new Rank(4)), - new Card(Suit.Diamond, new Rank(1)), + diamond3, + club3, + spade11, + heart4, + diamond1, new Card(Suit.Diamond, new Rank(2)), ]); }).toThrow('Invalid the number of cards'); @@ -140,8 +141,30 @@ describe('Hand', () => { it('too few cards', () => { expect(() => { - new Hand([new Card(Suit.Diamond, new Rank(3))]); + new Hand([diamond3]); }).toThrow('Invalid the number of cards'); }); }); + + describe('contain()', () => { + it('Handに含まれているカードの場合、 true が返る', () => { + expect(hand.contain(diamond1)).toBeTruthy(); + }); + + it('Handに含まれていないカードの場合、 false が返る', () => { + expect( + hand.contain(new Card(Suit.Diamond, new Rank(2))) + ).toBeFalsy(); + }); + }); + + describe('isEqual()', () => { + it('カードの順番が違っていても、同じカードの組み合わせならば一致', () => { + expect( + hand.isEqual( + new Hand([diamond1, diamond3, club3, heart4, spade11]) + ) + ).toBeTruthy(); + }); + }); }); From 35223fabd11c43b94916a838e01ec3524733cc9e Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sat, 10 Apr 2021 15:47:38 +0900 Subject: [PATCH 20/63] =?UTF-8?q?=E6=97=A7=E5=AE=9F=E8=A3=85=E3=82=92?= =?UTF-8?q?=E4=B8=80=E5=BA=A6=E3=82=B3=E3=83=A1=E3=83=B3=E3=83=88=E3=82=A2?= =?UTF-8?q?=E3=82=A6=E3=83=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/chapter2.test.ts | 86 ++++++++++++++++++------------------ poker/index.ts | 98 ++++++++++++++++++++---------------------- 2 files changed, 90 insertions(+), 94 deletions(-) diff --git a/poker/chapter2.test.ts b/poker/chapter2.test.ts index f477e75..0bcd579 100644 --- a/poker/chapter2.test.ts +++ b/poker/chapter2.test.ts @@ -1,11 +1,11 @@ import { Card, - FullHousePokerHand, + // FullHousePokerHand, Hand, - OnePairPokerHand, + // OnePairPokerHand, Rank, Suit, - ThreeCardPokerHand, + // ThreeCardPokerHand, } from './index'; it('Chapter2: Poker', () => { @@ -17,12 +17,12 @@ it('Chapter2: Poker', () => { new Card(Suit.Diamond, new Rank(1)), ]); - const taroPokerHands = [ - new OnePairPokerHand( - new Card(Suit.Diamond, new Rank(3)), - new Card(Suit.Club, new Rank(3)) - ), - ]; + // const taroPokerHands = [ + // new OnePairPokerHand( + // new Card(Suit.Diamond, new Rank(3)), + // new Card(Suit.Club, new Rank(3)) + // ), + // ]; const jiroHand = new Hand([ new Card(Suit.Diamond, new Rank(3)), @@ -32,38 +32,38 @@ it('Chapter2: Poker', () => { new Card(Suit.Diamond, new Rank(11)), ]); - const jiroCandidatePokerHands = [ - new OnePairPokerHand( - new Card(Suit.Diamond, new Rank(3)), - new Card(Suit.Club, new Rank(3)) - ), - new OnePairPokerHand( - new Card(Suit.Spade, new Rank(11)), - new Card(Suit.Heart, new Rank(11)) - ), - new OnePairPokerHand( - new Card(Suit.Spade, new Rank(11)), - new Card(Suit.Diamond, new Rank(11)) - ), - new OnePairPokerHand( - new Card(Suit.Spade, new Rank(11)), - new Card(Suit.Diamond, new Rank(11)) - ), - new ThreeCardPokerHand( - new Card(Suit.Spade, new Rank(11)), - new Card(Suit.Heart, new Rank(11)), - new Card(Suit.Diamond, new Rank(11)) - ), - new FullHousePokerHand( - [ - new Card(Suit.Diamond, new Rank(3)), - new Card(Suit.Club, new Rank(3)), - ], - [ - new Card(Suit.Spade, new Rank(11)), - new Card(Suit.Heart, new Rank(11)), - new Card(Suit.Diamond, new Rank(11)), - ] - ), - ]; + // const jiroCandidatePokerHands = [ + // new OnePairPokerHand( + // new Card(Suit.Diamond, new Rank(3)), + // new Card(Suit.Club, new Rank(3)) + // ), + // new OnePairPokerHand( + // new Card(Suit.Spade, new Rank(11)), + // new Card(Suit.Heart, new Rank(11)) + // ), + // new OnePairPokerHand( + // new Card(Suit.Spade, new Rank(11)), + // new Card(Suit.Diamond, new Rank(11)) + // ), + // new OnePairPokerHand( + // new Card(Suit.Spade, new Rank(11)), + // new Card(Suit.Diamond, new Rank(11)) + // ), + // new ThreeCardPokerHand( + // new Card(Suit.Spade, new Rank(11)), + // new Card(Suit.Heart, new Rank(11)), + // new Card(Suit.Diamond, new Rank(11)) + // ), + // new FullHousePokerHand( + // [ + // new Card(Suit.Diamond, new Rank(3)), + // new Card(Suit.Club, new Rank(3)), + // ], + // [ + // new Card(Suit.Spade, new Rank(11)), + // new Card(Suit.Heart, new Rank(11)), + // new Card(Suit.Diamond, new Rank(11)), + // ] + // ), + // ]; }); diff --git a/poker/index.ts b/poker/index.ts index b6d1a85..a72adbf 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -155,54 +155,50 @@ class Suit { export { Hand, Card, Rank, Suit }; // eslint-disable-next-line @typescript-eslint/no-empty-interface -interface IPokerHand {} - -class OnePairPokerHand implements IPokerHand { - readonly pair: [Card, Card]; - - constructor(cardA: Card, cardB: Card) { - if (cardA.rank === cardB.rank) { - this.pair = [cardA, cardB]; - } else { - throw new Error(`Invalid cards: ${cardA}, ${cardB}`); - } - } -} - -class ThreeCardPokerHand implements IPokerHand { - readonly cards: [Card, Card, Card]; - - constructor(cardA: Card, cardB: Card, cardC: Card) { - if (cardA.rank === cardB.rank && cardB.rank === cardC.rank) { - this.cards = [cardA, cardB, cardC]; - } else { - throw new Error(`Invalid cards: ${cardA}, ${cardB}, ${cardC}`); - } - } -} - -class FullHousePokerHand implements IPokerHand { - readonly pair: [Card, Card]; - readonly threeCards: [Card, Card, Card]; - - constructor(pair: [Card, Card], threeCards: [Card, Card, Card]) { - this.pair = pair; - this.threeCards = threeCards; - - if (this.pair[0].rank !== this.pair[1].rank) { - throw new Error(`Invalid pair: ${this.pair}`); - } - if ( - this.threeCards[0].rank !== this.threeCards[1].rank || - this.threeCards[0].rank !== this.threeCards[2].rank - ) { - throw new Error(`Invalid cards: ${this.threeCards}`); - } - - if (this.pair[0].rank === this.threeCards[0].rank) { - throw new Error(`Invalid cards`); - } - } -} - -export { IPokerHand, OnePairPokerHand, ThreeCardPokerHand, FullHousePokerHand }; +// interface IPokerHand {} +// +// class OnePairPokerHand implements IPokerHand { +// private readonly pair: Pair; +// +// constructor(cardA: Card, cardB: Card) { +// this.pair = new Pair(cardA, cardB); +// } +// +// toString(): string { +// return `OnePair(${this.pair.toString()})`; +// } +// } +// +// class TwoPairPokerHand implements IPokerHand { +// private readonly pairs: [Pair, Pair]; +// +// constructor(pairA: Pair, pairB: Pair) { +// this.pairs = [pairA, pairB]; +// } +// } +// +// class ThreeCardPokerHand implements IPokerHand { +// private readonly triple: Triple; +// +// constructor(cardA: Card, cardB: Card, cardC: Card) { +// this.triple = new Triple(cardA, cardB, cardC); +// } +// } +// +// class FullHousePokerHand implements IPokerHand { +// private readonly pair: Pair; +// private readonly triple: Triple; +// +// constructor(pair: [Card, Card], triple: [Card, Card, Card]) { +// this.pair = new Pair(...pair); +// this.triple = new Triple(...triple); +// +// if (this.pair.rank.isEqual(this.triple.rank)) { +// throw new Error( +// `Invalid pair and triple: ${this.pair}, ${this.triple}` +// ); +// } +// } +// } +// +// export { IPokerHand, OnePairPokerHand, ThreeCardPokerHand, FullHousePokerHand }; From 93084133b8ffd6a534a8898b0a6603ca1c60267b Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sat, 10 Apr 2021 15:48:23 +0900 Subject: [PATCH 21/63] =?UTF-8?q?=E5=BD=B9=E3=81=AE=E4=B8=80=E9=83=A8?= =?UTF-8?q?=E3=82=92=E6=A7=8B=E6=88=90=E3=81=99=E3=82=8B=E8=A6=81=E7=B4=A0?= =?UTF-8?q?=E3=82=AA=E3=83=96=E3=82=B8=E3=82=A7=E3=82=AF=E3=83=88=E3=82=92?= =?UTF-8?q?=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/index.ts | 50 ++++++++++++++++++++++++++++++ poker/latest.test.ts | 73 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 122 insertions(+), 1 deletion(-) diff --git a/poker/index.ts b/poker/index.ts index a72adbf..7b55268 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -154,6 +154,56 @@ class Suit { export { Hand, Card, Rank, Suit }; +class Pair { + private readonly cards: [Card, Card]; + + constructor(cardA: Card, cardB: Card) { + if (cardA.rank.isEqual(cardB.rank)) { + this.cards = [cardA, cardB]; + } else { + throw new Error(`Invalid cards: ${cardA}, ${cardB}`); + } + } + + get rank(): Rank { + return this.cards[0].rank; + } + + get suits(): Suit[] { + return this.cards.map((card) => card.suit).sort(Suit.compareByStrength); + } + + toString(): string { + return `Pair(${this.rank}, ${this.suits.join(', ')})`; + } +} + +class Triple { + private readonly cards: [Card, Card, Card]; + + constructor(cardA: Card, cardB: Card, cardC: Card) { + if (cardA.rank.isEqual(cardB.rank) && cardB.rank.isEqual(cardC.rank)) { + this.cards = [cardA, cardB, cardC]; + } else { + throw new Error(`Invalid cards: ${cardA}, ${cardB}, ${cardC}`); + } + } + + get rank(): Rank { + return this.cards[0].rank; + } + + get suits(): Suit[] { + return this.cards.map((card) => card.suit).sort(Suit.compareByStrength); + } + + toString(): string { + return `Triple(${this.rank}, ${this.suits.join(', ')})`; + } +} + +export { Pair, Triple }; + // eslint-disable-next-line @typescript-eslint/no-empty-interface // interface IPokerHand {} // diff --git a/poker/latest.test.ts b/poker/latest.test.ts index 5914257..c81fc0b 100644 --- a/poker/latest.test.ts +++ b/poker/latest.test.ts @@ -1,4 +1,4 @@ -import { Card, Hand, Rank, Suit } from './index'; +import { Card, Hand, Pair, Rank, Suit, Triple } from './index'; describe('Rank', () => { describe('constructor', () => { @@ -168,3 +168,74 @@ describe('Hand', () => { }); }); }); + +describe('Pair', () => { + const diamond3 = new Card(Suit.Diamond, new Rank(3)); + const club3 = new Card(Suit.Club, new Rank(3)); + const diamond1 = new Card(Suit.Diamond, new Rank(1)); + + const pair = new Pair(diamond3, club3); + + describe('constructor', () => { + it('success', () => { + expect(pair).toBeInstanceOf(Pair); + }); + + it('invalid pair', () => { + expect(() => new Pair(diamond3, diamond1)).toThrow('Invalid cards'); + }); + }); + + describe('rank', () => { + it('Rankが返ること', () => { + expect(pair.rank).toEqual(diamond3.rank); + }); + }); + + describe('suits', () => { + it('スートが強い順に返ること', () => { + expect(pair.suits).toEqual([diamond3.suit, club3.suit]); + expect(new Pair(club3, diamond3).suits).toEqual([ + diamond3.suit, + club3.suit, + ]); + }); + }); +}); + +describe('Triple', () => { + const club3 = new Card(Suit.Club, new Rank(3)); + const spade11 = new Card(Suit.Spade, new Rank(11)); + const heart11 = new Card(Suit.Heart, new Rank(11)); + const diamond11 = new Card(Suit.Diamond, new Rank(11)); + + const triple = new Triple(heart11, diamond11, spade11); + + describe('constructor', () => { + it('success', () => { + expect(triple).toBeInstanceOf(Triple); + }); + + it('invalid pair', () => { + expect(() => new Triple(spade11, heart11, club3)).toThrow( + 'Invalid cards' + ); + }); + }); + + describe('rank', () => { + it('Rankが返ること', () => { + expect(triple.rank).toEqual(spade11.rank); + }); + }); + + describe('suits', () => { + it('スートが強い順に返ること', () => { + expect(triple.suits).toEqual([ + spade11.suit, + heart11.suit, + diamond11.suit, + ]); + }); + }); +}); From 5a0a8eccc9c054191e28e27fe2a9ac72ace672ff Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sat, 10 Apr 2021 15:49:48 +0900 Subject: [PATCH 22/63] =?UTF-8?q?Card=E3=81=AB=E5=90=8C=E3=83=A9=E3=83=B3?= =?UTF-8?q?=E3=82=AF=E3=81=A7=E3=81=82=E3=82=8B=E3=81=93=E3=81=A8=E3=82=92?= =?UTF-8?q?=E3=83=81=E3=82=A7=E3=83=83=E3=82=AF=E3=81=99=E3=82=8BisSameRan?= =?UTF-8?q?k()=20=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/index.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/poker/index.ts b/poker/index.ts index 7b55268..970d06e 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -43,6 +43,10 @@ class Card { return this.suit.isEqual(other.suit) && this.rank.isEqual(other.rank); } + isSameRank(other: Card): boolean { + return this.rank.isEqual(other.rank); + } + compareByStrength(other: Card): number { const compareRank = this.rank.compareByStrength(other.rank); @@ -158,7 +162,7 @@ class Pair { private readonly cards: [Card, Card]; constructor(cardA: Card, cardB: Card) { - if (cardA.rank.isEqual(cardB.rank)) { + if (cardA.isSameRank(cardB)) { this.cards = [cardA, cardB]; } else { throw new Error(`Invalid cards: ${cardA}, ${cardB}`); @@ -182,7 +186,7 @@ class Triple { private readonly cards: [Card, Card, Card]; constructor(cardA: Card, cardB: Card, cardC: Card) { - if (cardA.rank.isEqual(cardB.rank) && cardB.rank.isEqual(cardC.rank)) { + if (cardA.isSameRank(cardB) && cardB.isSameRank(cardC)) { this.cards = [cardA, cardB, cardC]; } else { throw new Error(`Invalid cards: ${cardA}, ${cardB}, ${cardC}`); From 90766502ab29e613bf0ad452eb10a75f3ee60f01 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sat, 10 Apr 2021 15:59:55 +0900 Subject: [PATCH 23/63] =?UTF-8?q?OnePairPokerHand,=20TwoPairPokerHand=20?= =?UTF-8?q?=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/index.ts | 58 ++++++++++++++++++++++++++------------------ poker/latest.test.ts | 48 +++++++++++++++++++++++++++++++++++- 2 files changed, 81 insertions(+), 25 deletions(-) diff --git a/poker/index.ts b/poker/index.ts index 970d06e..9b25594 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -209,28 +209,38 @@ class Triple { export { Pair, Triple }; // eslint-disable-next-line @typescript-eslint/no-empty-interface -// interface IPokerHand {} -// -// class OnePairPokerHand implements IPokerHand { -// private readonly pair: Pair; -// -// constructor(cardA: Card, cardB: Card) { -// this.pair = new Pair(cardA, cardB); -// } -// -// toString(): string { -// return `OnePair(${this.pair.toString()})`; -// } -// } -// -// class TwoPairPokerHand implements IPokerHand { -// private readonly pairs: [Pair, Pair]; -// -// constructor(pairA: Pair, pairB: Pair) { -// this.pairs = [pairA, pairB]; -// } -// } -// +interface IPokerHand {} + +class OnePairPokerHand implements IPokerHand { + private readonly pair: Pair; + + constructor(pair: Pair) { + this.pair = pair; + } + + toString(): string { + return `OnePair[${this.pair.toString()}]`; + } +} + +class TwoPairPokerHand implements IPokerHand { + private readonly pairs: [Pair, Pair]; + + constructor(pairA: Pair, pairB: Pair) { + if (pairA.rank.isEqual(pairB.rank)) { + throw new Error(`Invalid pairs: pairA=${pairA}, pairB=${pairB}`); + } + + this.pairs = [pairA, pairB]; + } + + toString(): string { + return `TwoPair[${this.pairs + .map((pair) => pair.toString()) + .join(', ')}]`; + } +} + // class ThreeCardPokerHand implements IPokerHand { // private readonly triple: Triple; // @@ -254,5 +264,5 @@ export { Pair, Triple }; // } // } // } -// -// export { IPokerHand, OnePairPokerHand, ThreeCardPokerHand, FullHousePokerHand }; + +export { IPokerHand, OnePairPokerHand, TwoPairPokerHand }; diff --git a/poker/latest.test.ts b/poker/latest.test.ts index c81fc0b..b36e318 100644 --- a/poker/latest.test.ts +++ b/poker/latest.test.ts @@ -1,4 +1,13 @@ -import { Card, Hand, Pair, Rank, Suit, Triple } from './index'; +import { + Card, + Hand, + OnePairPokerHand, + Pair, + Rank, + Suit, + Triple, + TwoPairPokerHand, +} from './index'; describe('Rank', () => { describe('constructor', () => { @@ -239,3 +248,40 @@ describe('Triple', () => { }); }); }); + +describe('PokerHand', () => { + const diamond3 = new Card(Suit.Diamond, new Rank(3)); + const club3 = new Card(Suit.Club, new Rank(3)); + const diamond1 = new Card(Suit.Diamond, new Rank(1)); + const club1 = new Card(Suit.Club, new Rank(1)); + + describe('OnePairPokerHand', () => { + describe('constructor', () => { + it('success', () => { + const onePair = new OnePairPokerHand(new Pair(diamond3, club3)); + expect(onePair.toString()).toContain('OnePair'); + }); + }); + }); + + describe('TwoPairPokerHand', () => { + describe('constructor', () => { + it('success', () => { + const twoPair = new TwoPairPokerHand( + new Pair(diamond3, club3), + new Pair(diamond1, club1) + ); + expect(twoPair.toString()).toContain('TwoPair'); + }); + + it('failure', () => { + expect(() => { + new TwoPairPokerHand( + new Pair(diamond3, club3), + new Pair(diamond3, club3) + ); + }).toThrow('Invalid pairs'); + }); + }); + }); +}); From 75a79555faf885500cc96540a5361d0b0853e253 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sat, 10 Apr 2021 16:00:42 +0900 Subject: [PATCH 24/63] =?UTF-8?q?Pair=E3=81=ABisSameRank()=20=E3=82=92?= =?UTF-8?q?=E5=AE=9F=E8=A3=85=E3=81=97=E3=81=A6=E3=83=AA=E3=83=95=E3=82=A1?= =?UTF-8?q?=E3=82=AF=E3=82=BF=E3=83=AA=E3=83=B3=E3=82=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/index.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/poker/index.ts b/poker/index.ts index 9b25594..1cf64c6 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -180,6 +180,10 @@ class Pair { toString(): string { return `Pair(${this.rank}, ${this.suits.join(', ')})`; } + + isSameRank(other: Pair): boolean { + return this.rank.isEqual(other.rank); + } } class Triple { @@ -227,7 +231,7 @@ class TwoPairPokerHand implements IPokerHand { private readonly pairs: [Pair, Pair]; constructor(pairA: Pair, pairB: Pair) { - if (pairA.rank.isEqual(pairB.rank)) { + if (pairA.isSameRank(pairB)) { throw new Error(`Invalid pairs: pairA=${pairA}, pairB=${pairB}`); } From 19350344ee1a9be59eccb41b88459e3f67ce55dd Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sat, 10 Apr 2021 19:20:43 +0900 Subject: [PATCH 25/63] =?UTF-8?q?=E3=82=B9=E3=83=AA=E3=83=BC=E3=82=AB?= =?UTF-8?q?=E3=83=BC=E3=83=89=E3=81=AE=E5=BD=B9=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/index.ts | 22 +++++++++++++--------- poker/latest.test.ts | 14 ++++++++++++++ 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/poker/index.ts b/poker/index.ts index 1cf64c6..69b5c99 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -245,14 +245,18 @@ class TwoPairPokerHand implements IPokerHand { } } -// class ThreeCardPokerHand implements IPokerHand { -// private readonly triple: Triple; -// -// constructor(cardA: Card, cardB: Card, cardC: Card) { -// this.triple = new Triple(cardA, cardB, cardC); -// } -// } -// +class ThreeCardPokerHand implements IPokerHand { + private readonly triple: Triple; + + constructor(triple: Triple) { + this.triple = triple; + } + + toString(): string { + return `ThreeCard[${this.triple.toString()}]`; + } +} + // class FullHousePokerHand implements IPokerHand { // private readonly pair: Pair; // private readonly triple: Triple; @@ -269,4 +273,4 @@ class TwoPairPokerHand implements IPokerHand { // } // } -export { IPokerHand, OnePairPokerHand, TwoPairPokerHand }; +export { IPokerHand, OnePairPokerHand, TwoPairPokerHand, ThreeCardPokerHand }; diff --git a/poker/latest.test.ts b/poker/latest.test.ts index b36e318..9471562 100644 --- a/poker/latest.test.ts +++ b/poker/latest.test.ts @@ -5,6 +5,7 @@ import { Pair, Rank, Suit, + ThreeCardPokerHand, Triple, TwoPairPokerHand, } from './index'; @@ -252,6 +253,7 @@ describe('Triple', () => { describe('PokerHand', () => { const diamond3 = new Card(Suit.Diamond, new Rank(3)); const club3 = new Card(Suit.Club, new Rank(3)); + const spade3 = new Card(Suit.Spade, new Rank(3)); const diamond1 = new Card(Suit.Diamond, new Rank(1)); const club1 = new Card(Suit.Club, new Rank(1)); @@ -284,4 +286,16 @@ describe('PokerHand', () => { }); }); }); + + describe('ThreeCardPokerHand', () => { + describe('constructor', () => { + it('success', () => { + const threeCard = new ThreeCardPokerHand( + new Triple(diamond3, club3, spade3) + ); + expect(threeCard).toBeInstanceOf(ThreeCardPokerHand); + expect(threeCard.toString()).toContain('ThreeCard'); + }); + }); + }); }); From a9c6db4bec5cbaec5cffce4349f907dcd80d18ce Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sat, 10 Apr 2021 19:26:26 +0900 Subject: [PATCH 26/63] =?UTF-8?q?=E3=83=95=E3=83=AB=E3=83=8F=E3=82=A6?= =?UTF-8?q?=E3=82=B9=E3=81=AE=E5=BD=B9=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/index.ts | 42 +++++++++++++++++++++++++----------------- poker/latest.test.ts | 23 +++++++++++++++++++++++ 2 files changed, 48 insertions(+), 17 deletions(-) diff --git a/poker/index.ts b/poker/index.ts index 69b5c99..b1ea043 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -257,20 +257,28 @@ class ThreeCardPokerHand implements IPokerHand { } } -// class FullHousePokerHand implements IPokerHand { -// private readonly pair: Pair; -// private readonly triple: Triple; -// -// constructor(pair: [Card, Card], triple: [Card, Card, Card]) { -// this.pair = new Pair(...pair); -// this.triple = new Triple(...triple); -// -// if (this.pair.rank.isEqual(this.triple.rank)) { -// throw new Error( -// `Invalid pair and triple: ${this.pair}, ${this.triple}` -// ); -// } -// } -// } - -export { IPokerHand, OnePairPokerHand, TwoPairPokerHand, ThreeCardPokerHand }; +class FullHousePokerHand implements IPokerHand { + private readonly pair: Pair; + private readonly triple: Triple; + + constructor(pair: Pair, triple: Triple) { + if (pair.rank.isEqual(triple.rank)) { + throw new Error(`Invalid pair and triple: ${pair}, ${triple}`); + } + + this.pair = pair; + this.triple = triple; + } + + toString(): string { + return `FullHouse[${this.pair.toString()}, ${this.triple.toString()}]`; + } +} + +export { + IPokerHand, + OnePairPokerHand, + TwoPairPokerHand, + ThreeCardPokerHand, + FullHousePokerHand, +}; diff --git a/poker/latest.test.ts b/poker/latest.test.ts index 9471562..35e33d2 100644 --- a/poker/latest.test.ts +++ b/poker/latest.test.ts @@ -1,5 +1,6 @@ import { Card, + FullHousePokerHand, Hand, OnePairPokerHand, Pair, @@ -298,4 +299,26 @@ describe('PokerHand', () => { }); }); }); + + describe('FullHousePokerHand', () => { + describe('constructor', () => { + it('success', () => { + const fullHouse = new FullHousePokerHand( + new Pair(diamond1, club1), + new Triple(diamond3, club3, spade3) + ); + expect(fullHouse).toBeInstanceOf(FullHousePokerHand); + expect(fullHouse.toString()).toContain('FullHouse'); + }); + + it('failure', () => { + expect(() => { + new FullHousePokerHand( + new Pair(diamond3, club3), + new Triple(diamond3, club3, spade3) + ); + }).toThrow('Invalid pair and triple'); + }); + }); + }); }); From 334b219722106e0d28212a3901ffe9872d3111d9 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sat, 10 Apr 2021 21:21:56 +0900 Subject: [PATCH 27/63] =?UTF-8?q?OnePairPokerHand=20=E3=81=AE=E5=BC=B7?= =?UTF-8?q?=E5=BC=B1=E3=82=92=E6=AF=94=E8=BC=83=E3=81=A7=E3=81=8D=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/index.ts | 24 ++++++++++++++++++++++++ poker/latest.test.ts | 18 ++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/poker/index.ts b/poker/index.ts index b1ea043..5bccb1f 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -184,6 +184,10 @@ class Pair { isSameRank(other: Pair): boolean { return this.rank.isEqual(other.rank); } + + compareByStrength(other: Pair): number { + return this.rank.compareByStrength(other.rank); + } } class Triple { @@ -225,6 +229,10 @@ class OnePairPokerHand implements IPokerHand { toString(): string { return `OnePair[${this.pair.toString()}]`; } + + compareWithOnePair(other: OnePairPokerHand): number { + return this.pair.compareByStrength(other.pair); + } } class TwoPairPokerHand implements IPokerHand { @@ -275,10 +283,26 @@ class FullHousePokerHand implements IPokerHand { } } +class PokerHandCollection { + private readonly pokerHands: IPokerHand[]; + + constructor(pokerHands: IPokerHand[]) { + this.pokerHands = pokerHands; + } + + toString(): string { + const pokerHands = this.pokerHands.map((pokerHand) => + pokerHand.toString() + ); + return `PokerHandCollection(${pokerHands.join(', ')})`; + } +} + export { IPokerHand, OnePairPokerHand, TwoPairPokerHand, ThreeCardPokerHand, FullHousePokerHand, + PokerHandCollection, }; diff --git a/poker/latest.test.ts b/poker/latest.test.ts index 35e33d2..8d83a60 100644 --- a/poker/latest.test.ts +++ b/poker/latest.test.ts @@ -4,6 +4,7 @@ import { Hand, OnePairPokerHand, Pair, + PokerHandCollection, Rank, Suit, ThreeCardPokerHand, @@ -265,6 +266,23 @@ describe('PokerHand', () => { expect(onePair.toString()).toContain('OnePair'); }); }); + + describe('compareWithOnePair()', () => { + const onePairRank3 = new OnePairPokerHand( + new Pair(diamond3, club3) + ); + const onePairRank1 = new OnePairPokerHand( + new Pair(diamond1, club1) + ); + + it('役の強い順に並ぶこと', () => { + expect( + [onePairRank3, onePairRank1].sort((a, b) => + a.compareWithOnePair(b) + ) + ).toEqual([onePairRank1, onePairRank3]); + }); + }); }); describe('TwoPairPokerHand', () => { From b10072cee574ba673fd3c8fbe00d0eb004eaa880 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sat, 10 Apr 2021 21:34:28 +0900 Subject: [PATCH 28/63] =?UTF-8?q?TwoPair=20=E3=81=AE=E5=BD=B9=E5=90=8C?= =?UTF-8?q?=E5=A3=AB=E3=81=AE=E5=BC=B7=E3=81=95=E6=AF=94=E8=BC=83=E3=82=92?= =?UTF-8?q?=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/index.ts | 31 +++++++++++++++++++++++++++---- poker/latest.test.ts | 20 ++++++++++++++++++++ 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/poker/index.ts b/poker/index.ts index 5bccb1f..c16f0f0 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -186,6 +186,7 @@ class Pair { } compareByStrength(other: Pair): number { + // TODO: 相手のPairとランクが同じ場合には、スートで比較する return this.rank.compareByStrength(other.rank); } } @@ -243,13 +244,35 @@ class TwoPairPokerHand implements IPokerHand { throw new Error(`Invalid pairs: pairA=${pairA}, pairB=${pairB}`); } - this.pairs = [pairA, pairB]; + this.pairs = + pairA.compareByStrength(pairB) < 0 + ? [pairA, pairB] + : [pairB, pairA]; } toString(): string { - return `TwoPair[${this.pairs - .map((pair) => pair.toString()) - .join(', ')}]`; + const pairs = this.pairs.map((pair) => pair.toString()); + return `TwoPair[${pairs.join(', ')}]`; + } + + strongerPair(): Pair { + return this.pairs[0]; + } + + weakPair(): Pair { + return this.pairs[1]; + } + + compareWithTwoPair(other: TwoPairPokerHand): number { + const strongerPairCompare = this.strongerPair().compareByStrength( + other.strongerPair() + ); + + if (strongerPairCompare == 0) { + return this.weakPair().compareByStrength(other.weakPair()); + } else { + return strongerPairCompare; + } } } diff --git a/poker/latest.test.ts b/poker/latest.test.ts index 8d83a60..a4b40a6 100644 --- a/poker/latest.test.ts +++ b/poker/latest.test.ts @@ -304,6 +304,26 @@ describe('PokerHand', () => { }).toThrow('Invalid pairs'); }); }); + + describe('compareWithTwoPair()', () => { + const diamond11 = new Card(Suit.Diamond, new Rank(11)); + const club11 = new Card(Suit.Club, new Rank(11)); + + const twoPairA = new TwoPairPokerHand( + new Pair(diamond3, club3), + new Pair(diamond11, club11) + ); + const twoPairB = new TwoPairPokerHand( + new Pair(diamond3, club3), + new Pair(diamond1, club1) + ); + + it('役の強い順に並ぶこと', () => { + expect( + [twoPairA, twoPairB].sort((a, b) => a.compareWithTwoPair(b)) + ).toEqual([twoPairB, twoPairA]); + }); + }); }); describe('ThreeCardPokerHand', () => { From 590efc91158ec80b0cd66cbd1c97b96bb4cc454a Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sat, 10 Apr 2021 21:37:43 +0900 Subject: [PATCH 29/63] =?UTF-8?q?ThreeCard=E3=81=AE=E5=BD=B9=E5=90=8C?= =?UTF-8?q?=E5=A3=AB=E3=81=AE=E6=AF=94=E8=BC=83=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/index.ts | 9 +++++++++ poker/latest.test.ts | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/poker/index.ts b/poker/index.ts index c16f0f0..357683a 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -213,6 +213,11 @@ class Triple { toString(): string { return `Triple(${this.rank}, ${this.suits.join(', ')})`; } + + compareByStrength(other: Triple): number { + // TODO: 相手のPairとランクが同じ場合には、スートで比較する + return this.rank.compareByStrength(other.rank); + } } export { Pair, Triple }; @@ -286,6 +291,10 @@ class ThreeCardPokerHand implements IPokerHand { toString(): string { return `ThreeCard[${this.triple.toString()}]`; } + + compareWithThreeCard(other: ThreeCardPokerHand): number { + return this.triple.compareByStrength(other.triple); + } } class FullHousePokerHand implements IPokerHand { diff --git a/poker/latest.test.ts b/poker/latest.test.ts index a4b40a6..97c9915 100644 --- a/poker/latest.test.ts +++ b/poker/latest.test.ts @@ -336,6 +336,24 @@ describe('PokerHand', () => { expect(threeCard.toString()).toContain('ThreeCard'); }); }); + + describe('compareWithThreeCard', () => { + const spade1 = new Card(Suit.Spade, new Rank(1)); + const threeCardA = new ThreeCardPokerHand( + new Triple(diamond3, club3, spade3) + ); + const threeCardB = new ThreeCardPokerHand( + new Triple(diamond1, club1, spade1) + ); + + it('役の強い順に並ぶこと', () => { + expect( + [threeCardA, threeCardB].sort((a, b) => + a.compareWithThreeCard(b) + ) + ).toEqual([threeCardB, threeCardA]); + }); + }); }); describe('FullHousePokerHand', () => { From c4e577d6b0d0aab0cca7bf4f93bfa567ba81e604 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sat, 10 Apr 2021 21:44:30 +0900 Subject: [PATCH 30/63] =?UTF-8?q?FullHouse=E3=81=AE=E5=BD=B9=E5=90=8C?= =?UTF-8?q?=E5=A3=AB=E3=81=AE=E6=AF=94=E8=BC=83=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/index.ts | 4 ++++ poker/latest.test.ts | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/poker/index.ts b/poker/index.ts index 357683a..d6c163e 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -313,6 +313,10 @@ class FullHousePokerHand implements IPokerHand { toString(): string { return `FullHouse[${this.pair.toString()}, ${this.triple.toString()}]`; } + + compareWithFullHouse(other: FullHousePokerHand): number { + return this.triple.compareByStrength(other.triple); + } } class PokerHandCollection { diff --git a/poker/latest.test.ts b/poker/latest.test.ts index 97c9915..7a6465a 100644 --- a/poker/latest.test.ts +++ b/poker/latest.test.ts @@ -376,5 +376,30 @@ describe('PokerHand', () => { }).toThrow('Invalid pair and triple'); }); }); + + describe('compareWithFullHouse', () => { + const diamond5 = new Card(Suit.Diamond, new Rank(5)); + const club5 = new Card(Suit.Club, new Rank(5)); + const spade5 = new Card(Suit.Spade, new Rank(5)); + const diamond4 = new Card(Suit.Diamond, new Rank(4)); + const club4 = new Card(Suit.Club, new Rank(4)); + + const fullHouseA = new FullHousePokerHand( + new Pair(diamond1, club1), + new Triple(diamond3, club3, spade3) + ); + const fullHouseB = new FullHousePokerHand( + new Pair(diamond4, club4), + new Triple(diamond5, club5, spade5) + ); + + it('役の強い順に並ぶこと', () => { + expect( + [fullHouseA, fullHouseB].sort((a, b) => + a.compareWithFullHouse(b) + ) + ).toEqual([fullHouseB, fullHouseA]); + }); + }); }); }); From 9667082c284ec98b9a9ce8d869fa393b31ff66ad Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sat, 10 Apr 2021 22:08:17 +0900 Subject: [PATCH 31/63] =?UTF-8?q?IPokerHand=20=E3=81=AB=20name=20=E3=83=97?= =?UTF-8?q?=E3=83=AD=E3=83=91=E3=83=86=E3=82=A3=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/index.ts | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/poker/index.ts b/poker/index.ts index d6c163e..8634e2e 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -222,10 +222,42 @@ class Triple { export { Pair, Triple }; +class PokerHandName { + private readonly value: string; + private readonly pokerHandOrder = [ + 'FullHousePokerHand', + 'ThreeCardPokerHand', + 'TwoPairPokerHand', + 'OnePairPokerHand', + ]; + + private constructor(value: string) { + this.value = value; + } + + public static OnePairPokerHand = new PokerHandName('OnePairPokerHand'); + public static TwoPairPokerHand = new PokerHandName('TwoPairPokerHand'); + public static ThreeCardPokerHand = new PokerHandName('ThreeCardPokerHand'); + public static FullHousePokerHand = new PokerHandName('FullHousePokerHand'); + + compareByStrength(other: PokerHandName): number { + const myOrder = this.pokerHandOrder.indexOf(this.value); + const otherOrder = this.pokerHandOrder.indexOf(other.value); + return myOrder - otherOrder; + } + + static compareByStrength(a: PokerHandName, b: PokerHandName): number { + return a.compareByStrength(b); + } +} + // eslint-disable-next-line @typescript-eslint/no-empty-interface -interface IPokerHand {} +interface IPokerHand { + name: PokerHandName; +} class OnePairPokerHand implements IPokerHand { + public readonly name = PokerHandName.OnePairPokerHand; private readonly pair: Pair; constructor(pair: Pair) { @@ -242,6 +274,7 @@ class OnePairPokerHand implements IPokerHand { } class TwoPairPokerHand implements IPokerHand { + public readonly name = PokerHandName.TwoPairPokerHand; private readonly pairs: [Pair, Pair]; constructor(pairA: Pair, pairB: Pair) { @@ -282,6 +315,7 @@ class TwoPairPokerHand implements IPokerHand { } class ThreeCardPokerHand implements IPokerHand { + public readonly name = PokerHandName.ThreeCardPokerHand; private readonly triple: Triple; constructor(triple: Triple) { @@ -298,6 +332,7 @@ class ThreeCardPokerHand implements IPokerHand { } class FullHousePokerHand implements IPokerHand { + public readonly name = PokerHandName.FullHousePokerHand; private readonly pair: Pair; private readonly triple: Triple; From d29ba273bcda852739496fc5678e7ff828459c53 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sat, 10 Apr 2021 22:15:49 +0900 Subject: [PATCH 32/63] =?UTF-8?q?PokerHandCollection=20=E3=82=92=E5=AE=9F?= =?UTF-8?q?=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/index.ts | 45 +++++++++++++++++++++++++++++++++++++++++++- poker/latest.test.ts | 34 +++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/poker/index.ts b/poker/index.ts index 8634e2e..85ef4f8 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -254,6 +254,7 @@ class PokerHandName { // eslint-disable-next-line @typescript-eslint/no-empty-interface interface IPokerHand { name: PokerHandName; + compareByStrength(other: IPokerHand): number; } class OnePairPokerHand implements IPokerHand { @@ -268,6 +269,14 @@ class OnePairPokerHand implements IPokerHand { return `OnePair[${this.pair.toString()}]`; } + compareByStrength(other: IPokerHand): number { + if (other instanceof OnePairPokerHand) { + return this.compareWithOnePair(other); + } + + return this.name.compareByStrength(other.name); + } + compareWithOnePair(other: OnePairPokerHand): number { return this.pair.compareByStrength(other.pair); } @@ -301,6 +310,14 @@ class TwoPairPokerHand implements IPokerHand { return this.pairs[1]; } + compareByStrength(other: IPokerHand): number { + if (other instanceof TwoPairPokerHand) { + return this.compareWithTwoPair(other); + } + + return this.name.compareByStrength(other.name); + } + compareWithTwoPair(other: TwoPairPokerHand): number { const strongerPairCompare = this.strongerPair().compareByStrength( other.strongerPair() @@ -326,6 +343,14 @@ class ThreeCardPokerHand implements IPokerHand { return `ThreeCard[${this.triple.toString()}]`; } + compareByStrength(other: IPokerHand): number { + if (other instanceof ThreeCardPokerHand) { + return this.compareWithThreeCard(other); + } + + return this.name.compareByStrength(other.name); + } + compareWithThreeCard(other: ThreeCardPokerHand): number { return this.triple.compareByStrength(other.triple); } @@ -349,6 +374,14 @@ class FullHousePokerHand implements IPokerHand { return `FullHouse[${this.pair.toString()}, ${this.triple.toString()}]`; } + compareByStrength(other: IPokerHand): number { + if (other instanceof FullHousePokerHand) { + return this.compareWithFullHouse(other); + } + + return this.name.compareByStrength(other.name); + } + compareWithFullHouse(other: FullHousePokerHand): number { return this.triple.compareByStrength(other.triple); } @@ -358,7 +391,9 @@ class PokerHandCollection { private readonly pokerHands: IPokerHand[]; constructor(pokerHands: IPokerHand[]) { - this.pokerHands = pokerHands; + this.pokerHands = pokerHands.sort( + PokerHandCollection.compareByStrength + ); } toString(): string { @@ -367,6 +402,14 @@ class PokerHandCollection { ); return `PokerHandCollection(${pokerHands.join(', ')})`; } + + strongestPokerHand(): IPokerHand { + return this.pokerHands[0]; + } + + static compareByStrength(a: IPokerHand, b: IPokerHand): number { + return a.compareByStrength(b); + } } export { diff --git a/poker/latest.test.ts b/poker/latest.test.ts index 7a6465a..d1abb7d 100644 --- a/poker/latest.test.ts +++ b/poker/latest.test.ts @@ -403,3 +403,37 @@ describe('PokerHand', () => { }); }); }); + +describe('PokerHandCollection', () => { + const diamond3 = new Card(Suit.Diamond, new Rank(3)); + const club3 = new Card(Suit.Club, new Rank(3)); + const spade3 = new Card(Suit.Spade, new Rank(3)); + const diamond1 = new Card(Suit.Diamond, new Rank(1)); + const club1 = new Card(Suit.Club, new Rank(1)); + + const onePairRank3 = new OnePairPokerHand(new Pair(diamond3, club3)); + const onePairRank1 = new OnePairPokerHand(new Pair(diamond1, club1)); + const twoPair = new TwoPairPokerHand( + new Pair(diamond3, club3), + new Pair(diamond1, club1) + ); + const threeCard = new ThreeCardPokerHand( + new Triple(diamond3, club3, spade3) + ); + const fullHouse = new FullHousePokerHand( + new Pair(diamond1, club1), + new Triple(diamond3, club3, spade3) + ); + + const pokerHands = new PokerHandCollection([ + onePairRank1, + onePairRank3, + twoPair, + threeCard, + fullHouse, + ]); + + it('strongestPokerHand()', () => { + expect(pokerHands.strongestPokerHand()).toEqual(fullHouse); + }); +}); From 2d5d9b5d5dfd19f08721a2a20963cfc74a8cc13d Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sat, 10 Apr 2021 22:30:49 +0900 Subject: [PATCH 33/63] =?UTF-8?q?Hand=E3=81=8CCard=E3=81=AE=E9=85=8D?= =?UTF-8?q?=E5=88=97=E3=81=A7=E3=81=AF=E3=81=AA=E3=81=8FCardCollection?= =?UTF-8?q?=E3=82=92=E4=BF=9D=E6=8C=81=E3=81=99=E3=82=8B=E3=82=88=E3=81=86?= =?UTF-8?q?=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/chapter1.test.ts | 4 +++- poker/index.ts | 30 +++++++++++++++++++++++++----- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/poker/chapter1.test.ts b/poker/chapter1.test.ts index 9781b66..cc471bc 100644 --- a/poker/chapter1.test.ts +++ b/poker/chapter1.test.ts @@ -31,6 +31,8 @@ describe('Chapter1: ポーカー', () => { new Card(Suit.Diamond, new Rank(1)), ]); - expect(`${hand}`).toEqual('Hand([♦3], [♣3], [♠J], [♥4], [♦A])'); + expect(`${hand}`).toEqual( + 'Hand(CardCollection([♦3], [♣3], [♠J], [♥4], [♦A]))' + ); }); }); diff --git a/poker/index.ts b/poker/index.ts index 85ef4f8..c05ca2e 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -1,5 +1,5 @@ class Hand { - public readonly cards: Card[]; + public readonly cards: CardCollection; constructor(cards: Card[]) { if (cards.length != 5) { @@ -7,23 +7,43 @@ class Hand { `Invalid the number of cards: expected 5 cards, but got ${cards.length} cards` ); } - this.cards = cards; + this.cards = new CardCollection(cards); } toString(): string { - const cards = this.cards.map((card) => `${card}`); - return `Hand(${cards.join(', ')})`; + return `Hand(${this.cards.toString()})`; } contain(other: Card): boolean { - return !!this.cards.find((card) => card.isEqual(other)); + return this.cards.contain(other); } isEqual(other: Hand): boolean { + return this.cards.isEqual(other.cards); + } +} + +class CardCollection { + private readonly cards: Card[]; + + constructor(cards: Card[] = []) { + this.cards = Array.from(cards); + } + + contain(other: Card): boolean { + return !!this.cards.find((card) => card.isEqual(other)); + } + + isEqual(other: CardCollection): boolean { return this.cards.every((card) => { return other.contain(card); }); } + + toString(): string { + const cards = this.cards.map((card) => `${card}`); + return `CardCollection(${cards.join(', ')})`; + } } class Card { From ba12b4357fb25765dd83772c7d902b789024a9ba Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sun, 11 Apr 2021 00:27:23 +0900 Subject: [PATCH 34/63] =?UTF-8?q?PokerHandCollectionFactory=E3=82=92?= =?UTF-8?q?=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/index.ts | 144 ++++++++++++++++++++++++++++++++++++++++++- poker/latest.test.ts | 21 +++++++ 2 files changed, 162 insertions(+), 3 deletions(-) diff --git a/poker/index.ts b/poker/index.ts index c05ca2e..f7d23c3 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -44,6 +44,42 @@ class CardCollection { const cards = this.cards.map((card) => `${card}`); return `CardCollection(${cards.join(', ')})`; } + + combinationOfTwoCards(): [Card, Card][] { + const combinations: [Card, Card][] = []; + + this.cards.forEach((cardA, i) => { + this.cards.forEach((cardB, j) => { + if (j > i) { + combinations.push([cardA, cardB]); + } + }); + }); + + return combinations; + } + + all(): Card[] { + return Array.from(this.cards); + } + + filterByRank(rank: Rank): CardCollection { + return new CardCollection( + this.cards.filter((card) => card.rank.isEqual(rank)) + ); + } + + count(): number { + return this.cards.length; + } + + present(): boolean { + return this.cards.length > 0; + } + + ranks(): Rank[] { + return Rank.all().filter((rank) => this.filterByRank(rank).present()); + } } class Card { @@ -135,6 +171,24 @@ class Rank { static compareByStrength(a: Rank, b: Rank): number { return a.compareByStrength(b); } + + static all(): Rank[] { + return [ + new Rank(1), + new Rank(2), + new Rank(3), + new Rank(4), + new Rank(5), + new Rank(6), + new Rank(7), + new Rank(8), + new Rank(9), + new Rank(10), + new Rank(11), + new Rank(12), + new Rank(13), + ]; + } } class Suit { @@ -244,7 +298,7 @@ export { Pair, Triple }; class PokerHandName { private readonly value: string; - private readonly pokerHandOrder = [ + private static readonly pokerHandOrder = [ 'FullHousePokerHand', 'ThreeCardPokerHand', 'TwoPairPokerHand', @@ -261,8 +315,8 @@ class PokerHandName { public static FullHousePokerHand = new PokerHandName('FullHousePokerHand'); compareByStrength(other: PokerHandName): number { - const myOrder = this.pokerHandOrder.indexOf(this.value); - const otherOrder = this.pokerHandOrder.indexOf(other.value); + const myOrder = PokerHandName.pokerHandOrder.indexOf(this.value); + const otherOrder = PokerHandName.pokerHandOrder.indexOf(other.value); return myOrder - otherOrder; } @@ -432,6 +486,89 @@ class PokerHandCollection { } } +interface IPokerHandFactory { + buildCandidates(hand: Hand): IPokerHand[]; +} + +class OnePairPokerHandFactory implements IPokerHandFactory { + buildCandidates(hand: Hand): OnePairPokerHand[] { + const pokerHands: OnePairPokerHand[] = []; + + hand.cards.combinationOfTwoCards().forEach(([cardA, cardB]) => { + if (cardA.isSameRank(cardB)) { + const pair = new Pair(cardA, cardB); + pokerHands.push(new OnePairPokerHand(pair)); + } + }); + + return pokerHands; + } +} + +class TwoPairPokerHandFactory implements IPokerHandFactory { + buildCandidates(hand: Hand): TwoPairPokerHand[] { + // TODO: hand の持つ cards の任意の 4 枚を取り出して、その中に 2 つの2枚組(ペア) を取り出す + return []; + } +} + +class ThreeCardPokerHandFactory implements IPokerHandFactory { + buildCandidates(hand: Hand): ThreeCardPokerHand[] { + // TODO: hand の持つ cards の任意の 3枚を取り出して、それらの順位(Rank)が全て同じであれば ThreeCardPokerHand を作成して返す + return []; + } +} + +class FullHousePokerHandFactory implements IPokerHandFactory { + buildCandidates(hand: Hand): FullHousePokerHand[] { + const ranks = hand.cards.ranks(); + + // FullHouse を構成するのは Rank の種類が 2種類の場合 + if (ranks.length != 2) { + return []; + } + + const [rankA, rankB] = ranks; + const cardsA = hand.cards.filterByRank(rankA); + const cardsB = hand.cards.filterByRank(rankB); + + if (cardsA.count() == 2) { + return [this.buildFullHouse(cardsA.all(), cardsB.all())]; + } else { + return [this.buildFullHouse(cardsB.all(), cardsA.all())]; + } + } + + private buildFullHouse( + pairCards: Card[], + threeCards: Card[] + ): FullHousePokerHand { + const pair = new Pair(pairCards[0], pairCards[1]); + const triple = new Triple(threeCards[0], threeCards[1], threeCards[2]); + return new FullHousePokerHand(pair, triple); + } +} + +class PokerHandCollectionFactory { + private readonly factories: IPokerHandFactory[] = [ + new OnePairPokerHandFactory(), + new TwoPairPokerHandFactory(), + new ThreeCardPokerHandFactory(), + new FullHousePokerHandFactory(), + ]; + + buildCandidatePokerHands(hand: Hand): PokerHandCollection { + const pokerHands: IPokerHand[] = []; + + this.factories.forEach((factory) => { + const candidates = factory.buildCandidates(hand); + pokerHands.push(...candidates); + }); + + return new PokerHandCollection(pokerHands); + } +} + export { IPokerHand, OnePairPokerHand, @@ -439,4 +576,5 @@ export { ThreeCardPokerHand, FullHousePokerHand, PokerHandCollection, + PokerHandCollectionFactory, }; diff --git a/poker/latest.test.ts b/poker/latest.test.ts index d1abb7d..9be823d 100644 --- a/poker/latest.test.ts +++ b/poker/latest.test.ts @@ -5,6 +5,7 @@ import { OnePairPokerHand, Pair, PokerHandCollection, + PokerHandCollectionFactory, Rank, Suit, ThreeCardPokerHand, @@ -437,3 +438,23 @@ describe('PokerHandCollection', () => { expect(pokerHands.strongestPokerHand()).toEqual(fullHouse); }); }); + +describe('PokerHandCollectionFactory', () => { + const diamond3 = new Card(Suit.Diamond, new Rank(3)); + const club3 = new Card(Suit.Club, new Rank(3)); + const spade11 = new Card(Suit.Spade, new Rank(11)); + const heart11 = new Card(Suit.Heart, new Rank(11)); + const diamond11 = new Card(Suit.Diamond, new Rank(11)); + + const hand = new Hand([diamond3, club3, spade11, heart11, diamond11]); + + it('buildCandidatePokerHands', () => { + const candidatePokerHands = new PokerHandCollectionFactory().buildCandidatePokerHands( + hand + ); + expect(candidatePokerHands).toBeInstanceOf(PokerHandCollection); + expect(candidatePokerHands.strongestPokerHand()).toBeInstanceOf( + FullHousePokerHand + ); + }); +}); From 66f59855e38c36774083b779406b547730beb72a Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sun, 11 Apr 2021 11:17:23 +0900 Subject: [PATCH 35/63] =?UTF-8?q?Pair=20=E3=81=AE=E5=BC=95=E6=95=B0?= =?UTF-8?q?=E3=81=AE=E9=A0=86=E7=95=AA=E3=81=AB=E3=82=88=E3=82=89=E3=81=9A?= =?UTF-8?q?=E3=80=81=E7=B5=84=E3=81=BF=E5=90=88=E3=82=8F=E3=81=9B=E3=81=AE?= =?UTF-8?q?=E3=81=BF=E3=81=A7=E4=B8=80=E8=87=B4=E5=88=A4=E5=AE=9A=E3=81=99?= =?UTF-8?q?=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/index.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/poker/index.ts b/poker/index.ts index f7d23c3..91925d0 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -237,7 +237,10 @@ class Pair { constructor(cardA: Card, cardB: Card) { if (cardA.isSameRank(cardB)) { - this.cards = [cardA, cardB]; + this.cards = [cardA, cardB].sort(Card.compareByStrength) as [ + Card, + Card + ]; } else { throw new Error(`Invalid cards: ${cardA}, ${cardB}`); } @@ -248,7 +251,7 @@ class Pair { } get suits(): Suit[] { - return this.cards.map((card) => card.suit).sort(Suit.compareByStrength); + return this.cards.map((card) => card.suit); } toString(): string { From 513552e37ecef68c17f81767e8c70e022b97cace Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sun, 11 Apr 2021 11:17:48 +0900 Subject: [PATCH 36/63] =?UTF-8?q?=E5=A4=AA=E9=83=8E=E3=80=81=E6=AC=A1?= =?UTF-8?q?=E9=83=8E=E3=81=AE=E6=89=8B=E6=9C=AD=E3=81=8B=E3=82=89=E3=83=9D?= =?UTF-8?q?=E3=83=BC=E3=82=AB=E3=83=BC=E3=81=AE=E5=BD=B9=E3=82=92=E5=B0=8E?= =?UTF-8?q?=E3=81=8F=E5=87=A6=E7=90=86=E3=82=92=E3=83=86=E3=82=B9=E3=83=88?= =?UTF-8?q?=E3=82=B1=E3=83=BC=E3=82=B9=E3=81=A8=E3=81=97=E3=81=A6=E8=A8=98?= =?UTF-8?q?=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/latest.test.ts | 43 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/poker/latest.test.ts b/poker/latest.test.ts index 9be823d..1b3a4dd 100644 --- a/poker/latest.test.ts +++ b/poker/latest.test.ts @@ -443,18 +443,43 @@ describe('PokerHandCollectionFactory', () => { const diamond3 = new Card(Suit.Diamond, new Rank(3)); const club3 = new Card(Suit.Club, new Rank(3)); const spade11 = new Card(Suit.Spade, new Rank(11)); + const heart4 = new Card(Suit.Heart, new Rank(4)); + const diamond1 = new Card(Suit.Diamond, new Rank(1)); + + const diamond5 = new Card(Suit.Diamond, new Rank(5)); + const club5 = new Card(Suit.Club, new Rank(5)); + const club11 = new Card(Suit.Club, new Rank(11)); const heart11 = new Card(Suit.Heart, new Rank(11)); const diamond11 = new Card(Suit.Diamond, new Rank(11)); - const hand = new Hand([diamond3, club3, spade11, heart11, diamond11]); + const taroHand = new Hand([diamond3, club3, spade11, heart4, diamond1]); + const jiroHand = new Hand([diamond5, club5, club11, heart11, diamond11]); - it('buildCandidatePokerHands', () => { - const candidatePokerHands = new PokerHandCollectionFactory().buildCandidatePokerHands( - hand - ); - expect(candidatePokerHands).toBeInstanceOf(PokerHandCollection); - expect(candidatePokerHands.strongestPokerHand()).toBeInstanceOf( - FullHousePokerHand - ); + describe('buildCandidatePokerHands()', () => { + it('太郎の手札から導かれる一番強い役はワンペアであること', () => { + const candidatePokerHands = new PokerHandCollectionFactory().buildCandidatePokerHands( + taroHand + ); + expect(candidatePokerHands).toBeInstanceOf(PokerHandCollection); + const pokerHand = candidatePokerHands.strongestPokerHand(); + expect(pokerHand).toEqual( + new OnePairPokerHand(new Pair(club3, diamond3)) + ); + }); + + it('次郎の手札から導かれる一番強い役はフルハウスであること', () => { + const candidatePokerHands = new PokerHandCollectionFactory().buildCandidatePokerHands( + jiroHand + ); + expect(candidatePokerHands).toBeInstanceOf(PokerHandCollection); + const pokerHand = candidatePokerHands.strongestPokerHand(); + expect(pokerHand).toBeInstanceOf(FullHousePokerHand); + expect(pokerHand).toEqual( + new FullHousePokerHand( + new Pair(club5, diamond5), + new Triple(club11, heart11, diamond11) + ) + ); + }); }); }); From 5805e93623df76c50f045ed2a2abe43d28a34aac Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sun, 11 Apr 2021 12:07:03 +0900 Subject: [PATCH 37/63] =?UTF-8?q?=E5=A4=AA=E9=83=8E=E3=80=81=E6=AC=A1?= =?UTF-8?q?=E9=83=8E=E3=81=AE=E5=BD=B9=E3=81=AE=E5=80=99=E8=A3=9C=E3=81=AB?= =?UTF-8?q?=E5=AF=BE=E3=81=99=E3=82=8B=E3=83=86=E3=82=B9=E3=83=88=E3=82=B1?= =?UTF-8?q?=E3=83=BC=E3=82=B9=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/index.ts | 4 ++++ poker/latest.test.ts | 45 ++++++++++++++++++++++++++++---------------- 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/poker/index.ts b/poker/index.ts index 91925d0..8b5c17b 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -480,6 +480,10 @@ class PokerHandCollection { return `PokerHandCollection(${pokerHands.join(', ')})`; } + all(): IPokerHand[] { + return Array.from(this.pokerHands) + } + strongestPokerHand(): IPokerHand { return this.pokerHands[0]; } diff --git a/poker/latest.test.ts b/poker/latest.test.ts index 1b3a4dd..cfa8e77 100644 --- a/poker/latest.test.ts +++ b/poker/latest.test.ts @@ -456,30 +456,43 @@ describe('PokerHandCollectionFactory', () => { const jiroHand = new Hand([diamond5, club5, club11, heart11, diamond11]); describe('buildCandidatePokerHands()', () => { - it('太郎の手札から導かれる一番強い役はワンペアであること', () => { + describe('太郎の手札に対して', function () { const candidatePokerHands = new PokerHandCollectionFactory().buildCandidatePokerHands( taroHand ); - expect(candidatePokerHands).toBeInstanceOf(PokerHandCollection); - const pokerHand = candidatePokerHands.strongestPokerHand(); - expect(pokerHand).toEqual( - new OnePairPokerHand(new Pair(club3, diamond3)) - ); + + it('候補となる役は1つだけであること', () => { + expect(candidatePokerHands.all()).toHaveLength(1); + }); + + it('一番強い役はワンペアであること', () => { + const pokerHand = candidatePokerHands.strongestPokerHand(); + expect(pokerHand).toEqual( + new OnePairPokerHand(new Pair(club3, diamond3)) + ); + }); }); - it('次郎の手札から導かれる一番強い役はフルハウスであること', () => { + describe('次郎の手札に対して', () => { const candidatePokerHands = new PokerHandCollectionFactory().buildCandidatePokerHands( jiroHand ); - expect(candidatePokerHands).toBeInstanceOf(PokerHandCollection); - const pokerHand = candidatePokerHands.strongestPokerHand(); - expect(pokerHand).toBeInstanceOf(FullHousePokerHand); - expect(pokerHand).toEqual( - new FullHousePokerHand( - new Pair(club5, diamond5), - new Triple(club11, heart11, diamond11) - ) - ); + + it('候補となる役にワンペアが含まれること', () => { + expect(candidatePokerHands.all()).toContainEqual( + new OnePairPokerHand(new Pair(diamond5, club5)) + ); + }); + + it('一番強い役はフルハウスであること', () => { + const pokerHand = candidatePokerHands.strongestPokerHand(); + expect(pokerHand).toEqual( + new FullHousePokerHand( + new Pair(club5, diamond5), + new Triple(club11, heart11, diamond11) + ) + ); + }); }); }); }); From 3b2497cd9e19134ed708baf96185035aa55133ff Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sun, 11 Apr 2021 12:20:26 +0900 Subject: [PATCH 38/63] =?UTF-8?q?Plate=E3=82=AA=E3=83=96=E3=82=B8=E3=82=A7?= =?UTF-8?q?=E3=82=AF=E3=83=88=E3=81=8C=20DishCollection=20=E3=82=92?= =?UTF-8?q?=E4=BF=9D=E6=8C=81=E3=81=99=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= =?UTF-8?q?=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cafe/chapter1.test.ts | 30 ++++++++++++++++++++++++------ cafe/index.ts | 26 +++++++++++++++++++++----- cafe/latest.test.ts | 26 ++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 11 deletions(-) create mode 100644 cafe/latest.test.ts diff --git a/cafe/chapter1.test.ts b/cafe/chapter1.test.ts index b824a36..e1a3de1 100644 --- a/cafe/chapter1.test.ts +++ b/cafe/chapter1.test.ts @@ -12,18 +12,36 @@ describe('チャプター1', () => { }); it('Dish', () => { - const pasta = new Dish('パスタ&サラダ', new Price(250), new Nutrition(1, 1, 3)); - expect(pasta.toString()).toEqual('Dish(パスタ&サラダ, Nutrition(赤:1, 緑:1, 黄:3), Price(250円))'); + const pasta = new Dish( + 'パスタ&サラダ', + new Price(250), + new Nutrition(1, 1, 3) + ); + expect(pasta.toString()).toEqual( + 'Dish(パスタ&サラダ, Nutrition(赤:1, 緑:1, 黄:3), Price(250円))' + ); }); it('太郎のプレート', () => { - const pasta = new Dish('パスタ&ランチ', new Price(250), new Nutrition(1, 1, 3)); - const bread = new Dish('くるみパン', new Price(150), new Nutrition(0, 0, 3)); - const dessert = new Dish('フルーツ', new Price(150), new Nutrition(0, 1, 0)); + const pasta = new Dish( + 'パスタ&ランチ', + new Price(250), + new Nutrition(1, 1, 3) + ); + const bread = new Dish( + 'くるみパン', + new Price(150), + new Nutrition(0, 0, 3) + ); + const dessert = new Dish( + 'フルーツ', + new Price(150), + new Nutrition(0, 1, 0) + ); const taroPlate = new Plate('太郎のプレート', [pasta, bread, dessert]); expect(taroPlate).toBeInstanceOf(Plate); - expect(taroPlate.dishes).toHaveLength(3); + expect(taroPlate.dishItems()).toHaveLength(3); expect(taroPlate.toString()).toEqual( `Plate 太郎のプレート - Dish(パスタ&ランチ, Nutrition(赤:1, 緑:1, 黄:3), Price(250円)) diff --git a/cafe/index.ts b/cafe/index.ts index a9fd1e6..0a64a10 100644 --- a/cafe/index.ts +++ b/cafe/index.ts @@ -1,11 +1,11 @@ class Plate { public readonly name: string; // 1つの Plate は、複数個の Dish を持つ - public readonly dishes: Dish[]; + private readonly dishes: DishCollection; constructor(name: string, dishes: Dish[]) { this.name = name; - this.dishes = dishes; + this.dishes = new DishCollection(dishes); } toString(): string { @@ -21,7 +21,7 @@ class Plate { findLowestPriceGreenDish(): Dish | undefined { // 緑を含む料理を探す const greenDishes = []; - this.dishes.forEach((dish) => { + this.dishItems().forEach((dish) => { if (dish.nutrition.green > 0) { greenDishes.push(dish); } @@ -34,6 +34,14 @@ class Plate { // 最初の要素を返す return sortedGreenDishes[0]; } + + dishItems(): Dish[] { + return this.dishes.all(); + } + + itemCount(): number { + return this.dishes.count(); + } } class Plate2 { @@ -110,7 +118,15 @@ export { Plate, Dish, Nutrition, Price }; class DishCollection { private readonly dishes: Dish[]; constructor(dishes: Dish[]) { - this.dishes = dishes; + this.dishes = Array.from(dishes); + } + + count(): number { + return this.dishes.length; + } + + all(): Dish[] { + return Array.from(this.dishes); } map(fn: (value: Dish, index: number) => T): T[] { @@ -228,7 +244,7 @@ class NutritionBalanceDiscount implements IDiscount { // 緑を含む料理を探す const greenDishes = [] as Dish[]; - this.plate.dishes.forEach((dish) => { + this.plate.dishItems().forEach((dish) => { if (dish.nutrition.green > 0) { greenDishes.push(dish); } diff --git a/cafe/latest.test.ts b/cafe/latest.test.ts new file mode 100644 index 0000000..91722ae --- /dev/null +++ b/cafe/latest.test.ts @@ -0,0 +1,26 @@ +import { Dish, Nutrition, Plate, Price } from './index'; + +describe('Plate', () => { + describe('太郎のプレート', () => { + const pasta = new Dish( + 'パスタ&ランチ', + new Price(250), + new Nutrition(1, 1, 3) + ); + const bread = new Dish( + 'くるみパン', + new Price(150), + new Nutrition(0, 0, 3) + ); + const dessert = new Dish( + 'フルーツ', + new Price(150), + new Nutrition(0, 1, 0) + ); + const taroPlate = new Plate('太郎のプレート', [pasta, bread, dessert]); + + it('itemCount()', () => { + expect(taroPlate.itemCount()).toEqual(3); + }); + }); +}); From 1cf85247ea3604df93f36d8b62805b0dfba17127 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sun, 11 Apr 2021 18:00:07 +0900 Subject: [PATCH 39/63] =?UTF-8?q?DishCollection,=20Price=20=E3=81=AA?= =?UTF-8?q?=E3=81=A9=E3=82=92=E5=85=85=E5=AE=9F=E3=81=95=E3=81=9B=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cafe/index.ts | 30 ++++++++++++++++++++++++++---- cafe/latest.test.ts | 40 ++++++++++++++++++++++++---------------- 2 files changed, 50 insertions(+), 20 deletions(-) diff --git a/cafe/index.ts b/cafe/index.ts index 0a64a10..a592657 100644 --- a/cafe/index.ts +++ b/cafe/index.ts @@ -84,6 +84,14 @@ class Dish { toString(): string { return `Dish(${this.name}, ${this.nutrition}, ${this.price})`; } + + compareByPrice(other: Dish): number { + return this.price.compare(other.price); + } + + static compareByPrice(a: Dish, b: Dish): number { + return a.compareByPrice(b); + } } class Nutrition { @@ -108,14 +116,24 @@ class Price { this.value = value; } + static ZERO = new Price(0); + toString(): string { return `Price(${this.value}円)`; } + + compare(other: Price): number { + return this.value - other.value; + } + + add(other: Price): Price { + return new Price(this.value + other.value); + } } export { Plate, Dish, Nutrition, Price }; -class DishCollection { +export class DishCollection { private readonly dishes: Dish[]; constructor(dishes: Dish[]) { this.dishes = Array.from(dishes); @@ -145,11 +163,15 @@ class DishCollection { orderByPrice(): DishCollection { return new DishCollection( - Array.from(this.dishes).sort( - (a, b) => a.price.value - b.price.value - ) + Array.from(this.dishes).sort(Dish.compareByPrice) ); } + + totalAmount(): Price { + return this.dishes.reduce((price, dish) => { + return price.add(dish.price); + }, Price.ZERO); + } } class DiscountAmount { diff --git a/cafe/latest.test.ts b/cafe/latest.test.ts index 91722ae..0e08744 100644 --- a/cafe/latest.test.ts +++ b/cafe/latest.test.ts @@ -1,22 +1,30 @@ -import { Dish, Nutrition, Plate, Price } from './index'; +import { Dish, DishCollection, Nutrition, Plate, Price } from './index'; + +const pasta = new Dish('パスタ&ランチ', new Price(250), new Nutrition(1, 1, 3)); +const bread = new Dish('くるみパン', new Price(150), new Nutrition(0, 0, 3)); +const dessert = new Dish('フルーツ', new Price(150), new Nutrition(0, 1, 0)); + +describe('DishCollection', () => { + const dishCollection = new DishCollection([pasta, bread, dessert]); + describe('orderByPrice()', () => { + it('値段の安い順に並ぶこと', () => { + const sorted = new DishCollection([pasta, bread]).orderByPrice(); + expect(sorted).toBeInstanceOf(DishCollection); + expect(sorted.all()).toEqual([bread, pasta]); + }); + }); + + describe('totalAmount()', () => { + it('値段の合計金額', () => { + expect(dishCollection.totalAmount()).toEqual( + new Price(250 + 150 + 150) + ); + }); + }); +}); describe('Plate', () => { describe('太郎のプレート', () => { - const pasta = new Dish( - 'パスタ&ランチ', - new Price(250), - new Nutrition(1, 1, 3) - ); - const bread = new Dish( - 'くるみパン', - new Price(150), - new Nutrition(0, 0, 3) - ); - const dessert = new Dish( - 'フルーツ', - new Price(150), - new Nutrition(0, 1, 0) - ); const taroPlate = new Plate('太郎のプレート', [pasta, bread, dessert]); it('itemCount()', () => { From daa21548f5ca38289e6c0e61f0946053cb8d1104 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sun, 11 Apr 2021 18:42:11 +0900 Subject: [PATCH 40/63] =?UTF-8?q?DiscountAmount=20=E3=81=AE=E3=83=86?= =?UTF-8?q?=E3=82=B9=E3=83=88=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cafe/index.ts | 2 ++ cafe/latest.test.ts | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/cafe/index.ts b/cafe/index.ts index a592657..2740433 100644 --- a/cafe/index.ts +++ b/cafe/index.ts @@ -183,6 +183,8 @@ class DiscountAmount { add(other: DiscountAmount): DiscountAmount { return new DiscountAmount(this.value + other.value); } + + static ZERO = new DiscountAmount(0); } /** diff --git a/cafe/latest.test.ts b/cafe/latest.test.ts index 0e08744..b49ee26 100644 --- a/cafe/latest.test.ts +++ b/cafe/latest.test.ts @@ -1,4 +1,11 @@ -import { Dish, DishCollection, Nutrition, Plate, Price } from './index'; +import { + DiscountAmount, + Dish, + DishCollection, + Nutrition, + Plate, + Price, +} from './index'; const pasta = new Dish('パスタ&ランチ', new Price(250), new Nutrition(1, 1, 3)); const bread = new Dish('くるみパン', new Price(150), new Nutrition(0, 0, 3)); @@ -32,3 +39,11 @@ describe('Plate', () => { }); }); }); + +describe('DiscountAmount', function () { + it('add()', () => { + expect(new DiscountAmount(150).add(new DiscountAmount(30))).toEqual( + new DiscountAmount(180) + ); + }); +}); From 87435dee20c0299e09d4a22b9a8396e00a9b7462 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sun, 11 Apr 2021 19:06:03 +0900 Subject: [PATCH 41/63] =?UTF-8?q?=E3=83=A9=E3=83=B3=E3=83=81=20=E5=89=B2?= =?UTF-8?q?=E5=BC=95=E3=81=AE=E5=AE=9F=E8=A3=85=E3=82=92=E4=B8=80=E6=97=A6?= =?UTF-8?q?=E3=82=B3=E3=83=A1=E3=83=B3=E3=83=88=E3=82=A2=E3=82=A6=E3=83=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cafe/chapter2.test.ts | 24 ++--- cafe/index.ts | 228 +++++++++++++++++++++--------------------- 2 files changed, 121 insertions(+), 131 deletions(-) diff --git a/cafe/chapter2.test.ts b/cafe/chapter2.test.ts index 6b27284..cad84a4 100644 --- a/cafe/chapter2.test.ts +++ b/cafe/chapter2.test.ts @@ -1,14 +1,4 @@ -import { - Discount, - DiscountName, - Dish, - LowCarbonDiscount, - NiceCalorieDiscount, - Nutrition, - NutritionBalanceDiscount, - Plate, - Price, -} from './index'; +import { Discount, DiscountName, Dish, Nutrition, Plate, Price } from './index'; it('Chapter2: カフェ (太郎のプレート)', () => { const pasta = new Dish( @@ -34,14 +24,14 @@ it('Chapter2: カフェ (太郎のプレート)', () => { new Discount(DiscountName.NutritionGoodBalance, taroPlate), ]; - const taroDiscounts_2 = [ - new LowCarbonDiscount(taroPlate), - new NiceCalorieDiscount(taroPlate), - new NutritionBalanceDiscount(taroPlate), - ]; + // const taroDiscounts_2 = [ + // new LowCarbonDiscount(taroPlate), + // new NiceCalorieDiscount(taroPlate), + // new NutritionBalanceDiscount(taroPlate), + // ]; // 太郎のプレートに対する割引の候補の中から、有効なものだけを取り出す - taroDiscounts_2.filter((discount) => discount.available()); + // taroDiscounts_2.filter((discount) => discount.available()); }); it('Chapter2: カフェ (次郎のプレート)', () => { diff --git a/cafe/index.ts b/cafe/index.ts index 2740433..b331951 100644 --- a/cafe/index.ts +++ b/cafe/index.ts @@ -241,122 +241,122 @@ class Discount { } // 割引の種類に応じてクラスを分ける - -interface IDiscount { - available(): boolean; - calcDiscount(): DiscountAmount; -} - -class NutritionBalanceDiscount implements IDiscount { - private readonly plate: Plate; - - public constructor(plate: Plate) { - this.plate = plate; - } - - // 条件: 赤と緑の合計が 3点以上のとき - public available(): boolean { - return false; // ここは一旦モックで実装 - } - - // 割引: 緑を含む料理が 20% 割引(一番安いもの1点) - public calcDiscount(): DiscountAmount { - if (!this.available()) { - // 適用条件を満たさないときは 0円割引として返す - return new DiscountAmount(0); - } - - // 緑を含む料理を探す - const greenDishes = [] as Dish[]; - this.plate.dishItems().forEach((dish) => { - if (dish.nutrition.green > 0) { - greenDishes.push(dish); - } - }); - - // 値段の安い順に並び替えて - const sortedGreenDishes = greenDishes.sort( - (a, b) => a.price.value - b.price.value - ); - // 先頭の要素(=一番安い料理)を取り出す - const lowestPriceDish = sortedGreenDishes[0]; - if (lowestPriceDish) { - // その料理の 20% が割引金額 - return new DiscountAmount(lowestPriceDish.price.value * 0.2); - } else { - return new DiscountAmount(0); - } - } -} - -class NutritionBalanceDiscount2 implements IDiscount { - private readonly plate: Plate; - public constructor(plate: Plate) { - this.plate = plate; - } - - // 条件: 赤と緑の合計が 3点以上のとき - public available(): boolean { - return false; // TODO: 実装する - } - - // 割引: 緑を含む料理が 20% 割引(一番安いもの1点) - public calcDiscount(): DiscountAmount { - if (!this.available()) { - return new DiscountAmount(0); - } - - const targetDish = this.plate.findLowestPriceGreenDish(); - if (targetDish) { - return new DiscountAmount(targetDish.price.value * 0.2); - } else { - return new DiscountAmount(0); - } - } -} - -class NiceCalorieDiscount implements IDiscount { - private readonly plate: Plate; - public constructor(plate: Plate) { - this.plate = plate; - } - // 条件: 三色の合計点数が 6点〜8点 の間 - public available(): boolean { - return false; // ここは一旦モックで実装 - } - // 割引: 50円引 - public calcDiscount(): DiscountAmount { - if (this.available()) { - return new DiscountAmount(50); - } - return new DiscountAmount(0); - } -} - -class LowCarbonDiscount implements IDiscount { - private readonly plate: Plate; - public constructor(plate: Plate) { - this.plate = plate; - } - // 条件: 黄の合計が 5点以下 - public available(): boolean { - return false; // ここは一旦モックで実装 - } - // 割引: 30円引 - public calcDiscount(): DiscountAmount { - if (this.available()) { - return new DiscountAmount(30); - } - return new DiscountAmount(0); - } -} - +// +// interface IDiscount { +// available(): boolean; +// calcDiscount(): DiscountAmount; +// } +// +// class NutritionBalanceDiscount implements IDiscount { +// private readonly plate: Plate; +// +// public constructor(plate: Plate) { +// this.plate = plate; +// } +// +// // 条件: 赤と緑の合計が 3点以上のとき +// public available(): boolean { +// return false; // ここは一旦モックで実装 +// } +// +// // 割引: 緑を含む料理が 20% 割引(一番安いもの1点) +// public calcDiscount(): DiscountAmount { +// if (!this.available()) { +// // 適用条件を満たさないときは 0円割引として返す +// return new DiscountAmount(0); +// } +// +// // 緑を含む料理を探す +// const greenDishes = [] as Dish[]; +// this.plate.dishItems().forEach((dish) => { +// if (dish.nutrition.green > 0) { +// greenDishes.push(dish); +// } +// }); +// +// // 値段の安い順に並び替えて +// const sortedGreenDishes = greenDishes.sort( +// (a, b) => a.price.value - b.price.value +// ); +// // 先頭の要素(=一番安い料理)を取り出す +// const lowestPriceDish = sortedGreenDishes[0]; +// if (lowestPriceDish) { +// // その料理の 20% が割引金額 +// return new DiscountAmount(lowestPriceDish.price.value * 0.2); +// } else { +// return new DiscountAmount(0); +// } +// } +// } +// +// class NutritionBalanceDiscount2 implements IDiscount { +// private readonly plate: Plate; +// public constructor(plate: Plate) { +// this.plate = plate; +// } +// +// // 条件: 赤と緑の合計が 3点以上のとき +// public available(): boolean { +// return false; // TODO: 実装する +// } +// +// // 割引: 緑を含む料理が 20% 割引(一番安いもの1点) +// public calcDiscount(): DiscountAmount { +// if (!this.available()) { +// return new DiscountAmount(0); +// } +// +// const targetDish = this.plate.findLowestPriceGreenDish(); +// if (targetDish) { +// return new DiscountAmount(targetDish.price.value * 0.2); +// } else { +// return new DiscountAmount(0); +// } +// } +// } +// +// class NiceCalorieDiscount implements IDiscount { +// private readonly plate: Plate; +// public constructor(plate: Plate) { +// this.plate = plate; +// } +// // 条件: 三色の合計点数が 6点〜8点 の間 +// public available(): boolean { +// return false; // ここは一旦モックで実装 +// } +// // 割引: 50円引 +// public calcDiscount(): DiscountAmount { +// if (this.available()) { +// return new DiscountAmount(50); +// } +// return new DiscountAmount(0); +// } +// } +// +// class LowCarbonDiscount implements IDiscount { +// private readonly plate: Plate; +// public constructor(plate: Plate) { +// this.plate = plate; +// } +// // 条件: 黄の合計が 5点以下 +// public available(): boolean { +// return false; // ここは一旦モックで実装 +// } +// // 割引: 30円引 +// public calcDiscount(): DiscountAmount { +// if (this.available()) { +// return new DiscountAmount(30); +// } +// return new DiscountAmount(0); +// } +// } +// export { DiscountName, DiscountAmount, Discount, - IDiscount, - LowCarbonDiscount, - NiceCalorieDiscount, - NutritionBalanceDiscount, + // IDiscount, + // LowCarbonDiscount, + // NiceCalorieDiscount, + // NutritionBalanceDiscount, }; From 7547947c403da958da6092e695c5fbaa4a8afdfb Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sun, 11 Apr 2021 19:48:33 +0900 Subject: [PATCH 42/63] =?UTF-8?q?Discount,=20DiscountCollection,=20Factory?= =?UTF-8?q?=20=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cafe/index.ts | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) diff --git a/cafe/index.ts b/cafe/index.ts index b331951..09c5d8f 100644 --- a/cafe/index.ts +++ b/cafe/index.ts @@ -185,6 +185,11 @@ class DiscountAmount { } static ZERO = new DiscountAmount(0); + + static buildFromPrice(price: Price, rate: number): DiscountAmount { + // TODO: 端数処理が必要 + return new DiscountAmount(price.value * rate); + } } /** @@ -240,6 +245,142 @@ class Discount { } } +interface IDiscount { + amount(): DiscountAmount; +} + +interface IDiscountFactory { + discountAvailable(plate: Plate): boolean; + build(plate: Plate): IDiscount; +} + +class NutritionBalanceDiscount implements IDiscount { + private readonly targetDish: Dish; + static DISCOUNT_RATE = 0.2; + + constructor(targetDish: Dish) { + this.targetDish = targetDish; + } + + amount(): DiscountAmount { + return DiscountAmount.buildFromPrice( + this.targetDish.price, + NutritionBalanceDiscount.DISCOUNT_RATE + ); + } +} + +class NutritionBalanceDiscountFactory implements IDiscountFactory { + discountAvailable(plate: Plate): boolean { + // TODO: 赤と緑の合計が 3点以上のときに割引適用 + return false; + } + + build(plate: Plate): NutritionBalanceDiscount { + if (!this.discountAvailable(plate)) { + throw new Error( + `Cloud not build NutritionBalanceDiscount: ${plate}` + ); + } + + // TODO: 割引対象となる料理(緑を含む一番安いもの)を取得する + const targetDish = plate.dishItems()[0]; + return new NutritionBalanceDiscount(targetDish); + } +} + +class NiceCalorieDiscount implements IDiscount { + amount(): DiscountAmount { + return new DiscountAmount(50); + } +} + +class NiceCalorieDiscountFactory implements IDiscountFactory { + discountAvailable(plate: Plate): boolean { + // TODO: 三色の合計点数が 6点〜8点の間のときに割引適用 + return false; + } + + build(plate: Plate): NiceCalorieDiscount { + if (!this.discountAvailable(plate)) { + throw new Error(`Cloud not build NiceCalorieDiscount: ${plate}`); + } + + return new NiceCalorieDiscount(); + } +} + +class LowCarbonDiscount implements IDiscount { + amount(): DiscountAmount { + return new DiscountAmount(30); + } + + // 条件: 黄の合計が 5点以下 + public available(): boolean { + return false; // ここは一旦モックで実装 + } + // 割引: 30円引 + public calcDiscount(): DiscountAmount { + if (this.available()) { + return new DiscountAmount(30); + } + return new DiscountAmount(0); + } +} + +class LowCarbonDiscountFactory implements IDiscountFactory { + discountAvailable(plate: Plate): boolean { + // TODO: 黄色の合計が5点以下のときに割引適用 + return false; + } + + build(plate: Plate): LowCarbonDiscount { + if (!this.discountAvailable(plate)) { + throw new Error(`Cloud not build LowCarbonDiscount: ${plate}`); + } + + return new LowCarbonDiscount(); + } +} + +class DiscountCollection { + private readonly discounts: IDiscount[]; + + constructor(discounts: IDiscount[]) { + this.discounts = Array.from(discounts); + } + + all(): IDiscount[] { + return Array.from(this.discounts); + } + + totalAmount(): DiscountAmount { + return this.discounts.reduce((amount, discount) => { + return amount.add(discount.amount()); + }, DiscountAmount.ZERO); + } +} + +class DiscountCollectionFactory { + private readonly factories: IDiscountFactory[] = [ + new NutritionBalanceDiscountFactory(), + new NiceCalorieDiscountFactory(), + new LowCarbonDiscountFactory(), + ]; + + build(plate: Plate): DiscountCollection { + const discounts: IDiscount[] = []; + + this.factories.forEach((factory) => { + if (factory.discountAvailable(plate)) { + discounts.push(factory.build(plate)); + } + }); + + return new DiscountCollection(discounts); + } +} + // 割引の種類に応じてクラスを分ける // // interface IDiscount { From 51041f06b962f918c6f2f7f4598c28d5481fff5e Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sun, 11 Apr 2021 19:54:49 +0900 Subject: [PATCH 43/63] =?UTF-8?q?DishCollection=20=E3=81=AE=E6=A0=84?= =?UTF-8?q?=E9=A4=8A=E5=90=88=E8=A8=88=E3=82=92=E8=A8=88=E7=AE=97=E3=81=99?= =?UTF-8?q?=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cafe/index.ts | 16 ++++++++++++++++ cafe/latest.test.ts | 6 ++++++ 2 files changed, 22 insertions(+) diff --git a/cafe/index.ts b/cafe/index.ts index 09c5d8f..87d7d6e 100644 --- a/cafe/index.ts +++ b/cafe/index.ts @@ -108,6 +108,16 @@ class Nutrition { toString(): string { return `Nutrition(赤:${this.red}, 緑:${this.green}, 黄:${this.yellow})`; } + + add(other: Nutrition): Nutrition { + return new Nutrition( + this.red + other.red, + this.green + other.green, + this.yellow + other.yellow + ); + } + + static ZERO = new Nutrition(0, 0, 0); } class Price { @@ -172,6 +182,12 @@ export class DishCollection { return price.add(dish.price); }, Price.ZERO); } + + totalNutrition(): Nutrition { + return this.dishes.reduce((nutrition, dish) => { + return nutrition.add(dish.nutrition); + }, Nutrition.ZERO); + } } class DiscountAmount { diff --git a/cafe/latest.test.ts b/cafe/latest.test.ts index b49ee26..7a8ef9f 100644 --- a/cafe/latest.test.ts +++ b/cafe/latest.test.ts @@ -28,6 +28,12 @@ describe('DishCollection', () => { ); }); }); + + it('totalNutrition()', () => { + expect(dishCollection.totalNutrition()).toEqual( + new Nutrition(1, 1 + 1, 3 + 3) + ); + }); }); describe('Plate', () => { From 4af358a5dc6177d970fa2c650195336f73580133 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sun, 11 Apr 2021 19:57:04 +0900 Subject: [PATCH 44/63] =?UTF-8?q?=E6=97=A7=E5=AE=9F=E8=A3=85=E3=82=92?= =?UTF-8?q?=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cafe/index.ts | 111 -------------------------------------------------- 1 file changed, 111 deletions(-) diff --git a/cafe/index.ts b/cafe/index.ts index 87d7d6e..c94c9af 100644 --- a/cafe/index.ts +++ b/cafe/index.ts @@ -397,117 +397,6 @@ class DiscountCollectionFactory { } } -// 割引の種類に応じてクラスを分ける -// -// interface IDiscount { -// available(): boolean; -// calcDiscount(): DiscountAmount; -// } -// -// class NutritionBalanceDiscount implements IDiscount { -// private readonly plate: Plate; -// -// public constructor(plate: Plate) { -// this.plate = plate; -// } -// -// // 条件: 赤と緑の合計が 3点以上のとき -// public available(): boolean { -// return false; // ここは一旦モックで実装 -// } -// -// // 割引: 緑を含む料理が 20% 割引(一番安いもの1点) -// public calcDiscount(): DiscountAmount { -// if (!this.available()) { -// // 適用条件を満たさないときは 0円割引として返す -// return new DiscountAmount(0); -// } -// -// // 緑を含む料理を探す -// const greenDishes = [] as Dish[]; -// this.plate.dishItems().forEach((dish) => { -// if (dish.nutrition.green > 0) { -// greenDishes.push(dish); -// } -// }); -// -// // 値段の安い順に並び替えて -// const sortedGreenDishes = greenDishes.sort( -// (a, b) => a.price.value - b.price.value -// ); -// // 先頭の要素(=一番安い料理)を取り出す -// const lowestPriceDish = sortedGreenDishes[0]; -// if (lowestPriceDish) { -// // その料理の 20% が割引金額 -// return new DiscountAmount(lowestPriceDish.price.value * 0.2); -// } else { -// return new DiscountAmount(0); -// } -// } -// } -// -// class NutritionBalanceDiscount2 implements IDiscount { -// private readonly plate: Plate; -// public constructor(plate: Plate) { -// this.plate = plate; -// } -// -// // 条件: 赤と緑の合計が 3点以上のとき -// public available(): boolean { -// return false; // TODO: 実装する -// } -// -// // 割引: 緑を含む料理が 20% 割引(一番安いもの1点) -// public calcDiscount(): DiscountAmount { -// if (!this.available()) { -// return new DiscountAmount(0); -// } -// -// const targetDish = this.plate.findLowestPriceGreenDish(); -// if (targetDish) { -// return new DiscountAmount(targetDish.price.value * 0.2); -// } else { -// return new DiscountAmount(0); -// } -// } -// } -// -// class NiceCalorieDiscount implements IDiscount { -// private readonly plate: Plate; -// public constructor(plate: Plate) { -// this.plate = plate; -// } -// // 条件: 三色の合計点数が 6点〜8点 の間 -// public available(): boolean { -// return false; // ここは一旦モックで実装 -// } -// // 割引: 50円引 -// public calcDiscount(): DiscountAmount { -// if (this.available()) { -// return new DiscountAmount(50); -// } -// return new DiscountAmount(0); -// } -// } -// -// class LowCarbonDiscount implements IDiscount { -// private readonly plate: Plate; -// public constructor(plate: Plate) { -// this.plate = plate; -// } -// // 条件: 黄の合計が 5点以下 -// public available(): boolean { -// return false; // ここは一旦モックで実装 -// } -// // 割引: 30円引 -// public calcDiscount(): DiscountAmount { -// if (this.available()) { -// return new DiscountAmount(30); -// } -// return new DiscountAmount(0); -// } -// } -// export { DiscountName, DiscountAmount, From f1343f550e4fff4bcff6215486629fe9f0a3b580 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sun, 11 Apr 2021 20:07:48 +0900 Subject: [PATCH 45/63] =?UTF-8?q?=E5=A4=AA=E9=83=8E=E3=81=A8=E6=AC=A1?= =?UTF-8?q?=E9=83=8E=E3=81=AE=E3=83=A9=E3=83=B3=E3=83=81=E3=83=97=E3=83=AC?= =?UTF-8?q?=E3=83=BC=E3=83=88=E3=81=8B=E3=82=89=E3=80=81=E5=89=B2=E5=BC=95?= =?UTF-8?q?=E3=82=B3=E3=83=AC=E3=82=AF=E3=82=B7=E3=83=A7=E3=83=B3=E3=82=92?= =?UTF-8?q?Factory=E3=81=A7=E4=BD=9C=E6=88=90=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cafe/index.ts | 50 ++++++++++++++++++++++----------------------- cafe/latest.test.ts | 38 ++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 26 deletions(-) diff --git a/cafe/index.ts b/cafe/index.ts index c94c9af..7ed74ce 100644 --- a/cafe/index.ts +++ b/cafe/index.ts @@ -14,8 +14,11 @@ class Plate { } totalAmount(): Price { - // TODO: Dish の値段を合計したものを返す - return new Price(0); + return this.dishes.totalAmount(); + } + + totalNutrition(): Nutrition { + return this.dishes.totalNutrition(); } findLowestPriceGreenDish(): Dish | undefined { @@ -28,9 +31,7 @@ class Plate { }); // 値段の安い順に並び替えて - const sortedGreenDishes = greenDishes.sort( - (a, b) => a.price.value - b.price.value - ); + const sortedGreenDishes = greenDishes.sort(Dish.compareByPrice); // 最初の要素を返す return sortedGreenDishes[0]; } @@ -117,6 +118,10 @@ class Nutrition { ); } + total(): number { + return this.red + this.green + this.yellow; + } + static ZERO = new Nutrition(0, 0, 0); } @@ -289,7 +294,8 @@ class NutritionBalanceDiscount implements IDiscount { class NutritionBalanceDiscountFactory implements IDiscountFactory { discountAvailable(plate: Plate): boolean { // TODO: 赤と緑の合計が 3点以上のときに割引適用 - return false; + const nutrition = plate.totalNutrition(); + return nutrition.red + nutrition.green >= 3; } build(plate: Plate): NutritionBalanceDiscount { @@ -300,7 +306,7 @@ class NutritionBalanceDiscountFactory implements IDiscountFactory { } // TODO: 割引対象となる料理(緑を含む一番安いもの)を取得する - const targetDish = plate.dishItems()[0]; + const targetDish = plate.findLowestPriceGreenDish(); return new NutritionBalanceDiscount(targetDish); } } @@ -314,7 +320,8 @@ class NiceCalorieDiscount implements IDiscount { class NiceCalorieDiscountFactory implements IDiscountFactory { discountAvailable(plate: Plate): boolean { // TODO: 三色の合計点数が 6点〜8点の間のときに割引適用 - return false; + const score = plate.totalNutrition().total(); + return 6 <= score && score <= 8; } build(plate: Plate): NiceCalorieDiscount { @@ -328,26 +335,15 @@ class NiceCalorieDiscountFactory implements IDiscountFactory { class LowCarbonDiscount implements IDiscount { amount(): DiscountAmount { - return new DiscountAmount(30); - } - - // 条件: 黄の合計が 5点以下 - public available(): boolean { - return false; // ここは一旦モックで実装 - } - // 割引: 30円引 - public calcDiscount(): DiscountAmount { - if (this.available()) { - return new DiscountAmount(30); - } - return new DiscountAmount(0); + return new DiscountAmount(20); } } class LowCarbonDiscountFactory implements IDiscountFactory { discountAvailable(plate: Plate): boolean { // TODO: 黄色の合計が5点以下のときに割引適用 - return false; + const nutrition = plate.totalNutrition(); + return nutrition.yellow <= 5; } build(plate: Plate): LowCarbonDiscount { @@ -401,8 +397,10 @@ export { DiscountName, DiscountAmount, Discount, - // IDiscount, - // LowCarbonDiscount, - // NiceCalorieDiscount, - // NutritionBalanceDiscount, + IDiscount, + LowCarbonDiscount, + NiceCalorieDiscount, + NutritionBalanceDiscount, + DiscountCollection, + DiscountCollectionFactory, }; diff --git a/cafe/latest.test.ts b/cafe/latest.test.ts index 7a8ef9f..bd49ace 100644 --- a/cafe/latest.test.ts +++ b/cafe/latest.test.ts @@ -1,5 +1,6 @@ import { DiscountAmount, + DiscountCollectionFactory, Dish, DishCollection, Nutrition, @@ -9,6 +10,11 @@ import { const pasta = new Dish('パスタ&ランチ', new Price(250), new Nutrition(1, 1, 3)); const bread = new Dish('くるみパン', new Price(150), new Nutrition(0, 0, 3)); +const lowCarbonBread = new Dish( + '低糖質パン', + new Price(150), + new Nutrition(0, 0, 1) +); const dessert = new Dish('フルーツ', new Price(150), new Nutrition(0, 1, 0)); describe('DishCollection', () => { @@ -53,3 +59,35 @@ describe('DiscountAmount', function () { ); }); }); + +describe('DiscountCollectionFactory', () => { + describe('太郎のプレート', () => { + const plate = new Plate('太郎のプレート', [pasta, bread, dessert]); + const discounts = new DiscountCollectionFactory().build(plate); + + it('1つの割引が適用されていること', () => { + expect(discounts.all()).toHaveLength(1); + }); + + it('割引額が30円であること', () => { + expect(discounts.totalAmount()).toEqual(new DiscountAmount(30)); + }); + }); + + describe('次郎のプレート', () => { + const plate = new Plate('次郎のプレート', [ + pasta, + lowCarbonBread, + dessert, + ]); + const discounts = new DiscountCollectionFactory().build(plate); + + it('3つの割引が適用されていること', () => { + expect(discounts.all()).toHaveLength(3); + }); + + it('割引額が100円であること', () => { + expect(discounts.totalAmount()).toEqual(new DiscountAmount(100)); + }); + }); +}); From 44d0ff0f46ff0d6f62b5bd8577fef1f137e1ccfc Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Mon, 12 Apr 2021 10:00:36 +0900 Subject: [PATCH 46/63] =?UTF-8?q?Order=E3=82=AA=E3=83=96=E3=82=B8=E3=82=A7?= =?UTF-8?q?=E3=82=AF=E3=83=88=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cafe/index.ts | 31 +++++++++++++++++++++++++++++++ cafe/latest.test.ts | 31 +++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/cafe/index.ts b/cafe/index.ts index 7ed74ce..8bd79ee 100644 --- a/cafe/index.ts +++ b/cafe/index.ts @@ -36,6 +36,10 @@ class Plate { return sortedGreenDishes[0]; } + dishCollection(): DishCollection { + return this.dishes; + } + dishItems(): Dish[] { return this.dishes.all(); } @@ -211,6 +215,10 @@ class DiscountAmount { // TODO: 端数処理が必要 return new DiscountAmount(price.value * rate); } + + toPrice(): Price { + return new Price(-1 * this.value); + } } /** @@ -393,6 +401,28 @@ class DiscountCollectionFactory { } } +class Order { + private readonly dishes: DishCollection; + private readonly discounts: DiscountCollection; + + constructor(dishes: DishCollection, discounts: DiscountCollection) { + this.dishes = dishes; + this.discounts = discounts; + } + + subtotalAmount(): Price { + return this.dishes.totalAmount(); + } + + discountAmount(): DiscountAmount { + return this.discounts.totalAmount(); + } + + totalAmount(): Price { + return this.subtotalAmount().add(this.discountAmount().toPrice()); + } +} + export { DiscountName, DiscountAmount, @@ -403,4 +433,5 @@ export { NutritionBalanceDiscount, DiscountCollection, DiscountCollectionFactory, + Order, }; diff --git a/cafe/latest.test.ts b/cafe/latest.test.ts index bd49ace..40f6fa2 100644 --- a/cafe/latest.test.ts +++ b/cafe/latest.test.ts @@ -4,6 +4,7 @@ import { Dish, DishCollection, Nutrition, + Order, Plate, Price, } from './index'; @@ -91,3 +92,33 @@ describe('DiscountCollectionFactory', () => { }); }); }); + +describe('Order', () => { + describe('太郎のプレート', () => { + const plate = new Plate('太郎のプレート', [pasta, bread, dessert]); + const discounts = new DiscountCollectionFactory().build(plate); + const order = new Order(plate.dishCollection(), discounts); + + it('小計、割引額、合計額が計算できること', () => { + expect(order.subtotalAmount()).toEqual(new Price(550)); + expect(order.discountAmount()).toEqual(new DiscountAmount(30)); + expect(order.totalAmount()).toEqual(new Price(520)); + }); + }); + + describe('次郎のプレート', () => { + const plate = new Plate('次郎のプレート', [ + pasta, + lowCarbonBread, + dessert, + ]); + const discounts = new DiscountCollectionFactory().build(plate); + const order = new Order(plate.dishCollection(), discounts); + + it('小計、割引額、合計額が計算できること', () => { + expect(order.subtotalAmount()).toEqual(new Price(550)); + expect(order.discountAmount()).toEqual(new DiscountAmount(100)); + expect(order.totalAmount()).toEqual(new Price(450)); + }); + }); +}); From 402afcc09322cdcd0726372176aa6458066c22d5 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Mon, 12 Apr 2021 10:02:20 +0900 Subject: [PATCH 47/63] =?UTF-8?q?=E3=83=A9=E3=83=B3=E3=83=81=E3=83=97?= =?UTF-8?q?=E3=83=AC=E3=83=BC=E3=83=88=E3=81=AE=E3=82=B5=E3=83=B3=E3=83=97?= =?UTF-8?q?=E3=83=AB=E3=81=A7=E6=9C=AA=E4=BD=BF=E7=94=A8=E3=81=AE=E3=82=B5?= =?UTF-8?q?=E3=83=B3=E3=83=97=E3=83=AB=E3=82=AF=E3=83=A9=E3=82=B9=E3=82=92?= =?UTF-8?q?=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cafe/index.ts | 41 +++-------------------------------------- 1 file changed, 3 insertions(+), 38 deletions(-) diff --git a/cafe/index.ts b/cafe/index.ts index 8bd79ee..7d0dfe6 100644 --- a/cafe/index.ts +++ b/cafe/index.ts @@ -22,18 +22,9 @@ class Plate { } findLowestPriceGreenDish(): Dish | undefined { - // 緑を含む料理を探す - const greenDishes = []; - this.dishItems().forEach((dish) => { - if (dish.nutrition.green > 0) { - greenDishes.push(dish); - } - }); - - // 値段の安い順に並び替えて - const sortedGreenDishes = greenDishes.sort(Dish.compareByPrice); - // 最初の要素を返す - return sortedGreenDishes[0]; + // 緑を含む一番安い料理を探す + const greenDishes = this.dishes.greenDishes().orderByPrice(); + return greenDishes.first(); } dishCollection(): DishCollection { @@ -49,32 +40,6 @@ class Plate { } } -class Plate2 { - public readonly name: string; - public readonly dishes: DishCollection; - - constructor(name: string, dishes: Dish[]) { - this.name = name; - this.dishes = new DishCollection(dishes); - } - - toString(): string { - const dishes = this.dishes.map((dish) => ` - ${dish.toString()}`); - return `Plate ${this.name}\n${dishes.join('\n')}`; - } - - totalAmount(): Price { - // TODO: Dish の値段を合計したものを返す - return new Price(0); - } - - findLowestPriceGreenDish(): Dish | undefined { - // 緑を含む料理を探す - const greenDishes = this.dishes.greenDishes().orderByPrice(); - return greenDishes.first(); - } -} - class Dish { public readonly name: string; public readonly price: Price; From a014b67e4488b3612210cf8826f84399a7b9c343 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Mon, 12 Apr 2021 10:21:11 +0900 Subject: [PATCH 48/63] =?UTF-8?q?Plate=E3=81=A8DishCollection=E3=81=AE=20t?= =?UTF-8?q?oString()=20=E3=82=92=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cafe/chapter1.test.ts | 8 +++++--- cafe/index.ts | 12 ++++++------ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/cafe/chapter1.test.ts b/cafe/chapter1.test.ts index e1a3de1..72c8cc3 100644 --- a/cafe/chapter1.test.ts +++ b/cafe/chapter1.test.ts @@ -44,9 +44,11 @@ describe('チャプター1', () => { expect(taroPlate.dishItems()).toHaveLength(3); expect(taroPlate.toString()).toEqual( `Plate 太郎のプレート - - Dish(パスタ&ランチ, Nutrition(赤:1, 緑:1, 黄:3), Price(250円)) - - Dish(くるみパン, Nutrition(赤:0, 緑:0, 黄:3), Price(150円)) - - Dish(フルーツ, Nutrition(赤:0, 緑:1, 黄:0), Price(150円))` +DishCollection( + Dish(パスタ&ランチ, Nutrition(赤:1, 緑:1, 黄:3), Price(250円)), + Dish(くるみパン, Nutrition(赤:0, 緑:0, 黄:3), Price(150円)), + Dish(フルーツ, Nutrition(赤:0, 緑:1, 黄:0), Price(150円)) +)` ); // expect(taroPlate.dishes[0]).toEqual('パスタ&サラダ'); }); diff --git a/cafe/index.ts b/cafe/index.ts index 7d0dfe6..8c8b4f6 100644 --- a/cafe/index.ts +++ b/cafe/index.ts @@ -9,8 +9,7 @@ class Plate { } toString(): string { - const dishes = this.dishes.map((dish) => ` - ${dish.toString()}`); - return `Plate ${this.name}\n${dishes.join('\n')}`; + return `Plate ${this.name}\n${this.dishes.toString()}`; } totalAmount(): Price { @@ -127,12 +126,13 @@ export class DishCollection { return this.dishes.length; } - all(): Dish[] { - return Array.from(this.dishes); + toString(): string { + const dishes = this.dishes.map((dish) => ` ${dish.toString()}`); + return `DishCollection(\n${dishes.join(',\n')}\n)`; } - map(fn: (value: Dish, index: number) => T): T[] { - return this.dishes.map(fn); + all(): Dish[] { + return Array.from(this.dishes); } first(): Dish | undefined { From 1b5df134b25eb60f8badea9f3f8e5f7c2899fbcd Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Wed, 14 Apr 2021 18:43:13 +0900 Subject: [PATCH 49/63] =?UTF-8?q?Rank=20=E3=81=AB=20isStrongerThan()=20?= =?UTF-8?q?=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/index.ts | 13 ++++++++++++- poker/latest.test.ts | 23 +++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/poker/index.ts b/poker/index.ts index 8b5c17b..751894c 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -148,6 +148,15 @@ class Rank { return this.toString() === other.toString(); } + /** + * other よりも強いランクのときに true を返します + * + * @param other {Rank} + */ + isStrongerThan(other: Rank): boolean { + return this.compareByStrength(other) < 0; + } + private strength(): number { if (this.value == 1) { return 14; @@ -162,6 +171,8 @@ class Rank { * - other のほうが弱い時には、負の値を * - other と this が同じランクのときには、 0 を返します。 * + * sort() の compareFunction に渡すと、配列の先頭が最も強く、末尾が最も弱い順に並び替えます。 + * * @param other {Rank} */ compareByStrength(other: Rank): number { @@ -481,7 +492,7 @@ class PokerHandCollection { } all(): IPokerHand[] { - return Array.from(this.pokerHands) + return Array.from(this.pokerHands); } strongestPokerHand(): IPokerHand { diff --git a/poker/latest.test.ts b/poker/latest.test.ts index cfa8e77..fcd3b56 100644 --- a/poker/latest.test.ts +++ b/poker/latest.test.ts @@ -58,6 +58,29 @@ describe('Rank', () => { ).toEqual([ace, king, five, two]); }); }); + + describe('isStrongerThan()', () => { + const ace = new Rank(1); + const two = new Rank(2); + const five = new Rank(5); + const king = new Rank(13); + + it('ace が強い', () => { + expect(ace.isStrongerThan(two)).toBeTruthy(); + expect(ace.isStrongerThan(five)).toBeTruthy(); + expect(ace.isStrongerThan(king)).toBeTruthy(); + }); + + it('2, 5, K は ace より強くない', () => { + expect(two.isStrongerThan(ace)).toBeFalsy(); + expect(five.isStrongerThan(ace)).toBeFalsy(); + expect(king.isStrongerThan(ace)).toBeFalsy(); + }); + + it('同じランクのときは、 false', () => { + expect(ace.isStrongerThan(ace)).toBeFalsy(); + }); + }); }); describe('Suit', () => { From 18bf4a90924c86e3368961d14b1259add5838fd4 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Wed, 14 Apr 2021 18:54:18 +0900 Subject: [PATCH 50/63] =?UTF-8?q?Card=20=E3=81=AB=20isStrongerThan()=20?= =?UTF-8?q?=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/index.ts | 20 ++++++++++++++++++++ poker/latest.test.ts | 17 +++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/poker/index.ts b/poker/index.ts index 751894c..6a6c156 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -103,6 +103,26 @@ class Card { return this.rank.isEqual(other.rank); } + /** + * other よりも強いカードのときに true を返します + * + * @param other {Card} + */ + isStrongerThan(other: Card): boolean { + return this.compareByStrength(other) < 0; + } + + /** + * Cardの強い順に並び替える + * + * - other のほうが強い時には、正の値を + * - other のほうが弱い時には、負の値を + * - other と this が同じランクのときには、 0 を返します。 + * + * sort() の compareFunction に渡すと、配列の先頭が最も強く、末尾が最も弱い順に並び替えます。 + * + * @param other {Card} + */ compareByStrength(other: Card): number { const compareRank = this.rank.compareByStrength(other.rank); diff --git a/poker/latest.test.ts b/poker/latest.test.ts index fcd3b56..730a66f 100644 --- a/poker/latest.test.ts +++ b/poker/latest.test.ts @@ -146,6 +146,23 @@ describe('Card', () => { ).toEqual([card5, card4spade, card4club, card3]); }); }); + + describe('isStrongerThan()', () => { + const card3 = new Card(Suit.Diamond, new Rank(3)); + const card4club = new Card(Suit.Club, new Rank(4)); + const card4spade = new Card(Suit.Spade, new Rank(4)); + const card1 = new Card(Suit.Heart, new Rank(1)); + + it('エースのカードの方が強い', () => { + expect(card1.isStrongerThan(card3)).toBeTruthy(); + expect(card1.isStrongerThan(card4club)).toBeTruthy(); + expect(card1.isStrongerThan(card4spade)).toBeTruthy(); + }); + + it('同じランク(4)のときは、スートで比較してスペードのほうが強い', () => { + expect(card4spade.isStrongerThan(card4club)).toBeTruthy(); + }); + }); }); describe('Hand', () => { From 3937c3115ae3c839ad08f7eb088106248ee07fb0 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Wed, 14 Apr 2021 18:56:02 +0900 Subject: [PATCH 51/63] =?UTF-8?q?Pair=20=E3=81=AE=E3=82=B3=E3=83=B3?= =?UTF-8?q?=E3=82=B9=E3=83=88=E3=83=A9=E3=82=AF=E3=82=BF=E3=81=A7=E3=82=AB?= =?UTF-8?q?=E3=83=BC=E3=83=89=E3=81=AE=E5=BC=B7=E3=81=84=E9=A0=86=E3=81=AB?= =?UTF-8?q?=E4=B8=A6=E3=81=B3=E6=9B=BF=E3=81=88=E3=82=8B=E5=87=A6=E7=90=86?= =?UTF-8?q?=E3=82=92=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/index.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/poker/index.ts b/poker/index.ts index 6a6c156..0e1ccce 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -268,10 +268,9 @@ class Pair { constructor(cardA: Card, cardB: Card) { if (cardA.isSameRank(cardB)) { - this.cards = [cardA, cardB].sort(Card.compareByStrength) as [ - Card, - Card - ]; + this.cards = cardA.isStrongerThan(cardB) + ? [cardA, cardB] + : [cardB, cardA]; } else { throw new Error(`Invalid cards: ${cardA}, ${cardB}`); } From 7f3f850905466be0463c9efe90766a8f951eeefd Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Wed, 14 Apr 2021 18:56:57 +0900 Subject: [PATCH 52/63] =?UTF-8?q?Triple=20=E3=81=AE=E3=82=B3=E3=83=B3?= =?UTF-8?q?=E3=82=B9=E3=83=88=E3=83=A9=E3=82=AF=E3=82=BF=E3=81=A7=E3=82=AB?= =?UTF-8?q?=E3=83=BC=E3=83=89=E3=81=AE=E5=BC=B7=E3=81=84=E9=A0=86=E3=81=AB?= =?UTF-8?q?=E4=B8=A6=E3=81=B3=E6=9B=BF=E3=81=88=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/index.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/poker/index.ts b/poker/index.ts index 0e1ccce..b9de2d1 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -303,7 +303,10 @@ class Triple { constructor(cardA: Card, cardB: Card, cardC: Card) { if (cardA.isSameRank(cardB) && cardB.isSameRank(cardC)) { - this.cards = [cardA, cardB, cardC]; + const [c0, c1, c2] = [cardA, cardB, cardC].sort( + Card.compareByStrength + ); + this.cards = [c0, c1, c2]; } else { throw new Error(`Invalid cards: ${cardA}, ${cardB}, ${cardC}`); } From 4e26ca15879a19e6ce4b77bc2e818dd74e4e9918 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Wed, 14 Apr 2021 19:06:46 +0900 Subject: [PATCH 53/63] =?UTF-8?q?Chapter2=20=E5=AE=8C=E4=BA=86=E6=99=82?= =?UTF-8?q?=E3=81=AE=E3=83=9D=E3=83=BC=E3=82=AB=E3=83=BC=E3=81=AE=E8=A7=A3?= =?UTF-8?q?=E7=AD=94=E4=BE=8B=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/chapter2.snapshot.ts | 320 +++++++++++++++++++++++++++++++++++++ 1 file changed, 320 insertions(+) create mode 100644 poker/chapter2.snapshot.ts diff --git a/poker/chapter2.snapshot.ts b/poker/chapter2.snapshot.ts new file mode 100644 index 0000000..13aca98 --- /dev/null +++ b/poker/chapter2.snapshot.ts @@ -0,0 +1,320 @@ +class Hand { + public readonly cards: Card[]; + + constructor(cards: Card[]) { + if (cards.length != 5) { + throw new Error( + `Invalid the number of cards: expected 5 cards, but got ${cards.length} cards` + ); + } + this.cards = cards; + } + + toString(): string { + return `Hand(${this.cards.toString()})`; + } +} + +class Card { + public readonly suit: Suit; + public readonly rank: Rank; + + constructor(suit: Suit, rank: Rank) { + this.suit = suit; + this.rank = rank; + } + + toString(): string { + return `[${this.suit}${this.rank}]`; + } + + isEqual(other: Card): boolean { + return this.suit.isEqual(other.suit) && this.rank.isEqual(other.rank); + } + + isSameRank(other: Card): boolean { + return this.rank.isEqual(other.rank); + } + + /** + * other よりも強いカードのときに true を返します + * + * @param other {Card} + */ + isStrongerThan(other: Card): boolean { + return this.compareByStrength(other) < 0; + } + + /** + * Cardの強い順に並び替える + * + * - other のほうが強い時には、正の値を + * - other のほうが弱い時には、負の値を + * - other と this が同じランクのときには、 0 を返します。 + * + * sort() の compareFunction に渡すと、配列の先頭が最も強く、末尾が最も弱い順に並び替えます。 + * + * @param other {Card} + */ + compareByStrength(other: Card): number { + const compareRank = this.rank.compareByStrength(other.rank); + + if (compareRank == 0) { + return this.suit.compareByStrength(other.suit); + } else { + return compareRank; + } + } + + static compareByStrength(a: Card, b: Card): number { + return a.compareByStrength(b); + } +} + +class Rank { + private readonly value: number; + + constructor(value: number) { + if (value < 1 || 13 < value || !Number.isInteger(value)) { + throw new Error(`Invalid value of Rank: got ${value}`); + } + + this.value = value; + } + + toString(): string { + switch (this.value) { + case 1: + return 'A'; + case 11: + return 'J'; + case 12: + return 'Q'; + case 13: + return 'K'; + default: + return `${this.value}`; + } + } + + isEqual(other: Rank): boolean { + return this.toString() === other.toString(); + } + + private strength(): number { + if (this.value == 1) { + return 14; + } + return this.value; + } + + /** + * Rankの強い順に並び替える + * + * - other のほうが強い時には、正の値を + * - other のほうが弱い時には、負の値を + * - other と this が同じランクのときには、 0 を返します。 + * + * sort() の compareFunction に渡すと、配列の先頭が最も強く、末尾が最も弱い順に並び替えます。 + * + * @param other {Rank} + */ + compareByStrength(other: Rank): number { + return other.strength() - this.strength(); + } + + static compareByStrength(a: Rank, b: Rank): number { + return a.compareByStrength(b); + } +} + +class Suit { + private readonly value: string; + + private readonly strengthOrder = ['Spade', 'Heart', 'Diamond', 'Club']; + private mapping = { + Spade: '♠', + Heart: '♥', + Diamond: '♦', + Club: '♣', + }; + + private constructor(value: string) { + this.value = value; + } + + toString(): string { + return this.mapping[this.value]; + } + + isEqual(other: Suit): boolean { + return this.toString() === other.toString(); + } + + public static Spade = new Suit('Spade'); + public static Heart = new Suit('Heart'); + public static Diamond = new Suit('Diamond'); + public static Club = new Suit('Club'); + + compareByStrength(other: Suit): number { + const myOrder = this.strengthOrder.indexOf(this.value); + const otherOder = this.strengthOrder.indexOf(other.value); + return myOrder - otherOder; + } + + static compareByStrength(a: Suit, b: Suit): number { + return a.compareByStrength(b); + } +} + +class Pair { + private readonly cards: [Card, Card]; + + constructor(cardA: Card, cardB: Card) { + if (cardA.isSameRank(cardB)) { + this.cards = cardA.isStrongerThan(cardB) + ? [cardA, cardB] + : [cardB, cardA]; + } else { + throw new Error(`Invalid cards: ${cardA}, ${cardB}`); + } + } + + get rank(): Rank { + return this.cards[0].rank; + } + + get suits(): Suit[] { + return this.cards.map((card) => card.suit); + } + + toString(): string { + return `Pair(${this.rank}, ${this.suits.join(', ')})`; + } + + isSameRank(other: Pair): boolean { + return this.rank.isEqual(other.rank); + } + + isStrongerThan(other: Pair): boolean { + return this.compareByStrength(other) < 0; + } + + compareByStrength(other: Pair): number { + // TODO: 相手のPairとランクが同じ場合には、スートで比較する + return this.rank.compareByStrength(other.rank); + } +} + +class Triple { + private readonly cards: [Card, Card, Card]; + + constructor(cardA: Card, cardB: Card, cardC: Card) { + if (cardA.isSameRank(cardB) && cardB.isSameRank(cardC)) { + const [c0, c1, c2] = [cardA, cardB, cardC].sort( + Card.compareByStrength + ); + this.cards = [c0, c1, c2]; + } else { + throw new Error(`Invalid cards: ${cardA}, ${cardB}, ${cardC}`); + } + } + + get rank(): Rank { + return this.cards[0].rank; + } + + get suits(): Suit[] { + return this.cards.map((card) => card.suit).sort(Suit.compareByStrength); + } + + toString(): string { + return `Triple(${this.rank}, ${this.suits.join(', ')})`; + } + + compareByStrength(other: Triple): number { + // TODO: 相手のPairとランクが同じ場合には、スートで比較する + return this.rank.compareByStrength(other.rank); + } +} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +interface IPokerHand {} + +class OnePairPokerHand implements IPokerHand { + private readonly pair: Pair; + + constructor(pair: Pair) { + this.pair = pair; + } + + toString(): string { + return `OnePair[${this.pair.toString()}]`; + } +} + +class TwoPairPokerHand implements IPokerHand { + private readonly pairs: [Pair, Pair]; + + constructor(pairA: Pair, pairB: Pair) { + if (pairA.isSameRank(pairB)) { + throw new Error(`Invalid pairs: pairA=${pairA}, pairB=${pairB}`); + } + + this.pairs = pairA.isStrongerThan(pairB) + ? [pairA, pairB] + : [pairB, pairA]; + } + + toString(): string { + const pairs = this.pairs.map((pair) => pair.toString()); + return `TwoPair[${pairs.join(', ')}]`; + } + + strongerPair(): Pair { + return this.pairs[0]; + } + + weakPair(): Pair { + return this.pairs[1]; + } +} + +class ThreeCardPokerHand implements IPokerHand { + private readonly triple: Triple; + + constructor(triple: Triple) { + this.triple = triple; + } + + toString(): string { + return `ThreeCard[${this.triple.toString()}]`; + } +} + +class FullHousePokerHand implements IPokerHand { + private readonly pair: Pair; + private readonly triple: Triple; + + constructor(pair: Pair, triple: Triple) { + if (pair.rank.isEqual(triple.rank)) { + throw new Error(`Invalid pair and triple: ${pair}, ${triple}`); + } + + this.pair = pair; + this.triple = triple; + } + + toString(): string { + return `FullHouse[${this.pair.toString()}, ${this.triple.toString()}]`; + } +} + +export { + Hand, + IPokerHand, + OnePairPokerHand, + TwoPairPokerHand, + ThreeCardPokerHand, + FullHousePokerHand, +}; From aa4dd7242f9b31df76b1a550e2327abcd0f71314 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Wed, 14 Apr 2021 20:58:23 +0900 Subject: [PATCH 54/63] =?UTF-8?q?Pair,=20Triple=20=E3=82=92=E5=88=A9?= =?UTF-8?q?=E7=94=A8=E3=81=97=E3=81=AA=E3=81=84=E5=BD=A2=E3=81=A7=20OnePai?= =?UTF-8?q?r,=20ThreeCard=20=E3=82=92=E6=A7=8B=E6=88=90=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/chapter2.snapshot.ts | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/poker/chapter2.snapshot.ts b/poker/chapter2.snapshot.ts index 13aca98..cf7e4c5 100644 --- a/poker/chapter2.snapshot.ts +++ b/poker/chapter2.snapshot.ts @@ -253,6 +253,24 @@ class OnePairPokerHand implements IPokerHand { } } +class OnePairPokerHand_ implements IPokerHand { + private readonly cards: [Card, Card]; + + constructor(cardA: Card, cardB: Card) { + if (cardA.isSameRank(cardB)) { + this.cards = cardA.isStrongerThan(cardB) + ? [cardA, cardB] + : [cardB, cardA]; + } else { + throw new Error(`Invalid cards: ${cardA}, ${cardB}`); + } + } + toString(): string { + const cards = this.cards.map((card) => card.toString()); + return `OnePair[${cards.join(', ')}]`; + } +} + class TwoPairPokerHand implements IPokerHand { private readonly pairs: [Pair, Pair]; @@ -292,6 +310,25 @@ class ThreeCardPokerHand implements IPokerHand { } } +class ThreeCardPokerHand_ implements IPokerHand { + private readonly cards: [Card, Card, Card]; + + constructor(cardA: Card, cardB: Card, cardC: Card) { + if (cardA.isSameRank(cardB) && cardA.isSameRank(cardC)) { + const [c0, c1, c2] = [cardA, cardB, cardC].sort( + Card.compareByStrength + ); + this.cards = [c0, c1, c2]; + } else { + throw new Error(`Invalid cards: ${cardA}, ${cardB}`); + } + } + toString(): string { + const cards = this.cards.map((card) => card.toString()); + return `OnePair[${cards.join(', ')}]`; + } +} + class FullHousePokerHand implements IPokerHand { private readonly pair: Pair; private readonly triple: Triple; From e81b496562479fd742a91ebdcc4e5fe7fa660ca8 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Wed, 14 Apr 2021 22:20:08 +0900 Subject: [PATCH 55/63] =?UTF-8?q?Chapter2=20=E3=83=9D=E3=83=BC=E3=82=AB?= =?UTF-8?q?=E3=83=BC=E8=A7=A3=E7=AD=94=E4=BE=8B=E3=81=AE=E5=8F=96=E3=82=8A?= =?UTF-8?q?=E3=81=86=E3=82=8B=E5=BD=B9=E3=82=92=E5=85=A8=E3=81=A6=E5=88=97?= =?UTF-8?q?=E6=8C=99=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/chapter2.snapshot.ts | 48 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/poker/chapter2.snapshot.ts b/poker/chapter2.snapshot.ts index cf7e4c5..2cd09e9 100644 --- a/poker/chapter2.snapshot.ts +++ b/poker/chapter2.snapshot.ts @@ -347,6 +347,54 @@ class FullHousePokerHand implements IPokerHand { } } +const chapter2taro = () => { + const diamond3 = new Card(Suit.Diamond, new Rank(3)); + const club3 = new Card(Suit.Club, new Rank(3)); + const spade11 = new Card(Suit.Spade, new Rank(11)); + const heart4 = new Card(Suit.Heart, new Rank(4)); + const diamond1 = new Card(Suit.Diamond, new Rank(1)); + + const hand = new Hand([diamond3, club3, spade11, heart4, diamond1]); + + const candidatePokerHands = [ + new OnePairPokerHand(new Pair(diamond3, club3)), + ]; +}; + +const chapter2jiro = () => { + const diamond3 = new Card(Suit.Diamond, new Rank(3)); + const club3 = new Card(Suit.Club, new Rank(3)); + const spade11 = new Card(Suit.Club, new Rank(11)); + const heart11 = new Card(Suit.Heart, new Rank(11)); + const diamond11 = new Card(Suit.Diamond, new Rank(11)); + + const hand = new Hand([diamond3, club3, spade11, heart11, diamond11]); + + const candidatePokerHands = [ + new OnePairPokerHand(new Pair(diamond3, club3)), + new OnePairPokerHand(new Pair(spade11, heart11)), + new OnePairPokerHand(new Pair(spade11, diamond11)), + new OnePairPokerHand(new Pair(heart11, diamond11)), + new TwoPairPokerHand( + new Pair(diamond3, club3), + new Pair(spade11, heart11) + ), + new TwoPairPokerHand( + new Pair(diamond3, club3), + new Pair(spade11, diamond11) + ), + new TwoPairPokerHand( + new Pair(diamond3, club3), + new Pair(heart11, diamond11) + ), + new ThreeCardPokerHand(new Triple(spade11, heart11, diamond11)), + new FullHousePokerHand( + new Pair(diamond3, club3), + new Triple(spade11, heart11, diamond11) + ), + ]; +}; + export { Hand, IPokerHand, From 8c96edf6284fde7ded615653a3a712769451008f Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sun, 18 Apr 2021 13:58:10 +0900 Subject: [PATCH 56/63] =?UTF-8?q?FullHousePokerHandFactory=20=E3=81=A7=202?= =?UTF-8?q?=E6=9E=9A=E3=81=A83=E6=9E=9A=20=E3=81=AE=E7=B5=84=E3=81=A7?= =?UTF-8?q?=E3=81=82=E3=82=8B=E3=81=93=E3=81=A8=E3=82=92=E3=83=81=E3=82=A7?= =?UTF-8?q?=E3=83=83=E3=82=AF=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/index.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/poker/index.ts b/poker/index.ts index b9de2d1..feff02c 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -572,10 +572,12 @@ class FullHousePokerHandFactory implements IPokerHandFactory { const cardsA = hand.cards.filterByRank(rankA); const cardsB = hand.cards.filterByRank(rankB); - if (cardsA.count() == 2) { + if (cardsA.count() == 2 && cardsB.count() == 3) { return [this.buildFullHouse(cardsA.all(), cardsB.all())]; - } else { + } else if (cardsA.count() == 3 && cardsB.count() == 2) { return [this.buildFullHouse(cardsB.all(), cardsA.all())]; + } else { + return []; } } From 7b6ad0bd43662b4c3c192cc203311e981cdc4e62 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sun, 18 Apr 2021 14:00:46 +0900 Subject: [PATCH 57/63] Rename PokerHandName -> PokerHandType --- poker/index.ts | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/poker/index.ts b/poker/index.ts index feff02c..3b85f60 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -332,7 +332,7 @@ class Triple { export { Pair, Triple }; -class PokerHandName { +class PokerHandType { private readonly value: string; private static readonly pokerHandOrder = [ 'FullHousePokerHand', @@ -345,30 +345,30 @@ class PokerHandName { this.value = value; } - public static OnePairPokerHand = new PokerHandName('OnePairPokerHand'); - public static TwoPairPokerHand = new PokerHandName('TwoPairPokerHand'); - public static ThreeCardPokerHand = new PokerHandName('ThreeCardPokerHand'); - public static FullHousePokerHand = new PokerHandName('FullHousePokerHand'); + public static OnePairPokerHand = new PokerHandType('OnePairPokerHand'); + public static TwoPairPokerHand = new PokerHandType('TwoPairPokerHand'); + public static ThreeCardPokerHand = new PokerHandType('ThreeCardPokerHand'); + public static FullHousePokerHand = new PokerHandType('FullHousePokerHand'); - compareByStrength(other: PokerHandName): number { - const myOrder = PokerHandName.pokerHandOrder.indexOf(this.value); - const otherOrder = PokerHandName.pokerHandOrder.indexOf(other.value); + compareByStrength(other: PokerHandType): number { + const myOrder = PokerHandType.pokerHandOrder.indexOf(this.value); + const otherOrder = PokerHandType.pokerHandOrder.indexOf(other.value); return myOrder - otherOrder; } - static compareByStrength(a: PokerHandName, b: PokerHandName): number { + static compareByStrength(a: PokerHandType, b: PokerHandType): number { return a.compareByStrength(b); } } // eslint-disable-next-line @typescript-eslint/no-empty-interface interface IPokerHand { - name: PokerHandName; + name: PokerHandType; compareByStrength(other: IPokerHand): number; } class OnePairPokerHand implements IPokerHand { - public readonly name = PokerHandName.OnePairPokerHand; + public readonly name = PokerHandType.OnePairPokerHand; private readonly pair: Pair; constructor(pair: Pair) { @@ -393,7 +393,7 @@ class OnePairPokerHand implements IPokerHand { } class TwoPairPokerHand implements IPokerHand { - public readonly name = PokerHandName.TwoPairPokerHand; + public readonly name = PokerHandType.TwoPairPokerHand; private readonly pairs: [Pair, Pair]; constructor(pairA: Pair, pairB: Pair) { @@ -442,7 +442,7 @@ class TwoPairPokerHand implements IPokerHand { } class ThreeCardPokerHand implements IPokerHand { - public readonly name = PokerHandName.ThreeCardPokerHand; + public readonly name = PokerHandType.ThreeCardPokerHand; private readonly triple: Triple; constructor(triple: Triple) { @@ -467,7 +467,7 @@ class ThreeCardPokerHand implements IPokerHand { } class FullHousePokerHand implements IPokerHand { - public readonly name = PokerHandName.FullHousePokerHand; + public readonly name = PokerHandType.FullHousePokerHand; private readonly pair: Pair; private readonly triple: Triple; From b950117e1b71f5327e8183846ff22b331e3d624e Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sun, 18 Apr 2021 14:01:37 +0900 Subject: [PATCH 58/63] =?UTF-8?q?=E6=9C=AA=E7=9F=A5=E3=81=AESuit=E3=81=8C?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=E3=81=95=E3=82=8C=E3=81=9F=E3=81=A8=E3=81=8D?= =?UTF-8?q?=E3=81=AB=E4=BE=8B=E5=A4=96=E3=82=92=E6=8A=95=E3=81=92=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/index.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/poker/index.ts b/poker/index.ts index 3b85f60..f76f031 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -234,6 +234,9 @@ class Suit { }; private constructor(value: string) { + if (!this.mapping[value]) { + throw new Error(`Unknown value of Suit: ${value}`); + } this.value = value; } From 5c372ab415aa5eb8b483b07312d9ffff372b6d6d Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Sun, 18 Apr 2021 14:06:40 +0900 Subject: [PATCH 59/63] =?UTF-8?q?CardCollection=20=E3=82=92=20Card=20?= =?UTF-8?q?=E3=81=AE=E5=BC=B7=E3=81=95=E9=A0=86=E3=81=AB=E4=B8=A6=E3=81=B3?= =?UTF-8?q?=E6=9B=BF=E3=81=88=E3=82=8B=20&=20=E4=B8=80=E8=87=B4=E6=AF=94?= =?UTF-8?q?=E8=BC=83=E3=82=92=E3=82=BD=E3=83=BC=E3=83=88=E6=B8=88=E3=81=BF?= =?UTF-8?q?=E3=81=A7=E3=81=82=E3=82=8B=E3=81=93=E3=81=A8=E3=82=92=E5=89=8D?= =?UTF-8?q?=E6=8F=90=E3=81=AB=E6=9B=B8=E3=81=8D=E6=8F=9B=E3=81=88=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/chapter1.test.ts | 2 +- poker/index.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/poker/chapter1.test.ts b/poker/chapter1.test.ts index cc471bc..498c3ba 100644 --- a/poker/chapter1.test.ts +++ b/poker/chapter1.test.ts @@ -32,7 +32,7 @@ describe('Chapter1: ポーカー', () => { ]); expect(`${hand}`).toEqual( - 'Hand(CardCollection([♦3], [♣3], [♠J], [♥4], [♦A]))' + 'Hand(CardCollection([♦A], [♠J], [♥4], [♦3], [♣3]))' ); }); }); diff --git a/poker/index.ts b/poker/index.ts index f76f031..870d7f2 100644 --- a/poker/index.ts +++ b/poker/index.ts @@ -27,7 +27,7 @@ class CardCollection { private readonly cards: Card[]; constructor(cards: Card[] = []) { - this.cards = Array.from(cards); + this.cards = Array.from(cards).sort(Card.compareByStrength); } contain(other: Card): boolean { @@ -35,8 +35,8 @@ class CardCollection { } isEqual(other: CardCollection): boolean { - return this.cards.every((card) => { - return other.contain(card); + return this.cards.every((card, i) => { + return card.isEqual(other.cards[i]); }); } From cec5cf7477a6a13107ab1713528376545522a766 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Tue, 4 May 2021 22:11:01 +0900 Subject: [PATCH 60/63] ignore .idea directory --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 30a39ca..c40e978 100644 --- a/.gitignore +++ b/.gitignore @@ -114,3 +114,6 @@ dist .vscode-test # End of https://www.toptal.com/developers/gitignore/api/node + +# JetBrains IDE +.idea/ From f27d051befab2bcd4eaae5b54e748e92a6064f9c Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Tue, 4 May 2021 22:11:24 +0900 Subject: [PATCH 61/63] =?UTF-8?q?AvailableDiscountCollection=20=E3=81=A8?= =?UTF-8?q?=20finxMaxDiscount()=20=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cafe/index.ts | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/cafe/index.ts b/cafe/index.ts index 8c8b4f6..1104025 100644 --- a/cafe/index.ts +++ b/cafe/index.ts @@ -174,6 +174,10 @@ class DiscountAmount { return new DiscountAmount(this.value + other.value); } + compareTo(other: DiscountAmount): number { + return this.value - other.value + } + static ZERO = new DiscountAmount(0); static buildFromPrice(price: Price, rate: number): DiscountAmount { @@ -241,6 +245,7 @@ class Discount { interface IDiscount { amount(): DiscountAmount; + compareAmount(other: IDiscount): number; } interface IDiscountFactory { @@ -262,6 +267,10 @@ class NutritionBalanceDiscount implements IDiscount { NutritionBalanceDiscount.DISCOUNT_RATE ); } + + compareAmount(other: IDiscount): number { + return this.amount().compareTo(other.amount()) + } } class NutritionBalanceDiscountFactory implements IDiscountFactory { @@ -288,6 +297,9 @@ class NiceCalorieDiscount implements IDiscount { amount(): DiscountAmount { return new DiscountAmount(50); } + compareAmount(other: IDiscount): number { + return this.amount().compareTo(other.amount()) + } } class NiceCalorieDiscountFactory implements IDiscountFactory { @@ -310,6 +322,9 @@ class LowCarbonDiscount implements IDiscount { amount(): DiscountAmount { return new DiscountAmount(20); } + compareAmount(other: IDiscount): number { + return this.amount().compareTo(other.amount()) + } } class LowCarbonDiscountFactory implements IDiscountFactory { @@ -328,13 +343,23 @@ class LowCarbonDiscountFactory implements IDiscountFactory { } } -class DiscountCollection { +class AvailableDiscountCollection { private readonly discounts: IDiscount[]; constructor(discounts: IDiscount[]) { this.discounts = Array.from(discounts); } + findMaxDiscount(): IDiscount | null { + const sorted = this.discounts.sort((a,b) => a.compareAmount(b)); + return sorted[sorted.length] || null; + } + + _findMaxDiscount(): IDiscount | null { + const sorted = this.discounts.sort((a,b) => a.amount().value - b.amount().value); + return sorted[sorted.length] || null; + } + all(): IDiscount[] { return Array.from(this.discounts); } @@ -353,7 +378,7 @@ class DiscountCollectionFactory { new LowCarbonDiscountFactory(), ]; - build(plate: Plate): DiscountCollection { + build(plate: Plate): AvailableDiscountCollection { const discounts: IDiscount[] = []; this.factories.forEach((factory) => { @@ -362,15 +387,15 @@ class DiscountCollectionFactory { } }); - return new DiscountCollection(discounts); + return new AvailableDiscountCollection(discounts); } } class Order { private readonly dishes: DishCollection; - private readonly discounts: DiscountCollection; + private readonly discounts: AvailableDiscountCollection; - constructor(dishes: DishCollection, discounts: DiscountCollection) { + constructor(dishes: DishCollection, discounts: AvailableDiscountCollection) { this.dishes = dishes; this.discounts = discounts; } @@ -396,7 +421,7 @@ export { LowCarbonDiscount, NiceCalorieDiscount, NutritionBalanceDiscount, - DiscountCollection, + AvailableDiscountCollection, DiscountCollectionFactory, Order, }; From 28d91a069a448992ec4f13f07b33d9bb278d7770 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Wed, 5 May 2021 08:19:54 +0900 Subject: [PATCH 62/63] =?UTF-8?q?Discount#amount()=20=E3=82=92=20(?= =?UTF-8?q?=E3=81=84=E3=81=A3=E3=81=9F=E3=82=93)=20number=20=E3=81=AB?= =?UTF-8?q?=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cafe/index.ts | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/cafe/index.ts b/cafe/index.ts index 1104025..eb0779f 100644 --- a/cafe/index.ts +++ b/cafe/index.ts @@ -244,7 +244,7 @@ class Discount { } interface IDiscount { - amount(): DiscountAmount; + amount(): number; compareAmount(other: IDiscount): number; } @@ -261,15 +261,15 @@ class NutritionBalanceDiscount implements IDiscount { this.targetDish = targetDish; } - amount(): DiscountAmount { + amount(): number { return DiscountAmount.buildFromPrice( this.targetDish.price, NutritionBalanceDiscount.DISCOUNT_RATE - ); + ).value } compareAmount(other: IDiscount): number { - return this.amount().compareTo(other.amount()) + return this.amount() - other.amount() } } @@ -294,11 +294,11 @@ class NutritionBalanceDiscountFactory implements IDiscountFactory { } class NiceCalorieDiscount implements IDiscount { - amount(): DiscountAmount { - return new DiscountAmount(50); + amount(): number { + return 50 } compareAmount(other: IDiscount): number { - return this.amount().compareTo(other.amount()) + return this.amount() - other.amount() } } @@ -319,11 +319,11 @@ class NiceCalorieDiscountFactory implements IDiscountFactory { } class LowCarbonDiscount implements IDiscount { - amount(): DiscountAmount { - return new DiscountAmount(20); + amount(): number { + return 20 } compareAmount(other: IDiscount): number { - return this.amount().compareTo(other.amount()) + return this.amount() - other.amount() } } @@ -366,7 +366,7 @@ class AvailableDiscountCollection { totalAmount(): DiscountAmount { return this.discounts.reduce((amount, discount) => { - return amount.add(discount.amount()); + return amount.add(new DiscountAmount(discount.amount())); }, DiscountAmount.ZERO); } } From 84468e39ab7d947e383f512af5d7f0838966e30f Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Wed, 5 May 2021 09:04:14 +0900 Subject: [PATCH 63/63] =?UTF-8?q?=E5=89=B2=E5=BC=95=E9=87=91=E9=A1=8D?= =?UTF-8?q?=E3=81=AE=E8=A8=88=E7=AE=97=E5=87=A6=E7=90=86=E3=82=92=E5=AE=9F?= =?UTF-8?q?=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cafe/index.ts | 55 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 10 deletions(-) diff --git a/cafe/index.ts b/cafe/index.ts index eb0779f..9296200 100644 --- a/cafe/index.ts +++ b/cafe/index.ts @@ -175,7 +175,7 @@ class DiscountAmount { } compareTo(other: DiscountAmount): number { - return this.value - other.value + return this.value - other.value; } static ZERO = new DiscountAmount(0); @@ -265,11 +265,11 @@ class NutritionBalanceDiscount implements IDiscount { return DiscountAmount.buildFromPrice( this.targetDish.price, NutritionBalanceDiscount.DISCOUNT_RATE - ).value + ).value; } compareAmount(other: IDiscount): number { - return this.amount() - other.amount() + return this.amount() - other.amount(); } } @@ -295,10 +295,10 @@ class NutritionBalanceDiscountFactory implements IDiscountFactory { class NiceCalorieDiscount implements IDiscount { amount(): number { - return 50 + return 50; } compareAmount(other: IDiscount): number { - return this.amount() - other.amount() + return this.amount() - other.amount(); } } @@ -320,10 +320,10 @@ class NiceCalorieDiscountFactory implements IDiscountFactory { class LowCarbonDiscount implements IDiscount { amount(): number { - return 20 + return 20; } compareAmount(other: IDiscount): number { - return this.amount() - other.amount() + return this.amount() - other.amount(); } } @@ -343,6 +343,38 @@ class LowCarbonDiscountFactory implements IDiscountFactory { } } +function calcPaymentAmount(plate: Plate): number { + // プレートを下記のような形で作成して、この関数を呼び出す + // const pasta = new Dish('パスタ&ランチ', new Price(250), new Nutrition(1, 1, 3)); + // const plate = new Plate('次郎のプレート', [pasta, bread, dessert]); + const totalDishAmount = 550; // plate.totalDishAmount() のように取り出したい + + // プレートの持つ Dish の中から、バランス配慮セット割引の対象料理を選択する + // (ここでは疑似的に フルーツの Dish を用意する) + const dessert = new Dish( + 'フルーツ', + new Price(150), + new Nutrition(0, 1, 0) + ); + + // plate に対して適用可能な割引オブジェクトの集合を用意して + const availableDiscounts: IDiscount[] = [ + new LowCarbonDiscount(), + new NiceCalorieDiscount(), + new NutritionBalanceDiscount(dessert), + ]; + + // それを割引金額順に並び替えて + const sortedDiscounts = availableDiscounts.sort( + (a, b) => a.amount() - b.amount() + ); + // 一番最後 (=最大の割引額) の要素を取り出す + const discount = sortedDiscounts[sortedDiscounts.length]; + + // Dishの合計金額から割引金額を差し引く + return totalDishAmount - (discount ? discount.amount() : 0); +} + class AvailableDiscountCollection { private readonly discounts: IDiscount[]; @@ -351,12 +383,12 @@ class AvailableDiscountCollection { } findMaxDiscount(): IDiscount | null { - const sorted = this.discounts.sort((a,b) => a.compareAmount(b)); + const sorted = this.discounts.sort((a, b) => a.compareAmount(b)); return sorted[sorted.length] || null; } _findMaxDiscount(): IDiscount | null { - const sorted = this.discounts.sort((a,b) => a.amount().value - b.amount().value); + const sorted = this.discounts.sort((a, b) => a.amount() - b.amount()); return sorted[sorted.length] || null; } @@ -395,7 +427,10 @@ class Order { private readonly dishes: DishCollection; private readonly discounts: AvailableDiscountCollection; - constructor(dishes: DishCollection, discounts: AvailableDiscountCollection) { + constructor( + dishes: DishCollection, + discounts: AvailableDiscountCollection + ) { this.dishes = dishes; this.discounts = discounts; }